diff --git a/src/DataTypes/IDataType.h b/src/DataTypes/IDataType.h index cb9fc7f122c..dba5bc3f5a9 100644 --- a/src/DataTypes/IDataType.h +++ b/src/DataTypes/IDataType.h @@ -597,6 +597,7 @@ inline bool isEnum(const DataTypePtr & data_type) { return WhichDataType(data_ty inline bool isDecimal(const DataTypePtr & data_type) { return WhichDataType(data_type).isDecimal(); } inline bool isTuple(const DataTypePtr & data_type) { return WhichDataType(data_type).isTuple(); } inline bool isArray(const DataTypePtr & data_type) { return WhichDataType(data_type).isArray(); } +inline bool isMap(const DataTypePtr & data_type) {return WhichDataType(data_type).isMap(); } template inline bool isUInt8(const T & data_type) diff --git a/src/Functions/FunctionStringOrArrayToT.h b/src/Functions/FunctionStringOrArrayToT.h index 6330d8f90d6..2108fa7e8b6 100644 --- a/src/Functions/FunctionStringOrArrayToT.h +++ b/src/Functions/FunctionStringOrArrayToT.h @@ -7,6 +7,7 @@ #include #include #include +#include namespace DB @@ -42,7 +43,7 @@ public: DataTypePtr getReturnTypeImpl(const DataTypes & arguments) const override { if (!isStringOrFixedString(arguments[0]) - && !isArray(arguments[0])) + && !isArray(arguments[0]) && !isMap(arguments[0])) throw Exception("Illegal type " + arguments[0]->getName() + " of argument of function " + getName(), ErrorCodes::ILLEGAL_TYPE_OF_ARGUMENT); return std::make_shared>(); @@ -93,6 +94,22 @@ public: return col_res; } + else if (const ColumnMap* col_map = checkAndGetColumn(column.get())) + { + // only function length is implemented for ColumnMap + // TODO implemented other functions which use FunctionStringOrArrayToT + if (getName() != "length") + throw Exception("Illegal column " + arguments[0].column->getName() + " of argument of function " + getName(), + ErrorCodes::ILLEGAL_COLUMN); + + auto col_res = ColumnVector::create(); + typename ColumnVector::Container & vec_res = col_res->getData(); + vec_res.resize(col_map->size()); + const auto & col_nested = col_map->getNestedColumn(); + + Impl::array(col_nested.getOffsets(), vec_res); + return col_res; + } else throw Exception("Illegal column " + arguments[0].column->getName() + " of argument of function " + getName(), ErrorCodes::ILLEGAL_COLUMN); diff --git a/tests/queries/0_stateless/01592_length_map.reference b/tests/queries/0_stateless/01592_length_map.reference new file mode 100644 index 00000000000..51993f072d5 --- /dev/null +++ b/tests/queries/0_stateless/01592_length_map.reference @@ -0,0 +1,2 @@ +2 +2 diff --git a/tests/queries/0_stateless/01592_length_map.sql b/tests/queries/0_stateless/01592_length_map.sql new file mode 100644 index 00000000000..4f2b0737d82 --- /dev/null +++ b/tests/queries/0_stateless/01592_length_map.sql @@ -0,0 +1,6 @@ +set allow_experimental_map_type = 1; + +drop table if exists table_map; +create table table_map (a Map(String, String)) engine = Memory; +insert into table_map values ({'name':'zhangsan', 'gender':'male'}), ({'name':'lisi', 'gender':'female'}); +select length(a) from table_map;