From 7dcddafa6c89c664871f14b9fb6b1848cbdb9ed9 Mon Sep 17 00:00:00 2001 From: SteNicholas Date: Mon, 17 Jan 2022 18:14:34 +0800 Subject: [PATCH] [KYUUBI #1648] Implement Flink GetTypeInfo operation ### _Why are the changes needed?_ 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 Signed-off-by: Cheng Pan --- .../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(-) create mode 100644 externals/kyuubi-flink-sql-engine/src/main/scala/org/apache/kyuubi/engine/flink/operation/GetTypeInfo.scala 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 ac73ff757..37e8ec826 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 000000000..4748c648e --- /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 049970038..a84f5e39d 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 5088bbbae..16b67ebb1 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 = {