diff options
author | Vesa Pentti <vesa.pentti@mariadb.net> | 2018-01-20 13:46:47 +0000 |
---|---|---|
committer | Vesa Pentti <vesa.pentti@mariadb.net> | 2018-01-20 13:47:01 +0000 |
commit | b0d2a778fcd0c434bdb3e88a7449936aad8ef1ea (patch) | |
tree | 910c287ee4bd2dae1c3191729865014346b06abe | |
parent | 5e87f49a9927bf3fd0bd9af789bbdd329e4b4416 (diff) | |
download | mariadb-git-bb-10.0-pentve.tar.gz |
MDEV-14185 -- CREATE TEMPORARY TABLE AS SELECT causes error 1290 with read_only and InnoDBbb-10.0-pentve
* Did affect only transactional engines like InnoDB
* Note: During table creation handler's 'table_share' is NULL
* Now the transaction isn't marked rw for a temporary table when it's created
-rw-r--r-- | mysql-test/t/create_select_temporary_table.test | 23 | ||||
-rw-r--r-- | sql/handler.cc | 16 | ||||
-rw-r--r-- | sql/handler.h | 2 | ||||
-rw-r--r-- | sql/unireg.cc | 3 |
4 files changed, 37 insertions, 7 deletions
diff --git a/mysql-test/t/create_select_temporary_table.test b/mysql-test/t/create_select_temporary_table.test new file mode 100644 index 00000000000..d5dea48f43c --- /dev/null +++ b/mysql-test/t/create_select_temporary_table.test @@ -0,0 +1,23 @@ +--source include/have_innodb.inc + +SET GLOBAL read_only = on; +CREATE DATABASE mydb; +use mydb; +CREATE TABLE mytable (id INTEGER) ENGINE=InnoDB; +INSERT INTO mytable (id) VALUES (1); + +CREATE USER 'nosuper'@'localhost'; +GRANT SELECT, INSERT, UPDATE, DELETE, CREATE, DROP, CREATE TEMPORARY TABLES, LOCK TABLES ON mydb.* TO 'nosuper'@'localhost'; + +--connect (con1,localhost,nosuper,,mydb) + +CREATE TEMPORARY TABLE t1 ENGINE=InnoDB AS SELECT id FROM mytable; + +# Cleanup + +--disconnect con1 +--connection default +DROP DATABASE mydb; +DROP USER nosuper@localhost; +SET GLOBAL read_only = DEFAULT; + diff --git a/sql/handler.cc b/sql/handler.cc index 174034a7eb5..85b73719f0e 100644 --- a/sql/handler.cc +++ b/sql/handler.cc @@ -3995,7 +3995,8 @@ handler::mark_trx_read_write() DBUG_ASSERT(has_transactions()); /* table_share can be NULL in ha_delete_table(). See implementation - of standalone function ha_delete_table() in sql_base.cc. + of standalone function ha_delete_table() in sql_base.cc. It can + also be NULL during table creation. */ if (table_share == NULL || table_share->tmp_table == NO_TMP_TABLE) ha_info->set_trx_read_write(); @@ -4378,8 +4379,10 @@ handler::ha_create(const char *name, TABLE *form, HA_CREATE_INFO *info) */ int -handler::ha_create_partitioning_metadata(const char *name, const char *old_name, - int action_flag) +handler::ha_create_partitioning_metadata(const char *name, + const char *old_name, + int action_flag, + bool should_mark_rw) { /* Normally this is done when unlocked, but in fast_alter_partition_table, @@ -4387,8 +4390,11 @@ handler::ha_create_partitioning_metadata(const char *name, const char *old_name, partitions. */ DBUG_ASSERT(m_lock_type == F_UNLCK || - (!old_name && strcmp(name, table_share->path.str))); - mark_trx_read_write(); + (!old_name && table_share && strcmp(name, table_share->path.str))); + if (should_mark_rw) + { + mark_trx_read_write(); + } return create_partitioning_metadata(name, old_name, action_flag); } diff --git a/sql/handler.h b/sql/handler.h index c422094b4d5..194060f5de9 100644 --- a/sql/handler.h +++ b/sql/handler.h @@ -2734,7 +2734,7 @@ public: int ha_create(const char *name, TABLE *form, HA_CREATE_INFO *info); int ha_create_partitioning_metadata(const char *name, const char *old_name, - int action_flag); + int action_flag, bool should_mark_rw = true); int ha_change_partitions(HA_CREATE_INFO *create_info, const char *path, diff --git a/sql/unireg.cc b/sql/unireg.cc index 12d3c265a86..ed881e864eb 100644 --- a/sql/unireg.cc +++ b/sql/unireg.cc @@ -370,7 +370,8 @@ int rea_create_table(THD *thd, LEX_CUSTRING *frm, if (thd->variables.keep_files_on_create) create_info->options|= HA_CREATE_KEEP_FILES; - if (file->ha_create_partitioning_metadata(path, NULL, CHF_CREATE_FLAG)) + if (file->ha_create_partitioning_metadata(path, NULL, + CHF_CREATE_FLAG, !create_info->tmp_table())) goto err_part; if (!no_ha_create_table) |