diff --git a/mysql-test/suite/sql_sequence/create.result b/mysql-test/suite/sql_sequence/create.result index cb683d158d88c..55d45a75abf39 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 b2562058ca6ef..1bc62117526a9 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 8a374fe87b78e..828778062430e 100644 --- a/sql/ha_partition.h +++ b/sql/ha_partition.h @@ -1041,6 +1041,10 @@ class ha_partition :public handler 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 e52f9ddaefb2c..788ac4dd47450 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 c9676105dec92..b9fc431feb157 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 cfec257322e54..20dc215ee7f57 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()