From e0d85ffd1d36cd0fb87a5d450493bf155a2e3797 Mon Sep 17 00:00:00 2001 From: Vasily Nemkov Date: Mon, 26 Oct 2020 21:20:45 +0300 Subject: [PATCH] Allow casting Tuple as Map. SELECT CAST(([1, 2, 3], ['1', '2', 'foo']), 'Map(UInt8, String)') AS map --- src/Functions/FunctionsConversion.h | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/src/Functions/FunctionsConversion.h b/src/Functions/FunctionsConversion.h index 157d7de3842..3dba4faeee6 100644 --- a/src/Functions/FunctionsConversion.h +++ b/src/Functions/FunctionsConversion.h @@ -2164,6 +2164,27 @@ private: WrapperType createMapWrapper(const DataTypePtr & from_type_untyped, const DataTypeMap * to_type) const { + if (const auto from_tuple = checkAndGetDataType(from_type_untyped.get())) + { + if (from_tuple->getElements().size() != to_type->getElements().size()) + throw Exception{"CAST AS Map from tuple with not enough elements.\n" + "Left type: " + from_tuple->getName() + ", right type: " + to_type->getName(), ErrorCodes::TYPE_MISMATCH}; + + return [] + (ColumnsWithTypeAndName & arguments, const DataTypePtr &, const ColumnNullable * /*nullable_source*/, size_t /*input_rows_count*/) + { + const auto col = arguments.front().column.get(); + const auto & column_tuple = typeid_cast(*col); + + Columns converted_columns(2); + converted_columns[0] = column_tuple.getColumns()[0]; + converted_columns[1] = column_tuple.getColumns()[1]; + + return ColumnMap::create(converted_columns); + }; + } + + const auto from_type = checkAndGetDataType(from_type_untyped.get()); if (!from_type) throw Exception{"CAST AS Map can only be performed between map types.\nLeft type: "