diff options
author | unknown <monty@narttu.mysql.fi> | 2008-04-28 19:24:05 +0300 |
---|---|---|
committer | unknown <monty@narttu.mysql.fi> | 2008-04-28 19:24:05 +0300 |
commit | 50ceea65cf18a64db017f06d2be5197807927588 (patch) | |
tree | ff5ab0c71ce5a2792c4f169a880e0174f8e194ad /sql/sql_cursor.cc | |
parent | ed5fe6d3eb5d702e2fe27de3c65c550ea0dbf17f (diff) | |
parent | c481f6b3cf80f471321d2ef4e7c68fe9e6e5d0ca (diff) | |
download | mariadb-git-50ceea65cf18a64db017f06d2be5197807927588.tar.gz |
Merge mysql.com:/home/my/mysql-5.1
into mysql.com:/home/my/mysql-new
BitKeeper/etc/ignore:
auto-union
BUILD/SETUP.sh:
Auto merged
CMakeLists.txt:
Auto merged
client/get_password.c:
Auto merged
client/mysqldump.c:
Auto merged
client/mysqltest.c:
Auto merged
cmd-line-utils/readline/bind.c:
Auto merged
cmd-line-utils/readline/display.c:
Auto merged
cmd-line-utils/readline/histexpand.c:
Auto merged
cmd-line-utils/readline/history.c:
Auto merged
cmd-line-utils/readline/readline.c:
Auto merged
cmd-line-utils/readline/text.c:
Auto merged
dbug/user.r:
Auto merged
extra/yassl/src/handshake.cpp:
Auto merged
include/config-win.h:
Auto merged
include/m_string.h:
Auto merged
include/my_global.h:
Auto merged
include/my_pthread.h:
Auto merged
include/mysql/plugin.h:
Auto merged
include/mysql_com.h:
Auto merged
include/thr_alarm.h:
Auto merged
libmysql/CMakeLists.txt:
Auto merged
libmysql/Makefile.shared:
Auto merged
libmysql/dll.c:
Auto merged
libmysql/get_password.c:
Auto merged
libmysql/libmysql.c:
Auto merged
libmysqld/Makefile.am:
Auto merged
mysql-test/lib/mtr_cases.pl:
Auto merged
mysql-test/mysql-test-run.pl:
Auto merged
mysql-test/r/alter_table.result:
Auto merged
mysql-test/r/change_user.result:
Auto merged
mysql-test/r/create.result:
Auto merged
mysql-test/r/innodb.result:
Auto merged
mysql-test/r/merge.result:
Auto merged
mysql-test/r/mix2_myisam.result:
Auto merged
mysql-test/r/mysqldump.result:
Auto merged
mysql-test/r/query_cache.result:
Auto merged
mysql-test/r/subselect.result:
Auto merged
mysql-test/valgrind.supp:
Auto merged
mysql-test/r/view.result:
Auto merged
mysql-test/suite/rpl/r/rpl_events.result:
Auto merged
mysql-test/suite/rpl/t/rpl_switch_stm_row_mixed.test:
Auto merged
mysql-test/t/create.test:
Auto merged
mysql-test/t/mysqldump.test:
Auto merged
mysql-test/t/query_cache.test:
Auto merged
mysql-test/t/subselect.test:
Auto merged
mysql-test/t/variables.test:
Auto merged
mysql-test/t/view.test:
Auto merged
mysys/mf_iocache.c:
Auto merged
mysys/mf_tempfile.c:
Auto merged
mysys/my_atomic.c:
Auto merged
mysys/my_bit.c:
Auto merged
mysys/my_bitmap.c:
Auto merged
mysys/my_compress.c:
Auto merged
mysys/my_create.c:
Auto merged
mysys/my_delete.c:
Auto merged
mysys/my_error.c:
Auto merged
mysys/my_init.c:
Auto merged
mysys/my_open.c:
Auto merged
mysys/my_realloc.c:
Auto merged
mysys/my_rename.c:
Auto merged
mysys/my_symlink.c:
Auto merged
mysys/my_sync.c:
Auto merged
mysys/my_thr_init.c:
Auto merged
mysys/thr_alarm.c:
Auto merged
mysys/thr_lock.c:
Auto merged
scripts/make_binary_distribution.sh:
Auto merged
server-tools/instance-manager/mysql_connection.cc:
Auto merged
sql/CMakeLists.txt:
Auto merged
sql/Makefile.am:
Auto merged
sql/events.cc:
Auto merged
sql/field.cc:
Auto merged
sql/field.h:
Auto merged
sql/filesort.cc:
Auto merged
sql/gen_lex_hash.cc:
Auto merged
sql/ha_ndbcluster.cc:
Auto merged
sql/ha_partition.h:
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_func.h:
Auto merged
sql/item_strfunc.cc:
Auto merged
sql/item_strfunc.h:
Auto merged
sql/item_subselect.cc:
Auto merged
sql/lock.cc:
Auto merged
sql/log.cc:
Auto merged
sql/log_event.cc:
Auto merged
sql/net_serv.cc:
Auto merged
sql/opt_range.cc:
Auto merged
sql/partition_info.cc:
Auto merged
sql/rpl_injector.cc:
Auto merged
sql/set_var.cc:
Auto merged
sql/slave.cc:
Auto merged
sql/slave.h:
Auto merged
sql/sp_head.cc:
Auto merged
sql/sql_acl.cc:
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_load.cc:
Auto merged
sql/sql_plugin.cc:
Auto merged
sql/sql_prepare.cc:
Auto merged
sql/sql_repl.cc:
Auto merged
sql/sql_test.cc:
Auto merged
sql/sql_union.cc:
Auto merged
sql/sql_update.cc:
Auto merged
sql/sql_yacc.yy:
Auto merged
sql/table.cc:
Auto merged
sql/table.h:
Auto merged
sql/unireg.cc:
Auto merged
sql/share/errmsg.txt:
Auto merged
storage/csv/ha_tina.cc:
Auto merged
storage/csv/ha_tina.h:
Auto merged
storage/myisam/CMakeLists.txt:
Auto merged
storage/myisam/ft_boolean_search.c:
Auto merged
storage/myisam/ft_eval.c:
Auto merged
storage/myisam/ft_nlq_search.c:
Auto merged
storage/myisam/ft_parser.c:
Auto merged
storage/myisam/ft_static.c:
Auto merged
storage/myisam/ft_stopwords.c:
Auto merged
storage/myisam/ft_test1.c:
Auto merged
storage/myisam/ft_update.c:
Auto merged
storage/myisam/ha_myisam.cc:
Auto merged
storage/myisam/mi_check.c:
Auto merged
storage/myisam/mi_create.c:
Auto merged
storage/myisam/mi_delete.c:
Auto merged
storage/myisam/mi_delete_all.c:
Auto merged
storage/myisam/mi_dynrec.c:
Auto merged
storage/myisam/mi_key.c:
Auto merged
storage/myisam/mi_packrec.c:
Auto merged
storage/myisam/mi_range.c:
Auto merged
storage/myisam/mi_search.c:
Auto merged
storage/myisam/mi_test1.c:
Auto merged
storage/myisam/mi_test2.c:
Auto merged
storage/myisam/mi_test3.c:
Auto merged
storage/myisam/mi_unique.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/sort.c:
Auto merged
storage/myisam/sp_test.c:
Auto merged
support-files/mysql.spec.sh:
Auto merged
tests/mysql_client_test.c:
Auto merged
configure.in:
Manual merge
dbug/dbug.c:
Restore to original state in Maria tree
The big diff comes from a wrong pull from 5.0 -> 5.1 after backporting dbug to 5.0 from 5.1
include/Makefile.am:
Manual merge
include/my_atomic.h:
Ignore changes
include/my_base.h:
Manual merge
include/my_dbug.h:
Use orginal my_dbug.h from maria tree
include/my_handler.h:
Manual merge
include/my_sys.h:
Manual merge
include/myisam.h:
Manual merge
mysql-test/lib/mtr_report.pl:
Manual merge
mysql-test/r/myisam.result:
Manual merge
mysql-test/suite/binlog/r/binlog_unsafe.result:
Manual merge
mysql-test/suite/binlog/t/binlog_unsafe.test:
Manual merge
mysql-test/suite/rpl/r/rpl_row_flsh_tbls.result:
Manual merge
mysql-test/suite/rpl/r/rpl_switch_stm_row_mixed.result:
No changes
mysql-test/suite/rpl/t/rpl_row_flsh_tbls.test:
Manual merge
mysql-test/t/change_user.test:
Manual merge
mysql-test/t/disabled.def:
Manual merge
mysql-test/t/merge.test:
No changes
mysql-test/t/myisam.test:
Manual merge
mysys/Makefile.am:
Manual merge
mysys/array.c:
Manual merge
mysys/mf_keycache.c:
Manual merge
mysys/my_getsystime.c:
Manual merge
mysys/my_handler.c:
Manual merge
mysys/my_pread.c:
Manual merge
mysys/safemalloc.c:
Manual merge
sql/ha_partition.cc:
Manual merge
sql/handler.cc:
Manual merge
sql/lex.h:
Manual merge
sql/mysql_priv.h:
Manual merge
sql/mysqld.cc:
Manual merge
sql/set_var.h:
Manual merge
sql/sql_class.cc:
Manual merge
sql/sql_insert.cc:
Manual merge
sql/sql_parse.cc:
Manual merge
sql/sql_select.cc:
Manual merge
sql/sql_show.cc:
Manual merge
sql/sql_table.cc:
Manual merge
storage/myisam/mi_checksum.c:
No changes
storage/myisam/mi_extra.c:
Manual merge
storage/myisam/mi_open.c:
Manual merge
storage/myisammrg/ha_myisammrg.cc:
Manual merge
strings/strmake.c:
No changes
Diffstat (limited to 'sql/sql_cursor.cc')
-rw-r--r-- | sql/sql_cursor.cc | 103 |
1 files changed, 79 insertions, 24 deletions
diff --git a/sql/sql_cursor.cc b/sql/sql_cursor.cc index 2301b561797..5c4e93d4c74 100644 --- a/sql/sql_cursor.cc +++ b/sql/sql_cursor.cc @@ -88,6 +88,7 @@ class Materialized_cursor: public Server_side_cursor public: Materialized_cursor(select_result *result, TABLE *table); + int fill_item_list(THD *thd, List<Item> &send_fields); virtual bool is_open() const { return table != 0; } virtual int open(JOIN *join __attribute__((unused))); virtual void fetch(ulong num_rows); @@ -109,6 +110,7 @@ class Select_materialize: public select_union { select_result *result; /**< the result object of the caller (PS or SP) */ public: + Materialized_cursor *materialized_cursor; Select_materialize(select_result *result_arg) :result(result_arg) {} virtual bool send_fields(List<Item> &list, uint flags); }; @@ -151,7 +153,7 @@ int mysql_open_cursor(THD *thd, uint flags, select_result *result, if (! (sensitive_cursor= new (thd->mem_root) Sensitive_cursor(thd, result))) { - delete result; + delete result_materialize; return 1; } @@ -173,13 +175,13 @@ int mysql_open_cursor(THD *thd, uint flags, select_result *result, /* Possible options here: - a sensitive cursor is open. In this case rc is 0 and - result_materialize->table is NULL, or + result_materialize->materialized_cursor is NULL, or - a materialized cursor is open. In this case rc is 0 and - result_materialize->table is not NULL - - an error occured during materializaton. - result_materialize->table is not NULL, but rc != 0 + result_materialize->materialized is not NULL + - an error occurred during materialization. + result_materialize->materialized_cursor is not NULL, but rc != 0 - successful completion of mysql_execute_command without - a cursor: rc is 0, result_materialize->table is NULL, + a cursor: rc is 0, result_materialize->materialized_cursor is NULL, sensitive_cursor is not open. This is possible if some command writes directly to the network, bypassing select_result mechanism. An example of @@ -190,7 +192,7 @@ int mysql_open_cursor(THD *thd, uint flags, select_result *result, if (sensitive_cursor->is_open()) { - DBUG_ASSERT(!result_materialize->table); + DBUG_ASSERT(!result_materialize->materialized_cursor); /* It's safer if we grab THD state after mysql_execute_command is finished and not in Sensitive_cursor::open(), because @@ -201,18 +203,10 @@ int mysql_open_cursor(THD *thd, uint flags, select_result *result, *pcursor= sensitive_cursor; goto end; } - else if (result_materialize->table) + else if (result_materialize->materialized_cursor) { - Materialized_cursor *materialized_cursor; - TABLE *table= result_materialize->table; - MEM_ROOT *mem_root= &table->mem_root; - - if (!(materialized_cursor= new (mem_root) - Materialized_cursor(result, table))) - { - rc= 1; - goto err_open; - } + Materialized_cursor *materialized_cursor= + result_materialize->materialized_cursor; if ((rc= materialized_cursor->open(0))) { @@ -228,8 +222,6 @@ int mysql_open_cursor(THD *thd, uint flags, select_result *result, err_open: DBUG_ASSERT(! (sensitive_cursor && sensitive_cursor->is_open())); delete sensitive_cursor; - if (result_materialize->table) - free_tmp_table(thd, result_materialize->table); end: delete result_materialize; return rc; @@ -322,9 +314,10 @@ Sensitive_cursor::post_open(THD *thd) close_at_commit= FALSE; /* reset in case we're reusing the cursor */ info= &ht_info[0]; - for (handlerton **pht= thd->transaction.stmt.ht; *pht; pht++) + for (Ha_trx_info *ha_trx_info= thd->transaction.stmt.ha_list; + ha_trx_info; ha_trx_info= ha_trx_info->next()) { - handlerton *ht= *pht; + handlerton *ht= ha_trx_info->ht(); close_at_commit|= test(ht->flags & HTON_CLOSE_CURSORS_AT_COMMIT); if (ht->create_cursor_read_view) { @@ -553,6 +546,51 @@ Materialized_cursor::Materialized_cursor(select_result *result_arg, } +/** + Preserve the original metadata that would be sent to the client. + + @param thd Thread identifier. + @param send_fields List of fields that would be sent. +*/ + +int Materialized_cursor::fill_item_list(THD *thd, List<Item> &send_fields) +{ + Query_arena backup_arena; + int rc; + List_iterator_fast<Item> it_org(send_fields); + List_iterator_fast<Item> it_dst(item_list); + Item *item_org; + Item *item_dst; + + thd->set_n_backup_active_arena(this, &backup_arena); + + if ((rc= table->fill_item_list(&item_list))) + goto end; + + DBUG_ASSERT(send_fields.elements == item_list.elements); + + /* + Unless we preserve the original metadata, it will be lost, + since new fields describe columns of the temporary table. + Allocate a copy of the name for safety only. Currently + items with original names are always kept in memory, + but in case this changes a memory leak may be hard to notice. + */ + while ((item_dst= it_dst++, item_org= it_org++)) + { + Send_field send_field; + Item_ident *ident= static_cast<Item_ident *>(item_dst); + item_org->make_field(&send_field); + + ident->db_name= thd->strdup(send_field.db_name); + ident->table_name= thd->strdup(send_field.table_name); + } +end: + thd->restore_active_arena(this, &backup_arena); + /* Check for thd->is_error() in case of OOM */ + return rc || thd->is_error(); +} + int Materialized_cursor::open(JOIN *join __attribute__((unused))) { THD *thd= fake_unit.thd; @@ -561,8 +599,7 @@ int Materialized_cursor::open(JOIN *join __attribute__((unused))) thd->set_n_backup_active_arena(this, &backup_arena); /* Create a list of fields and start sequential scan */ - rc= (table->fill_item_list(&item_list) || - result->prepare(item_list, &fake_unit) || + rc= (result->prepare(item_list, &fake_unit) || table->file->ha_rnd_init(TRUE)); thd->restore_active_arena(this, &backup_arena); if (rc == 0) @@ -668,6 +705,24 @@ bool Select_materialize::send_fields(List<Item> &list, uint flags) if (create_result_table(unit->thd, unit->get_unit_column_types(), FALSE, thd->options | TMP_TABLE_ALL_COLUMNS, "")) return TRUE; + + materialized_cursor= new (&table->mem_root) + Materialized_cursor(result, table); + + if (! materialized_cursor) + { + free_tmp_table(table->in_use, table); + table= 0; + return TRUE; + } + if (materialized_cursor->fill_item_list(unit->thd, list)) + { + delete materialized_cursor; + table= 0; + materialized_cursor= 0; + return TRUE; + } + return FALSE; } |