diff options
author | bell@sanja.is.com.ua <> | 2002-11-27 01:12:16 +0200 |
---|---|---|
committer | bell@sanja.is.com.ua <> | 2002-11-27 01:12:16 +0200 |
commit | aa8af5d6f419b66477c1833f876ba30bce49cdd0 (patch) | |
tree | e798cab447b943542fca85b603038f2ef6b821f2 /sql | |
parent | 6b403114a2ed92a05c8c0a3df30847b6cac9e4ca (diff) | |
download | mariadb-git-aa8af5d6f419b66477c1833f876ba30bce49cdd0.tar.gz |
reverse order in global select list allow to avoid recursion in derived tables
Diffstat (limited to 'sql')
-rw-r--r-- | sql/sql_delete.cc | 2 | ||||
-rw-r--r-- | sql/sql_derived.cc | 15 | ||||
-rw-r--r-- | sql/sql_insert.cc | 2 | ||||
-rw-r--r-- | sql/sql_lex.h | 2 | ||||
-rw-r--r-- | sql/sql_parse.cc | 44 | ||||
-rw-r--r-- | sql/sql_select.cc | 4 | ||||
-rw-r--r-- | sql/sql_update.cc | 2 |
7 files changed, 30 insertions, 41 deletions
diff --git a/sql/sql_delete.cc b/sql/sql_delete.cc index 5b97b2f7750..07958ebcfab 100644 --- a/sql/sql_delete.cc +++ b/sql/sql_delete.cc @@ -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))) DBUG_RETURN(-1); - fix_tables_pointers(&thd->lex.select_lex); + fix_tables_pointers(thd->lex.all_selects_list); table= table_list->table; table->file->info(HA_STATUS_VARIABLE | HA_STATUS_NO_LOCK); thd->proc_info="init"; diff --git a/sql/sql_derived.cc b/sql/sql_derived.cc index 6dc001a1932..afdd1ccfdb2 100644 --- a/sql/sql_derived.cc +++ b/sql/sql_derived.cc @@ -50,21 +50,6 @@ int mysql_derived(THD *thd, LEX *lex, SELECT_LEX_UNIT *unit, TABLE_LIST *t) if (res) 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; List_iterator<Item> it(sl->item_list); diff --git a/sql/sql_insert.cc b/sql/sql_insert.cc index 295c1e339c5..1ca44046997 100644 --- a/sql/sql_insert.cc +++ b/sql/sql_insert.cc @@ -157,7 +157,7 @@ int mysql_insert(THD *thd,TABLE_LIST *table_list, List<Item> &fields, res= open_and_lock_tables(thd, table_list); if (res) DBUG_RETURN(-1); - fix_tables_pointers(&thd->lex.select_lex); + fix_tables_pointers(thd->lex.all_selects_list); table= table_list->table; thd->proc_info="init"; diff --git a/sql/sql_lex.h b/sql/sql_lex.h index 93f01dd66dc..65c6f4ceb49 100644 --- a/sql/sql_lex.h +++ b/sql/sql_lex.h @@ -388,6 +388,8 @@ typedef struct st_lex SELECT_LEX select_lex; /* first SELECT_LEX */ /* current SELECT_LEX in parsing */ SELECT_LEX_NODE *current_select; + /* list of all SELECT_LEX */ + SELECT_LEX *all_selects_list; 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 86333552837..7a1277e75bd 100644 --- a/sql/sql_parse.cc +++ b/sql/sql_parse.cc @@ -1316,7 +1316,7 @@ mysql_execute_command(THD *thd) that is not a SHOW command or a select that only access local 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); /* Save old warning count to be able to send to client how many warnings we @@ -1353,22 +1353,23 @@ mysql_execute_command(THD *thd) */ if (lex->derived_tables) { - for (SELECT_LEX *sl= &lex->select_lex; sl; sl= sl->next_select_in_list()) - if (sl->linkage != DERIVED_TABLE_TYPE) - for (TABLE_LIST *cursor= sl->get_table_list(); - cursor; - cursor= cursor->next) - if (cursor->derived && (res=mysql_derived(thd, lex, - (SELECT_LEX_UNIT *) - cursor->derived, - cursor))) - { - if (res < 0 || thd->net.report_error) - send_error(thd,thd->killed ? ER_SERVER_SHUTDOWN : 0); - DBUG_VOID_RETURN; - } - } - if ((lex->select_lex.next_select_in_list() && + for (SELECT_LEX *sl= lex->all_selects_list; + sl; + sl= sl->next_select_in_list()) + for (TABLE_LIST *cursor= sl->get_table_list(); + cursor; + cursor= cursor->next) + if (cursor->derived && (res=mysql_derived(thd, lex, + (SELECT_LEX_UNIT *) + cursor->derived, + cursor))) + { + if (res < 0 || thd->net.report_error) + send_error(thd,thd->killed ? ER_SERVER_SHUTDOWN : 0); + DBUG_VOID_RETURN; + } + } + if ((&lex->select_lex != lex->all_selects_list && lex->unit.create_total_list(thd, lex, &tables)) || (table_rules_on && tables && thd->slave_thread && !tables_ok(thd,tables))) @@ -1415,7 +1416,7 @@ mysql_execute_command(THD *thd) } else 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); MYSQL_LOCK *save_lock= thd->lock; thd->lock= (MYSQL_LOCK *)0; @@ -2841,9 +2842,11 @@ mysql_init_query(THD *thd) lex->value_list.empty(); lex->param_list.empty(); 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.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->derived_tables= false; thd->check_loops_counter= thd->select_number= @@ -2896,8 +2899,7 @@ mysql_new_select(LEX *lex, bool move_down) select_lex->master_unit()->global_parameters= 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()); + select_lex->include_global((st_select_lex_node**)&lex->all_selects_list); lex->current_select= select_lex; return 0; } diff --git a/sql/sql_select.cc b/sql/sql_select.cc index 8f406efc030..bb7f23a6710 100644 --- a/sql/sql_select.cc +++ b/sql/sql_select.cc @@ -158,7 +158,7 @@ int handle_select(THD *thd, LEX *lex, select_result *result) { int res; 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()) res=mysql_union(thd,lex,result); else @@ -7514,7 +7514,7 @@ int mysql_explain_union(THD *thd, SELECT_LEX_UNIT *unit, select_result *result) { res= mysql_explain_select(thd, sl, (((&thd->lex.select_lex)==sl)? - ((sl->next_select_in_list())?"PRIMARY": + ((thd->lex.all_selects_list != sl)?"PRIMARY": "SIMPLE"): ((sl == first)? ((sl->linkage == DERIVED_TABLE_TYPE) ? diff --git a/sql/sql_update.cc b/sql/sql_update.cc index 409b00b5703..c2ba65248a7 100644 --- a/sql/sql_update.cc +++ b/sql/sql_update.cc @@ -70,7 +70,7 @@ int mysql_update(THD *thd, if ((open_and_lock_tables(thd, table_list))) DBUG_RETURN(-1); - fix_tables_pointers(&thd->lex.select_lex); + fix_tables_pointers(thd->lex.all_selects_list); table= table_list->table; save_time_stamp=table->time_stamp; |