mirror of
https://github.com/ClickHouse/ClickHouse.git
synced 2024-11-22 07:31:57 +00:00
Fix lambdas parsing
This commit is contained in:
parent
8d23d2f2f2
commit
29371745bd
@ -701,7 +701,7 @@ public:
|
||||
/// 2. If there is already tuple do nothing
|
||||
if (tryGetFunctionName(elements.back()) == "tuple")
|
||||
{
|
||||
pushOperand(elements.back());
|
||||
pushOperand(std::move(elements.back()));
|
||||
elements.pop_back();
|
||||
}
|
||||
/// 3. Put all elements in a single tuple
|
||||
@ -711,6 +711,19 @@ public:
|
||||
elements.clear();
|
||||
pushOperand(function);
|
||||
}
|
||||
|
||||
/// We must check that tuple arguments are identifiers
|
||||
auto * func_ptr = operands.back()->as<ASTFunction>();
|
||||
auto * args_ptr = func_ptr->arguments->as<ASTExpressionList>();
|
||||
|
||||
for (const auto & child : args_ptr->children)
|
||||
{
|
||||
if (typeid_cast<ASTIdentifier *>(child.get()))
|
||||
continue;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -1064,9 +1077,7 @@ public:
|
||||
is_tuple = true;
|
||||
|
||||
// Special case for f(x, (y) -> z) = f(x, tuple(y) -> z)
|
||||
auto test_pos = pos;
|
||||
auto test_expected = expected;
|
||||
if (parseOperator(test_pos, "->", test_expected))
|
||||
if (pos->type == TokenType::Arrow)
|
||||
is_tuple = true;
|
||||
}
|
||||
|
||||
@ -1734,6 +1745,29 @@ private:
|
||||
bool parsed_interval_kind = false;
|
||||
};
|
||||
|
||||
class TupleLayer : public LayerWithSeparator<TokenType::Comma, TokenType::ClosingRoundBracket>
|
||||
{
|
||||
public:
|
||||
bool parse(IParser::Pos & pos, Expected & expected, Action & action) override
|
||||
{
|
||||
bool result = LayerWithSeparator::parse(pos, expected, action);
|
||||
|
||||
/// Check that after the tuple() function there is no lambdas operator
|
||||
if (finished && pos->type == TokenType::Arrow)
|
||||
return false;
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
protected:
|
||||
bool getResultImpl(ASTPtr & node) override
|
||||
{
|
||||
node = makeASTFunction("tuple", std::move(elements));
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
class IntervalLayer : public Layer
|
||||
{
|
||||
public:
|
||||
@ -2037,6 +2071,9 @@ std::unique_ptr<Layer> getFunctionLayer(ASTPtr identifier, bool is_table_functio
|
||||
return std::make_unique<ViewLayer>(true);
|
||||
}
|
||||
|
||||
if (function_name == "tuple")
|
||||
return std::make_unique<TupleLayer>();
|
||||
|
||||
if (function_name_lowercase == "cast")
|
||||
return std::make_unique<CastLayer>();
|
||||
else if (function_name_lowercase == "extract")
|
||||
|
@ -1,8 +1,4 @@
|
||||
SELECT f(x, y -> z)
|
||||
SELECT f(x, y -> z)
|
||||
SELECT f((x, y) -> z)
|
||||
SELECT f((x, y) -> z)
|
||||
SELECT f((x, y) -> z)
|
||||
SELECT f(x, (x, y) -> z)
|
||||
SELECT f(x, (x, y) -> z)
|
||||
CREATE FUNCTION func AS x -> plus(x, (x -> ('2' + 2)) -> plus(1), 1)
|
||||
|
@ -8,14 +8,7 @@ set -e
|
||||
|
||||
format="$CLICKHOUSE_FORMAT"
|
||||
|
||||
echo "SELECT f(x, tuple(y) -> z)" | $format
|
||||
echo "SELECT f(x, (y) -> z)" | $format
|
||||
|
||||
echo "SELECT f(x, y -> z)" | $format
|
||||
echo "SELECT f((x, y) -> z)" | $format
|
||||
echo "SELECT f(tuple(x, y) -> z)" | $format
|
||||
|
||||
echo "SELECT f(x, (x, y) -> z)" | $format
|
||||
echo "SELECT f(x, tuple(x, y) -> z)" | $format
|
||||
|
||||
echo "CREATE FUNCTION func AS x -> plus(x, (x -> ('2' + 2)) -> plus(1), 1)" | $format | $format
|
||||
|
7
tests/queries/0_stateless/02515_tuple_lambda_parsing.sql
Normal file
7
tests/queries/0_stateless/02515_tuple_lambda_parsing.sql
Normal file
@ -0,0 +1,7 @@
|
||||
explain ast select tuple(a) -> f(a); -- { clientError SYNTAX_ERROR }
|
||||
explain ast select tuple(a, b) -> f(a); -- { clientError SYNTAX_ERROR }
|
||||
explain ast select (tuple(a)) -> f(a); -- { clientError SYNTAX_ERROR }
|
||||
explain ast select (f(a)) -> f(a); -- { clientError SYNTAX_ERROR }
|
||||
explain ast select (a::UInt64) -> f(a); -- { clientError SYNTAX_ERROR }
|
||||
explain ast select (1) -> f(a); -- { clientError SYNTAX_ERROR }
|
||||
explain ast select (1::UInt64) -> f(a); -- { clientError SYNTAX_ERROR }
|
Loading…
Reference in New Issue
Block a user