This commit is contained in:
Yatsishin Ilya 2023-07-05 12:28:27 +00:00
parent 1ffc9245d7
commit e957600d5c
6 changed files with 126 additions and 3 deletions

View File

@ -44,6 +44,7 @@ ASTPtr ASTColumnDeclaration::clone() const
res->ttl = ttl->clone(); res->ttl = ttl->clone();
res->children.push_back(res->ttl); res->children.push_back(res->ttl);
} }
if (collation) if (collation)
{ {
res->collation = collation->clone(); res->collation = collation->clone();
@ -76,6 +77,10 @@ void ASTColumnDeclaration::formatImpl(const FormatSettings & settings, FormatSta
<< (*null_modifier ? "" : "NOT ") << "NULL" << (settings.hilite ? hilite_none : ""); << (*null_modifier ? "" : "NOT ") << "NULL" << (settings.hilite ? hilite_none : "");
} }
if (primary_key_specifier)
settings.ostr << ' ' << (settings.hilite ? hilite_keyword : "")
<< "PRIMARY KEY" << (settings.hilite ? hilite_none : "");
if (default_expression) if (default_expression)
{ {
settings.ostr << ' ' << (settings.hilite ? hilite_keyword : "") << default_specifier << (settings.hilite ? hilite_none : ""); settings.ostr << ' ' << (settings.hilite ? hilite_keyword : "") << default_specifier << (settings.hilite ? hilite_none : "");

View File

@ -21,6 +21,7 @@ public:
ASTPtr codec; ASTPtr codec;
ASTPtr ttl; ASTPtr ttl;
ASTPtr collation; ASTPtr collation;
bool primary_key_specifier = false;
String getID(char delim) const override { return "ColumnDeclaration" + (delim + name); } String getID(char delim) const override { return "ColumnDeclaration" + (delim + name); }

View File

@ -56,6 +56,7 @@ public:
ASTExpressionList * constraints = nullptr; ASTExpressionList * constraints = nullptr;
ASTExpressionList * projections = nullptr; ASTExpressionList * projections = nullptr;
IAST * primary_key = nullptr; IAST * primary_key = nullptr;
IAST * primary_key_from_columns = nullptr;
String getID(char) const override { return "Columns definition"; } String getID(char) const override { return "Columns definition"; }
@ -76,7 +77,7 @@ public:
f(reinterpret_cast<void **>(&primary_key)); f(reinterpret_cast<void **>(&primary_key));
f(reinterpret_cast<void **>(&constraints)); f(reinterpret_cast<void **>(&constraints));
f(reinterpret_cast<void **>(&projections)); f(reinterpret_cast<void **>(&projections));
f(reinterpret_cast<void **>(&primary_key)); f(reinterpret_cast<void **>(&primary_key_from_columns));
} }
}; };

View File

@ -300,11 +300,21 @@ bool ParserTablePropertiesDeclarationList::parseImpl(Pos & pos, ASTPtr & node, E
ASTPtr constraints = std::make_shared<ASTExpressionList>(); ASTPtr constraints = std::make_shared<ASTExpressionList>();
ASTPtr projections = std::make_shared<ASTExpressionList>(); ASTPtr projections = std::make_shared<ASTExpressionList>();
ASTPtr primary_key; ASTPtr primary_key;
ASTPtr primary_key_from_columns;
for (const auto & elem : list->children) for (const auto & elem : list->children)
{ {
if (elem->as<ASTColumnDeclaration>()) if (auto *cd = elem->as<ASTColumnDeclaration>())
{
if(cd->primary_key_specifier)
{
if(!primary_key_from_columns)
primary_key_from_columns = makeASTFunction("tuple");
auto column_identifier = std::make_shared<ASTIdentifier>(cd->name);
primary_key_from_columns->children.push_back(column_identifier);
}
columns->children.push_back(elem); columns->children.push_back(elem);
}
else if (elem->as<ASTIndexDeclaration>()) else if (elem->as<ASTIndexDeclaration>())
indices->children.push_back(elem); indices->children.push_back(elem);
else if (elem->as<ASTConstraintDeclaration>()) else if (elem->as<ASTConstraintDeclaration>())
@ -336,6 +346,8 @@ bool ParserTablePropertiesDeclarationList::parseImpl(Pos & pos, ASTPtr & node, E
res->set(res->projections, projections); res->set(res->projections, projections);
if (primary_key) if (primary_key)
res->set(res->primary_key, primary_key); res->set(res->primary_key, primary_key);
if (primary_key_from_columns)
res->set(res->primary_key_from_columns, primary_key_from_columns);
node = res; node = res;
@ -599,6 +611,7 @@ bool ParserCreateTableQuery::parseImpl(Pos & pos, ASTPtr & node, Expected & expe
/// List of columns. /// List of columns.
if (s_lparen.ignore(pos, expected)) if (s_lparen.ignore(pos, expected))
{ {
/// Columns and all table properties (indices, constraints, projections, primary_key)
if (!table_properties_p.parse(pos, columns_list, expected)) if (!table_properties_p.parse(pos, columns_list, expected))
return false; return false;
@ -699,6 +712,17 @@ bool ParserCreateTableQuery::parseImpl(Pos & pos, ASTPtr & node, Expected & expe
query->storage->primary_key = query->columns_list->primary_key; query->storage->primary_key = query->columns_list->primary_key;
} }
if (query->columns_list && (query->columns_list->primary_key_from_columns))
{
/// If engine is not set will use default one
if (!query->storage)
query->set(query->storage, std::make_shared<ASTStorage>());
else if (query->storage->primary_key)
throw Exception(ErrorCodes::BAD_ARGUMENTS, "Multiple primary keys are not allowed.");
query->storage->primary_key = query->columns_list->primary_key_from_columns;
}
tryGetIdentifierNameInto(as_database, query->as_database); tryGetIdentifierNameInto(as_database, query->as_database);
tryGetIdentifierNameInto(as_table, query->as_table); tryGetIdentifierNameInto(as_table, query->as_table);
query->set(query->select, select); query->set(query->select, select);

View File

@ -135,6 +135,7 @@ bool IParserColumnDeclaration<NameParser>::parseImpl(Pos & pos, ASTPtr & node, E
ParserKeyword s_remove{"REMOVE"}; ParserKeyword s_remove{"REMOVE"};
ParserKeyword s_type{"TYPE"}; ParserKeyword s_type{"TYPE"};
ParserKeyword s_collate{"COLLATE"}; ParserKeyword s_collate{"COLLATE"};
ParserKeyword s_primary_key{"PRIMARY KEY"};
ParserExpression expr_parser; ParserExpression expr_parser;
ParserStringLiteral string_literal_parser; ParserStringLiteral string_literal_parser;
ParserLiteral literal_parser; ParserLiteral literal_parser;
@ -177,6 +178,7 @@ bool IParserColumnDeclaration<NameParser>::parseImpl(Pos & pos, ASTPtr & node, E
ASTPtr codec_expression; ASTPtr codec_expression;
ASTPtr ttl_expression; ASTPtr ttl_expression;
ASTPtr collation_expression; ASTPtr collation_expression;
bool primary_key_specifier = false;
auto null_check_without_moving = [&]() -> bool auto null_check_without_moving = [&]() -> bool
{ {
@ -198,6 +200,7 @@ bool IParserColumnDeclaration<NameParser>::parseImpl(Pos & pos, ASTPtr & node, E
&& !s_ephemeral.checkWithoutMoving(pos, expected) && !s_ephemeral.checkWithoutMoving(pos, expected)
&& !s_alias.checkWithoutMoving(pos, expected) && !s_alias.checkWithoutMoving(pos, expected)
&& !s_auto_increment.checkWithoutMoving(pos, expected) && !s_auto_increment.checkWithoutMoving(pos, expected)
&& !s_primary_key.checkWithoutMoving(pos, expected)
&& (require_type && (require_type
|| (!s_comment.checkWithoutMoving(pos, expected) || (!s_comment.checkWithoutMoving(pos, expected)
&& !s_codec.checkWithoutMoving(pos, expected)))) && !s_codec.checkWithoutMoving(pos, expected))))
@ -266,7 +269,6 @@ bool IParserColumnDeclaration<NameParser>::parseImpl(Pos & pos, ASTPtr & node, E
ParserDataType().parse(tmp_pos, type, tmp_expected); ParserDataType().parse(tmp_pos, type, tmp_expected);
} }
} }
/// This will rule out unusual expressions like *, t.* that cannot appear in DEFAULT /// This will rule out unusual expressions like *, t.* that cannot appear in DEFAULT
if (default_expression && !dynamic_cast<const ASTWithAlias *>(default_expression.get())) if (default_expression && !dynamic_cast<const ASTWithAlias *>(default_expression.get()))
return false; return false;
@ -305,6 +307,11 @@ bool IParserColumnDeclaration<NameParser>::parseImpl(Pos & pos, ASTPtr & node, E
return false; return false;
} }
if (s_primary_key.ignore(pos, expected))
{
primary_key_specifier = true;
}
node = column_declaration; node = column_declaration;
if (type) if (type)
@ -346,6 +353,8 @@ bool IParserColumnDeclaration<NameParser>::parseImpl(Pos & pos, ASTPtr & node, E
column_declaration->children.push_back(std::move(collation_expression)); column_declaration->children.push_back(std::move(collation_expression));
} }
column_declaration->primary_key_specifier = primary_key_specifier;
return true; return true;
} }

View File

@ -0,0 +1,83 @@
DROP TABLE IF EXISTS pk_test1;
DROP TABLE IF EXISTS pk_test2;
DROP TABLE IF EXISTS pk_test3;
DROP TABLE IF EXISTS pk_test4;
DROP TABLE IF EXISTS pk_test5;
DROP TABLE IF EXISTS pk_test6;
DROP TABLE IF EXISTS pk_test7;
DROP TABLE IF EXISTS pk_test8;
DROP TABLE IF EXISTS pk_test9;
DROP TABLE IF EXISTS pk_test10;
DROP TABLE IF EXISTS pk_test11;
DROP TABLE IF EXISTS pk_test12;
DROP TABLE IF EXISTS pk_test12;
DROP TABLE IF EXISTS pk_test13;
DROP TABLE IF EXISTS pk_test14;
DROP TABLE IF EXISTS pk_test15;
DROP TABLE IF EXISTS pk_test16;
DROP TABLE IF EXISTS pk_test17;
DROP TABLE IF EXISTS pk_test18;
DROP TABLE IF EXISTS pk_test19;
DROP TABLE IF EXISTS pk_test20;
DROP TABLE IF EXISTS pk_test21;
DROP TABLE IF EXISTS pk_test22;
DROP TABLE IF EXISTS pk_test23;
SET default_table_engine=MergeTree;
CREATE TABLE pk_test1 (String a PRIMARY KEY, String b, String c);
CREATE TABLE pk_test2 (String a PRIMARY KEY, String b PRIMARY KEY, String c);
CREATE TABLE pk_test3 (String a PRIMARY KEY, String b PRIMARY KEY, String c PRIMARY KEY);
CREATE TABLE pk_test4 (String a, String b PRIMARY KEY, String c PRIMARY KEY);
CREATE TABLE pk_test5 (String a, String b PRIMARY KEY, String c);
CREATE TABLE pk_test6 (String a, String b, String c PRIMARY KEY);
CREATE TABLE pk_test7 (String a PRIMARY KEY, String b, String c, PRIMARY KEY (a));
CREATE TABLE pk_test8 (String a PRIMARY KEY, String b PRIMARY KEY, String c, PRIMARY KEY (a));
CREATE TABLE pk_test9 (String a PRIMARY KEY, String b PRIMARY KEY, String c PRIMARY KEY, PRIMARY KEY (a));
CREATE TABLE pk_test10 (String a, String b PRIMARY KEY, String c PRIMARY KEY, PRIMARY KEY (a));
CREATE TABLE pk_test11 (String a, String b PRIMARY KEY, String c, PRIMARY KEY (a));
CREATE TABLE pk_test12 (String a, String b, String c PRIMARY KEY, PRIMARY KEY (a));
CREATE TABLE pk_test12 (String a PRIMARY KEY, String b, String c) PRIMARY KEY (a,b,c);
CREATE TABLE pk_test13 (String a PRIMARY KEY, String b PRIMARY KEY, String c) PRIMARY KEY (a,b,c);
CREATE TABLE pk_test14 (String a PRIMARY KEY, String b PRIMARY KEY, String c PRIMARY KEY) PRIMARY KEY (a,b,c);
CREATE TABLE pk_test15 (String a, String b PRIMARY KEY, String c PRIMARY KEY) PRIMARY KEY (a,b,c);
CREATE TABLE pk_test16 (String a, String b PRIMARY KEY, String c) PRIMARY KEY (a,b,c);
CREATE TABLE pk_test17 (String a, String b, String c PRIMARY KEY) PRIMARY KEY (a,b,c);
CREATE TABLE pk_test18 (String a PRIMARY KEY, String b, String c) ORDER BY (a,b,c);
CREATE TABLE pk_test19 (String a PRIMARY KEY, String b PRIMARY KEY, String c) ORDER BY (a,b,c);
CREATE TABLE pk_test20 (String a PRIMARY KEY, String b PRIMARY KEY, String c PRIMARY KEY) ORDER BY (a,b,c);
CREATE TABLE pk_test21 (String a, String b PRIMARY KEY, String c PRIMARY KEY) ORDER BY (a,b,c);
CREATE TABLE pk_test22 (String a, String b PRIMARY KEY, String c) ORDER BY (a,b,c);
CREATE TABLE pk_test23 (String a, String b, String c PRIMARY KEY) ORDER BY (a,b,c);
DROP TABLE IF EXISTS pk_test1;
DROP TABLE IF EXISTS pk_test2;
DROP TABLE IF EXISTS pk_test3;
DROP TABLE IF EXISTS pk_test4;
DROP TABLE IF EXISTS pk_test5;
DROP TABLE IF EXISTS pk_test6;
DROP TABLE IF EXISTS pk_test7;
DROP TABLE IF EXISTS pk_test8;
DROP TABLE IF EXISTS pk_test9;
DROP TABLE IF EXISTS pk_test10;
DROP TABLE IF EXISTS pk_test11;
DROP TABLE IF EXISTS pk_test12;
DROP TABLE IF EXISTS pk_test12;
DROP TABLE IF EXISTS pk_test13;
DROP TABLE IF EXISTS pk_test14;
DROP TABLE IF EXISTS pk_test15;
DROP TABLE IF EXISTS pk_test16;
DROP TABLE IF EXISTS pk_test17;
DROP TABLE IF EXISTS pk_test18;
DROP TABLE IF EXISTS pk_test19;
DROP TABLE IF EXISTS pk_test20;
DROP TABLE IF EXISTS pk_test21;
DROP TABLE IF EXISTS pk_test22;
DROP TABLE IF EXISTS pk_test23;