mirror of
https://github.com/ClickHouse/ClickHouse.git
synced 2024-09-20 00:30:49 +00:00
change as request
This commit is contained in:
parent
a32c702caa
commit
5564489cca
@ -43,7 +43,7 @@ Result:
|
||||
|
||||
## mapFromArrays
|
||||
|
||||
Creates a map from an array of keys and an array of values.
|
||||
Creates a map from an array or map of keys and an array or map of values.
|
||||
|
||||
The function is a convenient alternative to syntax `CAST([...], 'Map(key_type, value_type)')`.
|
||||
For example, instead of writing
|
||||
@ -62,8 +62,8 @@ Alias: `MAP_FROM_ARRAYS(keys, values)`
|
||||
|
||||
**Arguments**
|
||||
|
||||
- `keys` — Array or map of keys to create the map from. [Array(T)](../data-types/array.md) where `T` can be any type supported by [Map](../data-types/map.md) as key type, or [Map](../data-types/map.md).
|
||||
- `values` - Array or map of values to create the map from. [Array](../data-types/array.md) or [Map](../data-types/map.md).
|
||||
- `keys` — Array or map of keys to create the map from [Array](../data-types/array.md) or [Map](../data-types/map.md). If `keys` is an array, we accept `Array(Nullable(T))` or `Array(LowCardinality(Nullable(T)))` as its type as long as it doesn't contain NULL value.
|
||||
- `values` - Array or map of values to create the map from [Array](../data-types/array.md) or [Map](../data-types/map.md).
|
||||
|
||||
**Returned value**
|
||||
|
||||
@ -99,6 +99,18 @@ Result:
|
||||
└───────────────────────────────────────────────────────┘
|
||||
```
|
||||
|
||||
```sql
|
||||
SELECT mapFromArrays(map('a', 1, 'b', 2, 'c', 3), [1, 2, 3])
|
||||
```
|
||||
|
||||
Result:
|
||||
|
||||
```
|
||||
┌─mapFromArrays(map('a', 1, 'b', 2, 'c', 3), [1, 2, 3])─┐
|
||||
│ {('a',1):1,('b',2):2,('c',3):3} │
|
||||
└───────────────────────────────────────────────────────┘
|
||||
```
|
||||
|
||||
## extractKeyValuePairs
|
||||
|
||||
Converts a string of key-value pairs to a [Map(String, String)](../data-types/map.md).
|
||||
|
@ -23,6 +23,7 @@ namespace ErrorCodes
|
||||
extern const int ILLEGAL_TYPE_OF_ARGUMENT;
|
||||
extern const int SIZES_OF_ARRAYS_DONT_MATCH;
|
||||
extern const int ILLEGAL_COLUMN;
|
||||
extern const int BAD_ARGUMENTS;
|
||||
}
|
||||
|
||||
namespace
|
||||
@ -157,7 +158,7 @@ private:
|
||||
bool use_variant_as_common_type = false;
|
||||
};
|
||||
|
||||
/// 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 or maps
|
||||
class FunctionMapFromArrays : public IFunction
|
||||
{
|
||||
public:
|
||||
@ -181,13 +182,13 @@ public:
|
||||
getName(),
|
||||
arguments.size());
|
||||
|
||||
auto get_nested_type = [this](const DataTypePtr & type) -> DataTypePtr
|
||||
auto get_nested_type = [&](const DataTypePtr & type)
|
||||
{
|
||||
DataTypePtr nested;
|
||||
if (const auto * array_type = checkAndGetDataType<DataTypeArray>(type.get()))
|
||||
nested = array_type->getNestedType();
|
||||
else if (const auto * map_type = checkAndGetDataType<DataTypeMap>(type.get()))
|
||||
nested = std::make_shared<DataTypeTuple>(map_type->getKeyValueTypes());
|
||||
if (const auto * type_as_array = checkAndGetDataType<DataTypeArray>(type.get()))
|
||||
nested = type_as_array->getNestedType();
|
||||
else if (const auto * type_as_map = checkAndGetDataType<DataTypeMap>(type.get()))
|
||||
nested = std::make_shared<DataTypeTuple>(type_as_map->getKeyValueTypes());
|
||||
else
|
||||
throw Exception(
|
||||
ErrorCodes::ILLEGAL_TYPE_OF_ARGUMENT,
|
||||
@ -201,8 +202,9 @@ public:
|
||||
auto key_type = get_nested_type(arguments[0]);
|
||||
auto value_type = get_nested_type(arguments[1]);
|
||||
|
||||
/// Remove Nullable from key_type if needed for map key must not be Nullable
|
||||
/// We accept Array(Nullable(T)) or Array(LowCardinality(Nullable(T))) as key types as long as the actual array doesn't contain NULL value(this is checked in executeImpl).
|
||||
key_type = removeNullableOrLowCardinalityNullable(key_type);
|
||||
|
||||
DataTypes key_value_types{key_type, value_type};
|
||||
return std::make_shared<DataTypeMap>(key_value_types);
|
||||
}
|
||||
@ -210,7 +212,7 @@ public:
|
||||
ColumnPtr executeImpl(
|
||||
const ColumnsWithTypeAndName & arguments, const DataTypePtr & /* result_type */, size_t /* input_rows_count */) const override
|
||||
{
|
||||
auto get_array_column = [this](const ColumnPtr & column) -> std::pair<const ColumnArray *, ColumnPtr>
|
||||
auto get_array_column = [&](const ColumnPtr & column) -> std::pair<const ColumnArray *, ColumnPtr>
|
||||
{
|
||||
bool is_const = isColumnConst(*column);
|
||||
ColumnPtr holder = is_const ? column->convertToFullColumnIfConst() : column;
|
||||
@ -231,8 +233,9 @@ public:
|
||||
};
|
||||
|
||||
auto [col_keys, key_holder] = get_array_column(arguments[0].column);
|
||||
auto [col_values, values_holder] = get_array_column(arguments[1].column);
|
||||
|
||||
/// Check if nested column of first argument contains NULL value in case its nested type is Nullable(T) type.
|
||||
/// Nullable(T) or LowCardinality(Nullable(T)) are okay as nested key types but actual NULL values are not okay.
|
||||
ColumnPtr data_keys = col_keys->getDataPtr();
|
||||
if (isColumnNullableOrLowCardinalityNullable(*data_keys))
|
||||
{
|
||||
@ -253,10 +256,9 @@ public:
|
||||
|
||||
if (null_map && !memoryIsZero(null_map->data(), 0, null_map->size()))
|
||||
throw Exception(
|
||||
ErrorCodes::ILLEGAL_COLUMN, "The nested column of first argument in function {} must not contain NULLs", getName());
|
||||
ErrorCodes::BAD_ARGUMENTS, "The nested column of first argument in function {} must not contain NULLs", getName());
|
||||
}
|
||||
|
||||
auto [col_values, values_holder] = get_array_column(arguments[1].column);
|
||||
if (!col_keys->hasEqualOffsets(*col_values))
|
||||
throw Exception(ErrorCodes::SIZES_OF_ARRAYS_DONT_MATCH, "Two arguments of function {} must have equal sizes", getName());
|
||||
|
||||
|
@ -55,3 +55,7 @@
|
||||
{1:3,2:4}
|
||||
{1:3,2:4}
|
||||
{1:3,2:4} {(1,3):'a',(2,4):'b'}
|
||||
{(1,'a'):'c',(2,'b'):'d'}
|
||||
{(1,'a'):'c',(2,'b'):'d'}
|
||||
{(1,'a'):'c',(2,'b'):'d'}
|
||||
{(1,'a'):'c',(2,'b'):'d'}
|
||||
|
@ -68,7 +68,7 @@ select mapFromArrays([[1,2], [3,4]], [4, 5, 6]); -- { serverError SIZES_OF_ARRAY
|
||||
select mapFromArrays(['a', 2], [4, 5]); -- { serverError NO_COMMON_TYPE}
|
||||
select mapFromArrays([1, 2], [4, 'a']); -- { serverError NO_COMMON_TYPE}
|
||||
select mapFromArrays(['aa', 'bb'], map('a', 4)); -- { serverError SIZES_OF_ARRAYS_DONT_MATCH }
|
||||
select mapFromArrays([1,null]::Array(Nullable(UInt8)), [3,4]); -- { serverError ILLEGAL_COLUMN }
|
||||
select mapFromArrays([1,null]::Array(Nullable(UInt8)), [3,4]); -- { serverError BAD_ARGUMENTS }
|
||||
|
||||
select mapFromArrays(['aa', 'bb'], map('a', 4, 'b', 5));
|
||||
select mapFromArrays(['aa', 'bb'], materialize(map('a', 4, 'b', 5))) from numbers(2);
|
||||
@ -79,3 +79,8 @@ select mapFromArrays([toLowCardinality(1), toLowCardinality(2)], materialize([4,
|
||||
select mapFromArrays([1,2], [3,4]);
|
||||
select mapFromArrays([1,2]::Array(Nullable(UInt8)), [3,4]);
|
||||
select mapFromArrays([1,2], [3,4]) as x, mapFromArrays(x, ['a', 'b']);
|
||||
|
||||
select mapFromArrays(map(1, 'a', 2, 'b'), array('c', 'd'));
|
||||
select mapFromArrays(materialize(map(1, 'a', 2, 'b')), array('c', 'd'));
|
||||
select mapFromArrays(map(1, 'a', 2, 'b'), materialize(array('c', 'd')));
|
||||
select mapFromArrays(materialize(map(1, 'a', 2, 'b')), materialize(array('c', 'd')));
|
||||
|
Loading…
Reference in New Issue
Block a user