Skip to content

Commit

Permalink
Backport #32138 to 21.12: Fix 'APPLY lambda' parsing
Browse files Browse the repository at this point in the history
  • Loading branch information
robot-clickhouse committed Dec 9, 2021
1 parent cdf50e7 commit 8bef054
Show file tree
Hide file tree
Showing 5 changed files with 37 additions and 9 deletions.
1 change: 1 addition & 0 deletions docker/test/fuzzer/run-fuzzer.sh
Original file line number Diff line number Diff line change
Expand Up @@ -189,6 +189,7 @@ continue
--receive_data_timeout_ms=10000 \
--stacktrace \
--query-fuzzer-runs=1000 \
--testmode \
--queries-file $(ls -1 ch/tests/queries/0_stateless/*.sql | sort -R) \
$NEW_TESTS_OPT \
> >(tail -n 100000 > fuzzer.log) \
Expand Down
10 changes: 5 additions & 5 deletions programs/client/Client.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -705,16 +705,16 @@ bool Client::processWithFuzzing(const String & full_query)
throw;
}

// `USE db` should not be executed
// since this will break every query after `DROP db`
if (orig_ast->as<ASTUseQuery>())
if (!orig_ast)
{
// Can't continue after a parsing error
return true;
}

if (!orig_ast)
// `USE db` should not be executed
// since this will break every query after `DROP db`
if (orig_ast->as<ASTUseQuery>())
{
// Can't continue after a parsing error
return true;
}

Expand Down
12 changes: 8 additions & 4 deletions src/Parsers/ExpressionElementParsers.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,6 @@
#include <Parsers/ASTSubquery.h>
#include <Parsers/ASTTTLElement.h>
#include <Parsers/ASTWindowDefinition.h>
#include <Parsers/IAST.h>
#include <Parsers/ASTAssignment.h>

#include <Parsers/parseIdentifierOrStringLiteral.h>
Expand All @@ -35,7 +34,6 @@
#include <Parsers/ParserCreateQuery.h>

#include <Parsers/queryToString.h>
#include <boost/algorithm/string.hpp>
#include "ASTColumnsMatcher.h"

#include <Interpreters/StorageID.h>
Expand Down Expand Up @@ -1935,15 +1933,21 @@ bool ParserColumnsTransformers::parseImpl(Pos & pos, ASTPtr & node, Expected & e
{
if (const auto * func = lambda->as<ASTFunction>(); func && func->name == "lambda")
{
if (func->arguments->children.size() != 2)
throw Exception(ErrorCodes::SYNTAX_ERROR, "lambda requires two arguments");

const auto * lambda_args_tuple = func->arguments->children.at(0)->as<ASTFunction>();
if (!lambda_args_tuple || lambda_args_tuple->name != "tuple")
throw Exception(ErrorCodes::SYNTAX_ERROR, "First argument of lambda must be a tuple");

const ASTs & lambda_arg_asts = lambda_args_tuple->arguments->children;
if (lambda_arg_asts.size() != 1)
throw Exception(ErrorCodes::BAD_ARGUMENTS, "APPLY column transformer can only accept lambda with one argument");
throw Exception(ErrorCodes::SYNTAX_ERROR, "APPLY column transformer can only accept lambda with one argument");

if (auto opt_arg_name = tryGetIdentifierName(lambda_arg_asts[0]); opt_arg_name)
lambda_arg = *opt_arg_name;
else
throw Exception(ErrorCodes::BAD_ARGUMENTS, "lambda argument declarations must be identifiers");
throw Exception(ErrorCodes::SYNTAX_ERROR, "lambda argument declarations must be identifiers");
}
else
{
Expand Down
10 changes: 10 additions & 0 deletions tests/queries/0_stateless/02128_apply_lambda_parsing.reference
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
1
1
1
1
1
1
2
3
4
5
13 changes: 13 additions & 0 deletions tests/queries/0_stateless/02128_apply_lambda_parsing.sql
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
WITH * APPLY lambda(e); -- { clientError SYNTAX_ERROR }
SELECT * APPLY lambda(); -- { clientError SYNTAX_ERROR }
SELECT * APPLY lambda(1); -- { clientError SYNTAX_ERROR }
SELECT * APPLY lambda(x); -- { clientError SYNTAX_ERROR }
SELECT * APPLY lambda(range(1)); -- { clientError SYNTAX_ERROR }
SELECT * APPLY lambda(range(x)); -- { clientError SYNTAX_ERROR }
SELECT * APPLY lambda(1, 2); -- { clientError SYNTAX_ERROR }
SELECT * APPLY lambda(x, y); -- { clientError SYNTAX_ERROR }
SELECT * APPLY lambda((x, y), 2); -- { clientError SYNTAX_ERROR }
SELECT * APPLY lambda((x, y), x + y); -- { clientError SYNTAX_ERROR }
SELECT * APPLY lambda(tuple(1), 1); -- { clientError SYNTAX_ERROR }
SELECT * APPLY lambda(tuple(x), 1) FROM numbers(5);
SELECT * APPLY lambda(tuple(x), x + 1) FROM numbers(5);

0 comments on commit 8bef054

Please sign in to comment.