You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@kyuubi.apache.org by ch...@apache.org on 2022/01/17 10:15:39 UTC

[incubator-kyuubi] branch master updated: [KYUUBI #1648] Implement Flink GetTypeInfo operation

This is an automated email from the ASF dual-hosted git repository.

chengpan pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/incubator-kyuubi.git


The following commit(s) were added to refs/heads/master by this push:
     new 7dcddaf  [KYUUBI #1648] Implement Flink GetTypeInfo operation
7dcddaf is described below

commit 7dcddafa6c89c664871f14b9fb6b1848cbdb9ed9
Author: SteNicholas <pr...@163.com>
AuthorDate: Mon Jan 17 18:14:34 2022 +0800

    [KYUUBI #1648] Implement Flink GetTypeInfo operation
    
    <!--
    Thanks for sending a pull request!
    
    Here are some tips for you:
      1. If this is your first time, please read our contributor guidelines: https://kyuubi.readthedocs.io/en/latest/community/contributions.html
      2. If the PR is related to an issue in https://github.com/apache/incubator-kyuubi/issues, add '[KYUUBI #XXXX]' in your PR title, e.g., '[KYUUBI #XXXX] Your PR title ...'.
      3. If the PR is unfinished, add '[WIP]' in your PR title, e.g., '[WIP][KYUUBI #XXXX] Your PR title ...'.
    -->
    
    ### _Why are the changes needed?_
    <!--
    Please clarify why the changes are needed. For instance,
      1. If you add a feature, you can talk about the use case of it.
      2. If you fix a bug, you can clarify why it is a bug.
    -->
    Implement GetTypeInfo operation.
    
    ### _How was this patch tested?_
    - [ ] Add some test cases that check the changes thoroughly including negative and positive cases if possible
    
    - [ ] Add screenshots for manual tests if appropriate
    
    - [x] [Run test](https://kyuubi.readthedocs.io/en/latest/develop_tools/testing.html#running-tests) locally before make a pull request
    
    Closes #1777 from SteNicholas/KYUUBI-1648.
    
    Closes #1648
    
    1c7c0417 [SteNicholas] [KYUUBI #1648] Implement GetTypeInfo operation
    abdba44c [SteNicholas] [KYUUBI #1648] Implement GetTypeInfo operation
    
    Authored-by: SteNicholas <pr...@163.com>
    Signed-off-by: Cheng Pan <ch...@apache.org>
---
 .../flink/operation/FlinkSQLOperationManager.scala |   5 +-
 .../engine/flink/operation/GetTypeInfo.scala       | 122 +++++++++
 .../flink/operation/FlinkOperationSuite.scala      | 277 ++++++++++++++++++++-
 .../engine/spark/operation/GetTypeInfo.scala       |   2 +-
 4 files changed, 397 insertions(+), 9 deletions(-)

diff --git a/externals/kyuubi-flink-sql-engine/src/main/scala/org/apache/kyuubi/engine/flink/operation/FlinkSQLOperationManager.scala b/externals/kyuubi-flink-sql-engine/src/main/scala/org/apache/kyuubi/engine/flink/operation/FlinkSQLOperationManager.scala
index ac73ff7..37e8ec8 100644
--- a/externals/kyuubi-flink-sql-engine/src/main/scala/org/apache/kyuubi/engine/flink/operation/FlinkSQLOperationManager.scala
+++ b/externals/kyuubi-flink-sql-engine/src/main/scala/org/apache/kyuubi/engine/flink/operation/FlinkSQLOperationManager.scala
@@ -37,7 +37,10 @@ class FlinkSQLOperationManager extends OperationManager("FlinkSQLOperationManage
     addOperation(op)
   }
 
-  override def newGetTypeInfoOperation(session: Session): Operation = null
+  override def newGetTypeInfoOperation(session: Session): Operation = {
+    val op = new GetTypeInfo(session)
+    addOperation(op)
+  }
 
   override def newGetCatalogsOperation(session: Session): Operation = {
     val op = new GetCatalogs(session)
diff --git a/externals/kyuubi-flink-sql-engine/src/main/scala/org/apache/kyuubi/engine/flink/operation/GetTypeInfo.scala b/externals/kyuubi-flink-sql-engine/src/main/scala/org/apache/kyuubi/engine/flink/operation/GetTypeInfo.scala
new file mode 100644
index 0000000..4748c64
--- /dev/null
+++ b/externals/kyuubi-flink-sql-engine/src/main/scala/org/apache/kyuubi/engine/flink/operation/GetTypeInfo.scala
@@ -0,0 +1,122 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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 org.apache.kyuubi.engine.flink.operation
+
+import java.lang
+import java.sql.Types._
+
+import org.apache.flink.table.api.{DataTypes, ResultKind}
+import org.apache.flink.table.catalog.Column
+import org.apache.flink.table.types.logical.LogicalTypeRoot
+import org.apache.flink.types.Row
+
+import org.apache.kyuubi.engine.flink.result.ResultSet
+import org.apache.kyuubi.operation.OperationType
+import org.apache.kyuubi.operation.meta.ResultSetSchemaConstant._
+import org.apache.kyuubi.session.Session
+
+class GetTypeInfo(session: Session)
+  extends FlinkOperation(OperationType.GET_TYPE_INFO, session) {
+
+  private def isNumericType(javaType: Int): Boolean = {
+    javaType == TINYINT || javaType == SMALLINT || javaType == INTEGER || javaType == BIGINT ||
+    javaType == FLOAT || javaType == DOUBLE || javaType == DECIMAL
+  }
+
+  private def toRow(name: String, javaType: Int, precision: Integer = null): Row = {
+    Row.of(
+      name, // TYPE_NAME
+      Integer.valueOf(javaType), // DATA_TYPE
+      precision, // PRECISION
+      null, // LITERAL_PREFIX
+      null, // LITERAL_SUFFIX
+      null, // CREATE_PARAMS
+      lang.Short.valueOf("1"), // NULLABLE
+      lang.Boolean.valueOf(javaType == VARCHAR), // CASE_SENSITIVE
+      if (javaType < 1111) lang.Short.valueOf("3") else lang.Short.valueOf("0"), // SEARCHABLE
+      lang.Boolean.valueOf(!isNumericType(javaType)), // UNSIGNED_ATTRIBUTE
+      lang.Boolean.valueOf(false), // FIXED_PREC_SCALE
+      lang.Boolean.valueOf(false), // AUTO_INCREMENT
+      null, // LOCAL_TYPE_NAME
+      lang.Short.valueOf("1"), // MINIMUM_SCALE
+      lang.Short.valueOf("1"), // MAXIMUM_SCALE
+      null, // SQL_DATA_TYPE
+      null, // SQL_DATETIME_SUB
+      if (isNumericType(javaType)) Integer.valueOf(10) else null // NUM_PREC_RADIX
+    )
+  }
+
+  override protected def runInternal(): Unit = {
+    try {
+      val dataTypes: Array[Row] = Array(
+        toRow(LogicalTypeRoot.CHAR.name(), CHAR),
+        toRow(LogicalTypeRoot.VARCHAR.name(), VARCHAR),
+        toRow(LogicalTypeRoot.BOOLEAN.name(), BOOLEAN),
+        toRow(LogicalTypeRoot.BINARY.name(), BINARY),
+        toRow(LogicalTypeRoot.VARBINARY.name(), VARBINARY),
+        toRow(LogicalTypeRoot.DECIMAL.name(), DECIMAL, 38),
+        toRow(LogicalTypeRoot.TINYINT.name(), TINYINT, 3),
+        toRow(LogicalTypeRoot.SMALLINT.name(), SMALLINT, 5),
+        toRow(LogicalTypeRoot.INTEGER.name(), INTEGER, 10),
+        toRow(LogicalTypeRoot.BIGINT.name(), BIGINT, 19),
+        toRow(LogicalTypeRoot.FLOAT.name(), FLOAT, 7),
+        toRow(LogicalTypeRoot.DOUBLE.name(), DOUBLE, 15),
+        toRow(LogicalTypeRoot.DATE.name(), DATE),
+        toRow(LogicalTypeRoot.TIME_WITHOUT_TIME_ZONE.name(), TIME),
+        toRow(LogicalTypeRoot.TIMESTAMP_WITHOUT_TIME_ZONE.name(), TIMESTAMP),
+        toRow(LogicalTypeRoot.TIMESTAMP_WITH_TIME_ZONE.name(), TIMESTAMP_WITH_TIMEZONE),
+        toRow(LogicalTypeRoot.TIMESTAMP_WITH_LOCAL_TIME_ZONE.name(), TIMESTAMP_WITH_TIMEZONE),
+        toRow(LogicalTypeRoot.INTERVAL_YEAR_MONTH.name(), OTHER),
+        toRow(LogicalTypeRoot.INTERVAL_DAY_TIME.name(), OTHER),
+        toRow(LogicalTypeRoot.ARRAY.name(), ARRAY),
+        toRow(LogicalTypeRoot.MULTISET.name(), JAVA_OBJECT),
+        toRow(LogicalTypeRoot.MAP.name(), JAVA_OBJECT),
+        toRow(LogicalTypeRoot.ROW.name(), JAVA_OBJECT),
+        toRow(LogicalTypeRoot.DISTINCT_TYPE.name(), OTHER),
+        toRow(LogicalTypeRoot.STRUCTURED_TYPE.name(), OTHER),
+        toRow(LogicalTypeRoot.NULL.name(), NULL),
+        toRow(LogicalTypeRoot.RAW.name(), OTHER),
+        toRow(LogicalTypeRoot.SYMBOL.name(), OTHER),
+        toRow(LogicalTypeRoot.UNRESOLVED.name(), OTHER))
+      resultSet = ResultSet.builder.resultKind(ResultKind.SUCCESS_WITH_CONTENT)
+        .columns(
+          Column.physical(TYPE_NAME, DataTypes.STRING()),
+          Column.physical(DATA_TYPE, DataTypes.INT()),
+          Column.physical(PRECISION, DataTypes.INT()),
+          Column.physical("LITERAL_PREFIX", DataTypes.STRING()),
+          Column.physical("LITERAL_SUFFIX", DataTypes.STRING()),
+          Column.physical("CREATE_PARAMS", DataTypes.STRING()),
+          Column.physical(NULLABLE, DataTypes.SMALLINT()),
+          Column.physical(CASE_SENSITIVE, DataTypes.BOOLEAN()),
+          Column.physical(SEARCHABLE, DataTypes.SMALLINT()),
+          Column.physical("UNSIGNED_ATTRIBUTE", DataTypes.BOOLEAN()),
+          Column.physical("FIXED_PREC_SCALE", DataTypes.BOOLEAN()),
+          Column.physical("AUTO_INCREMENT", DataTypes.BOOLEAN()),
+          Column.physical("LOCAL_TYPE_NAME", DataTypes.STRING()),
+          Column.physical("MINIMUM_SCALE", DataTypes.SMALLINT()),
+          Column.physical("MAXIMUM_SCALE", DataTypes.SMALLINT()),
+          Column.physical(SQL_DATA_TYPE, DataTypes.INT()),
+          Column.physical(SQL_DATETIME_SUB, DataTypes.INT()),
+          Column.physical(NUM_PREC_RADIX, DataTypes.INT()))
+        .data(dataTypes)
+        .build
+    } catch {
+      onError()
+    }
+  }
+}
diff --git a/externals/kyuubi-flink-sql-engine/src/test/scala/org/apache/kyuubi/engine/flink/operation/FlinkOperationSuite.scala b/externals/kyuubi-flink-sql-engine/src/test/scala/org/apache/kyuubi/engine/flink/operation/FlinkOperationSuite.scala
index 0499700..a84f5e3 100644
--- a/externals/kyuubi-flink-sql-engine/src/test/scala/org/apache/kyuubi/engine/flink/operation/FlinkOperationSuite.scala
+++ b/externals/kyuubi-flink-sql-engine/src/test/scala/org/apache/kyuubi/engine/flink/operation/FlinkOperationSuite.scala
@@ -19,19 +19,14 @@ package org.apache.kyuubi.engine.flink.operation
 
 import org.apache.flink.table.api.EnvironmentSettings.DEFAULT_BUILTIN_CATALOG
 import org.apache.flink.table.api.EnvironmentSettings.DEFAULT_BUILTIN_DATABASE
+import org.apache.flink.table.types.logical.LogicalTypeRoot
 import org.scalatest.concurrent.PatienceConfiguration.Timeout
 import org.scalatest.time.SpanSugar._
 
 import org.apache.kyuubi.engine.flink.WithFlinkSQLEngine
 import org.apache.kyuubi.engine.flink.result.Constants
 import org.apache.kyuubi.operation.HiveJDBCTestHelper
-import org.apache.kyuubi.operation.meta.ResultSetSchemaConstant.FUNCTION_CAT
-import org.apache.kyuubi.operation.meta.ResultSetSchemaConstant.FUNCTION_NAME
-import org.apache.kyuubi.operation.meta.ResultSetSchemaConstant.FUNCTION_SCHEM
-import org.apache.kyuubi.operation.meta.ResultSetSchemaConstant.TABLE_CAT
-import org.apache.kyuubi.operation.meta.ResultSetSchemaConstant.TABLE_CATALOG
-import org.apache.kyuubi.operation.meta.ResultSetSchemaConstant.TABLE_SCHEM
-import org.apache.kyuubi.operation.meta.ResultSetSchemaConstant.TABLE_TYPE
+import org.apache.kyuubi.operation.meta.ResultSetSchemaConstant._
 import org.apache.kyuubi.service.ServiceState._
 
 class FlinkOperationSuite extends WithFlinkSQLEngine with HiveJDBCTestHelper {
@@ -62,6 +57,274 @@ class FlinkOperationSuite extends WithFlinkSQLEngine with HiveJDBCTestHelper {
     }
   }
 
+  test("get type info") {
+    withJdbcStatement() { statement =>
+      val typeInfo = statement.getConnection.getMetaData.getTypeInfo
+
+      typeInfo.next()
+      assert(typeInfo.getString(TYPE_NAME) === LogicalTypeRoot.CHAR.name())
+      assert(typeInfo.getInt(DATA_TYPE) === java.sql.Types.CHAR)
+      assert(typeInfo.getInt(PRECISION) === 0)
+      assert(typeInfo.getShort(NULLABLE) === 1)
+      assert(!typeInfo.getBoolean(CASE_SENSITIVE))
+      assert(typeInfo.getShort(SEARCHABLE) === 3)
+      assert(typeInfo.getInt(NUM_PREC_RADIX) === 0)
+
+      typeInfo.next()
+      assert(typeInfo.getString(TYPE_NAME) === LogicalTypeRoot.VARCHAR.name())
+      assert(typeInfo.getInt(DATA_TYPE) === java.sql.Types.VARCHAR)
+      assert(typeInfo.getInt(PRECISION) === 0)
+      assert(typeInfo.getShort(NULLABLE) === 1)
+      assert(typeInfo.getBoolean(CASE_SENSITIVE))
+      assert(typeInfo.getShort(SEARCHABLE) === 3)
+      assert(typeInfo.getInt(NUM_PREC_RADIX) === 0)
+
+      typeInfo.next()
+      assert(typeInfo.getString(TYPE_NAME) === LogicalTypeRoot.BOOLEAN.name())
+      assert(typeInfo.getInt(DATA_TYPE) === java.sql.Types.BOOLEAN)
+      assert(typeInfo.getInt(PRECISION) === 0)
+      assert(typeInfo.getShort(NULLABLE) === 1)
+      assert(!typeInfo.getBoolean(CASE_SENSITIVE))
+      assert(typeInfo.getShort(SEARCHABLE) === 3)
+      assert(typeInfo.getInt(NUM_PREC_RADIX) === 0)
+
+      typeInfo.next()
+      assert(typeInfo.getString(TYPE_NAME) === LogicalTypeRoot.BINARY.name())
+      assert(typeInfo.getInt(DATA_TYPE) === java.sql.Types.BINARY)
+      assert(typeInfo.getInt(PRECISION) === 0)
+      assert(typeInfo.getShort(NULLABLE) === 1)
+      assert(!typeInfo.getBoolean(CASE_SENSITIVE))
+      assert(typeInfo.getShort(SEARCHABLE) === 3)
+      assert(typeInfo.getInt(NUM_PREC_RADIX) === 0)
+
+      typeInfo.next()
+      assert(typeInfo.getString(TYPE_NAME) === LogicalTypeRoot.VARBINARY.name())
+      assert(typeInfo.getInt(DATA_TYPE) === java.sql.Types.VARBINARY)
+      assert(typeInfo.getInt(PRECISION) === 0)
+      assert(typeInfo.getShort(NULLABLE) === 1)
+      assert(!typeInfo.getBoolean(CASE_SENSITIVE))
+      assert(typeInfo.getShort(SEARCHABLE) === 3)
+      assert(typeInfo.getInt(NUM_PREC_RADIX) === 0)
+
+      typeInfo.next()
+      assert(typeInfo.getString(TYPE_NAME) === LogicalTypeRoot.DECIMAL.name())
+      assert(typeInfo.getInt(DATA_TYPE) === java.sql.Types.DECIMAL)
+      assert(typeInfo.getInt(PRECISION) === 38)
+      assert(typeInfo.getShort(NULLABLE) === 1)
+      assert(!typeInfo.getBoolean(CASE_SENSITIVE))
+      assert(typeInfo.getShort(SEARCHABLE) === 3)
+      assert(typeInfo.getInt(NUM_PREC_RADIX) === 10)
+
+      typeInfo.next()
+      assert(typeInfo.getString(TYPE_NAME) === LogicalTypeRoot.TINYINT.name())
+      assert(typeInfo.getInt(DATA_TYPE) === java.sql.Types.TINYINT)
+      assert(typeInfo.getInt(PRECISION) === 3)
+      assert(typeInfo.getShort(NULLABLE) === 1)
+      assert(!typeInfo.getBoolean(CASE_SENSITIVE))
+      assert(typeInfo.getShort(SEARCHABLE) === 3)
+      assert(typeInfo.getInt(NUM_PREC_RADIX) === 10)
+
+      typeInfo.next()
+      assert(typeInfo.getString(TYPE_NAME) === LogicalTypeRoot.SMALLINT.name())
+      assert(typeInfo.getInt(DATA_TYPE) === java.sql.Types.SMALLINT)
+      assert(typeInfo.getInt(PRECISION) === 5)
+      assert(typeInfo.getShort(NULLABLE) === 1)
+      assert(!typeInfo.getBoolean(CASE_SENSITIVE))
+      assert(typeInfo.getShort(SEARCHABLE) === 3)
+      assert(typeInfo.getInt(NUM_PREC_RADIX) === 10)
+
+      typeInfo.next()
+      assert(typeInfo.getString(TYPE_NAME) === LogicalTypeRoot.INTEGER.name())
+      assert(typeInfo.getInt(DATA_TYPE) === java.sql.Types.INTEGER)
+      assert(typeInfo.getInt(PRECISION) === 10)
+      assert(typeInfo.getShort(NULLABLE) === 1)
+      assert(!typeInfo.getBoolean(CASE_SENSITIVE))
+      assert(typeInfo.getShort(SEARCHABLE) === 3)
+      assert(typeInfo.getInt(NUM_PREC_RADIX) === 10)
+
+      typeInfo.next()
+      assert(typeInfo.getString(TYPE_NAME) === LogicalTypeRoot.BIGINT.name())
+      assert(typeInfo.getInt(DATA_TYPE) === java.sql.Types.BIGINT)
+      assert(typeInfo.getInt(PRECISION) === 19)
+      assert(typeInfo.getShort(NULLABLE) === 1)
+      assert(!typeInfo.getBoolean(CASE_SENSITIVE))
+      assert(typeInfo.getShort(SEARCHABLE) === 3)
+      assert(typeInfo.getInt(NUM_PREC_RADIX) === 10)
+
+      typeInfo.next()
+      assert(typeInfo.getString(TYPE_NAME) === LogicalTypeRoot.FLOAT.name())
+      assert(typeInfo.getInt(DATA_TYPE) === java.sql.Types.FLOAT)
+      assert(typeInfo.getInt(PRECISION) === 7)
+      assert(typeInfo.getShort(NULLABLE) === 1)
+      assert(!typeInfo.getBoolean(CASE_SENSITIVE))
+      assert(typeInfo.getShort(SEARCHABLE) === 3)
+      assert(typeInfo.getInt(NUM_PREC_RADIX) === 10)
+
+      typeInfo.next()
+      assert(typeInfo.getString(TYPE_NAME) === LogicalTypeRoot.DOUBLE.name())
+      assert(typeInfo.getInt(DATA_TYPE) === java.sql.Types.DOUBLE)
+      assert(typeInfo.getInt(PRECISION) === 15)
+      assert(typeInfo.getShort(NULLABLE) === 1)
+      assert(!typeInfo.getBoolean(CASE_SENSITIVE))
+      assert(typeInfo.getShort(SEARCHABLE) === 3)
+      assert(typeInfo.getInt(NUM_PREC_RADIX) === 10)
+
+      typeInfo.next()
+      assert(typeInfo.getString(TYPE_NAME) === LogicalTypeRoot.DATE.name())
+      assert(typeInfo.getInt(DATA_TYPE) === java.sql.Types.DATE)
+      assert(typeInfo.getInt(PRECISION) === 0)
+      assert(typeInfo.getShort(NULLABLE) === 1)
+      assert(!typeInfo.getBoolean(CASE_SENSITIVE))
+      assert(typeInfo.getShort(SEARCHABLE) === 3)
+      assert(typeInfo.getInt(NUM_PREC_RADIX) === 0)
+
+      typeInfo.next()
+      assert(typeInfo.getString(TYPE_NAME) === LogicalTypeRoot.TIME_WITHOUT_TIME_ZONE.name())
+      assert(typeInfo.getInt(DATA_TYPE) === java.sql.Types.TIME)
+      assert(typeInfo.getInt(PRECISION) === 0)
+      assert(typeInfo.getShort(NULLABLE) === 1)
+      assert(!typeInfo.getBoolean(CASE_SENSITIVE))
+      assert(typeInfo.getShort(SEARCHABLE) === 3)
+      assert(typeInfo.getInt(NUM_PREC_RADIX) === 0)
+
+      typeInfo.next()
+      assert(typeInfo.getString(TYPE_NAME) === LogicalTypeRoot.TIMESTAMP_WITHOUT_TIME_ZONE.name())
+      assert(typeInfo.getInt(DATA_TYPE) === java.sql.Types.TIMESTAMP)
+      assert(typeInfo.getInt(PRECISION) === 0)
+      assert(typeInfo.getShort(NULLABLE) === 1)
+      assert(!typeInfo.getBoolean(CASE_SENSITIVE))
+      assert(typeInfo.getShort(SEARCHABLE) === 3)
+      assert(typeInfo.getInt(NUM_PREC_RADIX) === 0)
+
+      typeInfo.next()
+      assert(typeInfo.getString(TYPE_NAME) === LogicalTypeRoot.TIMESTAMP_WITH_TIME_ZONE.name())
+      assert(typeInfo.getInt(DATA_TYPE) === java.sql.Types.TIMESTAMP_WITH_TIMEZONE)
+      assert(typeInfo.getInt(PRECISION) === 0)
+      assert(typeInfo.getShort(NULLABLE) === 1)
+      assert(!typeInfo.getBoolean(CASE_SENSITIVE))
+      assert(typeInfo.getShort(SEARCHABLE) === 0)
+      assert(typeInfo.getInt(NUM_PREC_RADIX) === 0)
+
+      typeInfo.next()
+      assert(
+        typeInfo.getString(TYPE_NAME) === LogicalTypeRoot.TIMESTAMP_WITH_LOCAL_TIME_ZONE.name())
+      assert(typeInfo.getInt(DATA_TYPE) === java.sql.Types.TIMESTAMP_WITH_TIMEZONE)
+      assert(typeInfo.getInt(PRECISION) === 0)
+      assert(typeInfo.getShort(NULLABLE) === 1)
+      assert(!typeInfo.getBoolean(CASE_SENSITIVE))
+      assert(typeInfo.getShort(SEARCHABLE) === 0)
+      assert(typeInfo.getInt(NUM_PREC_RADIX) === 0)
+
+      typeInfo.next()
+      assert(typeInfo.getString(TYPE_NAME) === LogicalTypeRoot.INTERVAL_YEAR_MONTH.name())
+      assert(typeInfo.getInt(DATA_TYPE) === java.sql.Types.OTHER)
+      assert(typeInfo.getInt(PRECISION) === 0)
+      assert(typeInfo.getShort(NULLABLE) === 1)
+      assert(!typeInfo.getBoolean(CASE_SENSITIVE))
+      assert(typeInfo.getShort(SEARCHABLE) === 0)
+      assert(typeInfo.getInt(NUM_PREC_RADIX) === 0)
+
+      typeInfo.next()
+      assert(typeInfo.getString(TYPE_NAME) === LogicalTypeRoot.INTERVAL_DAY_TIME.name())
+      assert(typeInfo.getInt(DATA_TYPE) === java.sql.Types.OTHER)
+      assert(typeInfo.getInt(PRECISION) === 0)
+      assert(typeInfo.getShort(NULLABLE) === 1)
+      assert(!typeInfo.getBoolean(CASE_SENSITIVE))
+      assert(typeInfo.getShort(SEARCHABLE) === 0)
+      assert(typeInfo.getInt(NUM_PREC_RADIX) === 0)
+
+      typeInfo.next()
+      assert(typeInfo.getString(TYPE_NAME) === LogicalTypeRoot.ARRAY.name())
+      assert(typeInfo.getInt(DATA_TYPE) === java.sql.Types.ARRAY)
+      assert(typeInfo.getInt(PRECISION) === 0)
+      assert(typeInfo.getShort(NULLABLE) === 1)
+      assert(!typeInfo.getBoolean(CASE_SENSITIVE))
+      assert(typeInfo.getShort(SEARCHABLE) === 0)
+      assert(typeInfo.getInt(NUM_PREC_RADIX) === 0)
+
+      typeInfo.next()
+      assert(typeInfo.getString(TYPE_NAME) === LogicalTypeRoot.MULTISET.name())
+      assert(typeInfo.getInt(DATA_TYPE) === java.sql.Types.JAVA_OBJECT)
+      assert(typeInfo.getInt(PRECISION) === 0)
+      assert(typeInfo.getShort(NULLABLE) === 1)
+      assert(!typeInfo.getBoolean(CASE_SENSITIVE))
+      assert(typeInfo.getShort(SEARCHABLE) === 0)
+      assert(typeInfo.getInt(NUM_PREC_RADIX) === 0)
+
+      typeInfo.next()
+      assert(typeInfo.getString(TYPE_NAME) === LogicalTypeRoot.MAP.name())
+      assert(typeInfo.getInt(DATA_TYPE) === java.sql.Types.JAVA_OBJECT)
+      assert(typeInfo.getInt(PRECISION) === 0)
+      assert(typeInfo.getShort(NULLABLE) === 1)
+      assert(!typeInfo.getBoolean(CASE_SENSITIVE))
+      assert(typeInfo.getShort(SEARCHABLE) === 0)
+      assert(typeInfo.getInt(NUM_PREC_RADIX) === 0)
+
+      typeInfo.next()
+      assert(typeInfo.getString(TYPE_NAME) === LogicalTypeRoot.ROW.name())
+      assert(typeInfo.getInt(DATA_TYPE) === java.sql.Types.JAVA_OBJECT)
+      assert(typeInfo.getInt(PRECISION) === 0)
+      assert(typeInfo.getShort(NULLABLE) === 1)
+      assert(!typeInfo.getBoolean(CASE_SENSITIVE))
+      assert(typeInfo.getShort(SEARCHABLE) === 0)
+      assert(typeInfo.getInt(NUM_PREC_RADIX) === 0)
+
+      typeInfo.next()
+      assert(typeInfo.getString(TYPE_NAME) === LogicalTypeRoot.DISTINCT_TYPE.name())
+      assert(typeInfo.getInt(DATA_TYPE) === java.sql.Types.OTHER)
+      assert(typeInfo.getInt(PRECISION) === 0)
+      assert(typeInfo.getShort(NULLABLE) === 1)
+      assert(!typeInfo.getBoolean(CASE_SENSITIVE))
+      assert(typeInfo.getShort(SEARCHABLE) === 0)
+      assert(typeInfo.getInt(NUM_PREC_RADIX) === 0)
+
+      typeInfo.next()
+      assert(typeInfo.getString(TYPE_NAME) === LogicalTypeRoot.STRUCTURED_TYPE.name())
+      assert(typeInfo.getInt(DATA_TYPE) === java.sql.Types.OTHER)
+      assert(typeInfo.getInt(PRECISION) === 0)
+      assert(typeInfo.getShort(NULLABLE) === 1)
+      assert(!typeInfo.getBoolean(CASE_SENSITIVE))
+      assert(typeInfo.getShort(SEARCHABLE) === 0)
+      assert(typeInfo.getInt(NUM_PREC_RADIX) === 0)
+
+      typeInfo.next()
+      assert(typeInfo.getString(TYPE_NAME) === LogicalTypeRoot.NULL.name())
+      assert(typeInfo.getInt(DATA_TYPE) === java.sql.Types.NULL)
+      assert(typeInfo.getInt(PRECISION) === 0)
+      assert(typeInfo.getShort(NULLABLE) === 1)
+      assert(!typeInfo.getBoolean(CASE_SENSITIVE))
+      assert(typeInfo.getShort(SEARCHABLE) === 3)
+      assert(typeInfo.getInt(NUM_PREC_RADIX) === 0)
+
+      typeInfo.next()
+      assert(typeInfo.getString(TYPE_NAME) === LogicalTypeRoot.RAW.name())
+      assert(typeInfo.getInt(DATA_TYPE) === java.sql.Types.OTHER)
+      assert(typeInfo.getInt(PRECISION) === 0)
+      assert(typeInfo.getShort(NULLABLE) === 1)
+      assert(!typeInfo.getBoolean(CASE_SENSITIVE))
+      assert(typeInfo.getShort(SEARCHABLE) === 0)
+      assert(typeInfo.getInt(NUM_PREC_RADIX) === 0)
+
+      typeInfo.next()
+      assert(typeInfo.getString(TYPE_NAME) === LogicalTypeRoot.SYMBOL.name())
+      assert(typeInfo.getInt(DATA_TYPE) === java.sql.Types.OTHER)
+      assert(typeInfo.getInt(PRECISION) === 0)
+      assert(typeInfo.getShort(NULLABLE) === 1)
+      assert(!typeInfo.getBoolean(CASE_SENSITIVE))
+      assert(typeInfo.getShort(SEARCHABLE) === 0)
+      assert(typeInfo.getInt(NUM_PREC_RADIX) === 0)
+
+      typeInfo.next()
+      assert(typeInfo.getString(TYPE_NAME) === LogicalTypeRoot.UNRESOLVED.name())
+      assert(typeInfo.getInt(DATA_TYPE) === java.sql.Types.OTHER)
+      assert(typeInfo.getInt(PRECISION) === 0)
+      assert(typeInfo.getShort(NULLABLE) === 1)
+      assert(!typeInfo.getBoolean(CASE_SENSITIVE))
+      assert(typeInfo.getShort(SEARCHABLE) === 0)
+      assert(typeInfo.getInt(NUM_PREC_RADIX) === 0)
+    }
+  }
+
   test("get schemas") {
     withJdbcStatement() { statement =>
       val metaData = statement.getConnection.getMetaData
diff --git a/externals/kyuubi-spark-sql-engine/src/main/scala/org/apache/kyuubi/engine/spark/operation/GetTypeInfo.scala b/externals/kyuubi-spark-sql-engine/src/main/scala/org/apache/kyuubi/engine/spark/operation/GetTypeInfo.scala
index 5088bbb..16b67eb 100644
--- a/externals/kyuubi-spark-sql-engine/src/main/scala/org/apache/kyuubi/engine/spark/operation/GetTypeInfo.scala
+++ b/externals/kyuubi-spark-sql-engine/src/main/scala/org/apache/kyuubi/engine/spark/operation/GetTypeInfo.scala
@@ -77,7 +77,7 @@ class GetTypeInfo(session: Session)
 
   private def isNumericType(javaType: Int): Boolean = {
     javaType == TINYINT || javaType == SMALLINT || javaType == INTEGER || javaType == BIGINT ||
-    javaType == FLOAT || javaType == FLOAT || javaType == DOUBLE || javaType == DECIMAL
+    javaType == FLOAT || javaType == DOUBLE || javaType == DECIMAL
   }
 
   private def toRow(name: String, javaType: Int, precision: Integer = null): Row = {