fix IN with functions

This commit is contained in:
Anton Popov 2020-07-23 13:49:50 +03:00
parent fc515728f4
commit a642a66934

View File

@ -232,7 +232,7 @@ static Block createBlockFromAST(const ASTPtr & node, const DataTypes & types, co
*/ */
static Block createBlockForSet( static Block createBlockForSet(
const DataTypePtr & left_arg_type, const DataTypePtr & left_arg_type,
const std::shared_ptr<ASTLiteral> & right_arg, const ASTPtr & right_arg,
const DataTypes & set_element_types, const DataTypes & set_element_types,
const Context & context) const Context & context)
{ {
@ -275,18 +275,17 @@ static Block createBlockForSet(
* 'set_element_types' - types of what are on the left hand side of IN. * 'set_element_types' - types of what are on the left hand side of IN.
* 'right_arg' - list of values: 1, 2, 3 or list of tuples: (1, 2), (3, 4), (5, 6). * 'right_arg' - list of values: 1, 2, 3 or list of tuples: (1, 2), (3, 4), (5, 6).
* *
* We need special implementation for common AST, because in case, when we interpret tuple or array * We need special implementation for ASTFunction, because in case, when we interpret
* as function, `evaluateConstantExpression` works extremely slow. * large tuple or array as function, `evaluateConstantExpression` works extremely slow.
*/ */
static Block createBlockForSet( static Block createBlockForSet(
const DataTypePtr & left_arg_type, const DataTypePtr & left_arg_type,
const ASTPtr & right_arg, const std::shared_ptr<ASTFunction> & right_arg,
const DataTypes & set_element_types, const DataTypes & set_element_types,
const Context & context) const Context & context)
{ {
auto get_tuple_type_from_ast = [&context](const ASTPtr & tuple_ast) -> DataTypePtr auto get_tuple_type_from_ast = [&context](const auto & func) -> DataTypePtr
{ {
const auto * func = tuple_ast->as<ASTFunction>();
if (func && (func->name == "tuple" || func->name == "array") && !func->arguments->children.empty()) if (func && (func->name == "tuple" || func->name == "array") && !func->arguments->children.empty())
{ {
/// Won't parse all values of outer tuple. /// Won't parse all values of outer tuple.
@ -295,7 +294,7 @@ static Block createBlockForSet(
return std::make_shared<DataTypeTuple>(DataTypes({value_raw.second})); return std::make_shared<DataTypeTuple>(DataTypes({value_raw.second}));
} }
return evaluateConstantExpression(tuple_ast, context).second; return evaluateConstantExpression(func, context).second;
}; };
const DataTypePtr & right_arg_type = get_tuple_type_from_ast(right_arg); const DataTypePtr & right_arg_type = get_tuple_type_from_ast(right_arg);
@ -358,8 +357,9 @@ SetPtr makeExplicitSet(
return prepared_sets.at(set_key); /// Already prepared. return prepared_sets.at(set_key); /// Already prepared.
Block block; Block block;
if (const auto & right_arg_literal = std::dynamic_pointer_cast<ASTLiteral>(right_arg)) const auto & right_arg_func = std::dynamic_pointer_cast<ASTFunction>(right_arg);
block = createBlockForSet(left_arg_type, right_arg_literal, set_element_types, context); if (right_arg_func && (right_arg_func->name == "tuple" || right_arg_func->name == "array"))
block = createBlockForSet(left_arg_type, right_arg_func, set_element_types, context);
else else
block = createBlockForSet(left_arg_type, right_arg, set_element_types, context); block = createBlockForSet(left_arg_type, right_arg, set_element_types, context);