Skip to content

Commit

Permalink
Merge pull request ClickHouse#63425 from CurtizJ/fix-create-index-par…
Browse files Browse the repository at this point in the history
…sing

Fix parsing of `CREATE INDEX` query
  • Loading branch information
alexey-milovidov authored May 7, 2024
2 parents 4134864 + 216cd83 commit cef4f74
Show file tree
Hide file tree
Showing 3 changed files with 54 additions and 10 deletions.
46 changes: 36 additions & 10 deletions src/Parsers/ParserCreateIndexQuery.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -17,9 +17,9 @@ bool ParserCreateIndexDeclaration::parseImpl(Pos & pos, ASTPtr & node, Expected
{
ParserKeyword s_type(Keyword::TYPE);
ParserKeyword s_granularity(Keyword::GRANULARITY);
ParserToken open(TokenType::OpeningRoundBracket);
ParserToken close(TokenType::ClosingRoundBracket);
ParserOrderByExpressionList order_list;
ParserToken open_p(TokenType::OpeningRoundBracket);
ParserToken close_p(TokenType::ClosingRoundBracket);
ParserOrderByExpressionList order_list_p;

ParserDataType data_type_p;
ParserExpression expression_p;
Expand All @@ -29,17 +29,41 @@ bool ParserCreateIndexDeclaration::parseImpl(Pos & pos, ASTPtr & node, Expected
ASTPtr type;
ASTPtr granularity;

/// Skip name parser for SQL-standard CREATE INDEX
if (expression_p.parse(pos, expr, expected))
if (open_p.ignore(pos, expected))
{
}
else if (open.ignore(pos, expected))
{
if (!order_list.parse(pos, expr, expected))
ASTPtr order_list;
if (!order_list_p.parse(pos, order_list, expected))
return false;

if (!close_p.ignore(pos, expected))
return false;

if (!close.ignore(pos, expected))
if (order_list->children.empty())
return false;

/// CREATE INDEX with ASC, DESC is implemented only for SQL compatibility.
/// ASC and DESC modifiers are not supported and are ignored further.
if (order_list->children.size() == 1)
{
auto order_by_elem = order_list->children[0];
expr = order_by_elem->children[0];
}
else
{
auto tuple_func = makeASTFunction("tuple");
tuple_func->arguments = std::make_shared<ASTExpressionList>();

for (const auto & order_by_elem : order_list->children)
{
auto elem_expr = order_by_elem->children[0];
tuple_func->arguments->children.push_back(std::move(elem_expr));
}
expr = std::move(tuple_func);
}
}
else if (!expression_p.parse(pos, expr, expected))
{
return false;
}

if (s_type.ignore(pos, expected))
Expand All @@ -59,7 +83,9 @@ bool ParserCreateIndexDeclaration::parseImpl(Pos & pos, ASTPtr & node, Expected
index->part_of_create_index_query = true;

if (granularity)
{
index->granularity = granularity->as<ASTLiteral &>().value.safeGet<UInt64>();
}
else
{
auto index_type = index->getType();
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
CREATE TABLE default.t_index_3146\n(\n `a` UInt64,\n `b` UInt64,\n INDEX i1 a TYPE minmax GRANULARITY 1,\n INDEX i2 (a, b) TYPE minmax GRANULARITY 1,\n INDEX i3 (a, b) TYPE minmax GRANULARITY 1,\n INDEX i4 a TYPE minmax GRANULARITY 1\n)\nENGINE = MergeTree\nORDER BY tuple()\nSETTINGS index_granularity = 8192
17 changes: 17 additions & 0 deletions tests/queries/0_stateless/03146_create_index_compatibility.sql
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
DROP TABLE IF EXISTS t_index_3146;

CREATE TABLE t_index_3146 (a UInt64, b UInt64) ENGINE = MergeTree ORDER BY tuple();

SET allow_create_index_without_type = 1;

CREATE INDEX i1 ON t_index_3146 (a) TYPE minmax;
CREATE INDEX i2 ON t_index_3146 (a, b) TYPE minmax;
CREATE INDEX i3 ON t_index_3146 (a DESC, b ASC) TYPE minmax;
CREATE INDEX i4 ON t_index_3146 a TYPE minmax;
CREATE INDEX i5 ON t_index_3146 (a); -- ignored
CREATE INDEX i6 ON t_index_3146 (a DESC, b ASC); -- ignored
CREATE INDEX i7 ON t_index_3146; -- { clientError SYNTAX_ERROR }
CREATE INDEX i8 ON t_index_3146 a, b TYPE minmax; -- { clientError SYNTAX_ERROR }

SHOW CREATE TABLE t_index_3146;
DROP TABLE t_index_3146;

0 comments on commit cef4f74

Please sign in to comment.