| 700 | } |
| 701 | |
| 702 | InterpretIMResult ExpressionInterpreter::visitInFunction(const ASTFunction & function, const ConstASTPtr &) const |
| 703 | { |
| 704 | const auto & left_arg = function.arguments->children[0]; |
| 705 | const auto & right_arg = function.arguments->children[1]; |
| 706 | auto left_arg_result = visit(left_arg); |
| 707 | auto rewritten_left_arg = left_arg_result.convertToAST(context); |
| 708 | auto rewritten_in_func = makeASTFunction(function.name, rewritten_left_arg, right_arg); |
| 709 | |
| 710 | if (left_arg_result.isAST() && !setting.enable_function_simplify) |
| 711 | return {getType(rewritten_in_func), rewritten_in_func}; |
| 712 | |
| 713 | if (const auto * ast_prepared_param = right_arg->as<ASTPreparedParameter>()) |
| 714 | { |
| 715 | auto riget_arg_result = visitASTPreparedParameter(*ast_prepared_param, right_arg); |
| 716 | ColumnsWithTypeAndName columns_with_types; |
| 717 | columns_with_types.emplace_back(left_arg_result.value, left_arg_result.type, ""); |
| 718 | columns_with_types.emplace_back(riget_arg_result.value, riget_arg_result.type, ""); |
| 719 | auto overload_resolver = FunctionFactory::instance().tryGet(function.name, context); |
| 720 | return {overload_resolver->getReturnType(columns_with_types), rewritten_in_func}; |
| 721 | } |
| 722 | |
| 723 | // build set for IN statement(see also ActionsVisitor) |
| 724 | SetPtr set; |
| 725 | { |
| 726 | auto & left_arg_type = left_arg_result.type; |
| 727 | DataTypes set_element_types = {left_arg_type}; |
| 728 | const auto * left_tuple_type = typeid_cast<const DataTypeTuple *>(left_arg_type.get()); |
| 729 | if (left_tuple_type && left_tuple_type->getElements().size() != 1) |
| 730 | set_element_types = left_tuple_type->getElements(); |
| 731 | |
| 732 | for (auto & element_type : set_element_types) |
| 733 | if (const auto * low_cardinality_type = typeid_cast<const DataTypeLowCardinality *>(element_type.get())) |
| 734 | element_type = low_cardinality_type->getDictionaryType(); |
| 735 | |
| 736 | Block block; |
| 737 | auto right_arg_function = std::dynamic_pointer_cast<ASTFunction>(right_arg); |
| 738 | if (right_arg_function && (right_arg_function->name == "tuple" || right_arg_function->name == "array")) |
| 739 | block = createBlockForSet(left_arg_type, right_arg_function, set_element_types, context); |
| 740 | else |
| 741 | block = createBlockForSet(left_arg_type, right_arg, set_element_types, context); |
| 742 | |
| 743 | const auto & settings = context->getSettingsRef(); |
| 744 | SizeLimits size_limits{settings.max_rows_in_set, settings.max_bytes_in_set, settings.set_overflow_mode}; |
| 745 | set = std::make_shared<Set>(size_limits, true, settings.transform_null_in); |
| 746 | set->setHeader(block.cloneEmpty()); |
| 747 | set->insertFromBlock(block); |
| 748 | set->finishInsert(); |
| 749 | } |
| 750 | |
| 751 | // constant folding |
| 752 | if (left_arg_result.isValue()) |
| 753 | { |
| 754 | auto column_set = ColumnSet::create(1, set); |
| 755 | ColumnPtr const_column_set = ColumnConst::create(std::move(column_set), 1); |
| 756 | ColumnsWithTypeAndName columns_with_types; |
| 757 | columns_with_types.emplace_back(left_arg_result.value, left_arg_result.type, ""); |
| 758 | columns_with_types.emplace_back(const_column_set, std::make_shared<DataTypeSet>(), ""); |
| 759 | auto result = FunctionInvoker::execute(function.name, columns_with_types, context); |
nothing calls this directly
no test coverage detected