diff --git a/docs/en/sql-reference/functions/tuple-map-functions.md b/docs/en/sql-reference/functions/tuple-map-functions.md index d59204a7482..28f2f930d90 100644 --- a/docs/en/sql-reference/functions/tuple-map-functions.md +++ b/docs/en/sql-reference/functions/tuple-map-functions.md @@ -66,6 +66,40 @@ Result: - [Map(key, value)](../../sql-reference/data-types/map.md) data type +## mapFromArrays + +mapFromArrays merges an array of keys and an array of values into a Map. + +**Syntax** + +```sql +mapFromArrays(keys, values) +``` + +Alias: `MAP_FROM_ARRAYS(keys, values)` + +**Parameters** +- `keys` — Given key array to create a map from. The nested type of array must be: [String](../../sql-reference/data-types/string.md), [Integer](../../sql-reference/data-types/int-uint.md), [LowCardinality](../../sql-reference/data-types/lowcardinality.md), [FixedString](../../sql-reference/data-types/fixedstring.md), [UUID](../../sql-reference/data-types/uuid.md), [Date](../../sql-reference/data-types/date.md), [DateTime](../../sql-reference/data-types/datetime.md), [Date32](../../sql-reference/data-types/date32.md), [Enum](../../sql-reference/data-types/enum.md) +- `values` - Given value array to create a map from. + +**Returned value** + +- A map whose keys and values are constructed from the key and value arrays + +**Example** + +Query: + +```sql +select mapFromArrays(['a', 'b', 'c'], [1, 2, 3]) +``` + +```text +┌─mapFromArrays(['a', 'b', 'c'], [1, 2, 3])─┐ +│ {'a':1,'b':2,'c':3} │ +└───────────────────────────────────────────┘ +``` + ## mapAdd Collect all the keys and sum corresponding values. @@ -431,36 +465,6 @@ Result: ``` -## mapFromArrays {#mapFromArrays} - -**Syntax** - -```sql -mapFromArrays(keys, values) -``` - -**Parameters** - -- `keys` — Given key array to create a map from. -- `values` - Given value array to create a map from. - -**Returned value** - -- A map whose keys and values are from input arrays respectively. - -**Example** - -Query: - -```sql -select mapFromArrays(['a', 'b', 'c'], [1, 2, 3]) -``` - -```text -┌─mapFromArrays(['a', 'b', 'c'], [1, 2, 3])─┐ -│ {'a':1,'b':2,'c':3} │ -└───────────────────────────────────────────┘ -``` ## mapApply diff --git a/src/Functions/map.cpp b/src/Functions/map.cpp index 78985bd18fc..549de200bea 100644 --- a/src/Functions/map.cpp +++ b/src/Functions/map.cpp @@ -26,7 +26,7 @@ namespace ErrorCodes { extern const int NUMBER_OF_ARGUMENTS_DOESNT_MATCH; extern const int ILLEGAL_TYPE_OF_ARGUMENT; - extern const int SIZES_OF_ARRAYS_DOESNT_MATCH; + extern const int SIZES_OF_ARRAYS_DONT_MATCH; extern const int ILLEGAL_COLUMN; } @@ -149,26 +149,16 @@ public: } }; -// mapFromArrays(keys, values) is a function that allows you to make key-value pair from a pair of arrays +/// mapFromArrays(keys, values) is a function that allows you to make key-value pair from a pair of arrays class FunctionMapFromArrays : public IFunction { public: static constexpr auto name = "mapFromArrays"; - static FunctionPtr create(ContextPtr) - { - return std::make_shared(); - } + static FunctionPtr create(ContextPtr) { return std::make_shared(); } + String getName() const override { return name; } - String getName() const override - { - return name; - } - - size_t getNumberOfArguments() const override - { - return 2; - } + size_t getNumberOfArguments() const override { return 2; } bool isSuitableForShortCircuitArgumentsExecution(const DataTypesWithConstInfo & /*arguments*/) const override { return false; } bool useDefaultImplementationForNulls() const override { return false; } @@ -177,25 +167,22 @@ public: DataTypePtr getReturnTypeImpl(const DataTypes & arguments) const override { if (arguments.size() != 2) - throw Exception(ErrorCodes::NUMBER_OF_ARGUMENTS_DOESNT_MATCH, - "Function {} requires 2 arguments, but {} given", getName(), arguments.size()); + throw Exception( + ErrorCodes::NUMBER_OF_ARGUMENTS_DOESNT_MATCH, + "Function {} requires 2 arguments, but {} given", + getName(), + arguments.size()); const auto * keys_type = checkAndGetDataType(arguments[0].get()); if (!keys_type) - throw Exception{"First argument for function " + getName() + " must be a Array", - ErrorCodes::ILLEGAL_TYPE_OF_ARGUMENT}; + throw Exception(ErrorCodes::ILLEGAL_TYPE_OF_ARGUMENT, "First argument for function {} must be an Array", getName()); const auto * values_type = checkAndGetDataType(arguments[1].get()); if (!values_type) - throw Exception{"Second argument for function " + getName() + " must be a Array", - ErrorCodes::ILLEGAL_TYPE_OF_ARGUMENT}; + throw Exception(ErrorCodes::ILLEGAL_TYPE_OF_ARGUMENT, "Second argument for function {} must be an Array", getName()); - DataTypes tmp; - const auto & key_type = keys_type->getNestedType(); - const auto & value_type = values_type->getNestedType(); - tmp.emplace_back(key_type); - tmp.emplace_back(value_type); - return std::make_shared(tmp); + DataTypes key_value_types{keys_type->getNestedType(), values_type->getNestedType()}; + return std::make_shared(key_value_types); } ColumnPtr executeImpl( @@ -228,17 +215,15 @@ public: } if (!col_keys || !col_values) - throw Exception("Arguments of function " + getName() + " must be array.", ErrorCodes::ILLEGAL_COLUMN); + throw Exception(ErrorCodes::ILLEGAL_COLUMN, "Arguments of function {} must be array", getName()); if (!col_keys->hasEqualOffsets(*col_values)) - throw Exception("Array arguments for function " + getName() + " must have equal sizes", ErrorCodes::SIZES_OF_ARRAYS_DOESNT_MATCH); + throw Exception(ErrorCodes::SIZES_OF_ARRAYS_DONT_MATCH, "Array arguments for function {} must have equal sizes", getName()); const auto & data_keys = col_keys->getDataPtr(); const auto & data_values = col_values->getDataPtr(); const auto & offsets = col_keys->getOffsetsPtr(); - auto nested_column = ColumnArray::create( - ColumnTuple::create(Columns{std::move(data_keys), std::move(data_values)}), - std::move(offsets)); + auto nested_column = ColumnArray::create(ColumnTuple::create(Columns{data_keys, data_values}), offsets); return ColumnMap::create(nested_column); } }; @@ -745,6 +730,8 @@ REGISTER_FUNCTION(Map) factory.registerFunction(); factory.registerFunction(); factory.registerFunction(); + factory.registerAlias("MAP_FROM_ARRAYS", "mapFromArrays"); + } } diff --git a/tests/queries/0_stateless/01651_map_functions.reference b/tests/queries/0_stateless/01651_map_functions.reference index 284e27a1b0d..f7fd3503327 100644 --- a/tests/queries/0_stateless/01651_map_functions.reference +++ b/tests/queries/0_stateless/01651_map_functions.reference @@ -31,3 +31,5 @@ {'aa':4,'bb':5} {'aa':4,'bb':5} {'aa':4,'bb':5} +{'aa':4,'bb':5} +{'aa':4,'bb':5} diff --git a/tests/queries/0_stateless/01651_map_functions.sql b/tests/queries/0_stateless/01651_map_functions.sql index 57023d41470..4d2bb3a0812 100644 --- a/tests/queries/0_stateless/01651_map_functions.sql +++ b/tests/queries/0_stateless/01651_map_functions.sql @@ -31,7 +31,9 @@ select map( 'aa', 4, 'bb' , 5) as m, mapContains(m, 'aa'), mapContains(m, 'k'); select map(0, 0) as m, mapContains(m, number % 2) from numbers(2); select mapFromArrays(['aa', 'bb'], [4, 5]); -select mapFromArrays(['aa', 'bb'], materialize([4, 5])); -select mapFromArrays(['aa', 'bb'], materialize([4, 5])) from numbers(3); +select mapFromArrays(['aa', 'bb'], materialize([4, 5])) from numbers(2); +select mapFromArrays(materialize(['aa', 'bb']), [4, 5]) from numbers(2); +select mapFromArrays(materialize(['aa', 'bb']), materialize([4, 5])) from numbers(2); select mapFromArrays(['aa', 'bb'], [4, 5], [6, 7]); -- { serverError 42 } select mapFromArrays(['aa', 'bb'], [4, 5, 6]); -- { serverError 190 } +select mapFromArrays([[1,2], [3,4]], [4, 5, 6]); -- { serverError 36 }