This is an automated email from the ASF dual-hosted git repository. morningman pushed a commit to branch branch-1.2-lts in repository https://gitbox.apache.org/repos/asf/doris.git
commit cb2da2de31bf101e56cc0426d57e28e2e2e1ccea Author: yongkang.zhong <[email protected]> AuthorDate: Wed Mar 22 19:42:32 2023 +0800 [improve](clickhouse jdbc) support clickhouse array type (#17993) In this PR, I match the array type of ClickHouse to the array type of Doris's jdbc external. --- be/src/vec/exec/vjdbc_connector.cpp | 3 +- .../org/apache/doris/external/jdbc/JdbcClient.java | 8 ++++- .../java/org/apache/doris/udf/JdbcExecutor.java | 38 ++++++++++++++++++++-- 3 files changed, 45 insertions(+), 4 deletions(-) diff --git a/be/src/vec/exec/vjdbc_connector.cpp b/be/src/vec/exec/vjdbc_connector.cpp index 8887ad2223..830f4b491f 100644 --- a/be/src/vec/exec/vjdbc_connector.cpp +++ b/be/src/vec/exec/vjdbc_connector.cpp @@ -314,7 +314,8 @@ Status JdbcConnector::_check_type(SlotDescriptor* slot_desc, const std::string& break; } case TYPE_ARRAY: { - if (type_str != "java.sql.Array" && type_str != "java.lang.String") { + if (type_str != "java.sql.Array" && type_str != "java.lang.String" && + type_str != "java.lang.Object") { return Status::InternalError(error_msg); } if (!slot_desc->type().children[0].children.empty()) { diff --git a/fe/fe-core/src/main/java/org/apache/doris/external/jdbc/JdbcClient.java b/fe/fe-core/src/main/java/org/apache/doris/external/jdbc/JdbcClient.java index d3b58f9355..b152d324bc 100644 --- a/fe/fe-core/src/main/java/org/apache/doris/external/jdbc/JdbcClient.java +++ b/fe/fe-core/src/main/java/org/apache/doris/external/jdbc/JdbcClient.java @@ -17,6 +17,7 @@ package org.apache.doris.external.jdbc; +import org.apache.doris.catalog.ArrayType; import org.apache.doris.catalog.Column; import org.apache.doris.catalog.JdbcResource; import org.apache.doris.catalog.PrimitiveType; @@ -577,7 +578,12 @@ public class JdbcClient { || ckType.startsWith("FixedString")) { return ScalarType.createStringType(); } else if (ckType.startsWith("DateTime")) { - return ScalarType.getDefaultDateType(Type.DATETIME); + return ScalarType.createDatetimeV2Type(0); + } else if (ckType.startsWith("Array")) { + String cktype = ckType.substring(6, ckType.length() - 1); + fieldSchema.setDataTypeName(cktype); + Type type = clickhouseTypeToDoris(fieldSchema); + return ArrayType.create(type, true); } switch (ckType) { case "Bool": diff --git a/fe/java-udf/src/main/java/org/apache/doris/udf/JdbcExecutor.java b/fe/java-udf/src/main/java/org/apache/doris/udf/JdbcExecutor.java index 7918cd1142..4b848ef1a0 100644 --- a/fe/java-udf/src/main/java/org/apache/doris/udf/JdbcExecutor.java +++ b/fe/java-udf/src/main/java/org/apache/doris/udf/JdbcExecutor.java @@ -33,6 +33,8 @@ import java.lang.reflect.Array; import java.math.BigDecimal; import java.math.BigInteger; import java.math.RoundingMode; +import java.net.Inet4Address; +import java.net.Inet6Address; import java.net.MalformedURLException; import java.nio.charset.StandardCharsets; import java.sql.Connection; @@ -46,7 +48,11 @@ import java.time.LocalDate; import java.time.LocalDateTime; import java.util.ArrayList; import java.util.Arrays; +import java.util.HashMap; import java.util.List; +import java.util.Map; +import java.util.UUID; +import java.util.function.Function; public class JdbcExecutor { private static final Logger LOG = Logger.getLogger(JdbcExecutor.class); @@ -198,9 +204,37 @@ public class JdbcExecutor { Object[] columnData = (Object[]) obj; if (columnData[idx] instanceof String) { return (String) columnData[idx]; - } else { + } else if (columnData[idx] instanceof java.sql.Array) { return (java.sql.Array) columnData[idx]; - } + } else { + //For the ClickHouse array type, we need the concatenated string after toString + return convertClickHouseArray(columnData[idx]); + } + } + + private static final Map<Class<?>, Function<Object, String>> CK_ARRAY_CONVERTERS = new HashMap<>(); + + static { + CK_ARRAY_CONVERTERS.put(String[].class, res -> Arrays.toString((String[]) res)); + CK_ARRAY_CONVERTERS.put(byte[].class, res -> Arrays.toString((byte[]) res)); + CK_ARRAY_CONVERTERS.put(Byte[].class, res -> Arrays.toString((Byte[]) res)); + CK_ARRAY_CONVERTERS.put(LocalDate[].class, res -> Arrays.toString((LocalDate[]) res)); + CK_ARRAY_CONVERTERS.put(LocalDateTime[].class, res -> Arrays.toString((LocalDateTime[]) res)); + CK_ARRAY_CONVERTERS.put(float[].class, res -> Arrays.toString((float[]) res)); + CK_ARRAY_CONVERTERS.put(double[].class, res -> Arrays.toString((double[]) res)); + CK_ARRAY_CONVERTERS.put(short[].class, res -> Arrays.toString((short[]) res)); + CK_ARRAY_CONVERTERS.put(int[].class, res -> Arrays.toString((int[]) res)); + CK_ARRAY_CONVERTERS.put(long[].class, res -> Arrays.toString((long[]) res)); + CK_ARRAY_CONVERTERS.put(BigInteger[].class, res -> Arrays.toString((BigInteger[]) res)); + CK_ARRAY_CONVERTERS.put(BigDecimal[].class, res -> Arrays.toString((BigDecimal[]) res)); + CK_ARRAY_CONVERTERS.put(Inet4Address[].class, res -> Arrays.toString((Inet4Address[]) res)); + CK_ARRAY_CONVERTERS.put(Inet6Address[].class, res -> Arrays.toString((Inet6Address[]) res)); + CK_ARRAY_CONVERTERS.put(UUID[].class, res -> Arrays.toString((UUID[]) res)); + } + + public static Object convertClickHouseArray(Object obj) { + Function<Object, String> converter = CK_ARRAY_CONVERTERS.get(obj.getClass()); + return converter != null ? converter.apply(obj) : obj; } private void init(String driverUrl, String sql, int batchSize, String driverClass, String jdbcUrl, String jdbcUser, --------------------------------------------------------------------- To unsubscribe, e-mail: [email protected] For additional commands, e-mail: [email protected]
