change as request

This commit is contained in:
taiyang-li 2023-03-01 21:15:01 +08:00
parent f84eee778b
commit e8847f2fb6
4 changed files with 59 additions and 64 deletions

View File

@ -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

View File

@ -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<FunctionMapFromArrays>();
}
static FunctionPtr create(ContextPtr) { return std::make_shared<FunctionMapFromArrays>(); }
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<DataTypeArray>(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<DataTypeArray>(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<DataTypeMap>(tmp);
DataTypes key_value_types{keys_type->getNestedType(), values_type->getNestedType()};
return std::make_shared<DataTypeMap>(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<FunctionExtractKeyLike>();
factory.registerFunction<FunctionMapUpdate>();
factory.registerFunction<FunctionMapFromArrays>();
factory.registerAlias("MAP_FROM_ARRAYS", "mapFromArrays");
}
}

View File

@ -31,3 +31,5 @@
{'aa':4,'bb':5}
{'aa':4,'bb':5}
{'aa':4,'bb':5}
{'aa':4,'bb':5}
{'aa':4,'bb':5}

View File

@ -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 }