diff options
author | unknown <Sinisa@sinisa.nasamreza.org> | 2003-03-06 17:02:10 +0200 |
---|---|---|
committer | unknown <Sinisa@sinisa.nasamreza.org> | 2003-03-06 17:02:10 +0200 |
commit | 236015ed7ac81e3a4525e04a7769cf503af38e14 (patch) | |
tree | 41aacee98da8f1449de6964c7b87878106bb88ca /sql | |
parent | 6f5ea7022660f62e8e434c968f0d256aa8c8e47c (diff) | |
download | mariadb-git-236015ed7ac81e3a4525e04a7769cf503af38e14.tar.gz |
three bug fixes and major code cleanup
Diffstat (limited to 'sql')
-rw-r--r-- | sql/item_subselect.cc | 2 | ||||
-rw-r--r-- | sql/mysql_priv.h | 3 | ||||
-rw-r--r-- | sql/sql_derived.cc | 2 | ||||
-rw-r--r-- | sql/sql_lex.h | 12 | ||||
-rw-r--r-- | sql/sql_parse.cc | 2 | ||||
-rw-r--r-- | sql/sql_prepare.cc | 2 | ||||
-rw-r--r-- | sql/sql_select.cc | 30 | ||||
-rw-r--r-- | sql/sql_select.h | 3 | ||||
-rw-r--r-- | sql/sql_union.cc | 64 | ||||
-rw-r--r-- | sql/sql_update.cc | 2 |
10 files changed, 71 insertions, 51 deletions
diff --git a/sql/item_subselect.cc b/sql/item_subselect.cc index fb51b5561e9..524bb74d5a5 100644 --- a/sql/item_subselect.cc +++ b/sql/item_subselect.cc @@ -684,7 +684,7 @@ int subselect_single_select_engine::prepare() (ORDER*) select_lex->group_list.first, select_lex->having, (ORDER*) 0, select_lex, - select_lex->master_unit(), 0, 0)) + select_lex->master_unit(), 0)) return 1; thd->lex.current_select= save_select; return 0; diff --git a/sql/mysql_priv.h b/sql/mysql_priv.h index 5bf7e6e6951..df3e3f867e0 100644 --- a/sql/mysql_priv.h +++ b/sql/mysql_priv.h @@ -405,8 +405,7 @@ int mysql_select(THD *thd, Item ***rref_pointer_array, COND *conds, uint og_num, ORDER *order, ORDER *group, Item *having, ORDER *proc_param, ulong select_type, select_result *result, SELECT_LEX_UNIT *unit, - SELECT_LEX *select_lex, bool fake_select_lex, - bool tables_and_fields_initied); + SELECT_LEX *select_lex, bool tables_and_fields_initied); void free_underlaid_joins(THD *thd, SELECT_LEX *select); void fix_tables_pointers(SELECT_LEX *select_lex); void fix_tables_pointers(SELECT_LEX_UNIT *select_lex); diff --git a/sql/sql_derived.cc b/sql/sql_derived.cc index c0a4436a059..f2cddeead2f 100644 --- a/sql/sql_derived.cc +++ b/sql/sql_derived.cc @@ -172,7 +172,7 @@ int mysql_derived(THD *thd, LEX *lex, SELECT_LEX_UNIT *unit, (ORDER *) select_cursor->group_list.first, select_cursor->having, (ORDER*) NULL, select_cursor->options | thd->options | SELECT_NO_UNLOCK, - derived_result, unit, select_cursor, 0, 1); + derived_result, unit, select_cursor, 1); if (!res) { diff --git a/sql/sql_lex.h b/sql/sql_lex.h index aff3485dbe4..c0f24d6940e 100644 --- a/sql/sql_lex.h +++ b/sql/sql_lex.h @@ -311,6 +311,11 @@ public: 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_in_union() + { + return (slave && slave->linkage == GLOBAL_OPTIONS_TYPE) ? + (st_select_lex*) slave->next : (st_select_lex*) slave; + } st_select_lex_unit* next_unit() { return (st_select_lex_unit*) next; } void exclude_level(); @@ -404,6 +409,13 @@ public: } friend void mysql_init_query(THD *thd); + void make_empty_select(st_select_lex *last_select) + { + select_number=INT_MAX; + init_query(); + init_select(); + include_neighbour(last_select); + } }; typedef class st_select_lex SELECT_LEX; diff --git a/sql/sql_parse.cc b/sql/sql_parse.cc index ce782b0480c..78986c88062 100644 --- a/sql/sql_parse.cc +++ b/sql/sql_parse.cc @@ -2433,7 +2433,7 @@ mysql_execute_command(THD *thd) (ORDER *)NULL, select_lex->options | thd->options | SELECT_NO_JOIN_CACHE, - result, unit, select_lex, 0, 0); + result, unit, select_lex, 0); if (thd->net.report_error) res= -1; delete result; diff --git a/sql/sql_prepare.cc b/sql/sql_prepare.cc index 3cb4c4e8244..eefd1b5d4e1 100644 --- a/sql/sql_prepare.cc +++ b/sql/sql_prepare.cc @@ -567,7 +567,7 @@ static bool mysql_test_select_fields(PREP_STMT *stmt, TABLE_LIST *tables, if (join->prepare(&select_lex->ref_pointer_array, tables, wild_num, conds, og_num, order, group, having, proc, - select_lex, unit, 0, 0)) + select_lex, unit, 0)) DBUG_RETURN(1); /* diff --git a/sql/sql_select.cc b/sql/sql_select.cc index 47fe271f2b6..23381831ce3 100644 --- a/sql/sql_select.cc +++ b/sql/sql_select.cc @@ -182,7 +182,7 @@ int handle_select(THD *thd, LEX *lex, select_result *result) select_lex->having, (ORDER*) lex->proc_list.first, select_lex->options | thd->options, - result, &(lex->unit), &(lex->select_lex), 0, 0); + result, &(lex->unit), &(lex->select_lex), 0); if (res && result) result->abort(); @@ -268,7 +268,7 @@ JOIN::prepare(Item ***rref_pointer_array, Item *having_init, ORDER *proc_param_init, SELECT_LEX *select, SELECT_LEX_UNIT *unit, - bool fake_select_lex, bool tables_and_fields_initied) + bool tables_and_fields_initied) { DBUG_ENTER("JOIN::prepare"); @@ -279,8 +279,7 @@ JOIN::prepare(Item ***rref_pointer_array, proc_param= proc_param_init; tables_list= tables_init; select_lex= select; - if (!fake_select_lex) - select_lex->join= this; + select_lex->join= this; union_part= (unit->first_select()->next_select() != 0); /* Check that all tables, fields, conds and order are ok */ @@ -1261,7 +1260,6 @@ int JOIN::cleanup(THD *thd) { DBUG_ENTER("JOIN::cleanup"); - select_lex->join= 0; if (tmp_join) @@ -1292,15 +1290,14 @@ mysql_select(THD *thd, Item ***rref_pointer_array, COND *conds, uint og_num, ORDER *order, ORDER *group, Item *having, ORDER *proc_param, ulong select_options, select_result *result, SELECT_LEX_UNIT *unit, - SELECT_LEX *select_lex, bool fake_select_lex, - bool tables_and_fields_initied) + SELECT_LEX *select_lex, bool tables_and_fields_initied) { int err; bool free_join= 1; DBUG_ENTER("mysql_select"); JOIN *join; - if (!fake_select_lex && select_lex->join != 0) + if (select_lex->join != 0) { //here is EXPLAIN of subselect or derived table join= select_lex->join; @@ -1320,8 +1317,7 @@ mysql_select(THD *thd, Item ***rref_pointer_array, if (join->prepare(rref_pointer_array, tables, wild_num, conds, og_num, order, group, having, proc_param, - select_lex, unit, fake_select_lex, - tables_and_fields_initied)) + select_lex, unit, tables_and_fields_initied)) { DBUG_RETURN(-1); } @@ -1350,7 +1346,7 @@ err: thd->limit_found_rows= curr_join->send_records; thd->examined_row_count= curr_join->examined_rows; thd->proc_info="end"; - err= (fake_select_lex ? curr_join->error : join->cleanup(thd)); + err= join->cleanup(thd); if (thd->net.report_error) err= -1; delete join; @@ -7086,15 +7082,16 @@ find_order_in_list(THD *thd, Item **ref_pointer_array, TABLE_LIST *tables,ORDER *order, List<Item> &fields, List<Item> &all_fields) { - if ((*order->item)->type() == Item::INT_ITEM) + Item *itemptr=*order->item; + if (itemptr->type() == Item::INT_ITEM) { /* Order by position */ Item *item=0; - uint count= (uint) ((Item_int*) (*order->item))->value; + uint count= (uint) ((Item_int*)itemptr)->value; if (count > fields.elements) { my_printf_error(ER_BAD_FIELD_ERROR,ER(ER_BAD_FIELD_ERROR), - MYF(0),(*order->item)->full_name(), + MYF(0),itemptr->full_name(), thd->where); return 1; } @@ -7103,8 +7100,7 @@ find_order_in_list(THD *thd, Item **ref_pointer_array, return 0; } uint counter; - Item **item= find_item_in_list(*order->item, fields, &counter, - IGNORE_ERRORS); + Item **item= find_item_in_list(itemptr, fields, &counter, IGNORE_ERRORS); if (item) { order->item= ref_pointer_array + counter; @@ -8103,7 +8099,7 @@ int mysql_explain_select(THD *thd, SELECT_LEX *select_lex, char const *type, select_lex->having, (ORDER*) thd->lex.proc_list.first, select_lex->options | thd->options | SELECT_DESCRIBE, - result, unit, select_lex, 0, 0); + result, unit, select_lex, 0); DBUG_RETURN(res); } diff --git a/sql/sql_select.h b/sql/sql_select.h index bb928846186..c5411a8790b 100644 --- a/sql/sql_select.h +++ b/sql/sql_select.h @@ -256,8 +256,7 @@ class JOIN :public Sql_alloc int prepare(Item ***rref_pointer_array, TABLE_LIST *tables, uint wind_num, COND *conds, uint og_num, ORDER *order, ORDER *group, Item *having, ORDER *proc_param, SELECT_LEX *select, - SELECT_LEX_UNIT *unit, bool fake_select_lex, - bool tables_and_fields_initied); + SELECT_LEX_UNIT *unit, bool tables_and_fields_initied); int optimize(); int reinit(); void exec(); diff --git a/sql/sql_union.cc b/sql/sql_union.cc index feaa8371acb..607f3007d1d 100644 --- a/sql/sql_union.cc +++ b/sql/sql_union.cc @@ -122,9 +122,9 @@ int st_select_lex_unit::prepare(THD *thd, select_result *result, this->result= result; t_and_f= tables_and_fields_initied; SELECT_LEX_NODE *lex_select_save= thd->lex.current_select; - SELECT_LEX *sl; + SELECT_LEX *select_cursor; - thd->lex.current_select= sl= first_select(); + thd->lex.current_select= select_cursor= first_select_in_union(); /* Global option */ if (((void*)(global_parameters)) == ((void*)this)) { @@ -136,26 +136,27 @@ int st_select_lex_unit::prepare(THD *thd, select_result *result, if (t_and_f) { // Item list and tables will be initialized by mysql_derived - item_list= sl->item_list; + item_list= select_cursor->item_list; } else { item_list.empty(); - TABLE_LIST *first_table= (TABLE_LIST*) first_select()->table_list.first; + TABLE_LIST *first_table= (TABLE_LIST*) select_cursor->table_list.first; if (setup_tables(first_table) || - setup_wild(thd, first_table, sl->item_list, 0, sl->with_wild)) + setup_wild(thd, first_table, select_cursor->item_list, 0, select_cursor->with_wild)) goto err; - List_iterator<Item> it(sl->item_list); + List_iterator<Item> it(select_cursor->item_list); Item *item; while((item=it++)) item->maybe_null=1; - item_list= sl->item_list; - sl->with_wild= 0; - if (setup_ref_array(thd, &sl->ref_pointer_array, - (item_list.elements + sl->with_sum_func + - sl->order_list.elements + sl->group_list.elements)) || - setup_fields(thd, sl->ref_pointer_array, first_table, item_list, + item_list= select_cursor->item_list; + select_cursor->with_wild= 0; + if (setup_ref_array(thd, &select_cursor->ref_pointer_array, + (item_list.elements + select_cursor->with_sum_func + + select_cursor->order_list.elements + + select_cursor->group_list.elements)) || + setup_fields(thd, select_cursor->ref_pointer_array, first_table, item_list, 0, 0, 1)) goto err; t_and_f= 1; @@ -165,7 +166,7 @@ int st_select_lex_unit::prepare(THD *thd, select_result *result, tmp_table_param.field_count=item_list.elements; if (!(table= create_tmp_table(thd, &tmp_table_param, item_list, (ORDER*) 0, !union_option, - 1, (first_select()->options | thd->options | + 1, (select_cursor->options | thd->options | TMP_TABLE_ALL_COLUMNS), HA_POS_ERROR))) goto err; @@ -181,9 +182,16 @@ int st_select_lex_unit::prepare(THD *thd, select_result *result, union_result->not_describe=1; union_result->tmp_table_param=&tmp_table_param; + +/* + the following piece of code is placed here solely for the purpose of + getting correct results with EXPLAIN when UNION is withing a sub-select + or derived table ... +*/ + if (thd->lex.describe) { - for (SELECT_LEX *sl= first_select(); sl; sl= sl->next_select()) + for (SELECT_LEX *sl= select_cursor; sl; sl= sl->next_select()) { JOIN *join= new JOIN(thd, sl->item_list, sl->options | thd->options | SELECT_NO_UNLOCK, @@ -206,16 +214,17 @@ int st_select_lex_unit::prepare(THD *thd, select_result *result, (ORDER*) sl->group_list.first, sl->having, (ORDER*) NULL, - sl, this, 0, t_and_f); + sl, this, t_and_f); t_and_f= 0; if (res | thd->is_fatal_error) goto err; } } + item_list.empty(); thd->lex.current_select= lex_select_save; { - List_iterator<Item> it(first_select()->item_list); + List_iterator<Item> it(select_cursor->item_list); Field **field; for (field= table->field; *field; field++) @@ -236,7 +245,8 @@ int st_select_lex_unit::exec() { DBUG_ENTER("st_select_lex_unit::exec"); SELECT_LEX_NODE *lex_select_save= thd->lex.current_select; - + SELECT_LEX *select_cursor=first_select_in_union(), *last_select; + if (executed && !(dependent || uncacheable)) DBUG_RETURN(0); executed= 1; @@ -249,8 +259,9 @@ int st_select_lex_unit::exec() item->reset(); table->file->delete_all_rows(); } - for (SELECT_LEX *sl= first_select(); sl; sl= sl->next_select()) + for (SELECT_LEX *sl= select_cursor; sl; sl= sl->next_select()) { + last_select=sl; if (optimized) res= sl->join->reinit(); else @@ -276,7 +287,7 @@ int st_select_lex_unit::exec() (ORDER*) sl->group_list.first, sl->having, (ORDER*) NULL, - sl, this, 0, t_and_f); + sl, this, t_and_f); t_and_f=0; if (res | thd->is_fatal_error) { @@ -307,7 +318,7 @@ int st_select_lex_unit::exec() /* Send result to 'result' */ // to correct ORDER BY reference resolving - thd->lex.current_select = first_select(); + thd->lex.current_select = select_cursor; res =-1; { #if 0 @@ -321,9 +332,10 @@ int st_select_lex_unit::exec() if (!thd->is_fatal_error) // Check if EOM { - SELECT_LEX *sl=thd->lex.current_select->master_unit()->first_select(); - offset_limit_cnt= (sl->braces) ? global_parameters->offset_limit : 0; - select_limit_cnt= (sl->braces) ? global_parameters->select_limit+ + SELECT_LEX *fake_select = new SELECT_LEX(); + fake_select->make_empty_select(last_select); + offset_limit_cnt= (select_cursor->braces) ? global_parameters->offset_limit : 0; + select_limit_cnt= (select_cursor->braces) ? global_parameters->select_limit+ global_parameters->offset_limit : HA_POS_ERROR; if (select_limit_cnt < global_parameters->select_limit) select_limit_cnt= HA_POS_ERROR; // no limit @@ -334,9 +346,11 @@ int st_select_lex_unit::exec() global_parameters->order_list.elements, (ORDER*)global_parameters->order_list.first, (ORDER*) NULL, NULL, (ORDER*) NULL, - thd->options, result, this, first_select(), 1, 0); + thd->options, result, this, fake_select, 0); if (found_rows_for_union && !res) thd->limit_found_rows = (ulonglong)table->file->records; + fake_select->exclude(); + delete fake_select; } } thd->lex.select_lex.ftfunc_list= &thd->lex.select_lex.ftfunc_list_alloc; @@ -357,7 +371,7 @@ int st_select_lex_unit::cleanup() free_tmp_table(thd, table); table= 0; // Safety } - for (SELECT_LEX *sl= first_select(); sl; sl= sl->next_select()) + for (SELECT_LEX *sl= first_select_in_union(); sl; sl= sl->next_select()) { JOIN *join; if ((join= sl->join)) diff --git a/sql/sql_update.cc b/sql/sql_update.cc index 88f677938ad..dd3eb326b38 100644 --- a/sql/sql_update.cc +++ b/sql/sql_update.cc @@ -428,7 +428,7 @@ int mysql_multi_update(THD *thd, conds, 0, (ORDER *) NULL, (ORDER *)NULL, (Item *) NULL, (ORDER *)NULL, options | SELECT_NO_JOIN_CACHE, - result, unit, select_lex, 0, 0); + result, unit, select_lex, 0); delete result; DBUG_RETURN(res); } |