diff options
author | unknown <pem@mysql.com> | 2004-05-26 17:04:45 +0200 |
---|---|---|
committer | unknown <pem@mysql.com> | 2004-05-26 17:04:45 +0200 |
commit | f8866c162b57fa102298dbfc9e49d4f72f16c1d7 (patch) | |
tree | e4e5bb1f8b9718ec195b357c050b3dc3254b447d /sql/sql_union.cc | |
parent | 556b51e12aa58c5a7894a6bd010c2cd59d6e0cc3 (diff) | |
parent | 3a675ff5f8ed659344d7540f811ca052d999407d (diff) | |
download | mariadb-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.cc | 87 |
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); +} |