| 710 | ColumnNumbers getArgumentsThatAreAlwaysConstant() const override { return {1}; } |
| 711 | |
| 712 | FunctionBasePtr build(const ColumnsWithTypeAndName & arguments) const override |
| 713 | { |
| 714 | bool has_nothing_argument = false; |
| 715 | for (const auto & arg : arguments) |
| 716 | has_nothing_argument |= isNothing(arg.type); |
| 717 | |
| 718 | if (arguments.empty()) |
| 719 | throw Exception(ErrorCodes::NUMBER_OF_ARGUMENTS_DOESNT_MATCH, |
| 720 | "Function {} requires at least one argument", Name::name); |
| 721 | |
| 722 | const auto & first_column = arguments[0]; |
| 723 | auto first_type_base = removeNullable(removeLowCardinality(first_column.type)); |
| 724 | |
| 725 | bool is_string = isString(first_type_base); |
| 726 | bool is_object = isObject(first_type_base); |
| 727 | bool is_tuple = isTuple(first_type_base); |
| 728 | bool is_nothing = isNothing(first_type_base); |
| 729 | |
| 730 | if (!is_string && !is_object && !is_tuple && !is_nothing) |
| 731 | throw Exception(ErrorCodes::ILLEGAL_TYPE_OF_ARGUMENT, |
| 732 | "The first argument of function {} should be a string containing JSON or Object or Tuple, illegal type: {}", |
| 733 | Name::name, first_column.type->getName()); |
| 734 | |
| 735 | auto json_return_type = Impl<ObjectIterator>::getReturnType(Name::name, createBlockWithNestedColumns(arguments)); |
| 736 | NullPresence null_presence = getNullPresense(arguments); |
| 737 | DataTypePtr return_type; |
| 738 | if (has_nothing_argument) |
| 739 | return_type = std::make_shared<DataTypeNothing>(); |
| 740 | else if (null_presence.has_null_constant) |
| 741 | return_type = makeNullable(std::make_shared<DataTypeNothing>()); |
| 742 | else if (null_presence.has_nullable) |
| 743 | return_type = makeNullable(json_return_type); |
| 744 | else |
| 745 | return_type = json_return_type; |
| 746 | |
| 747 | /// Top-level LowCardinality columns are processed outside JSON parser. |
| 748 | json_return_type = removeLowCardinality(json_return_type); |
| 749 | |
| 750 | DataTypes argument_types; |
| 751 | argument_types.reserve(arguments.size()); |
| 752 | for (const auto & argument : arguments) |
| 753 | argument_types.emplace_back(argument.type); |
| 754 | |
| 755 | auto allow_simdjson = getContext()->getSettingsRef().allow_simdjson; |
| 756 | uint32_t parser_depth = getContext()->getSettingsRef().max_parser_depth; |
| 757 | DialectType dialect_type = getContext()->getSettingsRef().dialect_type; |
| 758 | if (is_string || is_nothing) |
| 759 | return std::make_unique<FunctionBaseFunctionSQLJSONString<Name, Impl>>( |
| 760 | allow_simdjson, null_presence, argument_types, return_type, json_return_type, parser_depth, dialect_type); |
| 761 | else if (is_object) |
| 762 | return std::make_unique<FunctionBaseFunctionSQLJSONObject<Name, Impl>>( |
| 763 | allow_simdjson, null_presence, argument_types, return_type, json_return_type, parser_depth, dialect_type); |
| 764 | else |
| 765 | return std::make_unique<FunctionBaseFunctionSQLJSONTuple<Name, Impl>>( |
| 766 | allow_simdjson, null_presence, argument_types, return_type, json_return_type, parser_depth, dialect_type); |
| 767 | } |
| 768 | }; |
| 769 |
no test coverage detected