Commit ded512d5 authored by bell@sanja.is.com.ua's avatar bell@sanja.is.com.ua

Merge sanja.is.com.ua:/home/bell/mysql/mysql-4.1

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