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

reverse order in global select list allow to avoid recursion in derived tables

parent 6b403114
...@@ -43,7 +43,7 @@ int mysql_delete(THD *thd, TABLE_LIST *table_list, COND *conds, ORDER *order, ...@@ -43,7 +43,7 @@ int mysql_delete(THD *thd, TABLE_LIST *table_list, COND *conds, ORDER *order,
if ((open_and_lock_tables(thd, table_list))) if ((open_and_lock_tables(thd, table_list)))
DBUG_RETURN(-1); DBUG_RETURN(-1);
fix_tables_pointers(&thd->lex.select_lex); fix_tables_pointers(thd->lex.all_selects_list);
table= table_list->table; table= table_list->table;
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";
......
...@@ -50,21 +50,6 @@ int mysql_derived(THD *thd, LEX *lex, SELECT_LEX_UNIT *unit, TABLE_LIST *t) ...@@ -50,21 +50,6 @@ int mysql_derived(THD *thd, LEX *lex, SELECT_LEX_UNIT *unit, TABLE_LIST *t)
if (res) if (res)
DBUG_RETURN(-1); DBUG_RETURN(-1);
for (SELECT_LEX *ssl= sl; ssl; ssl= ssl->next_select_in_list())
{
TABLE_LIST *t_tables= (TABLE_LIST *)ssl->table_list.first;
for (TABLE_LIST *cursor= (TABLE_LIST *)t_tables;
cursor;
cursor=cursor->next)
{
if (cursor->derived)
{
res= mysql_derived(thd, lex, (SELECT_LEX_UNIT *)cursor->derived,
cursor);
if (res) DBUG_RETURN(res);
}
}
}
Item *item; Item *item;
List_iterator<Item> it(sl->item_list); List_iterator<Item> it(sl->item_list);
......
...@@ -157,7 +157,7 @@ int mysql_insert(THD *thd,TABLE_LIST *table_list, List<Item> &fields, ...@@ -157,7 +157,7 @@ int mysql_insert(THD *thd,TABLE_LIST *table_list, List<Item> &fields,
res= open_and_lock_tables(thd, table_list); res= open_and_lock_tables(thd, table_list);
if (res) if (res)
DBUG_RETURN(-1); DBUG_RETURN(-1);
fix_tables_pointers(&thd->lex.select_lex); fix_tables_pointers(thd->lex.all_selects_list);
table= table_list->table; table= table_list->table;
thd->proc_info="init"; thd->proc_info="init";
......
...@@ -388,6 +388,8 @@ typedef struct st_lex ...@@ -388,6 +388,8 @@ typedef struct st_lex
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_LEX_NODE *current_select; SELECT_LEX_NODE *current_select;
/* list of all SELECT_LEX */
SELECT_LEX *all_selects_list;
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 */
......
...@@ -1316,7 +1316,7 @@ mysql_execute_command(THD *thd) ...@@ -1316,7 +1316,7 @@ mysql_execute_command(THD *thd)
that is not a SHOW command or a select that only access local that is not a SHOW command or a select that only access local
variables, but for now this is probably good enough. variables, but for now this is probably good enough.
*/ */
if (tables || lex->select_lex.next_select_in_list()) if (tables || &lex->select_lex != lex->all_selects_list)
mysql_reset_errors(thd); mysql_reset_errors(thd);
/* /*
Save old warning count to be able to send to client how many warnings we Save old warning count to be able to send to client how many warnings we
...@@ -1353,22 +1353,23 @@ mysql_execute_command(THD *thd) ...@@ -1353,22 +1353,23 @@ mysql_execute_command(THD *thd)
*/ */
if (lex->derived_tables) if (lex->derived_tables)
{ {
for (SELECT_LEX *sl= &lex->select_lex; sl; sl= sl->next_select_in_list()) for (SELECT_LEX *sl= lex->all_selects_list;
if (sl->linkage != DERIVED_TABLE_TYPE) sl;
for (TABLE_LIST *cursor= sl->get_table_list(); sl= sl->next_select_in_list())
cursor; for (TABLE_LIST *cursor= sl->get_table_list();
cursor= cursor->next) cursor;
if (cursor->derived && (res=mysql_derived(thd, lex, cursor= cursor->next)
(SELECT_LEX_UNIT *) if (cursor->derived && (res=mysql_derived(thd, lex,
cursor->derived, (SELECT_LEX_UNIT *)
cursor))) cursor->derived,
{ cursor)))
if (res < 0 || thd->net.report_error) {
send_error(thd,thd->killed ? ER_SERVER_SHUTDOWN : 0); if (res < 0 || thd->net.report_error)
DBUG_VOID_RETURN; send_error(thd,thd->killed ? ER_SERVER_SHUTDOWN : 0);
} DBUG_VOID_RETURN;
} }
if ((lex->select_lex.next_select_in_list() && }
if ((&lex->select_lex != lex->all_selects_list &&
lex->unit.create_total_list(thd, lex, &tables)) || lex->unit.create_total_list(thd, lex, &tables)) ||
(table_rules_on && tables && thd->slave_thread && (table_rules_on && tables && thd->slave_thread &&
!tables_ok(thd,tables))) !tables_ok(thd,tables)))
...@@ -1415,7 +1416,7 @@ mysql_execute_command(THD *thd) ...@@ -1415,7 +1416,7 @@ mysql_execute_command(THD *thd)
} }
else else
thd->send_explain_fields(result); thd->send_explain_fields(result);
fix_tables_pointers(select_lex); fix_tables_pointers(lex->all_selects_list);
res= mysql_explain_union(thd, &thd->lex.unit, result); res= mysql_explain_union(thd, &thd->lex.unit, result);
MYSQL_LOCK *save_lock= thd->lock; MYSQL_LOCK *save_lock= thd->lock;
thd->lock= (MYSQL_LOCK *)0; thd->lock= (MYSQL_LOCK *)0;
...@@ -2841,9 +2842,11 @@ mysql_init_query(THD *thd) ...@@ -2841,9 +2842,11 @@ mysql_init_query(THD *thd)
lex->value_list.empty(); lex->value_list.empty();
lex->param_list.empty(); lex->param_list.empty();
lex->unit.global_parameters= lex->unit.slave= lex->current_select= lex->unit.global_parameters= lex->unit.slave= lex->current_select=
&lex->select_lex; lex->all_selects_list= &lex->select_lex;
lex->select_lex.master= &lex->unit; lex->select_lex.master= &lex->unit;
lex->select_lex.prev= &lex->unit.slave; lex->select_lex.prev= &lex->unit.slave;
lex->select_lex.link_next= 0;
lex->select_lex.link_prev= (st_select_lex_node**)&(lex->all_selects_list);
lex->olap=lex->describe=0; lex->olap=lex->describe=0;
lex->derived_tables= false; lex->derived_tables= false;
thd->check_loops_counter= thd->select_number= thd->check_loops_counter= thd->select_number=
...@@ -2896,8 +2899,7 @@ mysql_new_select(LEX *lex, bool move_down) ...@@ -2896,8 +2899,7 @@ mysql_new_select(LEX *lex, bool move_down)
select_lex->master_unit()->global_parameters= select_lex; select_lex->master_unit()->global_parameters= select_lex;
DBUG_ASSERT(lex->current_select->linkage != GLOBAL_OPTIONS_TYPE); DBUG_ASSERT(lex->current_select->linkage != GLOBAL_OPTIONS_TYPE);
select_lex->include_global(lex->current_select->select_lex()-> select_lex->include_global((st_select_lex_node**)&lex->all_selects_list);
next_select_in_list_addr());
lex->current_select= select_lex; lex->current_select= select_lex;
return 0; return 0;
} }
......
...@@ -158,7 +158,7 @@ int handle_select(THD *thd, LEX *lex, select_result *result) ...@@ -158,7 +158,7 @@ int handle_select(THD *thd, LEX *lex, select_result *result)
{ {
int res; int res;
register SELECT_LEX *select_lex = &lex->select_lex; register SELECT_LEX *select_lex = &lex->select_lex;
fix_tables_pointers(select_lex); fix_tables_pointers(lex->all_selects_list);
if (select_lex->next_select()) if (select_lex->next_select())
res=mysql_union(thd,lex,result); res=mysql_union(thd,lex,result);
else else
...@@ -7514,7 +7514,7 @@ int mysql_explain_union(THD *thd, SELECT_LEX_UNIT *unit, select_result *result) ...@@ -7514,7 +7514,7 @@ int mysql_explain_union(THD *thd, SELECT_LEX_UNIT *unit, select_result *result)
{ {
res= mysql_explain_select(thd, sl, res= mysql_explain_select(thd, sl,
(((&thd->lex.select_lex)==sl)? (((&thd->lex.select_lex)==sl)?
((sl->next_select_in_list())?"PRIMARY": ((thd->lex.all_selects_list != sl)?"PRIMARY":
"SIMPLE"): "SIMPLE"):
((sl == first)? ((sl == first)?
((sl->linkage == DERIVED_TABLE_TYPE) ? ((sl->linkage == DERIVED_TABLE_TYPE) ?
......
...@@ -70,7 +70,7 @@ int mysql_update(THD *thd, ...@@ -70,7 +70,7 @@ int mysql_update(THD *thd,
if ((open_and_lock_tables(thd, table_list))) if ((open_and_lock_tables(thd, table_list)))
DBUG_RETURN(-1); DBUG_RETURN(-1);
fix_tables_pointers(&thd->lex.select_lex); fix_tables_pointers(thd->lex.all_selects_list);
table= table_list->table; table= table_list->table;
save_time_stamp=table->time_stamp; save_time_stamp=table->time_stamp;
......
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