Merge pull request #33794 from kitaisreal/support-cast-from-map-to-array-of-tuple

Support cast from Map to Array of Tuple
This commit is contained in:
Maksim Kita 2022-01-23 13:10:28 +01:00 committed by GitHub
commit c66d5c6dd0
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 55 additions and 4 deletions

View File

@ -2805,10 +2805,16 @@ private:
}
const auto * from_type = checkAndGetDataType<DataTypeArray>(from_type_untyped.get());
const auto * from_type_map = checkAndGetDataType<DataTypeMap>(from_type_untyped.get());
/// Convert from Map
if (from_type_map)
from_type = checkAndGetDataType<DataTypeArray>(from_type_map->getNestedType().get());
if (!from_type)
{
throw Exception(ErrorCodes::TYPE_MISMATCH,
"CAST AS Array can only be performed between same-dimensional Array or String types");
"CAST AS Array can only be performed between same-dimensional Array, Map or String types");
}
DataTypePtr from_nested_type = from_type->getNestedType();
@ -2828,9 +2834,16 @@ private:
return [nested_function, from_nested_type, to_nested_type](
ColumnsWithTypeAndName & arguments, const DataTypePtr &, const ColumnNullable * nullable_source, size_t /*input_rows_count*/) -> ColumnPtr
{
const auto & array_arg = arguments.front();
const auto & argument_column = arguments.front();
if (const ColumnArray * col_array = checkAndGetColumn<ColumnArray>(array_arg.column.get()))
const ColumnArray * col_array = nullptr;
if (const ColumnMap * col_map = checkAndGetColumn<ColumnMap>(argument_column.column.get()))
col_array = &col_map->getNestedColumn();
else
col_array = checkAndGetColumn<ColumnArray>(argument_column.column.get());
if (col_array)
{
/// create columns for converting nested column containing original and result columns
ColumnsWithTypeAndName nested_columns{{ col_array->getDataPtr(), from_nested_type, "" }};
@ -2842,7 +2855,11 @@ private:
return ColumnArray::create(result_column, col_array->getOffsetsPtr());
}
else
throw Exception{"Illegal column " + array_arg.column->getName() + " for function CAST AS Array", ErrorCodes::LOGICAL_ERROR};
{
throw Exception(ErrorCodes::LOGICAL_ERROR,
"Illegal column {} for function CAST AS Array",
argument_column.column->getName());
}
};
}

View File

@ -0,0 +1,8 @@
{1:'Test'} [(1,'Test')] [(1,'Test')]
{1:'1234'} [(1,1234)] [(1,1234)]
{1:[1,2,3]} [(1,['1','2','3'])] [(1,['1','2','3'])]
{1:['1','2','3']} [(1,[1,2,3])] [(1,[1,2,3])]
{1:{1:'1234'}} [(1,{1:'1234'})] [(1,{1:'1234'})]
{1:{1:'1234'}} [(1,{1:1234})] [(1,{1:1234})]
{1:{1:'1234'}} [(1,[(1,'1234')])] [(1,[(1,'1234')])]
{1:{1:'1234'}} [(1,[(1,1234)])] [(1,[(1,1234)])]

View File

@ -0,0 +1,26 @@
WITH map(1, 'Test') AS value, 'Array(Tuple(UInt64, String))' AS type
SELECT value, cast(value, type), cast(materialize(value), type);
WITH map(1, 'Test') AS value, 'Array(Tuple(UInt64, UInt64))' AS type
SELECT value, cast(value, type), cast(materialize(value), type); --{serverError 6}
WITH map(1, '1234') AS value, 'Array(Tuple(UInt64, UInt64))' AS type
SELECT value, cast(value, type), cast(materialize(value), type);
WITH map(1, [1, 2, 3]) AS value, 'Array(Tuple(UInt64, Array(String)))' AS type
SELECT value, cast(value, type), cast(materialize(value), type);
WITH map(1, ['1', '2', '3']) AS value, 'Array(Tuple(UInt64, Array(UInt64)))' AS type
SELECT value, cast(value, type), cast(materialize(value), type);
WITH map(1, map(1, '1234')) AS value, 'Array(Tuple(UInt64, Map(UInt64, String)))' AS type
SELECT value, cast(value, type), cast(materialize(value), type);
WITH map(1, map(1, '1234')) AS value, 'Array(Tuple(UInt64, Map(UInt64, UInt64)))' AS type
SELECT value, cast(value, type), cast(materialize(value), type);
WITH map(1, map(1, '1234')) AS value, 'Array(Tuple(UInt64, Array(Tuple(UInt64, String))))' AS type
SELECT value, cast(value, type), cast(materialize(value), type);
WITH map(1, map(1, '1234')) as value, 'Array(Tuple(UInt64, Array(Tuple(UInt64, UInt64))))' AS type
SELECT value, cast(value, type), cast(materialize(value), type);