diff options
author | tsmith@ramayana.hindu.god <> | 2007-08-01 18:59:41 -0600 |
---|---|---|
committer | tsmith@ramayana.hindu.god <> | 2007-08-01 18:59:41 -0600 |
commit | b13de9343f9ec6455f4a762838482af44e0a1996 (patch) | |
tree | 1fa7c6a583124fd9e3ba466b15acf7b8518f3303 /sql/sql_union.cc | |
parent | a52a078f75c1ecc2972a589165db320eddeb9981 (diff) | |
parent | d66b4bd4beb0c7d47e1b915f09439cd703f0fda0 (diff) | |
download | mariadb-git-b13de9343f9ec6455f4a762838482af44e0a1996.tar.gz |
Merge 50 -> 51 (-opt changesets)
Diffstat (limited to 'sql/sql_union.cc')
-rw-r--r-- | sql/sql_union.cc | 57 |
1 files changed, 40 insertions, 17 deletions
diff --git a/sql/sql_union.cc b/sql/sql_union.cc index c872d3cb241..5da4b97cc5d 100644 --- a/sql/sql_union.cc +++ b/sql/sql_union.cc @@ -547,6 +547,10 @@ bool st_select_lex_unit::exec() /* allocate JOIN for fake select only once (prevent mysql_select automatic allocation) + TODO: The above is nonsense. mysql_select() will not allocate the + join if one already exists. There must be some other reason why we + don't let it allocate the join. Perhaps this is because we need + some special parameter values passed to join constructor? */ if (!(fake_select_lex->join= new JOIN(thd, item_list, fake_select_lex->options, result))) @@ -554,33 +558,52 @@ bool st_select_lex_unit::exec() fake_select_lex->table_list.empty(); DBUG_RETURN(TRUE); } + fake_select_lex->join->no_const_tables= TRUE; /* Fake st_select_lex should have item list for correctref_array allocation. */ fake_select_lex->item_list= item_list; + saved_error= mysql_select(thd, &fake_select_lex->ref_pointer_array, + &result_table_list, + 0, item_list, NULL, + global_parameters->order_list.elements, + (ORDER*)global_parameters->order_list.first, + (ORDER*) NULL, NULL, (ORDER*) NULL, + fake_select_lex->options | SELECT_NO_UNLOCK, + result, this, fake_select_lex); } else { - JOIN_TAB *tab,*end; - for (tab=join->join_tab, end=tab+join->tables ; - tab && tab != end ; - tab++) - { - delete tab->select; - delete tab->quick; - } - join->init(thd, item_list, fake_select_lex->options, result); + if (describe) + { + /* + In EXPLAIN command, constant subqueries that do not use any + tables are executed two times: + - 1st time is a real evaluation to get the subquery value + - 2nd time is to produce EXPLAIN output rows. + 1st execution sets certain members (e.g. select_result) to perform + subquery execution rather than EXPLAIN line production. In order + to reset them back, we re-do all of the actions (yes it is ugly): + */ + join->init(thd, item_list, fake_select_lex->options, result); + saved_error= mysql_select(thd, &fake_select_lex->ref_pointer_array, + &result_table_list, + 0, item_list, NULL, + global_parameters->order_list.elements, + (ORDER*)global_parameters->order_list.first, + (ORDER*) NULL, NULL, (ORDER*) NULL, + fake_select_lex->options | SELECT_NO_UNLOCK, + result, this, fake_select_lex); + } + else + { + join->examined_rows= 0; + saved_error= join->reinit(); + join->exec(); + } } - saved_error= mysql_select(thd, &fake_select_lex->ref_pointer_array, - &result_table_list, - 0, item_list, NULL, - global_parameters->order_list.elements, - (ORDER*)global_parameters->order_list.first, - (ORDER*) NULL, NULL, (ORDER*) NULL, - fake_select_lex->options | SELECT_NO_UNLOCK, - result, this, fake_select_lex); fake_select_lex->table_list.empty(); if (!saved_error) |