From 668cd9729f8f1a35ebd6eb95bec9b612b7596f16 Mon Sep 17 00:00:00 2001 From: unknown Date: Tue, 29 Jul 2003 16:59:46 +0300 Subject: prevented finding references in item_list for non-SELECT st_select_lex (fixed BUG#943) mysql-test/r/subselect.result: test for bug 943 mysql-test/t/subselect.test: test for bug 943 sql/item.cc: bool field changed with enum prevented finding references in item_list for non-SELECT st_select_lex sql/sql_lex.cc: bool field changed with enum sql/sql_lex.h: bool field changed with enum sql/sql_parse.cc: all subqueries and UNION parts marked as SELECT sql/sql_yacc.yy: bool field changed with enum PRIMARY SELECT command st_select_lex marked as SELECT --- sql/item.cc | 11 +++++++---- sql/sql_lex.cc | 3 ++- sql/sql_lex.h | 17 +++++++++++++++-- sql/sql_parse.cc | 2 ++ sql/sql_yacc.yy | 13 +++++++++---- 5 files changed, 35 insertions(+), 11 deletions(-) (limited to 'sql') diff --git a/sql/item.cc b/sql/item.cc index 072dec4e6a6..db9708c9f21 100644 --- a/sql/item.cc +++ b/sql/item.cc @@ -862,7 +862,7 @@ bool Item_field::fix_fields(THD *thd, TABLE_LIST *tables, Item **ref) sl= sl->outer_select()) { table_list= (last= sl)->get_table_list(); - if (sl->insert_select && table_list) + if (sl->resolve_mode == SELECT_LEX::INSERT_MODE && table_list) { // it is primary INSERT st_select_lex => skip first table resolving table_list= table_list->next; @@ -871,7 +871,8 @@ bool Item_field::fix_fields(THD *thd, TABLE_LIST *tables, Item **ref) table_list, &where, 0)) != not_found_field) break; - if ((refer= find_item_in_list(this, sl->item_list, &counter, + if (sl->resolve_mode == SELECT_LEX::SELECT_MODE && + (refer= find_item_in_list(this, sl->item_list, &counter, REPORT_EXCEPT_NOT_FOUND)) != (Item **) not_found_item) break; @@ -1348,13 +1349,15 @@ bool Item_ref::fix_fields(THD *thd,TABLE_LIST *tables, Item **reference) SELECT_LEX *last=0; for ( ; sl ; sl= sl->outer_select()) { - if ((ref= find_item_in_list(this, (last= sl)->item_list, + last= sl; + if (sl->resolve_mode == SELECT_LEX::SELECT_MODE && + (ref= find_item_in_list(this, sl->item_list, &counter, REPORT_EXCEPT_NOT_FOUND)) != (Item **)not_found_item) break; table_list= sl->get_table_list(); - if (sl->insert_select && table_list) + if (sl->resolve_mode == SELECT_LEX::INSERT_MODE && table_list) { // it is primary INSERT st_select_lex => skip first table resolving table_list= table_list->next; diff --git a/sql/sql_lex.cc b/sql/sql_lex.cc index 16ebd758639..65469800a54 100644 --- a/sql/sql_lex.cc +++ b/sql/sql_lex.cc @@ -986,7 +986,8 @@ void st_select_lex::init_query() join= 0; where= 0; olap= UNSPECIFIED_OLAP_TYPE; - insert_select= having_fix_field= 0; + having_fix_field= 0; + resolve_mode= NOMATTER_MODE; with_wild= 0; } diff --git a/sql/sql_lex.h b/sql/sql_lex.h index faf7e16e54a..f9c0aec2fbc 100644 --- a/sql/sql_lex.h +++ b/sql/sql_lex.h @@ -360,14 +360,27 @@ public: bool braces; /* SELECT ... UNION (SELECT ... ) <- this braces */ /* TRUE when having fix field called in processing of this SELECT */ bool having_fix_field; + /* - TRUE for primary st_select_lex structure of simple INSERT/REPLACE + SELECT for SELECT command st_select_lex. Used to privent scaning + item_list of non-SELECT st_select_lex (no sense find to finding + reference in it (all should be in tables, it is dangerouse due + to order of fix_fields calling for non-SELECTs commands (item list + can be not fix_fieldsd)). This value will be assigned for + primary select (sql_yac.yy) and for any subquery and + UNION SELECT (sql_parse.cc mysql_new_select()) + + + INSERT for primary st_select_lex structure of simple INSERT/REPLACE (used for name resolution, see Item_fiels & Item_ref fix_fields, FALSE for INSERT/REPLACE ... SELECT, because it's st_select_lex->table_list will be preprocessed (first table removed) before passing to handle_select) + + NOMATTER for other */ - bool insert_select; + enum {NOMATTER_MODE, SELECT_MODE, INSERT_MODE} resolve_mode; + void init_query(); void init_select(); diff --git a/sql/sql_parse.cc b/sql/sql_parse.cc index 820bf3d73cc..9a62607bf93 100644 --- a/sql/sql_parse.cc +++ b/sql/sql_parse.cc @@ -3550,6 +3550,7 @@ mysql_new_select(LEX *lex, bool move_down) unit->link_prev= 0; unit->return_to= lex->current_select; select_lex->include_down(unit); + // TODO: assign resolve_mode for fake subquery after merging with new tree } else select_lex->include_neighbour(lex->current_select); @@ -3557,6 +3558,7 @@ mysql_new_select(LEX *lex, bool move_down) select_lex->master_unit()->global_parameters= select_lex; select_lex->include_global((st_select_lex_node**)&lex->all_selects_list); lex->current_select= select_lex; + select_lex->resolve_mode= SELECT_LEX::SELECT_MODE; return 0; } diff --git a/sql/sql_yacc.yy b/sql/sql_yacc.yy index a5ac04dc775..38df3bf3a06 100644 --- a/sql/sql_yacc.yy +++ b/sql/sql_yacc.yy @@ -1910,7 +1910,12 @@ opt_ignore_leaves: select: - select_init { Lex->sql_command=SQLCOM_SELECT; }; + select_init + { + LEX *lex= Lex; + lex->sql_command= SQLCOM_SELECT; + lex->select_lex.resolve_mode= SELECT_LEX::SELECT_MODE; + }; /* Need select_init2 for subselects. */ select_init: @@ -3401,7 +3406,7 @@ insert: lex->sql_command = SQLCOM_INSERT; /* for subselects */ lex->lock_option= (using_update_log) ? TL_READ_NO_INSERT : TL_READ; - lex->select_lex.insert_select= 1; + lex->select_lex.resolve_mode= SELECT_LEX::INSERT_MODE; } insert_lock_option opt_ignore insert2 { @@ -3417,7 +3422,7 @@ replace: LEX *lex=Lex; lex->sql_command = SQLCOM_REPLACE; lex->duplicates= DUP_REPLACE; - lex->select_lex.insert_select= 1; + lex->select_lex.resolve_mode= SELECT_LEX::INSERT_MODE; } replace_lock_option insert2 { @@ -3486,7 +3491,7 @@ insert_values: it is not simple select => table list will be preprocessed before passing to handle_select */ - lex->select_lex.insert_select= 0; + lex->select_lex.resolve_mode= SELECT_LEX::NOMATTER_MODE; lex->current_select->parsing_place= SELECT_LEX_NODE::SELECT_LIST; } select_options select_item_list -- cgit v1.2.1