mirror of
https://github.com/ClickHouse/ClickHouse.git
synced 2024-09-20 16:50:48 +00:00
Fix arrayJoin() capturing in lambda
Fixes the following LOGICAL_ERROR: $ clickhouse-client -q 'select arrayFilter((a) -> ((a, arrayJoin([[]])) IN (Null, [Null])), [])' 2020.08.16 00:32:01.967102 [ 1744189 ] {b40a5ebd-d710-4f03-bb18-57db67de1181} <Error> : Logical error: 'Lambda captured argument arrayJoin(array(array())) not found in required columns.'. clickhouse-server: ../src/Common/Exception.cpp:45: DB::Exception::Exception(const string&, int): Assertion `false' failed. Since there are multiple input columns for arrayJoin(): (gdb) p captured_names_ $6 = std::vector of length 3, capacity 4 = {"arrayJoin(array(array()))", "arrayJoin(array(array()))", "__set"} While FunctionCaptureOverloadResolver cannot handle non-unique columns.
This commit is contained in:
parent
e2dd668378
commit
308e094d04
@ -447,6 +447,19 @@ void ScopeStack::addAction(const ExpressionAction & action)
|
||||
}
|
||||
}
|
||||
|
||||
void ScopeStack::addActionNoInput(const ExpressionAction & action)
|
||||
{
|
||||
size_t level = 0;
|
||||
Names required = action.getNeededColumns();
|
||||
for (const auto & elem : required)
|
||||
level = std::max(level, getColumnLevel(elem));
|
||||
|
||||
Names added;
|
||||
stack[level].actions->add(action, added);
|
||||
|
||||
stack[level].new_columns.insert(added.begin(), added.end());
|
||||
}
|
||||
|
||||
ExpressionActionsPtr ScopeStack::popLevel()
|
||||
{
|
||||
ExpressionActionsPtr res = stack.back().actions;
|
||||
@ -549,7 +562,7 @@ void ActionsMatcher::visit(const ASTFunction & node, const ASTPtr & ast, Data &
|
||||
/// It could have been possible to implement arrayJoin which keeps source column,
|
||||
/// but in this case it will always be replicated (as many arrays), which is expensive.
|
||||
String tmp_name = data.getUniqueName("_array_join_" + arg->getColumnName());
|
||||
data.addAction(ExpressionAction::copyColumn(arg->getColumnName(), tmp_name));
|
||||
data.addActionNoInput(ExpressionAction::copyColumn(arg->getColumnName(), tmp_name));
|
||||
data.addAction(ExpressionAction::arrayJoin(tmp_name, result_name));
|
||||
}
|
||||
|
||||
|
@ -12,6 +12,7 @@ namespace DB
|
||||
class Context;
|
||||
class ASTFunction;
|
||||
|
||||
struct ExpressionAction;
|
||||
class ExpressionActions;
|
||||
using ExpressionActionsPtr = std::shared_ptr<ExpressionActions>;
|
||||
|
||||
@ -49,6 +50,8 @@ struct ScopeStack
|
||||
size_t getColumnLevel(const std::string & name);
|
||||
|
||||
void addAction(const ExpressionAction & action);
|
||||
/// For arrayJoin() to avoid double columns in the input.
|
||||
void addActionNoInput(const ExpressionAction & action);
|
||||
|
||||
ExpressionActionsPtr popLevel();
|
||||
|
||||
@ -115,6 +118,10 @@ public:
|
||||
{
|
||||
actions_stack.addAction(action);
|
||||
}
|
||||
void addActionNoInput(const ExpressionAction & action)
|
||||
{
|
||||
actions_stack.addActionNoInput(action);
|
||||
}
|
||||
|
||||
const Block & getSampleBlock() const
|
||||
{
|
||||
|
@ -0,0 +1 @@
|
||||
[]
|
6
tests/queries/0_stateless/01407_lambda_arrayJoin.sql
Normal file
6
tests/queries/0_stateless/01407_lambda_arrayJoin.sql
Normal file
@ -0,0 +1,6 @@
|
||||
SELECT arrayFilter((a) -> ((a, arrayJoin([])) IN (Null, [Null])), []);
|
||||
SELECT arrayFilter((a) -> ((a, arrayJoin([[]])) IN (Null, [Null])), []);
|
||||
|
||||
-- simplified from the https://clickhouse-test-reports.s3.yandex.net/10373/6c4748a63e7acde2cc3283d96ffec590aae1e724/fuzzer/fuzzer.log#fail1
|
||||
SELECT * FROM system.one ARRAY JOIN arrayFilter((a) -> ((a, arrayJoin([])) IN (NULL)), []) AS arr_x; -- { serverError 43; }
|
||||
SELECT * FROM numbers(1) LEFT ARRAY JOIN arrayFilter((x_0, x_1) -> (arrayJoin([]) IN (NULL)), [], []) AS arr_x;
|
Loading…
Reference in New Issue
Block a user