diff --git a/src/Storages/MergeTree/registerStorageMergeTree.cpp b/src/Storages/MergeTree/registerStorageMergeTree.cpp index f94425a81d3..91bf105af74 100644 --- a/src/Storages/MergeTree/registerStorageMergeTree.cpp +++ b/src/Storages/MergeTree/registerStorageMergeTree.cpp @@ -608,10 +608,14 @@ static StoragePtr create(const StorageFactory::Arguments & args) /// single default partition with name "all". metadata.partition_key = KeyDescription::getKeyFromAST(partition_by_key, metadata.columns, args.context); + /// PRIMARY KEY without ORDER BY is allowed and considered as ORDER BY. + if (!args.storage_def->order_by && args.storage_def->primary_key) + args.storage_def->set(args.storage_def->order_by, args.storage_def->primary_key->clone()); + if (!args.storage_def->order_by) throw Exception( - "You must provide an ORDER BY expression in the table definition. " - "If you don't want this table to be sorted, use ORDER BY tuple()", + "You must provide an ORDER BY or PRIMARY KEY expression in the table definition. " + "If you don't want this table to be sorted, use ORDER BY/PRIMARY KEY tuple()", ErrorCodes::BAD_ARGUMENTS); /// Get sorting key from engine arguments. @@ -627,7 +631,7 @@ static StoragePtr create(const StorageFactory::Arguments & args) { metadata.primary_key = KeyDescription::getKeyFromAST(args.storage_def->primary_key->ptr(), metadata.columns, args.context); } - else /// Otherwise we copy it from primary key definition + else /// Otherwise we don't have explicit primary key and copy it from order by { metadata.primary_key = KeyDescription::getKeyFromAST(args.storage_def->order_by->ptr(), metadata.columns, args.context); /// and set it's definition_ast to nullptr (so isPrimaryKeyDefined() diff --git a/tests/queries/0_stateless/01532_primary_key_without_order_by_zookeeper.reference b/tests/queries/0_stateless/01532_primary_key_without_order_by_zookeeper.reference new file mode 100644 index 00000000000..02d4fe64f8d --- /dev/null +++ b/tests/queries/0_stateless/01532_primary_key_without_order_by_zookeeper.reference @@ -0,0 +1,23 @@ +CREATE TABLE default.merge_tree_pk\n(\n `key` UInt64,\n `value` String\n)\nENGINE = ReplacingMergeTree()\nPRIMARY KEY key\nORDER BY key\nSETTINGS index_granularity = 8192 +1 a +2 b +1 c +2 b +CREATE TABLE default.merge_tree_pk_sql\n(\n `key` UInt64,\n `value` String\n)\nENGINE = ReplacingMergeTree()\nPRIMARY KEY key\nORDER BY key\nSETTINGS index_granularity = 8192 +1 a +2 b +1 c +2 b +1 c 0 +2 e 555 +2 b 0 +CREATE TABLE default.merge_tree_pk_sql\n(\n `key` UInt64,\n `value` String,\n `key2` UInt64\n)\nENGINE = ReplacingMergeTree()\nPRIMARY KEY key\nORDER BY (key, key2)\nSETTINGS index_granularity = 8192 +CREATE TABLE default.replicated_merge_tree_pk_sql\n(\n `key` UInt64,\n `value` String\n)\nENGINE = ReplicatedReplacingMergeTree(\'/clickhouse/test/01532_primary_key_without\', \'r1\')\nPRIMARY KEY key\nORDER BY key\nSETTINGS index_granularity = 8192 +1 a +2 b +1 c +2 b +1 c 0 +2 e 555 +2 b 0 +CREATE TABLE default.replicated_merge_tree_pk_sql\n(\n `key` UInt64,\n `value` String,\n `key2` UInt64\n)\nENGINE = ReplicatedReplacingMergeTree(\'/clickhouse/test/01532_primary_key_without\', \'r1\')\nPRIMARY KEY key\nORDER BY (key, key2)\nSETTINGS index_granularity = 8192 diff --git a/tests/queries/0_stateless/01532_primary_key_without_order_by_zookeeper.sql b/tests/queries/0_stateless/01532_primary_key_without_order_by_zookeeper.sql new file mode 100644 index 00000000000..31294d8ebbc --- /dev/null +++ b/tests/queries/0_stateless/01532_primary_key_without_order_by_zookeeper.sql @@ -0,0 +1,100 @@ +DROP TABLE IF EXISTS merge_tree_pk; + +CREATE TABLE merge_tree_pk +( + key UInt64, + value String +) +ENGINE = ReplacingMergeTree() +PRIMARY KEY key; + +SHOW CREATE TABLE merge_tree_pk; + +INSERT INTO merge_tree_pk VALUES (1, 'a'); +INSERT INTO merge_tree_pk VALUES (2, 'b'); + +SELECT * FROM merge_tree_pk ORDER BY key; + +INSERT INTO merge_tree_pk VALUES (1, 'c'); + +DETACH TABLE merge_tree_pk; +ATTACH TABLE merge_tree_pk; + +SELECT * FROM merge_tree_pk FINAL ORDER BY key; + +DROP TABLE IF EXISTS merge_tree_pk; + +DROP TABLE IF EXISTS merge_tree_pk_sql; + +CREATE TABLE merge_tree_pk_sql +( + key UInt64, + value String, + PRIMARY KEY (key) +) +ENGINE = ReplacingMergeTree(); + +SHOW CREATE TABLE merge_tree_pk_sql; + +INSERT INTO merge_tree_pk_sql VALUES (1, 'a'); +INSERT INTO merge_tree_pk_sql VALUES (2, 'b'); + +SELECT * FROM merge_tree_pk_sql ORDER BY key; + +INSERT INTO merge_tree_pk_sql VALUES (1, 'c'); + +DETACH TABLE merge_tree_pk_sql; +ATTACH TABLE merge_tree_pk_sql; + +SELECT * FROM merge_tree_pk_sql FINAL ORDER BY key; + +ALTER TABLE merge_tree_pk_sql ADD COLUMN key2 UInt64, MODIFY ORDER BY (key, key2); + +INSERT INTO merge_tree_pk_sql VALUES (2, 'd', 555); + +INSERT INTO merge_tree_pk_sql VALUES (2, 'e', 555); + +SELECT * FROM merge_tree_pk_sql FINAL ORDER BY key; + +SHOW CREATE TABLE merge_tree_pk_sql; + +DROP TABLE IF EXISTS merge_tree_pk_sql; + +DROP TABLE IF EXISTS replicated_merge_tree_pk_sql; + +CREATE TABLE replicated_merge_tree_pk_sql +( + key UInt64, + value String, + PRIMARY KEY (key) +) +ENGINE = ReplicatedReplacingMergeTree('/clickhouse/test/01532_primary_key_without', 'r1'); + +SHOW CREATE TABLE replicated_merge_tree_pk_sql; + +INSERT INTO replicated_merge_tree_pk_sql VALUES (1, 'a'); +INSERT INTO replicated_merge_tree_pk_sql VALUES (2, 'b'); + +SELECT * FROM replicated_merge_tree_pk_sql ORDER BY key; + +INSERT INTO replicated_merge_tree_pk_sql VALUES (1, 'c'); + +DETACH TABLE replicated_merge_tree_pk_sql; +ATTACH TABLE replicated_merge_tree_pk_sql; + +SELECT * FROM replicated_merge_tree_pk_sql FINAL ORDER BY key; + +ALTER TABLE replicated_merge_tree_pk_sql ADD COLUMN key2 UInt64, MODIFY ORDER BY (key, key2); + +INSERT INTO replicated_merge_tree_pk_sql VALUES (2, 'd', 555); + +INSERT INTO replicated_merge_tree_pk_sql VALUES (2, 'e', 555); + +SELECT * FROM replicated_merge_tree_pk_sql FINAL ORDER BY key; + +DETACH TABLE replicated_merge_tree_pk_sql; +ATTACH TABLE replicated_merge_tree_pk_sql; + +SHOW CREATE TABLE replicated_merge_tree_pk_sql; + +DROP TABLE IF EXISTS replicated_merge_tree_pk_sql;