diff options
author | unknown <tomas@poseidon.ndb.mysql.com> | 2005-10-06 10:54:07 +0200 |
---|---|---|
committer | unknown <tomas@poseidon.ndb.mysql.com> | 2005-10-06 10:54:07 +0200 |
commit | d04832d195aba5badc42310eaa69c628a4a183bd (patch) | |
tree | cbe58ba165511396b212afaa1654a226d8ae88a4 /sql/sql_union.cc | |
parent | 282855e90bf052e2cf126adfaada61924cd8dd41 (diff) | |
parent | 3c2dca475dfa91c95f2488831fafacacaf852347 (diff) | |
download | mariadb-git-d04832d195aba5badc42310eaa69c628a4a183bd.tar.gz |
Merge
BitKeeper/etc/ignore:
auto-union
BUILD/autorun.sh:
Auto merged
BitKeeper/deleted/.del-bdb.vcproj~ed8534936e40cefb:
Auto merged
BitKeeper/deleted/.del-heap.vcproj~70c0cc1d680a51c1:
Auto merged
BitKeeper/deleted/.del-innobase.vcproj~71e1de81f11138bf:
Auto merged
BitKeeper/deleted/.del-myisam.vcproj~32bb9e4a163fcb5a:
Auto merged
BitKeeper/deleted/.del-myisammrg.vcproj~6534e59acbfbb63:
Auto merged
BitKeeper/deleted/.del-mysqld.vcproj~703886a28862bb2:
Auto merged
Makefile.am:
Auto merged
client/mysqltest.c:
Auto merged
include/my_global.h:
Auto merged
include/mysql_com.h:
Auto merged
mysql-test/mysql-test-run.pl:
Auto merged
mysql-test/r/ndb_alter_table.result:
Auto merged
mysql-test/r/ps_6bdb.result:
Auto merged
mysql-test/r/ps_7ndb.result:
Auto merged
mysql-test/t/query_cache.test:
Auto merged
mysys/default.c:
Auto merged
scripts/make_win_src_distribution.sh:
Auto merged
scripts/mysql_create_system_tables.sh:
Auto merged
scripts/mysql_fix_privilege_tables.sql:
Auto merged
sql/Makefile.am:
Auto merged
sql/field.cc:
Auto merged
sql/ha_berkeley.cc:
Auto merged
sql/ha_berkeley.h:
Auto merged
sql/ha_federated.cc:
Auto merged
sql/ha_heap.cc:
Auto merged
sql/ha_innodb.cc:
Auto merged
sql/ha_innodb.h:
Auto merged
sql/ha_myisam.cc:
Auto merged
sql/ha_myisammrg.cc:
Auto merged
sql/ha_ndbcluster.h:
Auto merged
sql/handler.cc:
Auto merged
sql/item.cc:
Auto merged
sql/item_subselect.cc:
Auto merged
sql/log.cc:
Auto merged
sql/mysql_priv.h:
Auto merged
sql/opt_sum.cc:
Auto merged
sql/repl_failsafe.cc:
Auto merged
sql/set_var.cc:
Auto merged
sql/sp.cc:
Auto merged
sql/sql_acl.cc:
Auto merged
sql/sql_acl.h:
Auto merged
sql/sql_base.cc:
Auto merged
sql/sql_cache.cc:
Auto merged
sql/sql_class.h:
Auto merged
sql/sql_delete.cc:
Auto merged
sql/sql_insert.cc:
Auto merged
sql/sql_lex.cc:
Auto merged
sql/sql_lex.h:
Auto merged
sql/sql_load.cc:
Auto merged
sql/sql_prepare.cc:
Auto merged
sql/sql_select.cc:
Auto merged
sql/sql_select.h:
Auto merged
sql/sql_show.cc:
Auto merged
sql/sql_table.cc:
Auto merged
sql/sql_update.cc:
Auto merged
sql/sql_yacc.yy:
Auto merged
sql/table.h:
Auto merged
sql/unireg.cc:
Auto merged
storage/innobase/buf/buf0buf.c:
Auto merged
storage/innobase/buf/buf0flu.c:
Auto merged
storage/innobase/data/data0data.c:
Auto merged
storage/innobase/dict/dict0dict.c:
Auto merged
storage/innobase/include/btr0btr.h:
Auto merged
storage/innobase/include/data0type.ic:
Auto merged
storage/innobase/include/dict0dict.h:
Auto merged
storage/innobase/include/dict0mem.h:
Auto merged
storage/innobase/include/mem0mem.h:
Auto merged
storage/innobase/include/mem0mem.ic:
Auto merged
storage/innobase/include/os0file.h:
Auto merged
storage/innobase/include/row0mysql.h:
Auto merged
storage/innobase/include/trx0trx.h:
Auto merged
storage/innobase/include/ut0mem.h:
Auto merged
storage/innobase/mem/mem0mem.c:
Auto merged
storage/innobase/os/os0file.c:
Auto merged
storage/innobase/os/os0proc.c:
Auto merged
storage/innobase/rem/rem0rec.c:
Auto merged
storage/innobase/row/row0ins.c:
Auto merged
storage/innobase/row/row0mysql.c:
Auto merged
storage/innobase/srv/srv0start.c:
Auto merged
storage/innobase/trx/trx0sys.c:
Auto merged
storage/innobase/trx/trx0trx.c:
Auto merged
storage/innobase/ut/ut0mem.c:
Auto merged
storage/myisam/ft_boolean_search.c:
Auto merged
storage/myisam/mi_check.c:
Auto merged
storage/myisam/mi_dbug.c:
Auto merged
storage/myisam/mi_delete.c:
Auto merged
storage/myisam/mi_delete_all.c:
Auto merged
storage/myisam/mi_key.c:
Auto merged
storage/myisam/mi_open.c:
Auto merged
storage/myisam/mi_rkey.c:
Auto merged
storage/myisam/mi_search.c:
Auto merged
storage/myisam/mi_test1.c:
Auto merged
storage/myisam/mi_update.c:
Auto merged
storage/myisam/mi_write.c:
Auto merged
storage/myisam/myisamchk.c:
Auto merged
storage/myisam/myisamdef.h:
Auto merged
storage/myisam/myisampack.c:
Auto merged
storage/myisam/sp_key.c:
Auto merged
storage/myisammrg/myrg_rkey.c:
Auto merged
storage/ndb/include/kernel/GlobalSignalNumbers.h:
Auto merged
storage/ndb/include/kernel/signaldata/ApiVersion.hpp:
Auto merged
storage/ndb/include/kernel/signaldata/EventReport.hpp:
Auto merged
storage/ndb/include/kernel/signaldata/StopReq.hpp:
Auto merged
storage/ndb/include/mgmapi/ndb_logevent.h:
Auto merged
storage/ndb/include/ndbapi/NdbBlob.hpp:
Auto merged
storage/ndb/include/ndbapi/NdbIndexOperation.hpp:
Auto merged
storage/ndb/include/ndbapi/NdbIndexScanOperation.hpp:
Auto merged
storage/ndb/include/ndbapi/NdbOperation.hpp:
Auto merged
storage/ndb/include/ndbapi/NdbRecAttr.hpp:
Auto merged
storage/ndb/include/ndbapi/NdbTransaction.hpp:
Auto merged
storage/ndb/src/common/util/SimpleProperties.cpp:
Auto merged
storage/ndb/src/kernel/blocks/backup/Backup.cpp:
Auto merged
storage/ndb/src/kernel/blocks/dbdict/Dbdict.cpp:
Auto merged
storage/ndb/src/kernel/blocks/dbdict/printSchemaFile.cpp:
Auto merged
storage/ndb/src/kernel/blocks/dbtup/Dbtup.hpp:
Auto merged
storage/ndb/src/kernel/blocks/dbtup/DbtupRoutines.cpp:
Auto merged
storage/ndb/src/kernel/blocks/dbtup/DbtupTrigger.cpp:
Auto merged
storage/ndb/src/kernel/blocks/ndbcntr/NdbcntrMain.cpp:
Auto merged
storage/ndb/src/kernel/blocks/qmgr/QmgrMain.cpp:
Auto merged
storage/ndb/src/mgmapi/ndb_logevent.cpp:
Auto merged
storage/ndb/src/mgmclient/CommandInterpreter.cpp:
Auto merged
storage/ndb/src/mgmsrv/Config.cpp:
Auto merged
storage/ndb/src/mgmsrv/Config.hpp:
Auto merged
storage/ndb/src/mgmsrv/ConfigInfo.cpp:
Auto merged
storage/ndb/src/mgmsrv/InitConfigFileParser.cpp:
Auto merged
storage/ndb/src/mgmsrv/InitConfigFileParser.hpp:
Auto merged
storage/ndb/src/mgmsrv/MgmtSrvr.hpp:
Auto merged
storage/ndb/src/mgmsrv/MgmtSrvrConfig.cpp:
Auto merged
storage/ndb/src/mgmsrv/MgmtSrvrGeneralSignalHandling.cpp:
Auto merged
storage/ndb/src/mgmsrv/Services.cpp:
Auto merged
storage/ndb/src/mgmsrv/Services.hpp:
Auto merged
storage/ndb/src/mgmsrv/main.cpp:
Auto merged
storage/ndb/src/ndbapi/NdbApiSignal.cpp:
Auto merged
storage/ndb/src/ndbapi/NdbApiSignal.hpp:
Auto merged
storage/ndb/src/ndbapi/NdbBlob.cpp:
Auto merged
storage/ndb/src/ndbapi/NdbImpl.hpp:
Auto merged
storage/ndb/src/ndbapi/NdbRecAttr.cpp:
Auto merged
storage/ndb/src/ndbapi/NdbUtil.cpp:
Auto merged
storage/ndb/src/ndbapi/NdbUtil.hpp:
Auto merged
storage/ndb/src/ndbapi/Ndbif.cpp:
Auto merged
storage/ndb/src/ndbapi/Ndblist.cpp:
Auto merged
storage/ndb/src/ndbapi/ObjectMap.hpp:
Auto merged
storage/ndb/test/include/NDBT_Test.hpp:
Auto merged
storage/ndb/test/ndbapi/bank/BankLoad.cpp:
Auto merged
storage/ndb/test/ndbapi/testOIBasic.cpp:
Auto merged
storage/ndb/test/src/HugoCalculator.cpp:
Auto merged
storage/ndb/test/src/NDBT_Test.cpp:
Auto merged
storage/ndb/test/src/NdbBackup.cpp:
Auto merged
storage/ndb/test/src/NdbRestarts.cpp:
Auto merged
storage/ndb/tools/ndb_condig.cpp:
Auto merged
storage/ndb/tools/restore/Restore.cpp:
Auto merged
storage/ndb/tools/restore/consumer_restore.cpp:
Auto merged
support-files/mysql.spec.sh:
Auto merged
configure.in:
merge
BUILD/SETUP.sh:
merge
BitKeeper/deleted/.del-mysql.sln~f2120278f8a437be:
SCCS merged
libmysqld/Makefile.am:
merge
sql/ha_ndbcluster.cc:
merge
sql/handler.h:
merge
sql/mysqld.cc:
merge
sql/opt_range.cc:
merge
sql/slave.cc:
merge
sql/slave.h:
e
merge
sql/sql_parse.cc:
merge
sql/table.cc:
merge
sql/examples/ha_tina.cc:
merge
sql/examples/ha_tina.h:
merge
sql/share/errmsg.txt:
merge
storage/ndb/include/ndbapi/Ndb.hpp:
merge
storage/ndb/src/common/debugger/EventLogger.cpp:
merge
storage/ndb/src/kernel/blocks/dbdict/Makefile.am:
merge
storage/ndb/src/mgmsrv/MgmtSrvr.cpp:
merge
storage/ndb/src/ndbapi/Ndbinit.cpp:
SCCS merged
Diffstat (limited to 'sql/sql_union.cc')
-rw-r--r-- | sql/sql_union.cc | 176 |
1 files changed, 106 insertions, 70 deletions
diff --git a/sql/sql_union.cc b/sql/sql_union.cc index 556493f4fc8..951248e8cd8 100644 --- a/sql/sql_union.cc +++ b/sql/sql_union.cc @@ -23,6 +23,7 @@ #include "mysql_priv.h" #include "sql_select.h" +#include "sql_cursor.h" bool mysql_union(THD *thd, LEX *lex, select_result *result, SELECT_LEX_UNIT *unit, ulong setup_tables_done_option) @@ -30,13 +31,9 @@ bool mysql_union(THD *thd, LEX *lex, select_result *result, DBUG_ENTER("mysql_union"); bool res; if (!(res= unit->prepare(thd, result, SELECT_NO_UNLOCK | - setup_tables_done_option, ""))) + setup_tables_done_option))) res= unit->exec(); - if (!res && thd->cursor && thd->cursor->is_open()) - { - thd->cursor->set_unit(unit); - } - else + if (res || !thd->cursor || !thd->cursor->is_open()) res|= unit->cleanup(); DBUG_RETURN(res); } @@ -46,16 +43,6 @@ bool mysql_union(THD *thd, LEX *lex, select_result *result, ** store records in temporary table for UNION ***************************************************************************/ -select_union::select_union(TABLE *table_par) - :table(table_par) -{ -} - -select_union::~select_union() -{ -} - - int select_union::prepare(List<Item> &list, SELECT_LEX_UNIT *u) { unit= u; @@ -103,6 +90,45 @@ bool select_union::flush() return 0; } +/* + Create a temporary table to store the result of select_union. + + SYNOPSIS + select_union::create_result_table() + thd thread handle + column_types a list of items used to define columns of the + temporary table + is_union_distinct if set, the temporary table will eliminate + duplicates on insert + options create options + + DESCRIPTION + Create a temporary table that is used to store the result of a UNION, + derived table, or a materialized cursor. + + RETURN VALUE + 0 The table has been created successfully. + 1 create_tmp_table failed. +*/ + +bool +select_union::create_result_table(THD *thd, List<Item> *column_types, + bool is_union_distinct, ulonglong options, + const char *alias) +{ + DBUG_ASSERT(table == 0); + tmp_table_param.init(); + tmp_table_param.field_count= column_types->elements; + + if (! (table= create_tmp_table(thd, &tmp_table_param, *column_types, + (ORDER*) 0, is_union_distinct, 1, + options, HA_POS_ERROR, (char*) alias))) + return TRUE; + table->file->extra(HA_EXTRA_WRITE_CACHE); + table->file->extra(HA_EXTRA_IGNORE_DUP_KEY); + return FALSE; +} + /* initialization procedures before fake_select_lex preparation() @@ -133,11 +159,10 @@ st_select_lex_unit::init_prepare_fake_select_lex(THD *thd) bool st_select_lex_unit::prepare(THD *thd_arg, select_result *sel_result, - ulong additional_options, - const char *tmp_table_alias) + ulong additional_options) { SELECT_LEX *lex_select_save= thd_arg->lex->current_select; - SELECT_LEX *sl, *first_select; + SELECT_LEX *sl, *first_sl= first_select(); select_result *tmp_result; bool is_union; TABLE *empty_table= 0; @@ -156,7 +181,7 @@ bool st_select_lex_unit::prepare(THD *thd_arg, select_result *sel_result, if (describe) { /* fast reinit for EXPLAIN */ - for (sl= first_select_in_union(); sl; sl= sl->next_select()) + for (sl= first_sl; sl; sl= sl->next_select()) { sl->join->result= result; select_limit_cnt= HA_POS_ERROR; @@ -175,17 +200,16 @@ bool st_select_lex_unit::prepare(THD *thd_arg, select_result *sel_result, prepared= 1; res= FALSE; - thd_arg->lex->current_select= sl= first_select= first_select_in_union(); - found_rows_for_union= first_select->options & OPTION_FOUND_ROWS; - is_union= test(first_select->next_select()); + thd_arg->lex->current_select= sl= first_sl; + found_rows_for_union= first_sl->options & OPTION_FOUND_ROWS; + is_union= test(first_sl->next_select()); /* Global option */ if (is_union) { - if (!(tmp_result= union_result= new select_union(0))) + if (!(tmp_result= union_result= new select_union)) goto err; - union_result->tmp_table_param.init(); if (describe) tmp_result= sel_result; } @@ -238,8 +262,8 @@ bool st_select_lex_unit::prepare(THD *thd_arg, select_result *sel_result, information about fields lengths and exact types */ if (!is_union) - types= first_select_in_union()->item_list; - else if (sl == first_select) + types= first_sl->item_list; + else if (sl == first_sl) { /* We need to create an empty table object. It is used @@ -287,7 +311,6 @@ bool st_select_lex_unit::prepare(THD *thd_arg, select_result *sel_result, all collations together for UNION. */ List_iterator_fast<Item> tp(types); - Query_arena *arena= thd->stmt_arena; Item *type; ulonglong create_options; @@ -301,7 +324,7 @@ bool st_select_lex_unit::prepare(THD *thd_arg, select_result *sel_result, } } - create_options= (first_select_in_union()->options | thd_arg->options | + create_options= (first_sl->options | thd_arg->options | TMP_TABLE_ALL_COLUMNS); /* Force the temporary table to be a MyISAM table if we're going to use @@ -312,47 +335,35 @@ bool st_select_lex_unit::prepare(THD *thd_arg, select_result *sel_result, if (global_parameters->ftfunc_list->elements) create_options= create_options | TMP_TABLE_FORCE_MYISAM; - union_result->tmp_table_param.field_count= types.elements; - if (!(table= create_tmp_table(thd_arg, - &union_result->tmp_table_param, types, - (ORDER*) 0, (bool) union_distinct, 1, - create_options, HA_POS_ERROR, - (char *) tmp_table_alias))) + if (union_result->create_result_table(thd, &types, test(union_distinct), + create_options, "")) goto err; - table->file->extra(HA_EXTRA_WRITE_CACHE); - table->file->extra(HA_EXTRA_IGNORE_DUP_KEY); bzero((char*) &result_table_list, sizeof(result_table_list)); result_table_list.db= (char*) ""; result_table_list.table_name= result_table_list.alias= (char*) "union"; - result_table_list.table= table; - union_result->set_table(table); + result_table_list.table= table= union_result->table; thd_arg->lex->current_select= lex_select_save; if (!item_list.elements) { - Field **field; - Query_arena *tmp_arena,backup; - tmp_arena= thd->activate_stmt_arena_if_needed(&backup); + Query_arena *arena, backup_arena; - for (field= table->field; *field; field++) - { - Item_field *item= new Item_field(*field); - if (!item || item_list.push_back(item)) - { - if (tmp_arena) - thd->restore_active_arena(tmp_arena, &backup); - DBUG_RETURN(TRUE); - } - } - if (tmp_arena) - thd->restore_active_arena(tmp_arena, &backup); - if (arena->is_stmt_prepare_or_first_sp_execute()) + arena= thd->activate_stmt_arena_if_needed(&backup_arena); + + res= table->fill_item_list(&item_list); + + if (arena) + thd->restore_active_arena(arena, &backup_arena); + + if (res) + goto err; + + if (thd->stmt_arena->is_stmt_prepare()) { - /* prepare fake select to initialize it correctly */ + /* Validate the global parameters of this union */ + init_prepare_fake_select_lex(thd); - /* - Should be done only once (the only item_list per statement). - */ + /* Should be done only once (the only item_list per statement) */ DBUG_ASSERT(fake_select_lex->join == 0); if (!(fake_select_lex->join= new JOIN(thd, item_list, thd->options, result))) @@ -375,19 +386,14 @@ bool st_select_lex_unit::prepare(THD *thd_arg, select_result *sel_result, fake_select_lex->table_list.empty(); } } - else if (!arena->is_conventional()) + else { + DBUG_ASSERT(!thd->stmt_arena->is_conventional()); /* We're in execution of a prepared statement or stored procedure: reset field items to point at fields from the created temporary table. */ - List_iterator_fast<Item> it(item_list); - for (Field **field= table->field; *field; field++) - { - Item_field *item_field= (Item_field*) it++; - DBUG_ASSERT(item_field != 0); - item_field->reset_field(*field); - } + table->reset_item_list(&item_list); } } @@ -404,7 +410,7 @@ err: bool st_select_lex_unit::exec() { SELECT_LEX *lex_select_save= thd->lex->current_select; - SELECT_LEX *select_cursor=first_select_in_union(); + SELECT_LEX *select_cursor=first_select(); ulonglong add_rows=0; ha_rows examined_rows= 0; DBUG_ENTER("st_select_lex_unit::exec"); @@ -595,7 +601,7 @@ bool st_select_lex_unit::cleanup() table= 0; // Safety } - for (SELECT_LEX *sl= first_select_in_union(); sl; sl= sl->next_select()) + for (SELECT_LEX *sl= first_select(); sl; sl= sl->next_select()) error|= sl->cleanup(); if (fake_select_lex) @@ -652,7 +658,7 @@ bool st_select_lex_unit::change_result(select_subselect *result, select_subselect *old_result) { bool res= FALSE; - for (SELECT_LEX *sl= first_select_in_union(); sl; sl= sl->next_select()) + for (SELECT_LEX *sl= first_select(); sl; sl= sl->next_select()) { if (sl->join && sl->join->result == old_result) if (sl->join->change_result(result)) @@ -663,6 +669,36 @@ bool st_select_lex_unit::change_result(select_subselect *result, return (res); } +/* + Get column type information for this unit. + + SYNOPSIS + st_select_lex_unit::get_unit_column_types() + + DESCRIPTION + For a single-select the column types are taken + from the list of selected items. For a union this function + assumes that st_select_lex_unit::prepare has been called + and returns the type holders that were created for unioned + column types of all selects. + + NOTES + The implementation of this function should be in sync with + st_select_lex_unit::prepare() +*/ + +List<Item> *st_select_lex_unit::get_unit_column_types() +{ + bool is_union= test(first_select()->next_select()); + + if (is_union) + { + DBUG_ASSERT(prepared); + /* Types are generated during prepare */ + return &types; + } + return &first_select()->item_list; +} bool st_select_lex::cleanup() { |