From 7117b419b92cee78f40543bd65b130dcd94f6e08 Mon Sep 17 00:00:00 2001 From: Alexey Milovidov Date: Sun, 21 Jun 2020 21:22:34 +0300 Subject: [PATCH] Don't allow arrayJoin inside higher order functions #3933 --- src/Functions/FunctionsMiscellaneous.h | 7 +++++++ src/Functions/array/FunctionArrayMapped.h | 3 ++- .../01330_array_join_in_higher_order_function.reference | 0 .../01330_array_join_in_higher_order_function.sql | 1 + 4 files changed, 10 insertions(+), 1 deletion(-) create mode 100644 tests/queries/0_stateless/01330_array_join_in_higher_order_function.reference create mode 100644 tests/queries/0_stateless/01330_array_join_in_higher_order_function.sql diff --git a/src/Functions/FunctionsMiscellaneous.h b/src/Functions/FunctionsMiscellaneous.h index 3e2938f386b..5703f72ce2a 100644 --- a/src/Functions/FunctionsMiscellaneous.h +++ b/src/Functions/FunctionsMiscellaneous.h @@ -8,11 +8,13 @@ #include #include + namespace DB { namespace ErrorCodes { extern const int LOGICAL_ERROR; + extern const int BAD_ARGUMENTS; } class ExecutableFunctionExpression : public IExecutableFunctionImpl @@ -203,6 +205,11 @@ public: const String & expression_return_name_) : expression_actions(std::move(expression_actions_)) { + /// Check that expression does not contain unusual actions that will break blocks structure. + for (const auto & action : expression_actions->getActions()) + if (action.type == ExpressionAction::Type::JOIN || action.type == ExpressionAction::Type::ARRAY_JOIN) + throw Exception("Expression with arrayJoin or other unusual action cannot be captured", ErrorCodes::BAD_ARGUMENTS); + std::unordered_map arguments_map; const auto & all_arguments = expression_actions->getRequiredColumnsWithTypes(); diff --git a/src/Functions/array/FunctionArrayMapped.h b/src/Functions/array/FunctionArrayMapped.h index ee4c5c083d8..346f2e35555 100644 --- a/src/Functions/array/FunctionArrayMapped.h +++ b/src/Functions/array/FunctionArrayMapped.h @@ -33,7 +33,8 @@ namespace ErrorCodes * arrayMap(x1,...,xn -> expression, array1,...,arrayn) - apply the expression to each element of the array (or set of parallel arrays). * arrayFilter(x -> predicate, array) - leave in the array only the elements for which the expression is true. * - * For some functions arrayCount, arrayExists, arrayAll, an overload of the form f(array) is available, which works in the same way as f(x -> x, array). + * For some functions arrayCount, arrayExists, arrayAll, an overload of the form f(array) is available, + * which works in the same way as f(x -> x, array). * * See the example of Impl template parameter in arrayMap.cpp */ diff --git a/tests/queries/0_stateless/01330_array_join_in_higher_order_function.reference b/tests/queries/0_stateless/01330_array_join_in_higher_order_function.reference new file mode 100644 index 00000000000..e69de29bb2d diff --git a/tests/queries/0_stateless/01330_array_join_in_higher_order_function.sql b/tests/queries/0_stateless/01330_array_join_in_higher_order_function.sql new file mode 100644 index 00000000000..456b24a03d0 --- /dev/null +++ b/tests/queries/0_stateless/01330_array_join_in_higher_order_function.sql @@ -0,0 +1 @@ +SELECT arrayMap(x -> arrayJoin([x, 1]), [1, 2]); -- { serverError 36 }