summaryrefslogtreecommitdiff
path: root/sql/sql_cursor.cc
diff options
context:
space:
mode:
authorunknown <monty@narttu.mysql.fi>2008-04-28 19:24:05 +0300
committerunknown <monty@narttu.mysql.fi>2008-04-28 19:24:05 +0300
commit50ceea65cf18a64db017f06d2be5197807927588 (patch)
treeff5ab0c71ce5a2792c4f169a880e0174f8e194ad /sql/sql_cursor.cc
parented5fe6d3eb5d702e2fe27de3c65c550ea0dbf17f (diff)
parentc481f6b3cf80f471321d2ef4e7c68fe9e6e5d0ca (diff)
downloadmariadb-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.cc103
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;
}