From 08009631355ad31eb630e4b5f153c270cbbcf811 Mon Sep 17 00:00:00 2001 From: hexiaoting Date: Fri, 23 Oct 2020 17:15:55 +0800 Subject: [PATCH] Update parser for column transformers --- src/Parsers/ASTColumnsTransformers.cpp | 18 +++-- src/Parsers/ExpressionElementParsers.cpp | 70 ++++++++++++------- .../01470_columns_transformers.reference | 5 ++ .../01470_columns_transformers.sql | 4 ++ 4 files changed, 67 insertions(+), 30 deletions(-) diff --git a/src/Parsers/ASTColumnsTransformers.cpp b/src/Parsers/ASTColumnsTransformers.cpp index 474c3262d78..719c818b82d 100644 --- a/src/Parsers/ASTColumnsTransformers.cpp +++ b/src/Parsers/ASTColumnsTransformers.cpp @@ -33,7 +33,7 @@ void IASTColumnsTransformer::transform(const ASTPtr & transformer, ASTs & nodes) void ASTColumnsApplyTransformer::formatImpl(const FormatSettings & settings, FormatState &, FormatStateStacked) const { - settings.ostr << (settings.hilite ? hilite_keyword : "") << "APPLY" << (settings.hilite ? hilite_none : "") << "(" << func_name << ")"; + settings.ostr << (settings.hilite ? hilite_keyword : "") << "APPLY" << (settings.hilite ? hilite_none : "") << " " << func_name; } void ASTColumnsApplyTransformer::transform(ASTs & nodes) const @@ -46,7 +46,10 @@ void ASTColumnsApplyTransformer::transform(ASTs & nodes) const void ASTColumnsExceptTransformer::formatImpl(const FormatSettings & settings, FormatState & state, FormatStateStacked frame) const { - settings.ostr << (settings.hilite ? hilite_keyword : "") << "EXCEPT" << (is_strict ? " STRICT " : "") << (settings.hilite ? hilite_none : "") << "("; + settings.ostr << (settings.hilite ? hilite_keyword : "") << "EXCEPT" << (is_strict ? " STRICT " : "") << (settings.hilite ? hilite_none : ""); + + if (children.size() > 1) + settings.ostr << " ("; for (ASTs::const_iterator it = children.begin(); it != children.end(); ++it) { @@ -57,7 +60,8 @@ void ASTColumnsExceptTransformer::formatImpl(const FormatSettings & settings, Fo (*it)->formatImpl(settings, state, frame); } - settings.ostr << ")"; + if (children.size() > 1) + settings.ostr << ")"; } void ASTColumnsExceptTransformer::transform(ASTs & nodes) const @@ -110,7 +114,10 @@ void ASTColumnsReplaceTransformer::Replacement::formatImpl( void ASTColumnsReplaceTransformer::formatImpl(const FormatSettings & settings, FormatState & state, FormatStateStacked frame) const { - settings.ostr << (settings.hilite ? hilite_keyword : "") << "REPLACE" << (is_strict ? " STRICT " : "") << (settings.hilite ? hilite_none : "") << "("; + settings.ostr << (settings.hilite ? hilite_keyword : "") << "REPLACE" << (is_strict ? " STRICT " : "") << (settings.hilite ? hilite_none : ""); + + if (children.size() > 1) + settings.ostr << " ("; for (ASTs::const_iterator it = children.begin(); it != children.end(); ++it) { @@ -121,7 +128,8 @@ void ASTColumnsReplaceTransformer::formatImpl(const FormatSettings & settings, F (*it)->formatImpl(settings, state, frame); } - settings.ostr << ")"; + if (children.size() > 1) + settings.ostr << ")"; } void ASTColumnsReplaceTransformer::replaceChildren(ASTPtr & node, const ASTPtr & replacement, const String & name) diff --git a/src/Parsers/ExpressionElementParsers.cpp b/src/Parsers/ExpressionElementParsers.cpp index dc8f39ae894..501a9b00f3b 100644 --- a/src/Parsers/ExpressionElementParsers.cpp +++ b/src/Parsers/ExpressionElementParsers.cpp @@ -1240,17 +1240,24 @@ bool ParserColumnsTransformers::parseImpl(Pos & pos, ASTPtr & node, Expected & e if (apply.ignore(pos, expected)) { - if (pos->type != TokenType::OpeningRoundBracket) - return false; - ++pos; + bool with_open_round_bracket = false; + + if (pos->type == TokenType::OpeningRoundBracket) + { + ++pos; + with_open_round_bracket = true; + } String func_name; if (!parseIdentifierOrStringLiteral(pos, expected, func_name)) return false; - if (pos->type != TokenType::ClosingRoundBracket) - return false; - ++pos; + if (with_open_round_bracket) + { + if (pos->type != TokenType::ClosingRoundBracket) + return false; + ++pos; + } auto res = std::make_shared(); res->func_name = func_name; @@ -1259,14 +1266,9 @@ bool ParserColumnsTransformers::parseImpl(Pos & pos, ASTPtr & node, Expected & e } else if (except.ignore(pos, expected)) { - if (strict.ignore(pos, expected)) is_strict = true; - if (pos->type != TokenType::OpeningRoundBracket) - return false; - ++pos; - ASTs identifiers; auto parse_id = [&identifiers, &pos, &expected] { @@ -1278,12 +1280,23 @@ bool ParserColumnsTransformers::parseImpl(Pos & pos, ASTPtr & node, Expected & e return true; }; - if (!ParserList::parseUtil(pos, expected, parse_id, false)) - return false; + if (pos->type == TokenType::OpeningRoundBracket) + { + // support one or more parameter + ++pos; + if (!ParserList::parseUtil(pos, expected, parse_id, false)) + return false; - if (pos->type != TokenType::ClosingRoundBracket) - return false; - ++pos; + if (pos->type != TokenType::ClosingRoundBracket) + return false; + ++pos; + } + else + { + // only one parameter + if (!parse_id()) + return false; + } auto res = std::make_shared(); res->children = std::move(identifiers); @@ -1296,10 +1309,6 @@ bool ParserColumnsTransformers::parseImpl(Pos & pos, ASTPtr & node, Expected & e if (strict.ignore(pos, expected)) is_strict = true; - if (pos->type != TokenType::OpeningRoundBracket) - return false; - ++pos; - ASTs replacements; ParserExpression element_p; ParserIdentifier ident_p; @@ -1323,12 +1332,23 @@ bool ParserColumnsTransformers::parseImpl(Pos & pos, ASTPtr & node, Expected & e return true; }; - if (!ParserList::parseUtil(pos, expected, parse_id, false)) - return false; + if (pos->type == TokenType::OpeningRoundBracket) + { + ++pos; - if (pos->type != TokenType::ClosingRoundBracket) - return false; - ++pos; + if (!ParserList::parseUtil(pos, expected, parse_id, false)) + return false; + + if (pos->type != TokenType::ClosingRoundBracket) + return false; + ++pos; + } + else + { + // only one parameter + if (!parse_id()) + return false; + } auto res = std::make_shared(); res->children = std::move(replacements); diff --git a/tests/queries/0_stateless/01470_columns_transformers.reference b/tests/queries/0_stateless/01470_columns_transformers.reference index 2d8a1802289..9a8a02c7f98 100644 --- a/tests/queries/0_stateless/01470_columns_transformers.reference +++ b/tests/queries/0_stateless/01470_columns_transformers.reference @@ -1,4 +1,5 @@ 220 18 347 +220 18 347 110 9 173.5 1970-04-11 1970-01-11 1970-11-21 2 3 @@ -6,6 +7,10 @@ 18 347 110 173.5 1970-04-11 1970-01-11 1970-11-21 +10 324 +8 23 +101 10 324 +121 8 23 222 18 347 111 11 173.5 1970-04-11 1970-01-11 1970-11-21 diff --git a/tests/queries/0_stateless/01470_columns_transformers.sql b/tests/queries/0_stateless/01470_columns_transformers.sql index a3d103cd876..f7c30eef61b 100644 --- a/tests/queries/0_stateless/01470_columns_transformers.sql +++ b/tests/queries/0_stateless/01470_columns_transformers.sql @@ -4,6 +4,7 @@ CREATE TABLE columns_transformers (i Int64, j Int16, k Int64) Engine=TinyLog; INSERT INTO columns_transformers VALUES (100, 10, 324), (120, 8, 23); SELECT * APPLY(sum) from columns_transformers; +SELECT * APPLY sum from columns_transformers; SELECT columns_transformers.* APPLY(avg) from columns_transformers; SELECT a.* APPLY(toDate) APPLY(any) from columns_transformers a; SELECT COLUMNS('[jk]') APPLY(toString) APPLY(length) from columns_transformers; @@ -13,7 +14,10 @@ SELECT columns_transformers.* EXCEPT(j) APPLY(avg) from columns_transformers; -- EXCEPT after APPLY will not match anything SELECT a.* APPLY(toDate) EXCEPT(i, j) APPLY(any) from columns_transformers a; +SELECT * EXCEPT STRICT i from columns_transformers; +SELECT * EXCEPT STRICT i, j1 from columns_transformers; -- { serverError 47 } SELECT * EXCEPT STRICT(i, j1) from columns_transformers; -- { serverError 16 } +SELECT * REPLACE STRICT i + 1 AS i from columns_transformers; SELECT * REPLACE STRICT(i + 1 AS col) from columns_transformers; -- { serverError 16 } SELECT * REPLACE(i + 1 AS i) APPLY(sum) from columns_transformers; SELECT columns_transformers.* REPLACE(j + 2 AS j, i + 1 AS i) APPLY(avg) from columns_transformers;