diff options
author | unknown <bell@sanja.is.com.ua> | 2002-11-05 01:10:36 +0200 |
---|---|---|
committer | unknown <bell@sanja.is.com.ua> | 2002-11-05 01:10:36 +0200 |
commit | 1f176ab22603460be500e74e968bb8e72796ff93 (patch) | |
tree | 3fca24258dacd11814e356949bec53bdd299a208 | |
parent | b749585481d63b3e94e4c7258ea3ca87c340f117 (diff) | |
parent | 1b26dbbda09c1dbefda043b990ba1ca674e33ac9 (diff) | |
download | mariadb-git-1f176ab22603460be500e74e968bb8e72796ff93.tar.gz |
Merge sanja.is.com.ua:/home/bell/mysql/mysql-4.1
into sanja.is.com.ua:/home/bell/mysql/work-pointer-4.1
-rw-r--r-- | sql/item.cc | 53 | ||||
-rw-r--r-- | sql/item_subselect.cc | 18 | ||||
-rw-r--r-- | sql/item_sum.cc | 5 | ||||
-rw-r--r-- | sql/mysql_priv.h | 19 | ||||
-rw-r--r-- | sql/sql_base.cc | 12 | ||||
-rw-r--r-- | sql/sql_cache.cc | 6 | ||||
-rw-r--r-- | sql/sql_delete.cc | 7 | ||||
-rw-r--r-- | sql/sql_derived.cc | 4 | ||||
-rw-r--r-- | sql/sql_lex.cc | 172 | ||||
-rw-r--r-- | sql/sql_lex.h | 92 | ||||
-rw-r--r-- | sql/sql_parse.cc | 44 | ||||
-rw-r--r-- | sql/sql_prepare.cc | 4 | ||||
-rw-r--r-- | sql/sql_repl.cc | 4 | ||||
-rw-r--r-- | sql/sql_select.cc | 28 | ||||
-rw-r--r-- | sql/sql_union.cc | 27 | ||||
-rw-r--r-- | sql/sql_update.cc | 6 | ||||
-rw-r--r-- | sql/sql_yacc.yy | 349 |
17 files changed, 553 insertions, 297 deletions
diff --git a/sql/item.cc b/sql/item.cc index 7673aaf097e..037e57b2b8a 100644 --- a/sql/item.cc +++ b/sql/item.cc @@ -441,12 +441,11 @@ bool Item_field::fix_fields(THD *thd, TABLE_LIST *tables, Item **ref) cause error ER_NON_UNIQ_ERROR in find_field_in_tables. */ SELECT_LEX *last= 0; - for (SELECT_LEX *sl= thd->lex.select->outer_select(); + for (SELECT_LEX *sl= thd->lex.current_select->outer_select(); sl; sl= sl->outer_select()) if ((tmp= find_field_in_tables(thd, this, - (TABLE_LIST*) - (last= sl)->table_list.first, + (last= sl)->get_table_list(), 0)) != not_found_field) break; if (!tmp) @@ -464,20 +463,7 @@ bool Item_field::fix_fields(THD *thd, TABLE_LIST *tables, Item **ref) Mark all selects from resolved to 1 before select where was found table as depended (of select where was found table) */ - for (SELECT_LEX *s= thd->lex.select; - s &&s != last; - s= s->outer_select()) - if( !s->depended ) - { - // Select is depended of outer select - s->depended= s->master_unit()->depended= 1; - //Tables will be reopened many times - for (TABLE_LIST *tbl= - (TABLE_LIST*)s->table_list.first; - tbl; - tbl= tbl->next) - tbl->shared= 1; - } + thd->lex.current_select->mark_as_dependent(last); } } else if (!tmp) @@ -822,9 +808,11 @@ bool Item_ref::fix_fields(THD *thd,TABLE_LIST *tables, Item **reference) { if (!ref) { - SELECT_LEX *sl=thd->lex.select->outer_select(); - if ((ref= find_item_in_list(this, thd->lex.select->item_list, - (sl ? REPORT_EXCEPT_NOT_FOUND : REPORT_ALL_ERRORS))) == + SELECT_LEX *sl= thd->lex.current_select->outer_select(); + if ((ref= find_item_in_list(this, + *(thd->lex.current_select->get_item_list()), + (sl ? REPORT_EXCEPT_NOT_FOUND : + REPORT_ALL_ERRORS))) == (Item **)not_found_item) { /* @@ -850,31 +838,16 @@ bool Item_ref::fix_fields(THD *thd,TABLE_LIST *tables, Item **reference) else if (ref == (Item **)not_found_item) { // Call to report error - find_item_in_list(this, thd->lex.select->item_list, REPORT_ALL_ERRORS); - ref=0; + find_item_in_list(this, + *(thd->lex.current_select->get_item_list()), + REPORT_ALL_ERRORS); + ref= 0; return 1; } else { depended_from= last; - /* - Mark all selects from resolved to 1 before select where was - found table as depended (of select where was found table) - */ - for (SELECT_LEX *s= thd->lex.select; - s &&s != last; - s= s->outer_select()) - if( !s->depended ) - { - // Select is depended of outer select - s->depended= s->master_unit()->depended= 1; - //Tables will be reopened many times - for (TABLE_LIST *tbl= - (TABLE_LIST*)s->table_list.first; - tbl; - tbl= tbl->next) - tbl->shared= 1; - } + thd->lex.current_select->mark_as_dependent(last); } } else if (!ref) diff --git a/sql/item_subselect.cc b/sql/item_subselect.cc index 82310710a9d..f45f386fe46 100644 --- a/sql/item_subselect.cc +++ b/sql/item_subselect.cc @@ -252,8 +252,8 @@ int subselect_single_select_engine::prepare() if (prepared) return 0; prepared= 1; - SELECT_LEX *save_select= thd->lex.select; - thd->lex.select= select_lex; + SELECT_LEX_NODE *save_select= thd->lex.current_select; + thd->lex.current_select= select_lex; if(join->prepare((TABLE_LIST*) select_lex->table_list.first, select_lex->where, (ORDER*) select_lex->order_list.first, @@ -262,7 +262,7 @@ int subselect_single_select_engine::prepare() (ORDER*) 0, select_lex, select_lex->master_unit(), 0)) return 1; - thd->lex.select= save_select; + thd->lex.current_select= save_select; return 0; } @@ -310,7 +310,7 @@ int subselect_single_select_engine::exec() DBUG_RETURN(join->error?join->error:1); } } - if (select_lex->depended && executed) + if (select_lex->dependent && executed) { if (join->reinit()) DBUG_RETURN(1); @@ -319,10 +319,10 @@ int subselect_single_select_engine::exec() } if (!executed) { - SELECT_LEX *save_select= join->thd->lex.select; - join->thd->lex.select= select_lex; + SELECT_LEX_NODE *save_select= join->thd->lex.current_select; + join->thd->lex.current_select= select_lex; join->exec(); - join->thd->lex.select= save_select; + join->thd->lex.current_select= save_select; executed= 1; DBUG_RETURN(join->error||thd->fatal_error); } @@ -346,10 +346,10 @@ uint subselect_union_engine::cols() bool subselect_single_select_engine::depended() { - return select_lex->depended; + return select_lex->dependent; } bool subselect_union_engine::depended() { - return unit->depended; + return unit->dependent; } diff --git a/sql/item_sum.cc b/sql/item_sum.cc index ae1a86845bf..22b5e47fab5 100644 --- a/sql/item_sum.cc +++ b/sql/item_sum.cc @@ -943,7 +943,10 @@ bool Item_sum_count_distinct::fix_fields(THD *thd, TABLE_LIST *tables, bool Item_sum_count_distinct::setup(THD *thd) { List<Item> list; - SELECT_LEX *select_lex= current_lex->select; + SELECT_LEX *select_lex= current_lex->current_select->select_lex(); + if (select_lex->linkage == GLOBAL_OPTIONS_TYPE) + return 1; + /* Create a table with an unique key over all parameters */ for (uint i=0; i < arg_count ; i++) { diff --git a/sql/mysql_priv.h b/sql/mysql_priv.h index b7dc51755fb..7788056138c 100644 --- a/sql/mysql_priv.h +++ b/sql/mysql_priv.h @@ -539,11 +539,6 @@ bool add_field_to_list(char *field_name, enum enum_field_types type, char *change, TYPELIB *interval,CHARSET_INFO *cs); void store_position_for_column(const char *name); bool add_to_list(SQL_LIST &list,Item *group,bool asc=0); -TABLE_LIST *add_table_to_list(Table_ident *table,LEX_STRING *alias, - bool updating, - thr_lock_type flags=TL_UNLOCK, - List<String> *use_index=0, - List<String> *ignore_index=0); void add_join_on(TABLE_LIST *b,Item *expr); void add_join_natural(TABLE_LIST *a,TABLE_LIST *b); bool add_proc_to_list(Item *item); @@ -564,8 +559,8 @@ int setup_fields(THD *thd,TABLE_LIST *tables,List<Item> &item, bool set_query_id,List<Item> *sum_func_list, bool allow_sum_func); int setup_conds(THD *thd,TABLE_LIST *tables,COND **conds); -int setup_ftfuncs(THD *thd); -int init_ftfuncs(THD *thd, bool no_order); +int setup_ftfuncs(SELECT_LEX* select); +int init_ftfuncs(THD *thd, SELECT_LEX* select, bool no_order); void wait_for_refresh(THD *thd); int open_tables(THD *thd,TABLE_LIST *tables); int open_and_lock_tables(THD *thd,TABLE_LIST *tables); @@ -852,19 +847,19 @@ Item *get_system_var(enum_var_type var_type, const char *var_name, uint length, inline bool add_item_to_list(Item *item) { - return current_lex->select->item_list.push_back(item); + return current_lex->current_select->add_item_to_list(item); } inline bool add_value_to_list(Item *value) { return current_lex->value_list.push_back(value); } -inline bool add_order_to_list(Item *item,bool asc) +inline bool add_order_to_list(Item *item, bool asc) { - return add_to_list(current_lex->select->order_list,item,asc); + return current_lex->current_select->add_order_to_list(item, asc); } -inline bool add_group_to_list(Item *item,bool asc) +inline bool add_group_to_list(Item *item, bool asc) { - return add_to_list(current_lex->select->group_list,item,asc); + return current_lex->current_select->add_group_to_list(item, asc); } inline void mark_as_null_row(TABLE *table) { diff --git a/sql/sql_base.cc b/sql/sql_base.cc index 27848b141ac..77253d49ed0 100644 --- a/sql/sql_base.cc +++ b/sql/sql_base.cc @@ -2448,10 +2448,10 @@ bool remove_table_from_cache(THD *thd, const char *db, const char *table_name, DBUG_RETURN(result); } -int setup_ftfuncs(THD *thd) +int setup_ftfuncs(SELECT_LEX *select_lex) { - List_iterator<Item_func_match> li(*(thd->lex.select->ftfunc_list)), - lj(*(thd->lex.select->ftfunc_list)); + List_iterator<Item_func_match> li(*(select_lex->ftfunc_list)), + lj(*(select_lex->ftfunc_list)); Item_func_match *ftf, *ftf2; while ((ftf=li++)) @@ -2470,11 +2470,11 @@ int setup_ftfuncs(THD *thd) } -int init_ftfuncs(THD *thd, bool no_order) +int init_ftfuncs(THD *thd, SELECT_LEX *select_lex, bool no_order) { - if (thd->lex.select->ftfunc_list->elements) + if (select_lex->ftfunc_list->elements) { - List_iterator<Item_func_match> li(*(thd->lex.select->ftfunc_list)); + List_iterator<Item_func_match> li(*(select_lex->ftfunc_list)); Item_func_match *ifm; DBUG_PRINT("info",("Performing FULLTEXT search")); thd->proc_info="FULLTEXT initialization"; diff --git a/sql/sql_cache.cc b/sql/sql_cache.cc index 5bdefbaaa30..2f236da2aa3 100644 --- a/sql/sql_cache.cc +++ b/sql/sql_cache.cc @@ -2444,14 +2444,14 @@ TABLE_COUNTER_TYPE Query_cache::is_cacheable(THD *thd, uint32 query_len, if (lex->sql_command == SQLCOM_SELECT && (thd->variables.query_cache_type == 1 || - (thd->variables.query_cache_type == 2 && (lex->select->options & + (thd->variables.query_cache_type == 2 && (lex->select_lex.options & OPTION_TO_QUERY_CACHE))) && thd->safe_to_cache_query) { my_bool has_transactions = 0; DBUG_PRINT("qcache", ("options %lx %lx, type %u", OPTION_TO_QUERY_CACHE, - lex->select->options, + lex->select_lex.options, (int) thd->variables.query_cache_type)); for (; tables_used; tables_used= tables_used->next) @@ -2498,7 +2498,7 @@ TABLE_COUNTER_TYPE Query_cache::is_cacheable(THD *thd, uint32 query_len, ("not interesting query: %d or not cacheable, options %lx %lx, type %u", (int) lex->sql_command, OPTION_TO_QUERY_CACHE, - lex->select->options, + lex->select_lex.options, (int) thd->variables.query_cache_type)); DBUG_RETURN(0); } diff --git a/sql/sql_delete.cc b/sql/sql_delete.cc index cb1a9db70cd..64945fa2d4d 100644 --- a/sql/sql_delete.cc +++ b/sql/sql_delete.cc @@ -52,7 +52,8 @@ int mysql_delete(THD *thd, TABLE_LIST *table_list, COND *conds, ORDER *order, table->file->info(HA_STATUS_VARIABLE | HA_STATUS_NO_LOCK); thd->proc_info="init"; table->map=1; - if (setup_conds(thd,table_list,&conds) || setup_ftfuncs(thd)) + if (setup_conds(thd,table_list,&conds) || + setup_ftfuncs(&thd->lex.select_lex)) DBUG_RETURN(-1); /* Test if the user wants to delete all rows */ @@ -129,7 +130,7 @@ int mysql_delete(THD *thd, TABLE_LIST *table_list, COND *conds, ORDER *order, init_read_record(&info,thd,table,select,1,1); deleted=0L; - init_ftfuncs(thd,1); + init_ftfuncs(thd, &thd->lex.select_lex, 1); thd->proc_info="updating"; while (!(error=info.read_record(&info)) && !thd->killed) { @@ -284,7 +285,7 @@ multi_delete::initialize_tables(JOIN *join) table->file->ref_length, MEM_STRIP_BUF_SIZE); } - init_ftfuncs(thd,1); + init_ftfuncs(thd, thd->lex.current_select->select_lex(), 1); } diff --git a/sql/sql_derived.cc b/sql/sql_derived.cc index 9cc83a3835a..1335618b90d 100644 --- a/sql/sql_derived.cc +++ b/sql/sql_derived.cc @@ -57,8 +57,8 @@ int mysql_derived(THD *thd, LEX *lex, SELECT_LEX_UNIT *unit, TABLE_LIST *t, { if (cursor->derived) { - res=mysql_derived(thd, lex, (SELECT_LEX_UNIT *)cursor->derived, - cursor, 0); + res= mysql_derived(thd, lex, (SELECT_LEX_UNIT *)cursor->derived, + cursor, 0); if (res) DBUG_RETURN(res); } } diff --git a/sql/sql_lex.cc b/sql/sql_lex.cc index 52f1be6bddf..b5dd5218e7d 100644 --- a/sql/sql_lex.cc +++ b/sql/sql_lex.cc @@ -21,6 +21,7 @@ #include "item_create.h" #include <m_ctype.h> #include <hash.h> +#include <assert.h> LEX_STRING tmp_table_alias= {(char*) "tmp-table",8}; @@ -147,7 +148,7 @@ LEX *lex_start(THD *thd, uchar *buf,uint length) lex->select_lex.in_sum_expr=0; lex->select_lex.expr_list.empty(); lex->select_lex.ftfunc_list_alloc.empty(); - lex->select_lex.ftfunc_list= &lex->select->ftfunc_list_alloc; + lex->select_lex.ftfunc_list= &lex->select_lex.ftfunc_list_alloc; lex->convert_set= (lex->thd= thd)->variables.convert_set; lex->yacc_yyss=lex->yacc_yyvs=0; lex->ignore_space=test(thd->sql_mode & MODE_IGNORE_SPACE); @@ -934,7 +935,8 @@ void st_select_lex_node::init_select() order_list.first= 0; order_list.next= (byte**) &order_list.first; select_limit= HA_POS_ERROR; - offset_limit= 0; + offset_limit= 0; + create_refs= dependent= 0; } void st_select_lex_unit::init_query() @@ -974,7 +976,7 @@ void st_select_lex::init_select() ftfunc_list_alloc.empty(); ftfunc_list= &ftfunc_list_alloc; linkage= UNSPECIFIED_TYPE; - depended= having_fix_field= 0; + having_fix_field= 0; } /* @@ -1042,6 +1044,91 @@ void st_select_lex_node::exclude() */ } +st_select_lex* st_select_lex_node::select_lex() +{ + DBUG_ENTER("st_select_lex_node::select_lex (never should be called)"); + DBUG_ASSERT(1); + DBUG_RETURN(0); +} + +bool st_select_lex_node::add_item_to_list(Item *item) +{ + return 1; +} + +bool st_select_lex_node::add_group_to_list(Item *item, bool asc) +{ + return 1; +} + +bool st_select_lex_node::add_order_to_list(Item *item, bool asc) +{ + return add_to_list(order_list,item,asc); +} + +bool st_select_lex_node::add_ftfunc_to_list(Item_func_match *func) +{ + return 1; +} + +/* + st_select_lex_node::mark_as_dependent mark all st_select_lex struct from + this to 'last' as dependent + + SYNOPSIS + last - pointer to last st_select_lex struct, before wich all + st_select_lex have to be marked as dependent + + NOTE + 'last' should be reachable from this st_select_lex_node + +*/ + +void st_select_lex_node::mark_as_dependent(SELECT_LEX *last) +{ + /* + Mark all selects from resolved to 1 before select where was + found table as depended (of select where was found table) + */ + for (SELECT_LEX_NODE *s= this; + s &&s != last; + s= s->outer_select()) + if( !s->dependent ) + { + // Select is dependent of outer select + s->dependent= 1; + if (s->linkage != GLOBAL_OPTIONS_TYPE) + { + //s is st_select_lex* + + s->master_unit()->dependent= 1; + //Tables will be reopened many times + for (TABLE_LIST *tbl= + s->get_table_list(); + tbl; + tbl= tbl->next) + tbl->shared= 1; + } + } +} + +bool st_select_lex_node::set_braces(bool value) { return 1; } +bool st_select_lex_node::inc_in_sum_expr() { return 1; } +uint st_select_lex_node::get_in_sum_expr() { return 0; } +TABLE_LIST* st_select_lex_node::get_table_list() { return 0; } +List<Item>* st_select_lex_node::get_item_list() { return 0; } +List<String>* st_select_lex_node::get_use_index() { return 0; } +List<String>* st_select_lex_node::get_ignore_index() { return 0; } +TABLE_LIST *st_select_lex_node::add_table_to_list(Table_ident *table, + LEX_STRING *alias, + bool updating, + thr_lock_type flags, + List<String> *use_index, + List<String> *ignore_index) +{ + return 0; +} + /* This is used for UNION & subselect to create a new table list of all used tables. @@ -1118,3 +1205,82 @@ bool st_select_lex_unit::create_total_list_n_last_return(THD *thd, st_lex *lex, *result= new_table_list; return 0; } + +st_select_lex_unit* st_select_lex_unit::master_unit() +{ + return this; +} + +st_select_lex* st_select_lex_unit::outer_select() +{ + return (st_select_lex*) master; +} + +st_select_lex* st_select_lex::select_lex() +{ + return this; +} + +bool st_select_lex::add_item_to_list(Item *item) +{ + return item_list.push_back(item); +} + +bool st_select_lex::add_group_to_list(Item *item, bool asc) +{ + return add_to_list(group_list, item, asc); +} + +bool st_select_lex::add_ftfunc_to_list(Item_func_match *func) +{ + return !func || ftfunc_list->push_back(func); // end of memory? +} + +st_select_lex_unit* st_select_lex::master_unit() +{ + return (st_select_lex_unit*) master; +} + +st_select_lex* st_select_lex::outer_select() +{ + return (st_select_lex*) master->get_master(); +} + +bool st_select_lex::set_braces(bool value) +{ + braces= value; + return 0; +} + +bool st_select_lex::inc_in_sum_expr() +{ + in_sum_expr++; + return 0; +} + +uint st_select_lex::get_in_sum_expr() +{ + return in_sum_expr; +} + +TABLE_LIST* st_select_lex::get_table_list() +{ + return (TABLE_LIST*) table_list.first; +} + +List<Item>* st_select_lex::get_item_list() +{ + return &item_list; +} + +List<String>* st_select_lex::get_use_index() +{ + return use_index_ptr; +} + +List<String>* st_select_lex::get_ignore_index() +{ + return ignore_index_ptr; +} + +// There are st_select_lex::add_table_to_list in sql_parse.cc diff --git a/sql/sql_lex.h b/sql/sql_lex.h index 50bff7c7f63..ea944ef34c8 100644 --- a/sql/sql_lex.h +++ b/sql/sql_lex.h @@ -186,6 +186,8 @@ enum olap_type Base class for st_select_lex (SELECT_LEX) & st_select_lex_unit (SELECT_LEX_UNIT) */ +class st_select_lex; +class st_select_lex_unit; class st_select_lex_node { protected: st_select_lex_node *next, **prev, /* neighbor list */ @@ -195,23 +197,60 @@ public: ulong options; enum sub_select_type linkage; SQL_LIST order_list; /* ORDER clause */ + List<List_item> expr_list; + List<List_item> when_list; /* WHEN clause (expression) */ ha_rows select_limit, offset_limit; /* LIMIT clause parameters */ - void init_query(); - void init_select(); + bool create_refs; + bool dependent; /* dependent from outer select subselect */ + + static void *operator new(size_t size) + { + return (void*) sql_calloc((uint) size); + } + static void operator delete(void *ptr,size_t size) {} + virtual ~st_select_lex_node() {} + inline st_select_lex_node* get_master() { return master; } + virtual void init_query(); + virtual void init_select(); void include_down(st_select_lex_node *upper); void include_neighbour(st_select_lex_node *before); void include_global(st_select_lex_node **plink); void exclude(); + + virtual st_select_lex* select_lex(); + virtual bool add_item_to_list(Item *item); + bool add_order_to_list(Item *item, bool asc); + virtual bool add_group_to_list(Item *item, bool asc); + virtual bool add_ftfunc_to_list(Item_func_match *func); + + virtual st_select_lex_unit* master_unit()= 0; + virtual st_select_lex* outer_select()= 0; + + virtual bool set_braces(bool value); + virtual bool inc_in_sum_expr(); + virtual uint get_in_sum_expr(); + virtual TABLE_LIST* get_table_list(); + virtual List<Item>* get_item_list(); + virtual List<String>* get_use_index(); + virtual List<String>* get_ignore_index(); + virtual TABLE_LIST *add_table_to_list(Table_ident *table, + LEX_STRING *alias, + bool updating, + thr_lock_type flags= TL_UNLOCK, + List<String> *use_index= 0, + List<String> *ignore_index= 0); + + void mark_as_dependent(st_select_lex *last); private: void fast_exclude(); }; +typedef class st_select_lex_node SELECT_LEX_NODE; /* SELECT_LEX_UNIT - unit of selects (UNION, INTERSECT, ...) group SELECT_LEXs */ struct st_lex; -class st_select_lex; class THD; class select_result; class JOIN; @@ -238,14 +277,14 @@ public: st_select_lex_node *global_parameters; /* LIMIT clause runtime counters */ ha_rows select_limit_cnt, offset_limit_cnt; - bool depended; /* depended from outer select subselect */ /* not NULL if union used in subselect, point to subselect item */ Item_subselect *item; uint union_option; void init_query(); bool create_total_list(THD *thd, st_lex *lex, TABLE_LIST **result); - st_select_lex* outer_select() { return (st_select_lex*) master; } + st_select_lex_unit* master_unit(); + st_select_lex* outer_select(); st_select_lex* first_select() { return (st_select_lex*) slave; } st_select_lex_unit* next_unit() { return (st_select_lex_unit*) next; } @@ -270,8 +309,6 @@ public: char *db, *db1, *table1, *db2, *table2; /* For outer join using .. */ Item *where, *having; /* WHERE & HAVING clauses */ enum olap_type olap; - List<List_item> expr_list; - List<List_item> when_list; /* WHEN clause */ SQL_LIST table_list, group_list; /* FROM & GROUP BY clauses */ List<Item> item_list; /* list of fields & expressions */ List<String> interval_list, use_index, *use_index_ptr, @@ -286,23 +323,18 @@ public: const char *type; /* type of select for EXPLAIN */ uint in_sum_expr; uint select_number; /* number of select (used for EXPLAIN) */ - bool create_refs; bool braces; /* SELECT ... UNION (SELECT ... ) <- this braces */ - bool depended; /* depended from outer select subselect */ /* TRUE when having fix field called in processing of this SELECT */ bool having_fix_field; void init_query(); void init_select(); - st_select_lex_unit* master_unit() { return (st_select_lex_unit*) master; } + st_select_lex_unit* master_unit(); st_select_lex_unit* first_inner_unit() { return (st_select_lex_unit*) slave; } - st_select_lex* outer_select() - { - return (st_select_lex*) master_unit()->outer_select(); - } + st_select_lex* outer_select(); st_select_lex* next_select() { return (st_select_lex*) next; } st_select_lex* next_select_in_list() { @@ -313,6 +345,32 @@ public: return &link_next; } + bool set_braces(bool value); + bool inc_in_sum_expr(); + uint get_in_sum_expr(); + + st_select_lex* select_lex(); + bool add_item_to_list(Item *item); + bool add_group_to_list(Item *item, bool asc); + bool add_ftfunc_to_list(Item_func_match *func); + + TABLE_LIST* get_table_list(); + List<Item>* get_item_list(); + List<String>* get_use_index(); + List<String>* get_ignore_index(); + TABLE_LIST* add_table_to_list(Table_ident *table, + LEX_STRING *alias, + bool updating, + thr_lock_type flags= TL_UNLOCK, + List<String> *use_index= 0, + List<String> *ignore_index= 0); + inline void init_order() + { + order_list.elements= 0; + order_list.first= 0; + order_list.next= (byte**) &order_list.first; + } + friend void mysql_init_query(THD *thd); }; typedef class st_select_lex SELECT_LEX; @@ -325,9 +383,9 @@ typedef struct st_lex uint yylineno,yytoklen; /* Simulate lex */ LEX_YYSTYPE yylval; SELECT_LEX_UNIT unit; /* most upper unit */ - SELECT_LEX select_lex, /* first SELECT_LEX */ - /* current SELECT_LEX in parsing */ - *select; + SELECT_LEX select_lex; /* first SELECT_LEX */ + /* current SELECT_LEX in parsing */ + SELECT_LEX_NODE *current_select; uchar *ptr,*tok_start,*tok_end,*end_of_query; char *length,*dec,*change,*name; char *backup_dir; /* For RESTORE/BACKUP */ diff --git a/sql/sql_parse.cc b/sql/sql_parse.cc index d193370eef7..10b05a0550d 100644 --- a/sql/sql_parse.cc +++ b/sql/sql_parse.cc @@ -2911,9 +2911,9 @@ mysql_init_query(THD *thd) thd->select_number= thd->lex.select_lex.select_number= 1; thd->lex.value_list.empty(); thd->free_list= 0; - thd->lex.select= &thd->lex.select_lex; + thd->lex.current_select= &thd->lex.select_lex; thd->lex.olap=thd->lex.describe=0; - thd->lex.select->olap= UNSPECIFIED_OLAP_TYPE; + thd->lex.select_lex.olap= UNSPECIFIED_OLAP_TYPE; thd->fatal_error= 0; // Safety thd->total_warn_count=0; // Warnings for this query thd->last_insert_id_used= thd->query_start_used= thd->insert_id_used=0; @@ -2927,7 +2927,8 @@ mysql_init_query(THD *thd) void mysql_init_select(LEX *lex) { - SELECT_LEX *select_lex= lex->select; + SELECT_LEX *select_lex= lex->current_select->select_lex(); + DBUG_ASSERT(select_lex->linkage != GLOBAL_OPTIONS_TYPE); select_lex->init_select(); select_lex->master_unit()->select_limit= select_lex->select_limit= lex->thd->variables.select_limit; @@ -2941,7 +2942,7 @@ mysql_init_select(LEX *lex) bool mysql_new_select(LEX *lex, bool move_down) { - SELECT_LEX *select_lex = (SELECT_LEX *) lex->thd->calloc(sizeof(SELECT_LEX)); + SELECT_LEX *select_lex = new SELECT_LEX(); select_lex->select_number= ++lex->thd->select_number; if (!select_lex) return 1; @@ -2950,21 +2951,22 @@ mysql_new_select(LEX *lex, bool move_down) if (move_down) { /* first select_lex of subselect or derived table */ - SELECT_LEX_UNIT *unit= - (SELECT_LEX_UNIT *) lex->thd->calloc(sizeof(SELECT_LEX_UNIT)); + SELECT_LEX_UNIT *unit= new SELECT_LEX_UNIT(); if (!unit) return 1; unit->init_query(); unit->init_select(); - unit->include_down(lex->select); + unit->include_down(lex->current_select); select_lex->include_down(unit); } else - select_lex->include_neighbour(lex->select); + select_lex->include_neighbour(lex->current_select); select_lex->master_unit()->global_parameters= select_lex; - select_lex->include_global(lex->select->next_select_in_list_addr()); - lex->select= select_lex; + DBUG_ASSERT(lex->current_select->linkage != GLOBAL_OPTIONS_TYPE); + select_lex->include_global(lex->current_select->select_lex()-> + next_select_in_list_addr()); + lex->current_select= select_lex; return 0; } @@ -3000,10 +3002,10 @@ void mysql_init_multi_delete(LEX *lex) { lex->sql_command= SQLCOM_DELETE_MULTI; mysql_init_select(lex); - lex->select->select_limit= lex->select->master_unit()->select_limit_cnt= + lex->select_lex.select_limit= lex->unit.select_limit_cnt= HA_POS_ERROR; lex->auxilliary_table_list= lex->select_lex.table_list; - lex->select->init_query(); + lex->select_lex.init_query(); } @@ -3413,12 +3415,12 @@ bool add_to_list(SQL_LIST &list,Item *item,bool asc) } -TABLE_LIST *add_table_to_list(Table_ident *table, LEX_STRING *alias, - bool updating, - thr_lock_type flags, - List<String> *use_index, - List<String> *ignore_index - ) +TABLE_LIST *st_select_lex::add_table_to_list(Table_ident *table, + LEX_STRING *alias, + bool updating, + thr_lock_type flags, + List<String> *use_index, + List<String> *ignore_index) { register TABLE_LIST *ptr; THD *thd=current_thd; @@ -3480,7 +3482,7 @@ TABLE_LIST *add_table_to_list(Table_ident *table, LEX_STRING *alias, /* check that used name is unique */ if (flags != TL_IGNORE) { - for (TABLE_LIST *tables=(TABLE_LIST*) thd->lex.select->table_list.first ; + for (TABLE_LIST *tables=(TABLE_LIST*) table_list.first ; tables ; tables=tables->next) { @@ -3491,7 +3493,7 @@ TABLE_LIST *add_table_to_list(Table_ident *table, LEX_STRING *alias, } } } - link_in_list(&thd->lex.select->table_list,(byte*) ptr,(byte**) &ptr->next); + link_in_list(&table_list, (byte*) ptr, (byte**) &ptr->next); DBUG_RETURN(ptr); } @@ -3694,7 +3696,7 @@ static bool append_file_to_dir(THD *thd, char **filename_ptr, char *table_name) bool check_simple_select() { THD *thd= current_thd; - if (thd->lex.select != &thd->lex.select_lex) + if (thd->lex.current_select != &thd->lex.select_lex) { char command[80]; strmake(command, thd->lex.yylval->symbol.str, diff --git a/sql/sql_prepare.cc b/sql/sql_prepare.cc index bd115f0fc1e..2cf51f5d72e 100644 --- a/sql/sql_prepare.cc +++ b/sql/sql_prepare.cc @@ -497,7 +497,7 @@ static bool mysql_test_select_fields(PREP_STMT *stmt, TABLE_LIST *tables, if (having->with_sum_func) having->split_sum_func(all_fields); } - if (setup_ftfuncs(thd)) + if (setup_ftfuncs(&thd->lex.select_lex)) DBUG_RETURN(1); /* @@ -543,7 +543,7 @@ static bool send_prepare_results(PREP_STMT *stmt) stmt->free_list= thd->free_list; // Save items used in stmt thd->free_list= 0; - SELECT_LEX *select_lex = lex->select; + SELECT_LEX *select_lex = &lex->select_lex; TABLE_LIST *tables=(TABLE_LIST*) select_lex->table_list.first; switch (sql_command) { diff --git a/sql/sql_repl.cc b/sql/sql_repl.cc index 32b7c3be025..93545d10268 100644 --- a/sql/sql_repl.cc +++ b/sql/sql_repl.cc @@ -949,8 +949,8 @@ int show_binlog_events(THD* thd) LOG_INFO linfo; Log_event* ev; - limit_start = thd->lex.select->offset_limit; - limit_end = thd->lex.select->select_limit + limit_start; + limit_start = thd->lex.current_select->offset_limit; + limit_end = thd->lex.current_select->select_limit + limit_start; name= search_file_name; if (log_file_name) diff --git a/sql/sql_select.cc b/sql/sql_select.cc index 8acb5fa5635..93d48e3e1e0 100644 --- a/sql/sql_select.cc +++ b/sql/sql_select.cc @@ -38,7 +38,8 @@ static bool make_join_statistics(JOIN *join,TABLE_LIST *tables,COND *conds, DYNAMIC_ARRAY *keyuse); static bool update_ref_and_keys(THD *thd, DYNAMIC_ARRAY *keyuse, JOIN_TAB *join_tab, - uint tables,COND *conds,table_map table_map); + uint tables, COND *conds, + table_map table_map, SELECT_LEX *select_lex); static int sort_keyuse(KEYUSE *a,KEYUSE *b); static void set_position(JOIN *join,uint index,JOIN_TAB *table,KEYUSE *key); static bool create_ref_for_key(JOIN *join, JOIN_TAB *j, KEYUSE *org_keyuse, @@ -250,7 +251,7 @@ JOIN::prepare(TABLE_LIST *tables_init, if (having->with_sum_func) having->split_sum_func(all_fields); } - if (setup_ftfuncs(thd)) /* should be after having->fix_fields */ + if (setup_ftfuncs(select_lex)) /* should be after having->fix_fields */ DBUG_RETURN(-1); /* Check if one one uses a not constant column with group functions @@ -420,7 +421,7 @@ JOIN::optimize() thd->fatal_error) DBUG_RETURN(-1); - if (select_lex->depended) + if (select_lex->dependent) { /* Just remove all const-table optimization in case of depended query @@ -559,7 +560,7 @@ JOIN::optimize() make_join_readinfo(this, (select_options & (SELECT_DESCRIBE | SELECT_NO_JOIN_CACHE)) | - (thd->lex.select->ftfunc_list->elements ? + (select_lex->ftfunc_list->elements ? SELECT_NO_JOIN_CACHE : 0)); /* @@ -720,7 +721,7 @@ JOIN::exec() } /* Perform FULLTEXT search before all regular searches */ - init_ftfuncs(thd,test(order)); + init_ftfuncs(thd, select_lex, test(order)); /* Create a tmp table if distinct or if the sort is too complicated */ if (need_tmp) @@ -1239,8 +1240,8 @@ make_join_statistics(JOIN *join,TABLE_LIST *tables,COND *conds, } if (conds || outer_join) - if (update_ref_and_keys(join->thd,keyuse_array,stat,join->tables, - conds,~outer_join)) + if (update_ref_and_keys(join->thd, keyuse_array, stat, join->tables, + conds, ~outer_join, join->select_lex)) DBUG_RETURN(1); /* Read tables with 0 or 1 rows (system tables) */ @@ -1800,7 +1801,8 @@ sort_keyuse(KEYUSE *a,KEYUSE *b) static bool update_ref_and_keys(THD *thd, DYNAMIC_ARRAY *keyuse,JOIN_TAB *join_tab, - uint tables, COND *cond, table_map normal_tables) + uint tables, COND *cond, table_map normal_tables, + SELECT_LEX *select_lex) { uint and_level,i,found_eq_constant; @@ -1828,7 +1830,7 @@ update_ref_and_keys(THD *thd, DYNAMIC_ARRAY *keyuse,JOIN_TAB *join_tab, add_key_part(keyuse,field); } - if (thd->lex.select->ftfunc_list->elements) + if (select_lex->ftfunc_list->elements) { add_ft_keys(keyuse,join_tab,cond,normal_tables); } @@ -2930,7 +2932,7 @@ join_free(JOIN *join) end_read_record(&tab->read_record); } //TODO: is enough join_free at the end of mysql_select? - if (!join->select_lex->depended) + if (!join->select_lex->dependent) join->table=0; } /* @@ -7460,9 +7462,9 @@ int mysql_explain_union(THD *thd, SELECT_LEX_UNIT *unit, select_result *result) ((sl->next_select_in_list())?"PRIMARY": "SIMPLE"): ((sl == first)? - ((sl->depended)?"DEPENDENT SUBSELECT": + ((sl->dependent)?"DEPENDENT SUBSELECT": "SUBSELECT"): - ((sl->depended)?"DEPENDENT UNION": + ((sl->dependent)?"DEPENDENT UNION": "UNION"))), result); if (res) @@ -7480,7 +7482,7 @@ int mysql_explain_select(THD *thd, SELECT_LEX *select_lex, char const *type, DBUG_ENTER("mysql_explain_select"); DBUG_PRINT("info", ("Select 0x%lx, type %s", (ulong)select_lex, type)) select_lex->type= type; - thd->lex.select= select_lex; + thd->lex.current_select= select_lex; SELECT_LEX_UNIT *unit= select_lex->master_unit(); int res= mysql_select(thd,(TABLE_LIST*) select_lex->table_list.first, select_lex->item_list, diff --git a/sql/sql_union.cc b/sql/sql_union.cc index 899dceab9bc..53f89747ce7 100644 --- a/sql/sql_union.cc +++ b/sql/sql_union.cc @@ -115,7 +115,8 @@ int st_select_lex_unit::prepare(THD *thd, select_result *result) TMP_TABLE_PARAM tmp_table_param; this->thd= thd; this->result= result; - SELECT_LEX *lex_select_save= thd->lex.select, *sl; + SELECT_LEX_NODE *lex_select_save= thd->lex.current_select; + SELECT_LEX *sl; /* Global option */ if (((void*)(global_parameters)) == ((void*)this)) @@ -169,7 +170,7 @@ int st_select_lex_unit::prepare(THD *thd, select_result *result) sl->options | thd->options | SELECT_NO_UNLOCK, union_result); joins.push_back(new JOIN_P(join)); - thd->lex.select=sl; + thd->lex.current_select= sl; offset_limit_cnt= sl->offset_limit; select_limit_cnt= sl->select_limit+sl->offset_limit; if (select_limit_cnt < sl->select_limit) @@ -188,29 +189,29 @@ int st_select_lex_unit::prepare(THD *thd, select_result *result) if (res | thd->fatal_error) goto err; } - thd->lex.select= lex_select_save; + thd->lex.current_select= lex_select_save; DBUG_RETURN(res | thd->fatal_error); err: - thd->lex.select= lex_select_save; + thd->lex.current_select= lex_select_save; DBUG_RETURN(-1); } int st_select_lex_unit::exec() { DBUG_ENTER("st_select_lex_unit::exec"); - SELECT_LEX *lex_select_save= thd->lex.select; + SELECT_LEX_NODE *lex_select_save= thd->lex.current_select; - if (executed && !depended) + if (executed && !dependent) DBUG_RETURN(0); executed= 1; - if (depended || !item || !item->assigned()) + if (dependent || !item || !item->assigned()) { if (optimized && item && item->assigned()) item->assigned(0); // We will reinit & rexecute unit for (SELECT_LEX *sl= first_select(); sl; sl= sl->next_select()) { - thd->lex.select=sl; + thd->lex.current_select= sl; offset_limit_cnt= sl->offset_limit; select_limit_cnt= sl->select_limit+sl->offset_limit; if (select_limit_cnt < sl->select_limit) @@ -230,7 +231,7 @@ int st_select_lex_unit::exec() } if (res) { - thd->lex.select= lex_select_save; + thd->lex.current_select= lex_select_save; DBUG_RETURN(res); } } @@ -239,12 +240,14 @@ int st_select_lex_unit::exec() if (union_result->flush()) { - thd->lex.select= lex_select_save; + thd->lex.current_select= lex_select_save; DBUG_RETURN(1); } /* Send result to 'result' */ - thd->lex.select = first_select(); + + // to correct ORDER BY reference resolving + thd->lex.current_select = first_select(); res =-1; { /* Create a list of fields in the temporary table */ @@ -283,7 +286,7 @@ int st_select_lex_unit::exec() } } thd->lex.select_lex.ftfunc_list= &thd->lex.select_lex.ftfunc_list_alloc; - thd->lex.select= lex_select_save; + thd->lex.current_select= lex_select_save; DBUG_RETURN(res); } diff --git a/sql/sql_update.cc b/sql/sql_update.cc index e8d4af94640..be69935a49c 100644 --- a/sql/sql_update.cc +++ b/sql/sql_update.cc @@ -78,7 +78,7 @@ int mysql_update(THD *thd, want_privilege=table->grant.want_privilege; table->grant.want_privilege=(SELECT_ACL & ~table->grant.privilege); if (setup_tables(table_list) || setup_conds(thd,table_list,&conds) - || setup_ftfuncs(thd)) + || setup_ftfuncs(&thd->lex.select_lex)) DBUG_RETURN(-1); /* purecov: inspected */ old_used_keys=table->used_keys; // Keys used in WHERE @@ -142,7 +142,7 @@ int mysql_update(THD *thd, DBUG_RETURN(1); } } - init_ftfuncs(thd,1); + init_ftfuncs(thd, &thd->lex.select_lex, 1); /* Check if we are modifying a key that we are used to search with */ if (select && select->quick) used_key_is_modified= (!select->quick->unique_key_range() && @@ -508,7 +508,7 @@ multi_update::prepare(List<Item> &values, SELECT_LEX_UNIT *u) counter++; } } - init_ftfuncs(thd,1); + init_ftfuncs(thd, thd->lex.current_select->select_lex(), 1); error = 0; // Timestamps do not need to be restored, so far ... DBUG_RETURN(0); } diff --git a/sql/sql_yacc.yy b/sql/sql_yacc.yy index 9841e8254c8..b1cbe0ccf2b 100644 --- a/sql/sql_yacc.yy +++ b/sql/sql_yacc.yy @@ -21,7 +21,7 @@ #define YYINITDEPTH 100 #define YYMAXDEPTH 3200 /* Because of 64K stack */ #define Lex current_lex -#define Select Lex->select +#define Select Lex->current_select #include "mysql_priv.h" #include "slave.h" #include "sql_acl.h" @@ -581,7 +581,7 @@ bool my_yyoverflow(short **a, YYSTYPE **b,int *yystacksize); key_part %type <table_list> - join_table_list join_table + join_table_list join_table %type <udf> UDF_CHAR_FUNC UDF_FLOAT_FUNC UDF_INT_FUNC @@ -784,9 +784,11 @@ create: THD *thd=current_thd; LEX *lex=Lex; lex->sql_command= SQLCOM_CREATE_TABLE; - if (!add_table_to_list($5, - ($2 & HA_LEX_CREATE_TMP_TABLE ? - &tmp_table_alias : (LEX_STRING*) 0),1)) + if (!lex->select_lex.add_table_to_list($5, + ($2 & + HA_LEX_CREATE_TMP_TABLE ? + &tmp_table_alias : + (LEX_STRING*) 0),1)) YYABORT; lex->create_list.empty(); lex->key_list.empty(); @@ -803,7 +805,7 @@ create: { LEX *lex=Lex; lex->sql_command= SQLCOM_CREATE_INDEX; - if (!add_table_to_list($7,NULL,1)) + if (!lex->current_select->add_table_to_list($7,NULL,1)) YYABORT; lex->create_list.empty(); lex->key_list.empty(); @@ -913,12 +915,12 @@ create_table_option: { /* Move the union list to the merge_list */ LEX *lex=Lex; - TABLE_LIST *table_list= (TABLE_LIST*) lex->select->table_list.first; - lex->create_info.merge_list= lex->select->table_list; + TABLE_LIST *table_list= lex->select_lex.get_table_list(); + lex->create_info.merge_list= lex->select_lex.table_list; lex->create_info.merge_list.elements--; lex->create_info.merge_list.first= (byte*) (table_list->next); - lex->select->table_list.elements=1; - lex->select->table_list.next= (byte**) &(table_list->next); + lex->select_lex.table_list.elements=1; + lex->select_lex.table_list.next= (byte**) &(table_list->next); table_list->next=0; lex->create_info.used_fields|= HA_CREATE_USED_UNION; } @@ -1302,10 +1304,10 @@ alter: ALTER opt_ignore TABLE_SYM table_ident { THD *thd=current_thd; - LEX *lex=Lex; + LEX *lex=&thd->lex; lex->sql_command = SQLCOM_ALTER_TABLE; lex->name=0; - if (!add_table_to_list($4, NULL,1)) + if (!lex->select_lex.add_table_to_list($4, NULL,1)) YYABORT; lex->drop_primary=0; lex->create_list.empty(); @@ -1313,10 +1315,8 @@ alter: lex->col_list.empty(); lex->drop_list.empty(); lex->alter_list.empty(); - lex->select->order_list.elements=0; - lex->select->order_list.first=0; - lex->select->order_list.next= (byte**) &lex->select->order_list.first; - lex->select->db=lex->name=0; + lex->select_lex.init_order(); + lex->select_lex.db=lex->name=0; bzero((char*) &lex->create_info,sizeof(lex->create_info)); lex->create_info.db_type= DB_TYPE_DEFAULT; lex->create_info.table_charset=thd->db_charset?thd->db_charset:default_charset_info; @@ -1405,7 +1405,7 @@ alter_list_item: | RENAME opt_to table_ident { LEX *lex=Lex; - lex->select->db=$3->db.str; + lex->select_lex.db=$3->db.str; lex->name= $3->table.str; } | create_table_options_space_separated { Lex->simple_alter=0; } @@ -1557,9 +1557,11 @@ table_to_table_list: table_to_table: table_ident TO_SYM table_ident - { if (!add_table_to_list($1,NULL,1,TL_IGNORE) || - !add_table_to_list($3,NULL,1,TL_IGNORE)) - YYABORT; + { + SELECT_LEX_NODE *sl= Lex->current_select; + if (!sl->add_table_to_list($1,NULL,1,TL_IGNORE) || + !sl->add_table_to_list($3,NULL,1,TL_IGNORE)) + YYABORT; }; /* @@ -1571,12 +1573,26 @@ select: select_init { Lex->sql_command=SQLCOM_SELECT; }; select_init: - SELECT_SYM select_part2 { Select->braces=false; } union + SELECT_SYM select_part2 + { + LEX *lex= Lex; + if (lex->current_select->set_braces(false)) + { + send_error(lex->thd, ER_SYNTAX_ERROR); + YYABORT; + } + } + union | '(' SELECT_SYM select_part2 ')' { - SELECT_LEX * sel=Select; - sel->braces=true; + LEX *lex= Lex; + SELECT_LEX_NODE * sel= lex->current_select; + if (sel->set_braces(true)) + { + send_error(lex->thd, ER_SYNTAX_ERROR); + YYABORT; + } /* select in braces, can't contain global parameters */ sel->master_unit()->global_parameters= sel->master_unit(); @@ -1857,10 +1873,10 @@ simple_expr: | singleval_subselect { $$= $1; } | '{' ident expr '}' { $$= $3; } | MATCH ident_list_arg AGAINST '(' expr ')' - { Select->ftfunc_list->push_back((Item_func_match *) + { Select->add_ftfunc_to_list((Item_func_match *) ($$=new Item_func_match_nl(*$2,$5))); } | MATCH ident_list_arg AGAINST '(' expr IN_SYM BOOLEAN_SYM MODE_SYM ')' - { Select->ftfunc_list->push_back((Item_func_match *) + { Select->add_ftfunc_to_list((Item_func_match *) ($$=new Item_func_match_bool(*$2,$5))); } | BINARY expr %prec NEG { $$= new Item_func_set_collation($2,my_charset_bin); } | CAST_SYM '(' expr AS cast_type ')' { $$= create_func_cast($3, $5); } @@ -2186,10 +2202,17 @@ sum_expr: { $$=new Item_sum_sum($3); }; in_sum_expr: - { Select->in_sum_expr++; } + { + LEX *lex= Lex; + if (lex->current_select->inc_in_sum_expr()) + { + send_error(lex->thd, ER_SYNTAX_ERROR); + YYABORT; + } + } expr { - Select->in_sum_expr--; + Select->select_lex()->in_sum_expr--; $$=$2; }; @@ -2241,13 +2264,13 @@ when_list: when_list2: expr THEN_SYM expr { - SELECT_LEX *sel=Select; + SELECT_LEX_NODE *sel=Select; sel->when_list.head()->push_back($1); sel->when_list.head()->push_back($3); } | when_list2 WHEN_SYM expr THEN_SYM expr { - SELECT_LEX *sel=Select; + SELECT_LEX_NODE *sel=Select; sel->when_list.head()->push_back($3); sel->when_list.head()->push_back($5); }; @@ -2266,7 +2289,7 @@ join_table_list: { add_join_on($4,$6); $$=$4; } | join_table_list INNER_SYM JOIN_SYM join_table_list { - SELECT_LEX *sel=Select; + SELECT_LEX *sel= Select->select_lex(); sel->db1=$1->db; sel->table1=$1->alias; sel->db2=$4->db; sel->table2=$4->alias; } @@ -2276,7 +2299,7 @@ join_table_list: { add_join_on($5,$7); $5->outer_join|=JOIN_TYPE_LEFT; $$=$5; } | join_table_list LEFT opt_outer JOIN_SYM join_table_list { - SELECT_LEX *sel=Select; + SELECT_LEX *sel= Select->select_lex(); sel->db1=$1->db; sel->table1=$1->alias; sel->db2=$5->db; sel->table2=$5->alias; } @@ -2288,7 +2311,7 @@ join_table_list: { add_join_on($1,$7); $1->outer_join|=JOIN_TYPE_RIGHT; $$=$1; } | join_table_list RIGHT opt_outer JOIN_SYM join_table_list { - SELECT_LEX *sel=Select; + SELECT_LEX *sel= Select->select_lex(); sel->db1=$1->db; sel->table1=$1->alias; sel->db2=$5->db; sel->table2=$5->alias; } @@ -2306,14 +2329,15 @@ normal_join: join_table: { - SELECT_LEX *sel=Select; + SELECT_LEX *sel= Select->select_lex(); sel->use_index_ptr=sel->ignore_index_ptr=0; } table_ident opt_table_alias opt_key_definition { - SELECT_LEX *sel=Select; - if (!($$=add_table_to_list($2,$3,0,TL_UNLOCK, sel->use_index_ptr, - sel->ignore_index_ptr))) + SELECT_LEX_NODE *sel=Select; + if (!($$= sel->add_table_to_list($2, $3, 0, TL_UNLOCK, + sel->get_use_index(), + sel->get_ignore_index()))) YYABORT; } | '{' ident join_table LEFT OUTER JOIN_SYM join_table ON expr '}' @@ -2321,10 +2345,10 @@ join_table: | '(' SELECT_SYM select_part3 ')' opt_table_alias { LEX *lex=Lex; - SELECT_LEX_UNIT *unit= lex->select->master_unit(); - lex->select= unit->outer_select(); - if (!($$= add_table_to_list(new Table_ident(unit), - $5,0,TL_UNLOCK))) + SELECT_LEX_UNIT *unit= lex->current_select->master_unit(); + lex->current_select= unit->outer_select(); + if (!($$= lex->current_select-> + add_table_to_list(new Table_ident(unit), $5, 0, TL_UNLOCK))) YYABORT; }; @@ -2332,11 +2356,11 @@ select_part3: { LEX *lex= Lex; lex->derived_tables= true; - if (lex->select->linkage == GLOBAL_OPTIONS_TYPE || + if (lex->current_select->linkage == GLOBAL_OPTIONS_TYPE || mysql_new_select(lex, 1)) YYABORT; mysql_init_select(lex); - lex->select->linkage= DERIVED_TABLE_TYPE; + lex->current_select->linkage= DERIVED_TABLE_TYPE; } select_options select_item_list select_intoto; @@ -2352,39 +2376,49 @@ opt_key_definition: /* empty */ {} | USE_SYM key_usage_list { - SELECT_LEX *sel=Select; + SELECT_LEX *sel= Select->select_lex(); sel->use_index= *$2; sel->use_index_ptr= &sel->use_index; } | IGNORE_SYM key_usage_list { - SELECT_LEX *sel=Select; + SELECT_LEX *sel= Select->select_lex(); sel->ignore_index= *$2; sel->ignore_index_ptr= &sel->ignore_index; }; key_usage_list: - key_or_index { Select->interval_list.empty(); } '(' key_usage_list2 ')' - { $$= &Select->interval_list; }; + key_or_index { Select->select_lex()->interval_list.empty(); } + '(' key_usage_list2 ')' + { $$= &Select->select_lex()->interval_list; }; key_usage_list2: key_usage_list2 ',' ident - { Select->interval_list.push_back(new String((const char*) $3.str,$3.length,default_charset_info)); } + { Select->select_lex()-> + interval_list.push_back(new String((const char*) $3.str, $3.length, + default_charset_info)); } | ident - { Select->interval_list.push_back(new String((const char*) $1.str,$1.length,default_charset_info)); } + { Select->select_lex()-> + interval_list.push_back(new String((const char*) $1.str, $1.length, + default_charset_info)); } | PRIMARY_SYM - { Select->interval_list.push_back(new String("PRIMARY",7,default_charset_info)); }; + { Select->select_lex()-> + interval_list.push_back(new String("PRIMARY", 7, + default_charset_info)); }; using_list: ident { - SELECT_LEX *sel=Select; - if (!($$= new Item_func_eq(new Item_field(sel->db1,sel->table1, $1.str), new Item_field(sel->db2,sel->table2,$1.str)))) + SELECT_LEX *sel= Select->select_lex(); + if (!($$= new Item_func_eq(new Item_field(sel->db1, sel->table1, + $1.str), + new Item_field(sel->db2, sel->table2, + $1.str)))) YYABORT; } | using_list ',' ident { - SELECT_LEX *sel=Select; + SELECT_LEX *sel= Select->select_lex(); if (!($$= new Item_cond_and(new Item_func_eq(new Item_field(sel->db1,sel->table1,$3.str), new Item_field(sel->db2,sel->table2,$3.str)), $1))) YYABORT; }; @@ -2416,14 +2450,14 @@ opt_table_alias: where_clause: - /* empty */ { Select->where= 0; } - | WHERE expr { Select->where= $2; }; + /* empty */ { Select->select_lex()->where= 0; } + | WHERE expr { Select->select_lex()->where= $2; }; having_clause: /* empty */ - | HAVING { Select->create_refs=1; } expr + | HAVING { Select->select_lex()->create_refs= 1; } expr { - SELECT_LEX *sel=Select; + SELECT_LEX *sel= Select->select_lex(); sel->having= $3; sel->create_refs=0; }; @@ -2452,15 +2486,27 @@ olap_opt: { LEX *lex=Lex; lex->olap = true; - lex->select->olap= CUBE_TYPE; + if (lex->current_select->linkage == GLOBAL_OPTIONS_TYPE) + { + net_printf(lex->thd, ER_WRONG_USAGE, "WITH CUBE", + "global union parameters"); + YYABORT; + } + lex->current_select->select_lex()->olap= CUBE_TYPE; net_printf(lex->thd, ER_NOT_SUPPORTED_YET, "CUBE"); YYABORT; /* To be deleted in 4.1 */ } | WITH ROLLUP_SYM { - LEX *lex=Lex; - lex->olap = true; - lex->select->olap= ROLLUP_TYPE; + LEX *lex= Lex; + lex->olap= true; + if (lex->current_select->linkage == GLOBAL_OPTIONS_TYPE) + { + net_printf(lex->thd, ER_WRONG_USAGE, "WITH ROLLUP", + "global union parameters"); + YYABORT; + } + lex->current_select->select_lex()->olap= ROLLUP_TYPE; net_printf(lex->thd, ER_NOT_SUPPORTED_YET, "ROLLUP"); YYABORT; /* To be deleted in 4.1 */ } @@ -2483,8 +2529,9 @@ order_clause: net_printf(lex->thd, ER_WRONG_USAGE, "UPDATE", "ORDER BY"); YYABORT; } - if (lex->select->linkage != GLOBAL_OPTIONS_TYPE && - lex->select->olap != UNSPECIFIED_OLAP_TYPE) + if (lex->current_select->linkage != GLOBAL_OPTIONS_TYPE && + lex->current_select->select_lex()->olap != + UNSPECIFIED_OLAP_TYPE) { net_printf(lex->thd, ER_WRONG_USAGE, "CUBE/ROLLUP", @@ -2509,29 +2556,31 @@ limit_clause: /* empty */ {} | LIMIT ULONG_NUM { - LEX *lex=Lex; - if (lex->select->linkage != GLOBAL_OPTIONS_TYPE && - lex->select->olap != UNSPECIFIED_OLAP_TYPE) + LEX *lex= Lex; + if (lex->current_select->linkage != GLOBAL_OPTIONS_TYPE && + lex->current_select->select_lex()->olap != + UNSPECIFIED_OLAP_TYPE) { net_printf(lex->thd, ER_WRONG_USAGE, "CUBE/ROLLUP", "LIMIT"); YYABORT; } - SELECT_LEX *sel=Select; + SELECT_LEX_NODE *sel= Select; sel->select_limit= $2; sel->offset_limit= 0L; } | LIMIT ULONG_NUM ',' ULONG_NUM { LEX *lex=Lex; - if (lex->select->linkage != GLOBAL_OPTIONS_TYPE && - lex->select->olap != UNSPECIFIED_OLAP_TYPE) + if (lex->current_select->linkage != GLOBAL_OPTIONS_TYPE && + lex->current_select->select_lex()->olap != + UNSPECIFIED_OLAP_TYPE) { net_printf(lex->thd, ER_WRONG_USAGE, "CUBE/ROLLUP", "LIMIT"); YYABORT; } - SELECT_LEX *sel=lex->select; + SELECT_LEX_NODE *sel= lex->current_select; sel->select_limit= $4; sel->offset_limit= $2; }; @@ -2545,7 +2594,7 @@ delete_limit_clause: net_printf(lex->thd, ER_WRONG_USAGE, "DELETE", "LIMIT"); YYABORT; } - lex->select->select_limit= HA_POS_ERROR; + lex->current_select->select_limit= HA_POS_ERROR; } | LIMIT ulonglong_num { Select->select_limit= (ha_rows) $2; }; @@ -2679,7 +2728,7 @@ drop: lex->drop_list.empty(); lex->drop_list.push_back(new Alter_drop(Alter_drop::KEY, $3.str)); - if (!add_table_to_list($5,NULL, 1)) + if (!lex->current_select->add_table_to_list($5,NULL, 1)) YYABORT; } | DROP DATABASE if_exists ident @@ -2703,7 +2752,7 @@ table_list: table_name: table_ident - { if (!add_table_to_list($1,NULL,1)) YYABORT; }; + { if (!Select->add_table_to_list($1, NULL, 1)) YYABORT; }; if_exists: /* empty */ { $$=0; } @@ -2848,11 +2897,9 @@ expr_or_default: update: UPDATE_SYM { - LEX *lex=Lex; - lex->sql_command = SQLCOM_UPDATE; - lex->select->order_list.elements=0; - lex->select->order_list.first=0; - lex->select->order_list.next= (byte**) &lex->select->order_list.first; + LEX *lex= Lex; + lex->sql_command= SQLCOM_UPDATE; + lex->select_lex.init_order(); } opt_low_priority opt_ignore join_table_list SET update_list where_clause opt_order_clause delete_limit_clause; @@ -2877,12 +2924,11 @@ opt_low_priority: delete: DELETE_SYM { - LEX *lex=Lex; - lex->sql_command= SQLCOM_DELETE; lex->select->options=0; + LEX *lex= Lex; + lex->sql_command= SQLCOM_DELETE; + lex->select_lex.options= 0; lex->lock_option= lex->thd->update_lock_default; - lex->select->order_list.elements=0; - lex->select->order_list.first=0; - lex->select->order_list.next= (byte**) &lex->select->order_list.first; + lex->select_lex.init_order(); } opt_delete_options single_multi {}; @@ -2902,12 +2948,14 @@ table_wild_list: table_wild_one: ident opt_wild { - if (!add_table_to_list(new Table_ident($1),NULL,1,TL_WRITE)) + if (!Select->add_table_to_list(new Table_ident($1), NULL, 1, + TL_WRITE)) YYABORT; } | ident '.' ident opt_wild { - if (!add_table_to_list(new Table_ident($1,$3,0),NULL,1,TL_WRITE)) + if (!Select->add_table_to_list(new Table_ident($1, $3, 0), NULL, + 1, TL_WRITE)) YYABORT; }; @@ -2927,13 +2975,11 @@ opt_delete_option: truncate: TRUNCATE_SYM opt_table_sym table_name { - LEX* lex = Lex; + LEX* lex= Lex; lex->sql_command= SQLCOM_TRUNCATE; - lex->select->options=0; - lex->select->order_list.elements=0; - lex->select->order_list.first=0; - lex->select->order_list.next= (byte**) &lex->select->order_list.first; - lex->lock_option= current_thd->update_lock_default; }; + lex->select_lex.options= 0; + lex->select_lex.init_order(); + lex->lock_option= lex->thd->update_lock_default; }; opt_table_sym: /* empty */ @@ -2948,30 +2994,31 @@ show_param: { Lex->sql_command= SQLCOM_SHOW_DATABASES; } | TABLES opt_db wild { - LEX *lex=Lex; + LEX *lex= Lex; lex->sql_command= SQLCOM_SHOW_TABLES; - lex->select->db= $2; lex->select->options=0; + lex->select_lex.db= $2; + lex->select_lex.options= 0; } | TABLE_SYM STATUS_SYM opt_db wild { - LEX *lex=Lex; + LEX *lex= Lex; lex->sql_command= SQLCOM_SHOW_TABLES; - lex->select->options|= SELECT_DESCRIBE; - lex->select->db= $3; + lex->select_lex.options|= SELECT_DESCRIBE; + lex->select_lex.db= $3; } | OPEN_SYM TABLES opt_db wild { - LEX *lex=Lex; + LEX *lex= Lex; lex->sql_command= SQLCOM_SHOW_OPEN_TABLES; - lex->select->db= $3; - lex->select->options=0; + lex->select_lex.db= $3; + lex->select_lex.options= 0; } | opt_full COLUMNS from_or_in table_ident opt_db wild { Lex->sql_command= SQLCOM_SHOW_FIELDS; if ($5) $4->change_db($5); - if (!add_table_to_list($4,NULL,0)) + if (!Select->add_table_to_list($4, NULL, 0)) YYABORT; } | NEW_SYM MASTER_SYM FOR_SYM SLAVE WITH MASTER_LOG_FILE_SYM EQ @@ -2994,17 +3041,17 @@ show_param: } | BINLOG_SYM EVENTS_SYM binlog_in binlog_from { - LEX *lex=Lex; - lex->sql_command = SQLCOM_SHOW_BINLOG_EVENTS; - lex->select->select_limit= lex->thd->variables.select_limit; - lex->select->offset_limit= 0L; + LEX *lex= Lex; + lex->sql_command= SQLCOM_SHOW_BINLOG_EVENTS; + lex->select_lex.select_limit= lex->thd->variables.select_limit; + lex->select_lex.offset_limit= 0L; } limit_clause | keys_or_index FROM table_ident opt_db { Lex->sql_command= SQLCOM_SHOW_KEYS; if ($4) $3->change_db($4); - if (!add_table_to_list($3,NULL,0)) + if (!Select->add_table_to_list($3, NULL, 0)) YYABORT; } | COLUMN_SYM TYPES_SYM @@ -3061,7 +3108,7 @@ show_param: | CREATE TABLE_SYM table_ident { Lex->sql_command = SQLCOM_SHOW_CREATE; - if(!add_table_to_list($3, NULL,0)) + if(!Select->add_table_to_list($3, NULL,0)) YYABORT; } | MASTER_SYM STATUS_SYM @@ -3106,7 +3153,7 @@ describe: lex->wild=0; lex->verbose=0; lex->sql_command=SQLCOM_SHOW_FIELDS; - if (!add_table_to_list($2, NULL,0)) + if (!Select->add_table_to_list($2, NULL,0)) YYABORT; } opt_describe_column @@ -3207,7 +3254,8 @@ kill: use: USE_SYM ident { LEX *lex=Lex; - lex->sql_command=SQLCOM_CHANGE_DB; lex->select->db= $2.str; + lex->sql_command=SQLCOM_CHANGE_DB; + lex->select_lex.db= $2.str; }; /* import, export of files */ @@ -3224,14 +3272,14 @@ load: LOAD DATA_SYM load_data_lock opt_local INFILE TEXT_STRING opt_duplicate INTO TABLE_SYM table_ident opt_field_term opt_line_term opt_ignore_lines opt_field_spec { - if (!add_table_to_list($11,NULL,1)) + if (!Select->add_table_to_list($11, NULL, 1)) YYABORT; } | LOAD TABLE_SYM table_ident FROM MASTER_SYM { Lex->sql_command = SQLCOM_LOAD_MASTER_TABLE; - if (!add_table_to_list($3,NULL,1)) + if (!Select->add_table_to_list($3, NULL, 1)) YYABORT; } @@ -3356,23 +3404,23 @@ order_ident: simple_ident: ident { - SELECT_LEX *sel=Select; - $$ = !sel->create_refs || sel->in_sum_expr > 0 ? (Item*) new Item_field(NullS,NullS,$1.str) : (Item*) new Item_ref(NullS,NullS,$1.str); + SELECT_LEX_NODE *sel=Select; + $$ = !sel->create_refs || sel->get_in_sum_expr() > 0 ? (Item*) new Item_field(NullS,NullS,$1.str) : (Item*) new Item_ref(NullS,NullS,$1.str); } | ident '.' ident { - SELECT_LEX *sel=Select; - $$ = !sel->create_refs || sel->in_sum_expr > 0 ? (Item*) new Item_field(NullS,$1.str,$3.str) : (Item*) new Item_ref(NullS,$1.str,$3.str); + SELECT_LEX_NODE *sel=Select; + $$ = !sel->create_refs || sel->get_in_sum_expr() > 0 ? (Item*) new Item_field(NullS,$1.str,$3.str) : (Item*) new Item_ref(NullS,$1.str,$3.str); } | '.' ident '.' ident { - SELECT_LEX *sel=Select; - $$ = !sel->create_refs || sel->in_sum_expr > 0 ? (Item*) new Item_field(NullS,$2.str,$4.str) : (Item*) new Item_ref(NullS,$2.str,$4.str); + SELECT_LEX_NODE *sel=Select; + $$ = !sel->create_refs || sel->get_in_sum_expr() > 0 ? (Item*) new Item_field(NullS,$2.str,$4.str) : (Item*) new Item_ref(NullS,$2.str,$4.str); } | ident '.' ident '.' ident { - SELECT_LEX *sel=Select; - $$ = !sel->create_refs || sel->in_sum_expr > 0 ? (Item*) new Item_field((current_thd->client_capabilities & CLIENT_NO_SCHEMA ? NullS :$1.str),$3.str,$5.str) : (Item*) new Item_ref((current_thd->client_capabilities & CLIENT_NO_SCHEMA ? NullS :$1.str),$3.str,$5.str); + SELECT_LEX_NODE *sel=Select; + $$ = !sel->create_refs || sel->get_in_sum_expr() > 0 ? (Item*) new Item_field((current_thd->client_capabilities & CLIENT_NO_SCHEMA ? NullS :$1.str),$3.str,$5.str) : (Item*) new Item_ref((current_thd->client_capabilities & CLIENT_NO_SCHEMA ? NullS :$1.str),$3.str,$5.str); }; @@ -3724,7 +3772,10 @@ table_lock_list: table_lock: table_ident opt_table_alias lock_option - { if (!add_table_to_list($1,$2,0,(thr_lock_type) $3)) YYABORT; } + { + if (!Select->add_table_to_list($1, $2, 0, (thr_lock_type) $3)) + YYABORT; + } ; lock_option: @@ -3746,14 +3797,16 @@ unlock: handler: HANDLER_SYM table_ident OPEN_SYM opt_table_alias { - Lex->sql_command = SQLCOM_HA_OPEN; - if (!add_table_to_list($2,$4,0)) + LEX *lex= Lex; + lex->sql_command = SQLCOM_HA_OPEN; + if (!lex->current_select->add_table_to_list($2, $4, 0)) YYABORT; } | HANDLER_SYM table_ident CLOSE_SYM { - Lex->sql_command = SQLCOM_HA_CLOSE; - if (!add_table_to_list($2,0,0)) + LEX *lex= Lex; + lex->sql_command = SQLCOM_HA_CLOSE; + if (!lex->current_select->add_table_to_list($2, 0, 0)) YYABORT; } | HANDLER_SYM table_ident READ_SYM @@ -3761,9 +3814,9 @@ handler: LEX *lex=Lex; lex->sql_command = SQLCOM_HA_READ; lex->ha_rkey_mode= HA_READ_KEY_EXACT; /* Avoid purify warnings */ - lex->select->select_limit= 1; - lex->select->offset_limit= 0L; - if (!add_table_to_list($2,0,0)) + lex->current_select->select_limit= 1; + lex->current_select->offset_limit= 0L; + if (!lex->current_select->add_table_to_list($2, 0, 0)) YYABORT; } handler_read_or_scan where_clause limit_clause { } @@ -3812,7 +3865,7 @@ revoke: lex->users_list.empty(); lex->columns.empty(); lex->grant= lex->grant_tot_col=0; - lex->select->db=0; + lex->select_lex.db=0; lex->ssl_type= SSL_TYPE_NOT_SPECIFIED; lex->ssl_cipher= lex->x509_subject= lex->x509_issuer= 0; bzero((char*) &lex->mqh, sizeof(lex->mqh)); @@ -3827,7 +3880,7 @@ grant: lex->columns.empty(); lex->sql_command = SQLCOM_GRANT; lex->grant= lex->grant_tot_col= 0; - lex->select->db= 0; + lex->select_lex.db= 0; lex->ssl_type= SSL_TYPE_NOT_SPECIFIED; lex->ssl_cipher= lex->x509_subject= lex->x509_issuer= 0; bzero(&(lex->mqh),sizeof(lex->mqh)); @@ -3917,8 +3970,8 @@ require_list_element: opt_table: '*' { - LEX *lex=Lex; - lex->select->db=lex->thd->db; + LEX *lex= Lex; + lex->current_select->select_lex()->db= lex->thd->db; if (lex->grant == GLOBAL_ACLS) lex->grant = DB_ACLS & ~GRANT_ACL; else if (lex->columns.elements) @@ -3929,8 +3982,8 @@ opt_table: } | ident '.' '*' { - LEX *lex=Lex; - lex->select->db = $1.str; + LEX *lex= Lex; + lex->current_select->select_lex()->db = $1.str; if (lex->grant == GLOBAL_ACLS) lex->grant = DB_ACLS & ~GRANT_ACL; else if (lex->columns.elements) @@ -3941,8 +3994,8 @@ opt_table: } | '*' '.' '*' { - LEX *lex=Lex; - lex->select->db = NULL; + LEX *lex= Lex; + lex->current_select->select_lex()->db = NULL; if (lex->grant == GLOBAL_ACLS) lex->grant= GLOBAL_ACLS & ~GRANT_ACL; else if (lex->columns.elements) @@ -3954,7 +4007,7 @@ opt_table: | table_ident { LEX *lex=Lex; - if (!add_table_to_list($1,NULL,0)) + if (!lex->current_select->add_table_to_list($1,NULL,0)) YYABORT; if (lex->grant == GLOBAL_ACLS) lex->grant = TABLE_ACLS & ~GRANT_ACL; @@ -4109,14 +4162,14 @@ union_list: net_printf(lex->thd, ER_WRONG_USAGE, "UNION", "INTO"); YYABORT; } - if (lex->select->linkage == GLOBAL_OPTIONS_TYPE) + if (lex->current_select->linkage == GLOBAL_OPTIONS_TYPE) { send_error(lex->thd, ER_SYNTAX_ERROR); YYABORT; } if (mysql_new_select(lex, 0)) YYABORT; - lex->select->linkage=UNION_TYPE; + lex->current_select->linkage=UNION_TYPE; } select_init ; @@ -4130,19 +4183,17 @@ optional_order_or_limit: | { LEX *lex=Lex; - if (!lex->select->braces) + if (!lex->current_select->linkage == GLOBAL_OPTIONS_TYPE) { send_error(lex->thd, ER_SYNTAX_ERROR); YYABORT; } - lex->select->master_unit()->global_parameters= - lex->select->master_unit(); - /* - Following type conversion looks like hack, but all that need - SELECT_LEX fields always check linkage type. - */ - lex->select= (SELECT_LEX*)lex->select->master_unit(); - lex->select->select_limit=lex->thd->variables.select_limit; + SELECT_LEX *sel= lex->current_select->select_lex(); + sel->master_unit()->global_parameters= + sel->master_unit(); + lex->current_select= sel->master_unit(); + lex->current_select->select_limit= + lex->thd->variables.select_limit; } opt_order_clause limit_clause ; @@ -4162,7 +4213,8 @@ singleval_subselect_init: select_init { $$= new Item_singleval_subselect(current_thd, - Lex->select->master_unit()->first_select()); + Lex->current_select->master_unit()-> + first_select()); }; exists_subselect: @@ -4176,7 +4228,8 @@ exists_subselect_init: select_init { $$= new Item_exists_subselect(current_thd, - Lex->select->master_unit()->first_select()); + Lex->current_select->master_unit()-> + first_select()); }; subselect_start: @@ -4190,5 +4243,5 @@ subselect_end: ')' { LEX *lex=Lex; - lex->select = lex->select->outer_select(); + lex->current_select = lex->current_select->outer_select(); }; |