diff --git a/plugin/trino-adb/pom.xml b/plugin/trino-adb/pom.xml
index 13d5d258ad6a..774c9726cd52 100644
--- a/plugin/trino-adb/pom.xml
+++ b/plugin/trino-adb/pom.xml
@@ -70,6 +70,12 @@
io.airlift
http-server
compile
+
+
+ jakarta.annotation
+ jakarta.annotation-api
+
+
@@ -199,6 +205,12 @@
compile
+
+ jakarta.annotation
+ jakarta.annotation-api
+ compile
+
+
jakarta.servlet
jakarta.servlet-api
diff --git a/plugin/trino-adb/src/main/java/io/trino/plugin/adb/TypeUtil.java b/plugin/trino-adb/src/main/java/io/trino/plugin/adb/TypeUtil.java
index 540c3ca6389c..6251f58a7ee7 100644
--- a/plugin/trino-adb/src/main/java/io/trino/plugin/adb/TypeUtil.java
+++ b/plugin/trino-adb/src/main/java/io/trino/plugin/adb/TypeUtil.java
@@ -73,6 +73,11 @@
public final class TypeUtil
{
+ public static final String ARRAY_TYPE_ELEMENT_DELIMITER = ",";
+ public static final String MAP_TYPE_VALUE_SEPARATOR = "=>";
+ public static final String MAP_TYPE_NULL_VALUE = "NULL";
+ public static final String MAP_TYPE_ENTRY_SEPARATOR = ", ";
+ public static final char MAP_TYPE_VALUE_QUOTE = '"';
public static final int POSTGRESQL_MAX_SUPPORTED_TIMESTAMP_PRECISION = 6;
public static final DateTimeFormatter TIMESTAMP_TYPE_FORMATTER = new DateTimeFormatterBuilder()
.appendValue(ChronoField.YEAR_OF_ERA, 4, 9, SignStyle.NORMAL)
diff --git a/plugin/trino-adb/src/main/java/io/trino/plugin/adb/connector/AdbSqlClient.java b/plugin/trino-adb/src/main/java/io/trino/plugin/adb/connector/AdbSqlClient.java
index b61be7e351b2..6fca6785fb49 100644
--- a/plugin/trino-adb/src/main/java/io/trino/plugin/adb/connector/AdbSqlClient.java
+++ b/plugin/trino-adb/src/main/java/io/trino/plugin/adb/connector/AdbSqlClient.java
@@ -772,6 +772,11 @@ public ColumnDataType getColumnDataType(ConnectorSession session, JdbcTypeHandle
return dataTypeMapper.getColumnDataType(session, typeHandle);
}
+ public List getColumnDataTypes(ConnectorSession session, List jdbcColumnHandles)
+ {
+ return dataTypeMapper.getColumnDataTypes(session, jdbcColumnHandles);
+ }
+
@Override
public WriteMapping toWriteMapping(ConnectorSession session, Type type)
{
diff --git a/plugin/trino-adb/src/main/java/io/trino/plugin/adb/connector/datatype/ArrayDataType.java b/plugin/trino-adb/src/main/java/io/trino/plugin/adb/connector/datatype/ArrayDataType.java
new file mode 100644
index 000000000000..79c23730647a
--- /dev/null
+++ b/plugin/trino-adb/src/main/java/io/trino/plugin/adb/connector/datatype/ArrayDataType.java
@@ -0,0 +1,57 @@
+/*
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package io.trino.plugin.adb.connector.datatype;
+
+import io.trino.spi.type.ArrayType;
+
+import static com.google.common.base.Preconditions.checkArgument;
+
+public class ArrayDataType
+ implements ColumnDataType
+{
+ private final String name;
+ private final ArrayType arrayType;
+ private final ColumnDataType elementType;
+
+ public ArrayDataType(ArrayType arrayType, ColumnDataType elementType)
+ {
+ checkArgument(arrayType != null, "arrayType is null");
+ checkArgument(elementType != null, "elementType is null");
+ this.name = elementType.getName() + "[]";
+ this.arrayType = arrayType;
+ this.elementType = elementType;
+ }
+
+ @Override
+ public String getName()
+ {
+ return name;
+ }
+
+ @Override
+ public ConnectorDataType getType()
+ {
+ return ConnectorDataType.ARRAY;
+ }
+
+ public ArrayType getArrayType()
+ {
+ return arrayType;
+ }
+
+ public ColumnDataType getElementType()
+ {
+ return elementType;
+ }
+}
diff --git a/plugin/trino-adb/src/main/java/io/trino/plugin/adb/connector/datatype/ConnectorDataType.java b/plugin/trino-adb/src/main/java/io/trino/plugin/adb/connector/datatype/ConnectorDataType.java
index cf12a8784039..d96b8dff736d 100644
--- a/plugin/trino-adb/src/main/java/io/trino/plugin/adb/connector/datatype/ConnectorDataType.java
+++ b/plugin/trino-adb/src/main/java/io/trino/plugin/adb/connector/datatype/ConnectorDataType.java
@@ -37,5 +37,6 @@ public enum ConnectorDataType
TIMESTAMP_WITHOUT_TIME_ZONE,
ENUM,
ARRAY,
+ MAP,
UNSUPPORTED
}
diff --git a/plugin/trino-adb/src/main/java/io/trino/plugin/adb/connector/datatype/MapDataType.java b/plugin/trino-adb/src/main/java/io/trino/plugin/adb/connector/datatype/MapDataType.java
new file mode 100644
index 000000000000..342dffaf58df
--- /dev/null
+++ b/plugin/trino-adb/src/main/java/io/trino/plugin/adb/connector/datatype/MapDataType.java
@@ -0,0 +1,46 @@
+/*
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package io.trino.plugin.adb.connector.datatype;
+
+import io.trino.spi.type.MapType;
+
+public class MapDataType
+ implements ColumnDataType
+{
+ private final String name;
+ private final MapType mapType;
+
+ public MapDataType(MapType mapType)
+ {
+ this.name = "hstore";
+ this.mapType = mapType;
+ }
+
+ @Override
+ public String getName()
+ {
+ return name;
+ }
+
+ @Override
+ public ConnectorDataType getType()
+ {
+ return ConnectorDataType.MAP;
+ }
+
+ public MapType getTrinoMapType()
+ {
+ return mapType;
+ }
+}
diff --git a/plugin/trino-adb/src/main/java/io/trino/plugin/adb/connector/datatype/mapper/DataTypeMapper.java b/plugin/trino-adb/src/main/java/io/trino/plugin/adb/connector/datatype/mapper/DataTypeMapper.java
index 1e4d435a6151..f6e5cf3408d1 100644
--- a/plugin/trino-adb/src/main/java/io/trino/plugin/adb/connector/datatype/mapper/DataTypeMapper.java
+++ b/plugin/trino-adb/src/main/java/io/trino/plugin/adb/connector/datatype/mapper/DataTypeMapper.java
@@ -15,6 +15,7 @@
import io.trino.plugin.adb.connector.datatype.ColumnDataType;
import io.trino.plugin.jdbc.ColumnMapping;
+import io.trino.plugin.jdbc.JdbcColumnHandle;
import io.trino.plugin.jdbc.JdbcOutputTableHandle;
import io.trino.plugin.jdbc.JdbcTypeHandle;
import io.trino.plugin.jdbc.WriteMapping;
@@ -35,5 +36,7 @@ public interface DataTypeMapper
List getColumnDataTypes(ConnectorSession session, JdbcOutputTableHandle outputTableHandle);
- Optional fromTrinoType(Type type);
+ List getColumnDataTypes(ConnectorSession session, List jdbcColumnHandles);
+
+ Optional fromTrinoType(ConnectorSession session, Type type);
}
diff --git a/plugin/trino-adb/src/main/java/io/trino/plugin/adb/connector/datatype/mapper/DataTypeMapperImpl.java b/plugin/trino-adb/src/main/java/io/trino/plugin/adb/connector/datatype/mapper/DataTypeMapperImpl.java
index fe386962e37d..a4eb39c645c4 100644
--- a/plugin/trino-adb/src/main/java/io/trino/plugin/adb/connector/datatype/mapper/DataTypeMapperImpl.java
+++ b/plugin/trino-adb/src/main/java/io/trino/plugin/adb/connector/datatype/mapper/DataTypeMapperImpl.java
@@ -20,6 +20,7 @@
import io.trino.plugin.adb.AdbPluginConfig;
import io.trino.plugin.adb.connector.AdbPushdownSessionProperties;
import io.trino.plugin.adb.connector.AdbSessionProperties;
+import io.trino.plugin.adb.connector.datatype.ArrayDataType;
import io.trino.plugin.adb.connector.datatype.BigintDataType;
import io.trino.plugin.adb.connector.datatype.BitDataType;
import io.trino.plugin.adb.connector.datatype.BooleanDataType;
@@ -34,6 +35,7 @@
import io.trino.plugin.adb.connector.datatype.EnumDataType;
import io.trino.plugin.adb.connector.datatype.IntegerDataType;
import io.trino.plugin.adb.connector.datatype.JsonbDataType;
+import io.trino.plugin.adb.connector.datatype.MapDataType;
import io.trino.plugin.adb.connector.datatype.MoneyDataType;
import io.trino.plugin.adb.connector.datatype.RealDataType;
import io.trino.plugin.adb.connector.datatype.SmallintDataType;
@@ -48,7 +50,9 @@
import io.trino.plugin.jdbc.BaseJdbcConfig;
import io.trino.plugin.jdbc.BooleanReadFunction;
import io.trino.plugin.jdbc.ColumnMapping;
+import io.trino.plugin.jdbc.ConnectionFactory;
import io.trino.plugin.jdbc.DoubleReadFunction;
+import io.trino.plugin.jdbc.JdbcColumnHandle;
import io.trino.plugin.jdbc.JdbcMetadataSessionProperties;
import io.trino.plugin.jdbc.JdbcOutputTableHandle;
import io.trino.plugin.jdbc.JdbcTypeHandle;
@@ -62,10 +66,11 @@
import io.trino.plugin.jdbc.SliceWriteFunction;
import io.trino.plugin.jdbc.StandardColumnMappings;
import io.trino.plugin.jdbc.WriteMapping;
-import io.trino.spi.StandardErrorCode;
import io.trino.spi.TrinoException;
import io.trino.spi.block.Block;
import io.trino.spi.block.BlockBuilder;
+import io.trino.spi.block.MapBlock;
+import io.trino.spi.block.SqlMap;
import io.trino.spi.connector.ConnectorSession;
import io.trino.spi.predicate.Domain;
import io.trino.spi.type.ArrayType;
@@ -74,6 +79,7 @@
import io.trino.spi.type.Decimals;
import io.trino.spi.type.LongTimestamp;
import io.trino.spi.type.LongTimestampWithTimeZone;
+import io.trino.spi.type.MapType;
import io.trino.spi.type.TimeType;
import io.trino.spi.type.TimestampType;
import io.trino.spi.type.TimestampWithTimeZoneType;
@@ -100,16 +106,19 @@
import java.time.LocalTime;
import java.time.OffsetDateTime;
import java.util.ArrayList;
+import java.util.Collections;
+import java.util.HashMap;
import java.util.List;
+import java.util.Map;
import java.util.Optional;
import java.util.Set;
import java.util.UUID;
+import java.util.stream.IntStream;
import static com.google.common.base.Preconditions.checkArgument;
import static com.google.common.base.Verify.verify;
import static io.airlift.slice.Slices.utf8Slice;
import static io.trino.plugin.adb.AdbPluginConfig.ArrayMapping.AS_ARRAY;
-import static io.trino.plugin.adb.AdbPluginConfig.ArrayMapping.AS_JSON;
import static io.trino.plugin.adb.AdbPluginConfig.ArrayMapping.DISABLED;
import static io.trino.plugin.adb.TypeUtil.POSTGRESQL_MAX_SUPPORTED_TIMESTAMP_PRECISION;
import static io.trino.plugin.adb.TypeUtil.TIME_TYPE_FORMATTER;
@@ -154,6 +163,7 @@
import static io.trino.plugin.jdbc.StandardColumnMappings.varcharWriteFunction;
import static io.trino.plugin.jdbc.TypeHandlingJdbcSessionProperties.getUnsupportedTypeHandling;
import static io.trino.plugin.jdbc.UnsupportedTypeHandling.CONVERT_TO_VARCHAR;
+import static io.trino.spi.StandardErrorCode.INVALID_FUNCTION_ARGUMENT;
import static io.trino.spi.StandardErrorCode.NOT_SUPPORTED;
import static io.trino.spi.type.BigintType.BIGINT;
import static io.trino.spi.type.BooleanType.BOOLEAN;
@@ -211,18 +221,23 @@ else if (AdbSessionProperties.isEnableStringPushdownWithCollate(session)) {
: PredicatePushdownController.FULL_PUSHDOWN.apply(session, simplifiedDomain);
}
};
+ private final MapType mapType;
private final Type jsonType;
private final Type uuidType;
private final Set jdbcTypesMappedToVarchar;
+ private final ConnectionFactory connectionFactory;
@Inject
- public DataTypeMapperImpl(TypeManager typeManager, BaseJdbcConfig jdbcConfig)
+ public DataTypeMapperImpl(TypeManager typeManager, BaseJdbcConfig jdbcConfig, ConnectionFactory connectionFactory)
{
this.jsonType = typeManager.getType(new TypeSignature("json"));
this.uuidType = typeManager.getType(new TypeSignature("uuid"));
this.jdbcTypesMappedToVarchar = ImmutableSortedSet.orderedBy(CASE_INSENSITIVE_ORDER)
.addAll(requireNonNull(jdbcConfig.getJdbcTypesMappedToVarchar(), "jdbcTypesMappedToVarchar is null"))
.build();
+ this.connectionFactory = connectionFactory;
+ mapType = (MapType) typeManager.getType(
+ TypeSignature.mapType(VarcharType.VARCHAR.getTypeSignature(), VarcharType.VARCHAR.getTypeSignature()));
}
@Override
@@ -358,6 +373,8 @@ private AdbColumnMapping toColumnMappingInternal(ConnectorSession session, Optio
case "timestamptz":
int decimalDigits = typeHandle.requiredDecimalDigits();
return timestampWithTimeZoneColumnMapping(decimalDigits);
+ case "hstore":
+ return new AdbColumnMapping(hstoreColumnMapping(session), new MapDataType(mapType));
}
switch (typeHandle.jdbcType()) {
case Types.BIT:
@@ -401,7 +418,7 @@ private AdbColumnMapping toColumnMappingInternal(ConnectorSession session, Optio
return new AdbColumnMapping(decimalColumnMapping(decimalType, RoundingMode.UNNECESSARY),
columnDataType);
}
- throw new TrinoException(StandardErrorCode.NOT_SUPPORTED,
+ throw new TrinoException(NOT_SUPPORTED,
format("Type %s(%d,%d) is not supported", jdbcTypeName, columnSize, precision));
}
case Types.CHAR:
@@ -445,7 +462,13 @@ timestampType, timestampReadFunction(timestampType),
Optional arrayColumnMapping =
arrayToTrinoType(session, connection.get(), typeHandle);
if (arrayColumnMapping.isPresent()) {
- return new AdbColumnMapping(arrayColumnMapping.get(), new UnsupportedDataType(jdbcTypeName));
+ ColumnMapping arrayMapping = arrayColumnMapping.get();
+ ArrayType arrayType = (ArrayType) arrayMapping.getType();
+ return fromTrinoType(session, arrayType.getElementType())
+ .map(elementType -> new AdbColumnMapping(arrayMapping,
+ new ArrayDataType(arrayType, elementType)))
+ .orElseThrow(() -> new TrinoException(NOT_SUPPORTED,
+ format("Failed to get array element type for %s", arrayType)));
}
}
break;
@@ -461,7 +484,7 @@ timestampType, timestampReadFunction(timestampType),
}
@Override
- public Optional fromTrinoType(Type type)
+ public Optional fromTrinoType(ConnectorSession session, Type type)
{
if (type == BOOLEAN) {
return Optional.of(new BooleanDataType());
@@ -515,6 +538,15 @@ else if (type == VARBINARY) {
else if (type == JsonType.JSON) {
return Optional.of(new JsonbDataType());
}
+ else if (type instanceof ArrayType arrayType) {
+ ColumnDataType elementType = fromTrinoType(session, arrayType.getElementType())
+ .orElseThrow(() -> new IllegalArgumentException("Unsupported array element type: " + arrayType));
+ if (elementType.getType() == ConnectorDataType.ARRAY && getArrayMapping(session) == AS_ARRAY) {
+ throw new IllegalArgumentException(
+ "Multidimensional array type with array mapping 'AS_ARRAY' is not supported");
+ }
+ return Optional.of(new ArrayDataType(arrayType, elementType));
+ }
else {
return type == UuidType.UUID ? Optional.of(new UuidDataType()) : Optional.empty();
}
@@ -522,34 +554,81 @@ else if (type == JsonType.JSON) {
@Override
public List getColumnDataTypes(ConnectorSession session, JdbcOutputTableHandle outputTableHandle)
+ {
+ if (outputTableHandle.getJdbcColumnTypes().isEmpty()) {
+ return getDataTypesFromTrinoTypes(session, outputTableHandle);
+ }
+ else {
+ return getDataTypesFromJdbcTypes(session, outputTableHandle);
+ }
+ }
+
+ private List getDataTypesFromTrinoTypes(ConnectorSession session,
+ JdbcOutputTableHandle outputTableHandle)
{
List columnDataTypes = new ArrayList<>();
for (int i = 0; i < outputTableHandle.getColumnNames().size(); i++) {
- ColumnDataType columnDataType;
- if (outputTableHandle.getJdbcColumnTypes().isEmpty()) {
- Type columnType = outputTableHandle.getColumnTypes().get(i);
- columnDataType = fromTrinoType(columnType)
- .orElseThrow(() -> new TrinoException(NOT_SUPPORTED,
- format(COLUMN_TYPE_NOT_SUPPORTED_ERROR_MSG_TEMPLATE, columnType)));
- }
- else {
- JdbcTypeHandle columnType = (outputTableHandle.getJdbcColumnTypes().get()).get(i);
- columnDataType = Optional.ofNullable(toColumnMappingInternal(session,
- Optional.empty(),
- columnType))
- .orElseThrow(() -> new TrinoException(NOT_SUPPORTED,
- format(COLUMN_TYPE_NOT_SUPPORTED_ERROR_MSG_TEMPLATE, columnType)))
- .columnDataType();
- if (columnDataType.getType() == ConnectorDataType.UNSUPPORTED) {
- throw new TrinoException(NOT_SUPPORTED,
- format(COLUMN_TYPE_NOT_SUPPORTED_ERROR_MSG_TEMPLATE, columnType));
- }
- }
+ Type columnType = outputTableHandle.getColumnTypes().get(i);
+ ColumnDataType columnDataType = fromTrinoType(session, columnType)
+ .orElseThrow(() -> new TrinoException(NOT_SUPPORTED,
+ format(COLUMN_TYPE_NOT_SUPPORTED_ERROR_MSG_TEMPLATE, columnType)));
columnDataTypes.add(columnDataType);
}
return columnDataTypes;
}
+ private List getDataTypesFromJdbcTypes(ConnectorSession session,
+ JdbcOutputTableHandle outputTableHandle)
+ {
+ try (Connection connection = connectionFactory.openConnection(session)) {
+ List columnDataTypes = new ArrayList<>();
+ IntStream.range(0, outputTableHandle.getColumnNames().size()).boxed()
+ .forEach(i -> outputTableHandle.getJdbcColumnTypes().ifPresentOrElse(type -> {
+ JdbcTypeHandle jdbcTypeHandle = type.get(i);
+ ColumnDataType columnDataType =
+ getColumnDataTypeFromTypeHandle(session, connection, jdbcTypeHandle);
+ columnDataTypes.add(columnDataType);
+ }, () -> new IllegalArgumentException("Failed to get jdbc column type")));
+ return columnDataTypes;
+ }
+ catch (SQLException e) {
+ throw new TrinoException(JDBC_ERROR, e);
+ }
+ }
+
+ @Override
+ public List getColumnDataTypes(ConnectorSession session, List jdbcColumnHandles)
+ {
+ try (Connection connection = connectionFactory.openConnection(session)) {
+ List columnDataTypes = new ArrayList<>();
+ jdbcColumnHandles.forEach(columnHandle -> {
+ JdbcTypeHandle columnType = columnHandle.getJdbcTypeHandle();
+ ColumnDataType columnDataType = getColumnDataTypeFromTypeHandle(session, connection, columnType);
+ columnDataTypes.add(columnDataType);
+ });
+ return columnDataTypes;
+ }
+ catch (SQLException e) {
+ throw new TrinoException(JDBC_ERROR, e);
+ }
+ }
+
+ private ColumnDataType getColumnDataTypeFromTypeHandle(ConnectorSession session, Connection connection,
+ JdbcTypeHandle columnType)
+ {
+ ColumnDataType columnDataType = Optional.ofNullable(toColumnMappingInternal(session,
+ Optional.of(connection),
+ columnType))
+ .orElseThrow(() -> new TrinoException(NOT_SUPPORTED,
+ format(COLUMN_TYPE_NOT_SUPPORTED_ERROR_MSG_TEMPLATE, columnType)))
+ .columnDataType();
+ if (columnDataType.getType() == ConnectorDataType.UNSUPPORTED) {
+ throw new TrinoException(NOT_SUPPORTED,
+ format(COLUMN_TYPE_NOT_SUPPORTED_ERROR_MSG_TEMPLATE, columnType));
+ }
+ return columnDataType;
+ }
+
private Optional getForcedMappingToVarchar(JdbcTypeHandle typeHandle)
{
if (typeHandle.jdbcTypeName().isPresent() &&
@@ -574,6 +653,59 @@ protected static Optional mapToUnboundedVarchar(JdbcTypeHandle ty
DISABLE_PUSHDOWN));
}
+ private ColumnMapping hstoreColumnMapping(ConnectorSession session)
+ {
+ return ColumnMapping.objectMapping(
+ mapType,
+ varcharMapReadFunction(),
+ hstoreWriteFunction(session),
+ PredicatePushdownController.DISABLE_PUSHDOWN);
+ }
+
+ private ObjectReadFunction varcharMapReadFunction()
+ {
+ return ObjectReadFunction.of(SqlMap.class, (resultSet, columnIndex) -> {
+ @SuppressWarnings("unchecked")
+ Map map = (Map) resultSet.getObject(columnIndex);
+ BlockBuilder keyBlockBuilder = mapType.getKeyType().createBlockBuilder(null, map.size());
+ BlockBuilder valueBlockBuilder = mapType.getValueType().createBlockBuilder(null, map.size());
+ for (Map.Entry entry : map.entrySet()) {
+ if (entry.getKey() == null) {
+ throw new TrinoException(INVALID_FUNCTION_ARGUMENT, "hstore key is null");
+ }
+ mapType.getKeyType().writeSlice(keyBlockBuilder, utf8Slice(entry.getKey()));
+ if (entry.getValue() == null) {
+ valueBlockBuilder.appendNull();
+ }
+ else {
+ mapType.getValueType().writeSlice(valueBlockBuilder, utf8Slice(entry.getValue()));
+ }
+ }
+ MapBlock mapBlock = mapType.createBlockFromKeyValue(Optional.empty(), new int[] {0, map.size()},
+ keyBlockBuilder.build(), valueBlockBuilder.build());
+ return mapType.getObject(mapBlock, 0);
+ });
+ }
+
+ private ObjectWriteFunction hstoreWriteFunction(ConnectorSession session)
+ {
+ return ObjectWriteFunction.of(SqlMap.class, (statement, index, sqlMap) -> {
+ int rawOffset = sqlMap.getRawOffset();
+ Block rawKeyBlock = sqlMap.getRawKeyBlock();
+ Block rawValueBlock = sqlMap.getRawValueBlock();
+
+ Type keyType = mapType.getKeyType();
+ Type valueType = mapType.getValueType();
+
+ Map