summaryrefslogtreecommitdiff
path: root/sql/sql_union.cc
diff options
context:
space:
mode:
authorunknown <pem@mysql.com>2004-05-26 17:04:45 +0200
committerunknown <pem@mysql.com>2004-05-26 17:04:45 +0200
commitf8866c162b57fa102298dbfc9e49d4f72f16c1d7 (patch)
treee4e5bb1f8b9718ec195b357c050b3dc3254b447d /sql/sql_union.cc
parent556b51e12aa58c5a7894a6bd010c2cd59d6e0cc3 (diff)
parent3a675ff5f8ed659344d7540f811ca052d999407d (diff)
downloadmariadb-git-f8866c162b57fa102298dbfc9e49d4f72f16c1d7.tar.gz
Merging 4.1 to 5.0.
BitKeeper/etc/ignore: auto-union BitKeeper/etc/logging_ok: auto-union client/mysqltest.c: Auto merged configure.in: Auto merged include/my_sys.h: Auto merged include/mysql_com.h: Auto merged libmysql/libmysql.c: Auto merged libmysqld/Makefile.am: Auto merged libmysqld/lib_sql.cc: Auto merged myisam/mi_check.c: Auto merged myisam/myisamchk.c: Auto merged myisam/myisamdef.h: Auto merged mysql-test/r/func_group.result: Auto merged mysql-test/r/func_time.result: Auto merged mysql-test/r/null.result: Auto merged mysql-test/r/query_cache.result: Auto merged mysql-test/r/rpl_server_id2.result: Auto merged mysql-test/r/select.result: Auto merged mysql-test/r/subselect.result: Auto merged mysql-test/r/variables.result: Auto merged mysql-test/t/rpl000015.test: Auto merged mysql-test/t/rpl_error_ignored_table.test: Auto merged mysql-test/t/rpl_log.test: Auto merged mysql-test/t/rpl_log_pos.test: Auto merged mysql-test/t/rpl_max_relay_size.test: Auto merged mysql-test/t/rpl_relayrotate.test: Auto merged mysql-test/t/rpl_rotate_logs.test: Auto merged mysql-test/t/rpl_server_id2.test: Auto merged mysql-test/t/subselect.test: Auto merged mysql-test/t/variables.test: Auto merged mysys/my_pthread.c: Auto merged netware/BUILD/compile-netware-all: Auto merged netware/BUILD/compile-netware-standard: Auto merged netware/BUILD/mwenv: Auto merged netware/Makefile.am: Auto merged netware/my_manage.c: Auto merged netware/my_manage.h: Auto merged netware/mysql_test_run.c: Auto merged scripts/mysql_install_db.sh: Auto merged sql/Makefile.am: Auto merged sql/ha_berkeley.cc: Auto merged sql/ha_berkeley.h: Auto merged sql/ha_innodb.cc: Auto merged sql/ha_innodb.h: Auto merged sql/ha_myisam.cc: Auto merged sql/handler.cc: Auto merged sql/handler.h: Auto merged sql/item.cc: Auto merged sql/item.h: Auto merged sql/item_cmpfunc.cc: Auto merged sql/item_func.cc: Auto merged sql/item_subselect.cc: Auto merged sql/item_subselect.h: Auto merged sql/item_sum.cc: Auto merged sql/item_sum.h: Auto merged sql/item_timefunc.cc: Auto merged sql/lock.cc: Auto merged sql/mysql_priv.h: Auto merged sql/opt_range.cc: Auto merged sql/protocol.cc: Auto merged sql/protocol.h: Auto merged sql/repl_failsafe.cc: Auto merged sql/set_var.cc: Auto merged sql/sql_acl.cc: Auto merged sql/sql_base.cc: Auto merged sql/sql_cache.cc: Auto merged sql/sql_class.cc: Auto merged sql/sql_class.h: Auto merged sql/sql_db.cc: Auto merged sql/sql_insert.cc: Auto merged sql/sql_parse.cc: Auto merged sql/sql_prepare.cc: Auto merged sql/sql_select.h: Auto merged sql/sql_show.cc: Auto merged sql/sql_string.cc: Auto merged sql/sql_string.h: Auto merged sql/sql_table.cc: Auto merged sql/sql_union.cc: Auto merged sql/sql_yacc.yy: Auto merged tests/client_test.c: Auto merged
Diffstat (limited to 'sql/sql_union.cc')
-rw-r--r--sql/sql_union.cc87
1 files changed, 73 insertions, 14 deletions
diff --git a/sql/sql_union.cc b/sql/sql_union.cc
index 794fbc74c73..73d4616b313 100644
--- a/sql/sql_union.cc
+++ b/sql/sql_union.cc
@@ -41,7 +41,7 @@ int mysql_union(THD *thd, LEX *lex, select_result *result,
***************************************************************************/
select_union::select_union(TABLE *table_par)
- :table(table_par), not_describe(0)
+ :table(table_par)
{
bzero((char*) &info,sizeof(info));
/*
@@ -120,7 +120,7 @@ bool select_union::flush()
ulong
st_select_lex_unit::init_prepare_fake_select_lex(THD *thd)
{
- ulong options_tmp= thd->options;
+ ulong options_tmp= thd->options | fake_select_lex->options;
thd->lex->current_select= fake_select_lex;
offset_limit_cnt= global_parameters->offset_limit;
select_limit_cnt= global_parameters->select_limit +
@@ -149,6 +149,8 @@ int st_select_lex_unit::prepare(THD *thd_arg, select_result *sel_result,
select_result *tmp_result;
DBUG_ENTER("st_select_lex_unit::prepare");
+ describe= test(additional_options & SELECT_DESCRIBE);
+
/*
result object should be reassigned even if preparing already done for
max/min subquery (ALL/ANY optimization)
@@ -156,7 +158,26 @@ int st_select_lex_unit::prepare(THD *thd_arg, select_result *sel_result,
result= sel_result;
if (prepared)
+ {
+ if (describe)
+ {
+ /* fast reinit for EXPLAIN */
+ for (sl= first_select_in_union(); sl; sl= sl->next_select())
+ {
+ sl->join->result= result;
+ select_limit_cnt= HA_POS_ERROR;
+ offset_limit_cnt= 0;
+ if (!sl->join->procedure &&
+ result->prepare(sl->join->fields_list, this))
+ {
+ DBUG_RETURN(1);
+ }
+ sl->join->select_options|= SELECT_DESCRIBE;
+ sl->join->reinit();
+ }
+ }
DBUG_RETURN(0);
+ }
prepared= 1;
res= 0;
@@ -169,8 +190,9 @@ int st_select_lex_unit::prepare(THD *thd_arg, select_result *sel_result,
{
if (!(tmp_result= union_result= new select_union(0)))
goto err;
- union_result->not_describe= 1;
union_result->tmp_table_param.init();
+ if (describe)
+ tmp_result= sel_result;
}
else
{
@@ -329,20 +351,24 @@ int st_select_lex_unit::exec()
ulonglong add_rows=0;
DBUG_ENTER("st_select_lex_unit::exec");
- if (executed && !uncacheable)
+ if (executed && !uncacheable && !describe)
DBUG_RETURN(0);
executed= 1;
- if (uncacheable || !item || !item->assigned())
+ if (uncacheable || !item || !item->assigned() || describe)
{
- if (optimized && item && item->assigned())
+ if (optimized && item)
{
- item->assigned(0); // We will reinit & rexecute unit
- item->reset();
- table->file->delete_all_rows();
+ if (item->assigned())
+ {
+ item->assigned(0); // We will reinit & rexecute unit
+ item->reset();
+ table->file->delete_all_rows();
+ }
+ /* re-enabling indexes for next subselect iteration */
+ if (union_distinct && table->file->enable_indexes(HA_KEY_SWITCH_ALL))
+ DBUG_ASSERT(1);
}
- if (union_distinct) // for subselects
- table->file->extra(HA_EXTRA_CHANGE_KEY_TO_UNIQUE);
for (SELECT_LEX *sl= select_cursor; sl; sl= sl->next_select())
{
ha_rows records_at_start= 0;
@@ -352,7 +378,7 @@ int st_select_lex_unit::exec()
res= sl->join->reinit();
else
{
- if (sl != global_parameters)
+ if (sl != global_parameters && !describe)
{
offset_limit_cnt= sl->offset_limit;
select_limit_cnt= sl->select_limit+sl->offset_limit;
@@ -364,7 +390,7 @@ int st_select_lex_unit::exec()
We can't use LIMIT at this stage if we are using ORDER BY for the
whole query
*/
- if (sl->order_list.first)
+ if (sl->order_list.first || describe)
select_limit_cnt= HA_POS_ERROR;
else
select_limit_cnt= sl->select_limit+sl->offset_limit;
@@ -394,7 +420,11 @@ int st_select_lex_unit::exec()
records_at_start= table->file->records;
sl->join->exec();
if (sl == union_distinct)
- table->file->extra(HA_EXTRA_CHANGE_KEY_TO_DUP);
+ {
+ if (table->file->disable_indexes(HA_KEY_SWITCH_ALL))
+ DBUG_RETURN(1);
+ table->no_keyread=1;
+ }
res= sl->join->error;
offset_limit_cnt= sl->offset_limit;
if (!res && union_result->flush())
@@ -557,3 +587,32 @@ void st_select_lex_unit::reinit_exec_mechanism()
}
#endif
}
+
+
+/*
+ change select_result object of unit
+
+ SYNOPSIS
+ st_select_lex_unit::change_result()
+ result new select_result object
+ old_result old select_result object
+
+ RETURN
+ 0 - OK
+ -1 - error
+*/
+
+int st_select_lex_unit::change_result(select_subselect *result,
+ select_subselect *old_result)
+{
+ int res= 0;
+ for (SELECT_LEX *sl= first_select_in_union(); sl; sl= sl->next_select())
+ {
+ if (sl->join && sl->join->result == old_result)
+ if ((res= sl->join->change_result(result)))
+ return (res);
+ }
+ if (fake_select_lex && fake_select_lex->join)
+ res= fake_select_lex->join->change_result(result);
+ return (res);
+}