| 845 | } |
| 846 | |
| 847 | ColumnPtr executeImpl(const ColumnsWithTypeAndName & arguments, const DataTypePtr & result_type, size_t input_rows_count) const override |
| 848 | { |
| 849 | /// handle null constant value in arguments |
| 850 | NullPresence null_presence = getNullPresense(arguments); |
| 851 | if (null_presence.has_null_constant) |
| 852 | return result_type->createColumnConstWithDefaultValue(input_rows_count); |
| 853 | |
| 854 | const auto * col_map = checkAndGetColumn<ColumnMap>(arguments[0].column.get()); |
| 855 | const auto * col_const_map = checkAndGetColumnConst<ColumnMap>(arguments[0].column.get()); |
| 856 | const DataTypeMap * map_type = checkAndGetDataType<DataTypeMap>(arguments[0].type.get()); |
| 857 | if ((!col_map && !col_const_map) || !map_type) |
| 858 | throw Exception(ErrorCodes::LOGICAL_ERROR, |
| 859 | "First argument for function '{}' must be map, got '{}' instead", |
| 860 | getName(),arguments[0].type->getName()); |
| 861 | |
| 862 | if (col_const_map) |
| 863 | col_map = typeid_cast<const ColumnMap *>(&col_const_map->getDataColumn()); |
| 864 | |
| 865 | auto & key_column = col_map->getKey(); |
| 866 | auto & value_column = col_map->getValue(); |
| 867 | auto & offsets = col_map->getOffsets(); |
| 868 | |
| 869 | /// At first step calculate indices in array of values for requested keys. |
| 870 | auto indices_column = DataTypeNumber<UInt64>().createColumn(); |
| 871 | indices_column->reserve(input_rows_count); |
| 872 | auto & indices_data = assert_cast<ColumnVector<UInt64> &>(*indices_column).getData(); |
| 873 | |
| 874 | bool executed = false; |
| 875 | if (!isColumnConst(*arguments[1].column)) |
| 876 | { |
| 877 | executed = FunctionArrayElement::matchKeyToIndexNumber(key_column, offsets, !!col_const_map, *arguments[1].column, indices_data) |
| 878 | || FunctionArrayElement::matchKeyToIndexString(key_column, offsets, !!col_const_map, *arguments[1].column, indices_data); |
| 879 | } |
| 880 | else |
| 881 | { |
| 882 | Field index = (*arguments[1].column)[0]; |
| 883 | |
| 884 | /// try convert const index to right type |
| 885 | auto index_lit = std::make_shared<ASTLiteral>(index); |
| 886 | Field key_field = tryConvertToMapKeyField(map_type->getKeyType(), index_lit->getColumnName()); |
| 887 | if (!key_field.isNull()) |
| 888 | index = key_field; |
| 889 | |
| 890 | executed = FunctionArrayElement::matchKeyToIndexNumberConst(key_column, offsets, index, indices_data) |
| 891 | || FunctionArrayElement::matchKeyToIndexStringConst(key_column, offsets, index, indices_data); |
| 892 | } |
| 893 | if (!executed) |
| 894 | throw Exception(ErrorCodes::ILLEGAL_TYPE_OF_ARGUMENT, |
| 895 | "Illegal types of arguments: {}, {} for function {}", |
| 896 | arguments[0].type->getName(), arguments[1].type->getName(), getName()); |
| 897 | |
| 898 | auto col_res = IColumn::mutate(result_type->createColumn()); |
| 899 | auto & col_res_ref = typeid_cast<ColumnNullable &>(*col_res); |
| 900 | bool add_nullable = !value_column.lowCardinality() && value_column.canBeInsideNullable(); |
| 901 | for (size_t i = 0, size = indices_data.size(); i < size; ++i) |
| 902 | { |
| 903 | auto offset = col_const_map ? 0: offsets[i - 1]; |
| 904 | if (indices_data[i] == 0) |
nothing calls this directly
no test coverage detected