Support cast from Map to Array of Tuple

This commit is contained in:
Maksim Kita 2022-01-21 15:14:31 +00:00
parent 4100512818
commit 4be393fba5
3 changed files with 57 additions and 4 deletions

View File

@ -2805,10 +2805,18 @@ private:
} }
const auto * from_type = checkAndGetDataType<DataTypeArray>(from_type_untyped.get()); const auto * from_type = checkAndGetDataType<DataTypeArray>(from_type_untyped.get());
if (!from_type)
{
/// Convert from Map
const auto * from_type_map = checkAndGetDataType<DataTypeMap>(from_type_untyped.get());
from_type = checkAndGetDataType<DataTypeArray>(from_type_map->getNestedType().get());
}
if (!from_type) if (!from_type)
{ {
throw Exception(ErrorCodes::TYPE_MISMATCH, 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(); DataTypePtr from_nested_type = from_type->getNestedType();
@ -2828,9 +2836,16 @@ private:
return [nested_function, from_nested_type, to_nested_type]( return [nested_function, from_nested_type, to_nested_type](
ColumnsWithTypeAndName & arguments, const DataTypePtr &, const ColumnNullable * nullable_source, size_t /*input_rows_count*/) -> ColumnPtr 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 /// create columns for converting nested column containing original and result columns
ColumnsWithTypeAndName nested_columns{{ col_array->getDataPtr(), from_nested_type, "" }}; ColumnsWithTypeAndName nested_columns{{ col_array->getDataPtr(), from_nested_type, "" }};
@ -2842,7 +2857,11 @@ private:
return ColumnArray::create(result_column, col_array->getOffsetsPtr()); return ColumnArray::create(result_column, col_array->getOffsetsPtr());
} }
else 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);