From d30124e844cdcd2eef4b13199e91aa5c304e907c Mon Sep 17 00:00:00 2001 From: Monty Date: Mon, 29 Oct 2018 16:12:52 +0200 Subject: [PATCH] MDEV-17503 CREATE SEQUENCE failed with innodb_force_primary_key =1 Fixed by adding table flag HA_WANTS_PRIMARY_KEY, which is like HA_REQUIRE_PRIMARY_KEY but tells SQL upper layer that the storage engine internally can handle tables without primary keys (for example for sequences or trough user variables) --- mysql-test/suite/sql_sequence/create.result | 9 +++++++++ mysql-test/suite/sql_sequence/create.test | 11 +++++++++++ sql/ha_partition.h | 4 ++++ sql/handler.h | 3 +++ sql/sql_table.cc | 4 +++- storage/innobase/handler/ha_innodb.cc | 2 +- 6 files changed, 31 insertions(+), 2 deletions(-) diff --git a/mysql-test/suite/sql_sequence/create.result b/mysql-test/suite/sql_sequence/create.result index cb683d158d8..55d45a75abf 100644 --- a/mysql-test/suite/sql_sequence/create.result +++ b/mysql-test/suite/sql_sequence/create.result @@ -644,3 +644,12 @@ TABLE_ID NAME FLAG N_COLS SPACE ROW_FORMAT ZIP_PAGE_SIZE SPACE_TYPE DROP SEQUENCE seq1; CREATE TEMPORARY SEQUENCE seq1 ENGINE=InnoDB ROW_FORMAT=REDUNDANT; DROP TEMPORARY SEQUENCE seq1; +# +# MDEV-17503 CREATE SEQUENCE failed with innodb_force_primary_key =1 +# +set global innodb_force_primary_key =1; +CREATE SEQUENCE s1 START WITH 100 INCREMENT BY 10 ENGINE=innodb; +set global innodb_force_primary_key=default; +ALTER TABLE s1 ADD PRIMARY KEY (next_not_cached_value); +ERROR HY000: Sequence 'test.s1' table structure is invalid (Sequence tables cannot have any keys) +DROP SEQUENCE s1; diff --git a/mysql-test/suite/sql_sequence/create.test b/mysql-test/suite/sql_sequence/create.test index b2562058ca6..1bc62117526 100644 --- a/mysql-test/suite/sql_sequence/create.test +++ b/mysql-test/suite/sql_sequence/create.test @@ -462,3 +462,14 @@ SELECT * FROM INFORMATION_SCHEMA.INNODB_SYS_TABLES WHERE NAME='test/seq1'; DROP SEQUENCE seq1; CREATE TEMPORARY SEQUENCE seq1 ENGINE=InnoDB ROW_FORMAT=REDUNDANT; DROP TEMPORARY SEQUENCE seq1; + +--echo # +--echo # MDEV-17503 CREATE SEQUENCE failed with innodb_force_primary_key =1 +--echo # + +set global innodb_force_primary_key =1; +CREATE SEQUENCE s1 START WITH 100 INCREMENT BY 10 ENGINE=innodb; +set global innodb_force_primary_key=default; +--error ER_SEQUENCE_INVALID_TABLE_STRUCTURE +ALTER TABLE s1 ADD PRIMARY KEY (next_not_cached_value); +DROP SEQUENCE s1; diff --git a/sql/ha_partition.h b/sql/ha_partition.h index 8a374fe87b7..82877806243 100644 --- a/sql/ha_partition.h +++ b/sql/ha_partition.h @@ -1041,6 +1041,10 @@ public: with hidden primary key) (No handler has this limitation currently) + HA_WANTS_PRIMARY_KEY: + Can't define a table without primary key except sequences + (Only InnoDB has this when using innodb_force_primary_key == ON) + HA_STATS_RECORDS_IS_EXACT: Does the counter of records after the info call specify an exact value or not. If it does this flag is set. diff --git a/sql/handler.h b/sql/handler.h index e52f9ddaefb..788ac4dd474 100644 --- a/sql/handler.h +++ b/sql/handler.h @@ -301,6 +301,9 @@ enum enum_alter_inplace_result { /* calling cmp_ref() on the engine is expensive */ #define HA_CMP_REF_IS_EXPENSIVE (1ULL << 54) +/* Engine wants primary keys for everything except sequences */ +#define HA_WANTS_PRIMARY_KEY (1ULL << 55) + /* bits in index_flags(index_number) for what you can do with index */ #define HA_READ_NEXT 1 /* TODO really use this flag */ #define HA_READ_PREV 2 /* supports ::index_prev */ diff --git a/sql/sql_table.cc b/sql/sql_table.cc index c9676105dec..b9fc431feb1 100644 --- a/sql/sql_table.cc +++ b/sql/sql_table.cc @@ -4134,7 +4134,9 @@ mysql_prepare_create_table(THD *thd, HA_CREATE_INFO *create_info, } if (!unique_key && !primary_key && - (file->ha_table_flags() & HA_REQUIRE_PRIMARY_KEY)) + ((file->ha_table_flags() & HA_REQUIRE_PRIMARY_KEY) || + ((file->ha_table_flags() & HA_WANTS_PRIMARY_KEY) && + !create_info->sequence))) { my_message(ER_REQUIRES_PRIMARY_KEY, ER_THD(thd, ER_REQUIRES_PRIMARY_KEY), MYF(0)); diff --git a/storage/innobase/handler/ha_innodb.cc b/storage/innobase/handler/ha_innodb.cc index cfec257322e..20dc215ee7f 100644 --- a/storage/innobase/handler/ha_innodb.cc +++ b/storage/innobase/handler/ha_innodb.cc @@ -2918,7 +2918,7 @@ ha_innobase::ha_innobase( | HA_CAN_RTREEKEYS | HA_CAN_TABLES_WITHOUT_ROLLBACK | HA_CONCURRENT_OPTIMIZE - | (srv_force_primary_key ? HA_REQUIRE_PRIMARY_KEY : 0) + | (srv_force_primary_key ? HA_WANTS_PRIMARY_KEY : 0) ), m_start_of_scan(), m_mysql_has_locked()