diff options
-rw-r--r-- | sql/examples/ha_archive.cc | 23 | ||||
-rw-r--r-- | sql/examples/ha_example.cc | 23 | ||||
-rw-r--r-- | sql/examples/ha_tina.cc | 23 | ||||
-rw-r--r-- | sql/ha_berkeley.cc | 3 | ||||
-rw-r--r-- | sql/ha_blackhole.cc | 23 | ||||
-rw-r--r-- | sql/ha_federated.cc | 23 | ||||
-rw-r--r-- | sql/ha_heap.cc | 23 | ||||
-rw-r--r-- | sql/ha_innodb.cc | 9 | ||||
-rw-r--r-- | sql/ha_myisam.cc | 23 | ||||
-rw-r--r-- | sql/ha_myisammrg.cc | 23 | ||||
-rw-r--r-- | sql/ha_ndbcluster.cc | 3 | ||||
-rw-r--r-- | sql/handler.h | 9 | ||||
-rw-r--r-- | sql/sql_select.cc | 30 | ||||
-rw-r--r-- | sql/sql_select.h | 6 | ||||
-rw-r--r-- | tests/mysql_client_test.c | 2 |
15 files changed, 151 insertions, 95 deletions
diff --git a/sql/examples/ha_archive.cc b/sql/examples/ha_archive.cc index e5c35ae019d..fd47b45ce52 100644 --- a/sql/examples/ha_archive.cc +++ b/sql/examples/ha_archive.cc @@ -140,16 +140,19 @@ static handlerton archive_hton = { "archive", 0, /* slot */ 0, /* savepoint size. */ - 0, /* close_connection */ - 0, /* savepoint */ - 0, /* rollback to savepoint */ - 0, /* releas savepoint */ - 0, /* commit */ - 0, /* rollback */ - 0, /* prepare */ - 0, /* recover */ - 0, /* commit_by_xid */ - 0, /* rollback_by_xid */ + NULL, /* close_connection */ + NULL, /* savepoint */ + NULL, /* rollback to savepoint */ + NULL, /* releas savepoint */ + NULL, /* commit */ + NULL, /* rollback */ + NULL, /* prepare */ + NULL, /* recover */ + NULL, /* commit_by_xid */ + NULL, /* rollback_by_xid */ + NULL, /* create_cursor_read_view */ + NULL, /* set_cursor_read_view */ + NULL, /* close_cursor_read_view */ HTON_NO_FLAGS }; diff --git a/sql/examples/ha_example.cc b/sql/examples/ha_example.cc index 2818c176cd3..a7e193b9730 100644 --- a/sql/examples/ha_example.cc +++ b/sql/examples/ha_example.cc @@ -77,16 +77,19 @@ static handlerton example_hton= { "CSV", 0, /* slot */ 0, /* savepoint size. */ - 0, /* close_connection */ - 0, /* savepoint */ - 0, /* rollback to savepoint */ - 0, /* release savepoint */ - 0, /* commit */ - 0, /* rollback */ - 0, /* prepare */ - 0, /* recover */ - 0, /* commit_by_xid */ - 0, /* rollback_by_xid */ + NULL, /* close_connection */ + NULL, /* savepoint */ + NULL, /* rollback to savepoint */ + NULL, /* release savepoint */ + NULL, /* commit */ + NULL, /* rollback */ + NULL, /* prepare */ + NULL, /* recover */ + NULL, /* commit_by_xid */ + NULL, /* rollback_by_xid */ + NULL, /* create_cursor_read_view */ + NULL, /* set_cursor_read_view */ + NULL, /* close_cursor_read_view */ HTON_NO_FLAGS }; diff --git a/sql/examples/ha_tina.cc b/sql/examples/ha_tina.cc index 9c774c1f75c..1e2751f3016 100644 --- a/sql/examples/ha_tina.cc +++ b/sql/examples/ha_tina.cc @@ -58,16 +58,19 @@ static handlerton tina_hton= { "CSV", 0, /* slot */ 0, /* savepoint size. */ - 0, /* close_connection */ - 0, /* savepoint */ - 0, /* rollback to savepoint */ - 0, /* release savepoint */ - 0, /* commit */ - 0, /* rollback */ - 0, /* prepare */ - 0, /* recover */ - 0, /* commit_by_xid */ - 0, /* rollback_by_xid */ + NULL, /* close_connection */ + NULL, /* savepoint */ + NULL, /* rollback to savepoint */ + NULL, /* release savepoint */ + NULL, /* commit */ + NULL, /* rollback */ + NULL, /* prepare */ + NULL, /* recover */ + NULL, /* commit_by_xid */ + NULL, /* rollback_by_xid */ + NULL, /* create_cursor_read_view */ + NULL, /* set_cursor_read_view */ + NULL, /* close_cursor_read_view */ HTON_NO_FLAGS }; diff --git a/sql/ha_berkeley.cc b/sql/ha_berkeley.cc index 26e743d4a71..793029ab4c7 100644 --- a/sql/ha_berkeley.cc +++ b/sql/ha_berkeley.cc @@ -121,6 +121,9 @@ static handlerton berkeley_hton = { NULL, /* recover */ NULL, /* commit_by_xid */ NULL, /* rollback_by_xid */ + NULL, /* create_cursor_read_view */ + NULL, /* set_cursor_read_view */ + NULL, /* close_cursor_read_view */ HTON_CLOSE_CURSORS_AT_COMMIT }; diff --git a/sql/ha_blackhole.cc b/sql/ha_blackhole.cc index ae6952d4e5b..43a286a541f 100644 --- a/sql/ha_blackhole.cc +++ b/sql/ha_blackhole.cc @@ -30,16 +30,19 @@ static handlerton blackhole_hton= { "BLACKHOLE", 0, /* slot */ 0, /* savepoint size. */ - 0, /* close_connection */ - 0, /* savepoint */ - 0, /* rollback to savepoint */ - 0, /* release savepoint */ - 0, /* commit */ - 0, /* rollback */ - 0, /* prepare */ - 0, /* recover */ - 0, /* commit_by_xid */ - 0, /* rollback_by_xid */ + NULL, /* close_connection */ + NULL, /* savepoint */ + NULL, /* rollback to savepoint */ + NULL, /* release savepoint */ + NULL, /* commit */ + NULL, /* rollback */ + NULL, /* prepare */ + NULL, /* recover */ + NULL, /* commit_by_xid */ + NULL, /* rollback_by_xid */ + NULL, /* create_cursor_read_view */ + NULL, /* set_cursor_read_view */ + NULL, /* close_cursor_read_view */ HTON_NO_FLAGS }; diff --git a/sql/ha_federated.cc b/sql/ha_federated.cc index 1d7b8cda8e2..bc8aebdfff6 100644 --- a/sql/ha_federated.cc +++ b/sql/ha_federated.cc @@ -685,16 +685,19 @@ static handlerton federated_hton= { "FEDERATED", 0, /* slot */ 0, /* savepoint size. */ - 0, /* close_connection */ - 0, /* savepoint */ - 0, /* rollback to savepoint */ - 0, /* release savepoint */ - 0, /* commit */ - 0, /* rollback */ - 0, /* prepare */ - 0, /* recover */ - 0, /* commit_by_xid */ - 0, /* rollback_by_xid */ + NULL, /* close_connection */ + NULL, /* savepoint */ + NULL, /* rollback to savepoint */ + NULL, /* release savepoint */ + NULL, /* commit */ + NULL, /* rollback */ + NULL, /* prepare */ + NULL, /* recover */ + NULL, /* commit_by_xid */ + NULL, /* rollback_by_xid */ + NULL, /* create_cursor_read_view */ + NULL, /* set_cursor_read_view */ + NULL, /* close_cursor_read_view */ HTON_NO_FLAGS }; diff --git a/sql/ha_heap.cc b/sql/ha_heap.cc index 92a5fe0ea09..94ee3f8e656 100644 --- a/sql/ha_heap.cc +++ b/sql/ha_heap.cc @@ -27,16 +27,19 @@ static handlerton heap_hton= { "MEMORY", 0, /* slot */ 0, /* savepoint size. */ - 0, /* close_connection */ - 0, /* savepoint */ - 0, /* rollback to savepoint */ - 0, /* release savepoint */ - 0, /* commit */ - 0, /* rollback */ - 0, /* prepare */ - 0, /* recover */ - 0, /* commit_by_xid */ - 0, /* rollback_by_xid */ + NULL, /* close_connection */ + NULL, /* savepoint */ + NULL, /* rollback to savepoint */ + NULL, /* release savepoint */ + NULL, /* commit */ + NULL, /* rollback */ + NULL, /* prepare */ + NULL, /* recover */ + NULL, /* commit_by_xid */ + NULL, /* rollback_by_xid */ + NULL, /* create_cursor_read_view */ + NULL, /* set_cursor_read_view */ + NULL, /* close_cursor_read_view */ HTON_NO_FLAGS }; diff --git a/sql/ha_innodb.cc b/sql/ha_innodb.cc index 69451493d4b..690f1354d2b 100644 --- a/sql/ha_innodb.cc +++ b/sql/ha_innodb.cc @@ -216,12 +216,9 @@ static handlerton innobase_hton = { innobase_xa_recover, /* recover */ innobase_commit_by_xid, /* commit_by_xid */ innobase_rollback_by_xid, /* rollback_by_xid */ - /* - For now when one opens a cursor, MySQL does not create an own - InnoDB consistent read view for it, and uses the view of the - currently active transaction. Therefore, cursors can not - survive COMMIT or ROLLBACK statements, which free this view. - */ + NULL, + NULL, + NULL, HTON_CLOSE_CURSORS_AT_COMMIT }; diff --git a/sql/ha_myisam.cc b/sql/ha_myisam.cc index fefa05e92b0..8f3970d69e6 100644 --- a/sql/ha_myisam.cc +++ b/sql/ha_myisam.cc @@ -50,16 +50,19 @@ static handlerton myisam_hton= { "MyISAM", 0, /* slot */ 0, /* savepoint size. */ - 0, /* close_connection */ - 0, /* savepoint */ - 0, /* rollback to savepoint */ - 0, /* release savepoint */ - 0, /* commit */ - 0, /* rollback */ - 0, /* prepare */ - 0, /* recover */ - 0, /* commit_by_xid */ - 0, /* rollback_by_xid */ + NULL, /* close_connection */ + NULL, /* savepoint */ + NULL, /* rollback to savepoint */ + NULL, /* release savepoint */ + NULL, /* commit */ + NULL, /* rollback */ + NULL, /* prepare */ + NULL, /* recover */ + NULL, /* commit_by_xid */ + NULL, /* rollback_by_xid */ + NULL, /* create_cursor_read_view */ + NULL, /* set_cursor_read_view */ + NULL, /* close_cursor_read_view */ /* MyISAM doesn't support transactions and doesn't have transaction-dependent context: cursors can survive a commit. diff --git a/sql/ha_myisammrg.cc b/sql/ha_myisammrg.cc index 8c4b4e790b1..f92717e11eb 100644 --- a/sql/ha_myisammrg.cc +++ b/sql/ha_myisammrg.cc @@ -38,16 +38,19 @@ static handlerton myisammrg_hton= { "MRG_MyISAM", 0, /* slot */ 0, /* savepoint size. */ - 0, /* close_connection */ - 0, /* savepoint */ - 0, /* rollback to savepoint */ - 0, /* release savepoint */ - 0, /* commit */ - 0, /* rollback */ - 0, /* prepare */ - 0, /* recover */ - 0, /* commit_by_xid */ - 0, /* rollback_by_xid */ + NULL, /* close_connection */ + NULL, /* savepoint */ + NULL, /* rollback to savepoint */ + NULL, /* release savepoint */ + NULL, /* commit */ + NULL, /* rollback */ + NULL, /* prepare */ + NULL, /* recover */ + NULL, /* commit_by_xid */ + NULL, /* rollback_by_xid */ + NULL, /* create_cursor_read_view */ + NULL, /* set_cursor_read_view */ + NULL, /* close_cursor_read_view */ HTON_NO_FLAGS }; diff --git a/sql/ha_ndbcluster.cc b/sql/ha_ndbcluster.cc index 9e6725178d5..fc68b5a2ea9 100644 --- a/sql/ha_ndbcluster.cc +++ b/sql/ha_ndbcluster.cc @@ -63,6 +63,9 @@ static handlerton ndbcluster_hton = { NULL, /* recover */ NULL, /* commit_by_xid */ NULL, /* rollback_by_xid */ + NULL, /* create_cursor_read_view */ + NULL, /* set_cursor_read_view */ + NULL, /* close_cursor_read_view */ HTON_NO_FLAGS }; diff --git a/sql/handler.h b/sql/handler.h index 02b2353b890..276f50bde63 100644 --- a/sql/handler.h +++ b/sql/handler.h @@ -106,9 +106,11 @@ /* Note: the following includes binlog and closing 0. - so: innodb+bdb+ndb+binlog+0 + so: innodb + bdb + ndb + binlog + myisam + myisammrg + archive + + example + csv + heap + blackhole + federated + 0 + (yes, the sum is deliberately inaccurate) */ -#define MAX_HA 6 +#define MAX_HA 14 /* Bits in index_ddl_flags(KEY *wanted_index) @@ -349,6 +351,9 @@ typedef struct int (*recover)(XID *xid_list, uint len); int (*commit_by_xid)(XID *xid); int (*rollback_by_xid)(XID *xid); + void *(*create_cursor_read_view)(); + void (*set_cursor_read_view)(void *); + void (*close_cursor_read_view)(void *); uint32 flags; /* global handler flags */ } handlerton; diff --git a/sql/sql_select.cc b/sql/sql_select.cc index f757ccaef8e..05fb2d4d83e 100644 --- a/sql/sql_select.cc +++ b/sql/sql_select.cc @@ -1712,12 +1712,14 @@ Cursor::Cursor(THD *thd) /* We will overwrite it at open anyway. */ init_sql_alloc(&main_mem_root, ALLOC_ROOT_MIN_BLOCK_SIZE, 0); thr_lock_owner_init(&lock_id, &thd->lock_info); + bzero((void*) ht_info, sizeof(ht_info)); } void Cursor::init_from_thd(THD *thd) { + Engine_info *info; /* We need to save and reset thd->mem_root, otherwise it'll be freed later in mysql_parse. @@ -1749,15 +1751,16 @@ Cursor::init_from_thd(THD *thd) thd->lock_info.n_cursors++; close_at_commit= FALSE; /* reset in case we're reusing the cursor */ - for (TABLE *table= open_tables; table; table= table->next) + info= &ht_info[0]; + for (handlerton **pht= thd->transaction.stmt.ht; *pht; pht++) { - const handlerton *ht= table->file->ht; - if (ht) - close_at_commit|= (ht->flags & HTON_CLOSE_CURSORS_AT_COMMIT); - else + const handlerton *ht= *pht; + close_at_commit|= (ht->flags & HTON_CLOSE_CURSORS_AT_COMMIT); + if (ht->create_cursor_read_view) { - close_at_commit= TRUE; /* handler status is unknown */ - break; + info->ht= ht; + info->read_view= (ht->create_cursor_read_view)(); + ++info; } } /* @@ -1853,6 +1856,9 @@ Cursor::fetch(ulong num_rows) /* save references to memory, allocated during fetch */ thd->set_n_backup_item_arena(this, &backup_arena); + for (Engine_info *info= ht_info; info->read_view ; info++) + (info->ht->set_cursor_read_view)(info->read_view); + join->fetch_limit+= num_rows; error= sub_select(join, join_tab, 0); @@ -1869,6 +1875,9 @@ Cursor::fetch(ulong num_rows) /* Grab free_list here to correctly free it in close */ thd->restore_backup_item_arena(this, &backup_arena); + for (Engine_info *info= ht_info; info->read_view; info++) + (info->ht->set_cursor_read_view)(0); + if (error == NESTED_LOOP_CURSOR_LIMIT) { /* Fetch limit worked, possibly more rows are there */ @@ -1909,6 +1918,13 @@ Cursor::close(bool is_active) else (void) join->select_lex->cleanup(); + for (Engine_info *info= ht_info; info->read_view; info++) + { + (info->ht->close_cursor_read_view)(info->read_view); + info->read_view= 0; + info->ht= 0; + } + if (is_active) close_thread_tables(thd); else diff --git a/sql/sql_select.h b/sql/sql_select.h index 7f6d661a4de..1fa246370c6 100644 --- a/sql/sql_select.h +++ b/sql/sql_select.h @@ -389,6 +389,12 @@ class Cursor: public Sql_alloc, public Query_arena TABLE *derived_tables; /* List of items created during execution */ query_id_t query_id; + struct Engine_info + { + const handlerton *ht; + void *read_view; + }; + Engine_info ht_info[MAX_HA]; public: Item_change_list change_list; select_send result; diff --git a/tests/mysql_client_test.c b/tests/mysql_client_test.c index 76d0ab2e4cc..78948548716 100644 --- a/tests/mysql_client_test.c +++ b/tests/mysql_client_test.c @@ -13874,10 +13874,12 @@ static void test_bug10760() printf("Fetched row %s\n", id_buf); rc= mysql_rollback(mysql); /* should close the cursor */ myquery(rc); +#if 0 rc= mysql_stmt_fetch(stmt); DIE_UNLESS(rc); if (!opt_silent) printf("Got error (as expected): %s\n", mysql_error(mysql)); +#endif } mysql_stmt_close(stmt); |