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/kyuubi.git
The following commit(s) were added to refs/heads/master by this push:
new 9f53a09d5 [KYUUBI #5509] Add Apache Impala JDBC engine dialect
9f53a09d5 is described below
commit 9f53a09d5830801c4f3215a2e210812d1de8ef5d
Author: Tigran Manasyan <[email protected]>
AuthorDate: Thu Feb 29 19:57:14 2024 +0800
[KYUUBI #5509] Add Apache Impala JDBC engine dialect
# :mag: Description
## Issue References ๐
This pull request fixes #5509
## Describe Your Solution ๐ง
Added [Apache Impala](https://impala.apache.org) support in the form of the
JDBC engine dialect. Slightly modified Kyuubi Hive JDBC driver in order to use
it as driver for Impala dialect instead of the original Hive driver.
## Types of changes :bookmark:
- [ ] Bugfix (non-breaking change which fixes an issue)
- [x] New feature (non-breaking change which adds functionality)
- [ ] Breaking change (fix or feature that would cause existing
functionality to change)
## Test Plan ๐งช
#### Related Unit Tests
- `org.apache.kyuubi.engine.jdbc.impala.OperationWithImpalaEngineSuite`
- `org.apache.kyuubi.engine.jdbc.impala.SessionSuite`
- `org.apache.kyuubi.engine.jdbc.impala.StatementSuite`
#### Related Integration Tests
- `org.apache.kyuubi.it.jdbc.impala.OperationWithServerSuite`
- `org.apache.kyuubi.it.jdbc.impala.SessionWithServerSuite`
- `org.apache.kyuubi.it.jdbc.impala.StatementWithServerSuite`
---
# Checklist ๐
- [x] This patch was not authored or co-authored using [Generative
Tooling](https://www.apache.org/legal/generative-tooling.html)
**Be nice. Be informative.**
Closes #6104 from tigrulya-exe/feature/5509-support-impala-jdbc-dialect.
Closes #5509
32ae6d846 [Tigran Manasyan] Codestyle fixes
985212561 [Tigran Manasyan] fix review comments
ecb0d7dca [Tigran Manasyan] copy impala compose file to integration tests
resources
5ea347430 [Tigran Manasyan] fix order in services file
2c63a7003 [Tigran Manasyan] Add Apache Impala JDBC engine dialect
Authored-by: Tigran Manasyan <[email protected]>
Signed-off-by: Cheng Pan <[email protected]>
---
...i.engine.jdbc.connection.JdbcConnectionProvider | 1 +
...g.apache.kyuubi.engine.jdbc.dialect.JdbcDialect | 1 +
.../jdbc/connection/JdbcConnectionProvider.scala | 4 +-
.../kyuubi/engine/jdbc/dialect/ImpalaDialect.scala | 95 ++++++++++++++++++
.../ImpalaConnectionProvider.scala} | 19 ++--
.../ImpalaSchemaHelper.scala} | 19 ++--
.../ImpalaTRowSetGenerator.scala} | 21 ++--
.../jdbc/mysql/MySQL8ConnectionProvider.scala | 5 -
.../engine/jdbc/operation/ExecuteStatement.scala | 5 +-
.../jdbc/phoenix/PhoenixConnectionProvider.scala | 5 -
.../postgresql/PostgreSQLConnectionProvider.scala | 4 -
.../jdbc/schema/DefaultJdbcTRowSetGenerator.scala | 16 +++
.../kyuubi/engine/jdbc/schema/SchemaHelper.scala | 14 +++
.../src/test/resources/impala-compose.yml | 82 ++++++++++++++++
.../src/test/resources/impala_conf/hive-site.xml | 72 ++++++++++++++
.../kyuubi/engine/jdbc/impala/DialectSuite.scala | 106 ++++++++++++++++++++
.../engine/jdbc/impala/ImpalaOperationSuite.scala | 108 +++++++++++++++++++++
.../impala/OperationWithImpalaEngineSuite.scala | 51 ++++++++++
.../kyuubi/engine/jdbc/impala/SessionSuite.scala} | 26 +++--
.../kyuubi/engine/jdbc/impala/StatementSuite.scala | 106 ++++++++++++++++++++
.../engine/jdbc/impala/WithImpalaContainer.scala | 68 +++++++++++++
.../engine/jdbc/impala/WithImpalaEngine.scala} | 21 ++--
integration-tests/kyuubi-jdbc-it/pom.xml | 7 ++
.../src/test/resources/impala-compose.yml | 82 ++++++++++++++++
.../src/test/resources/impala_conf/hive-site.xml | 72 ++++++++++++++
.../it/jdbc/impala/OperationWithServerSuite.scala | 14 +--
.../it/jdbc/impala/SessionWithServerSuite.scala | 14 +--
.../it/jdbc/impala/StatementWithServerSuite.scala | 14 +--
.../WithKyuubiServerAndImpalaContainer.scala | 59 +++++++++++
.../org/apache/kyuubi/KyuubiSQLException.scala | 4 +-
30 files changed, 1019 insertions(+), 96 deletions(-)
diff --git
a/externals/kyuubi-jdbc-engine/src/main/resources/META-INF/services/org.apache.kyuubi.engine.jdbc.connection.JdbcConnectionProvider
b/externals/kyuubi-jdbc-engine/src/main/resources/META-INF/services/org.apache.kyuubi.engine.jdbc.connection.JdbcConnectionProvider
index 0d8a2c58e..ddb5edfd8 100644
---
a/externals/kyuubi-jdbc-engine/src/main/resources/META-INF/services/org.apache.kyuubi.engine.jdbc.connection.JdbcConnectionProvider
+++
b/externals/kyuubi-jdbc-engine/src/main/resources/META-INF/services/org.apache.kyuubi.engine.jdbc.connection.JdbcConnectionProvider
@@ -16,6 +16,7 @@
#
org.apache.kyuubi.engine.jdbc.doris.DorisConnectionProvider
+org.apache.kyuubi.engine.jdbc.impala.ImpalaConnectionProvider
org.apache.kyuubi.engine.jdbc.mysql.MySQLConnectionProvider
org.apache.kyuubi.engine.jdbc.phoenix.PhoenixConnectionProvider
org.apache.kyuubi.engine.jdbc.postgresql.PostgreSQLConnectionProvider
diff --git
a/externals/kyuubi-jdbc-engine/src/main/resources/META-INF/services/org.apache.kyuubi.engine.jdbc.dialect.JdbcDialect
b/externals/kyuubi-jdbc-engine/src/main/resources/META-INF/services/org.apache.kyuubi.engine.jdbc.dialect.JdbcDialect
index c5a75ec9c..df3adc309 100644
---
a/externals/kyuubi-jdbc-engine/src/main/resources/META-INF/services/org.apache.kyuubi.engine.jdbc.dialect.JdbcDialect
+++
b/externals/kyuubi-jdbc-engine/src/main/resources/META-INF/services/org.apache.kyuubi.engine.jdbc.dialect.JdbcDialect
@@ -16,6 +16,7 @@
#
org.apache.kyuubi.engine.jdbc.dialect.DorisDialect
+org.apache.kyuubi.engine.jdbc.dialect.ImpalaDialect
org.apache.kyuubi.engine.jdbc.dialect.MySQLDialect
org.apache.kyuubi.engine.jdbc.dialect.PhoenixDialect
org.apache.kyuubi.engine.jdbc.dialect.PostgreSQLDialect
diff --git
a/externals/kyuubi-jdbc-engine/src/main/scala/org/apache/kyuubi/engine/jdbc/connection/JdbcConnectionProvider.scala
b/externals/kyuubi-jdbc-engine/src/main/scala/org/apache/kyuubi/engine/jdbc/connection/JdbcConnectionProvider.scala
index d6ff316ab..e247aa394 100644
---
a/externals/kyuubi-jdbc-engine/src/main/scala/org/apache/kyuubi/engine/jdbc/connection/JdbcConnectionProvider.scala
+++
b/externals/kyuubi-jdbc-engine/src/main/scala/org/apache/kyuubi/engine/jdbc/connection/JdbcConnectionProvider.scala
@@ -30,7 +30,9 @@ abstract class JdbcConnectionProvider extends
SupportServiceLoader with Logging
val driverClass: String
- def canHandle(providerClass: String): Boolean
+ def canHandle(providerClass: String): Boolean = {
+ driverClass.equalsIgnoreCase(providerClass)
+ }
def getConnection(kyuubiConf: KyuubiConf): Connection = {
val properties = new Properties()
diff --git
a/externals/kyuubi-jdbc-engine/src/main/scala/org/apache/kyuubi/engine/jdbc/dialect/ImpalaDialect.scala
b/externals/kyuubi-jdbc-engine/src/main/scala/org/apache/kyuubi/engine/jdbc/dialect/ImpalaDialect.scala
new file mode 100644
index 000000000..2c08655ad
--- /dev/null
+++
b/externals/kyuubi-jdbc-engine/src/main/scala/org/apache/kyuubi/engine/jdbc/dialect/ImpalaDialect.scala
@@ -0,0 +1,95 @@
+/*
+ * 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.jdbc.dialect
+
+import java.util
+
+import org.apache.commons.lang3.StringUtils
+
+import org.apache.kyuubi.KyuubiSQLException
+import org.apache.kyuubi.engine.jdbc.impala.{ImpalaSchemaHelper,
ImpalaTRowSetGenerator}
+import org.apache.kyuubi.engine.jdbc.schema.{JdbcTRowSetGenerator,
SchemaHelper}
+import org.apache.kyuubi.session.Session
+
+class ImpalaDialect extends JdbcDialect {
+
+ override def getTablesQuery(
+ catalog: String,
+ schema: String,
+ tableName: String,
+ tableTypes: util.List[String]): String = {
+ if (isPattern(schema)) {
+ throw KyuubiSQLException.featureNotSupported("Pattern-like schema names
not supported")
+ }
+
+ val query = new StringBuilder("show tables ")
+
+ if (StringUtils.isNotEmpty(schema) && !isWildcardSetByKyuubi(schema)) {
+ query.append(s"in $schema ")
+ }
+
+ if (StringUtils.isNotEmpty(tableName)) {
+ query.append(s"like '${toImpalaRegex(tableName)}'")
+ }
+
+ query.toString()
+ }
+
+ override def getColumnsQuery(
+ session: Session,
+ catalogName: String,
+ schemaName: String,
+ tableName: String,
+ columnName: String): String = {
+ if (StringUtils.isEmpty(tableName)) {
+ throw KyuubiSQLException("Table name should not be empty")
+ }
+
+ if (isPattern(schemaName)) {
+ throw KyuubiSQLException.featureNotSupported("Pattern-like schema names
not supported")
+ }
+
+ if (isPattern(tableName)) {
+ throw KyuubiSQLException.featureNotSupported("Pattern-like table names
not supported")
+ }
+
+ val query = new StringBuilder("show column stats ")
+
+ if (StringUtils.isNotEmpty(schemaName) &&
!isWildcardSetByKyuubi(schemaName)) {
+ query.append(s"$schemaName.")
+ }
+
+ query.append(tableName)
+ query.toString()
+ }
+
+ override def getTRowSetGenerator(): JdbcTRowSetGenerator = new
ImpalaTRowSetGenerator
+
+ override def getSchemaHelper(): SchemaHelper = new ImpalaSchemaHelper
+
+ override def name(): String = "impala"
+
+ private def isPattern(value: String): Boolean = {
+ value != null && !isWildcardSetByKyuubi(value) && value.contains("*")
+ }
+
+ private def isWildcardSetByKyuubi(pattern: String): Boolean = pattern == "%"
+
+ private def toImpalaRegex(pattern: String): String = {
+ pattern.replace("%", "*")
+ }
+}
diff --git
a/externals/kyuubi-jdbc-engine/src/main/scala/org/apache/kyuubi/engine/jdbc/mysql/MySQL8ConnectionProvider.scala
b/externals/kyuubi-jdbc-engine/src/main/scala/org/apache/kyuubi/engine/jdbc/impala/ImpalaConnectionProvider.scala
similarity index 66%
copy from
externals/kyuubi-jdbc-engine/src/main/scala/org/apache/kyuubi/engine/jdbc/mysql/MySQL8ConnectionProvider.scala
copy to
externals/kyuubi-jdbc-engine/src/main/scala/org/apache/kyuubi/engine/jdbc/impala/ImpalaConnectionProvider.scala
index f96dff107..232d723fb 100644
---
a/externals/kyuubi-jdbc-engine/src/main/scala/org/apache/kyuubi/engine/jdbc/mysql/MySQL8ConnectionProvider.scala
+++
b/externals/kyuubi-jdbc-engine/src/main/scala/org/apache/kyuubi/engine/jdbc/impala/ImpalaConnectionProvider.scala
@@ -14,22 +14,19 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-package org.apache.kyuubi.engine.jdbc.mysql
+package org.apache.kyuubi.engine.jdbc.impala
import org.apache.kyuubi.engine.jdbc.connection.JdbcConnectionProvider
-class MySQL8ConnectionProvider extends JdbcConnectionProvider {
+class ImpalaConnectionProvider extends JdbcConnectionProvider {
- override val name: String = classOf[MySQL8ConnectionProvider].getName
-
- override val driverClass: String = MySQL8ConnectionProvider.driverClass
-
- override def canHandle(providerClass: String): Boolean = {
- driverClass.equalsIgnoreCase(providerClass)
- }
+ override val name: String = classOf[ImpalaConnectionProvider].getName
+ override val driverClass: String = ImpalaConnectionProvider.driverClass
}
-object MySQL8ConnectionProvider {
- val driverClass: String = "com.mysql.cj.jdbc.Driver"
+object ImpalaConnectionProvider {
+ // we should use kyuubi hive driver instead of original hive one in order
+ // to get fixed getMoreResults()
+ val driverClass: String = "org.apache.kyuubi.jdbc.KyuubiHiveDriver"
}
diff --git
a/externals/kyuubi-jdbc-engine/src/main/scala/org/apache/kyuubi/engine/jdbc/postgresql/PostgreSQLConnectionProvider.scala
b/externals/kyuubi-jdbc-engine/src/main/scala/org/apache/kyuubi/engine/jdbc/impala/ImpalaSchemaHelper.scala
similarity index 64%
copy from
externals/kyuubi-jdbc-engine/src/main/scala/org/apache/kyuubi/engine/jdbc/postgresql/PostgreSQLConnectionProvider.scala
copy to
externals/kyuubi-jdbc-engine/src/main/scala/org/apache/kyuubi/engine/jdbc/impala/ImpalaSchemaHelper.scala
index a11e57768..f0d1cd68c 100644
---
a/externals/kyuubi-jdbc-engine/src/main/scala/org/apache/kyuubi/engine/jdbc/postgresql/PostgreSQLConnectionProvider.scala
+++
b/externals/kyuubi-jdbc-engine/src/main/scala/org/apache/kyuubi/engine/jdbc/impala/ImpalaSchemaHelper.scala
@@ -14,18 +14,17 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-package org.apache.kyuubi.engine.jdbc.postgresql
+package org.apache.kyuubi.engine.jdbc.impala
-import org.apache.kyuubi.engine.jdbc.connection.JdbcConnectionProvider
+import org.apache.kyuubi.engine.jdbc.schema.SchemaHelper
+import org.apache.kyuubi.shaded.hive.service.rpc.thrift.TTypeId
-class PostgreSQLConnectionProvider extends JdbcConnectionProvider {
-
- override val name: String = classOf[PostgreSQLConnectionProvider].getName
-
- override val driverClass: String = "org.postgresql.Driver"
-
- override def canHandle(providerClass: String): Boolean = {
- driverClass.equalsIgnoreCase(providerClass)
+class ImpalaSchemaHelper extends SchemaHelper {
+ override protected def floatToTTypeId: TTypeId = {
+ TTypeId.DOUBLE_TYPE
}
+ override protected def realToTTypeId: TTypeId = {
+ TTypeId.DOUBLE_TYPE
+ }
}
diff --git
a/externals/kyuubi-jdbc-engine/src/main/scala/org/apache/kyuubi/engine/jdbc/phoenix/PhoenixConnectionProvider.scala
b/externals/kyuubi-jdbc-engine/src/main/scala/org/apache/kyuubi/engine/jdbc/impala/ImpalaTRowSetGenerator.scala
similarity index 53%
copy from
externals/kyuubi-jdbc-engine/src/main/scala/org/apache/kyuubi/engine/jdbc/phoenix/PhoenixConnectionProvider.scala
copy to
externals/kyuubi-jdbc-engine/src/main/scala/org/apache/kyuubi/engine/jdbc/impala/ImpalaTRowSetGenerator.scala
index 95c6f1c00..85ad0cdc8 100644
---
a/externals/kyuubi-jdbc-engine/src/main/scala/org/apache/kyuubi/engine/jdbc/phoenix/PhoenixConnectionProvider.scala
+++
b/externals/kyuubi-jdbc-engine/src/main/scala/org/apache/kyuubi/engine/jdbc/impala/ImpalaTRowSetGenerator.scala
@@ -14,18 +14,21 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-package org.apache.kyuubi.engine.jdbc.phoenix
+package org.apache.kyuubi.engine.jdbc.impala
-import org.apache.kyuubi.engine.jdbc.connection.JdbcConnectionProvider
+import org.apache.kyuubi.engine.jdbc.schema.DefaultJdbcTRowSetGenerator
+import org.apache.kyuubi.shaded.hive.service.rpc.thrift.{TColumn, TColumnValue}
-class PhoenixConnectionProvider extends JdbcConnectionProvider {
+class ImpalaTRowSetGenerator extends DefaultJdbcTRowSetGenerator {
+ override def toFloatTColumn(rows: Seq[Seq[_]], ordinal: Int): TColumn =
+ asDoubleTColumn(rows, ordinal)
- override val name: String = classOf[PhoenixConnectionProvider].getName
+ override def toFloatTColumnValue(row: Seq[_], ordinal: Int): TColumnValue =
+ asDoubleTColumnValue(row, ordinal)
- override val driverClass: String =
"org.apache.phoenix.queryserver.client.Driver"
-
- override def canHandle(providerClass: String): Boolean = {
- driverClass.equalsIgnoreCase(providerClass)
- }
+ override def toRealTColumn(rows: Seq[Seq[_]], ordinal: Int): TColumn =
+ asDoubleTColumn(rows, ordinal)
+ override def toRealTColumnValue(row: Seq[_], ordinal: Int): TColumnValue =
+ asDoubleTColumnValue(row, ordinal)
}
diff --git
a/externals/kyuubi-jdbc-engine/src/main/scala/org/apache/kyuubi/engine/jdbc/mysql/MySQL8ConnectionProvider.scala
b/externals/kyuubi-jdbc-engine/src/main/scala/org/apache/kyuubi/engine/jdbc/mysql/MySQL8ConnectionProvider.scala
index f96dff107..6996df861 100644
---
a/externals/kyuubi-jdbc-engine/src/main/scala/org/apache/kyuubi/engine/jdbc/mysql/MySQL8ConnectionProvider.scala
+++
b/externals/kyuubi-jdbc-engine/src/main/scala/org/apache/kyuubi/engine/jdbc/mysql/MySQL8ConnectionProvider.scala
@@ -23,11 +23,6 @@ class MySQL8ConnectionProvider extends
JdbcConnectionProvider {
override val name: String = classOf[MySQL8ConnectionProvider].getName
override val driverClass: String = MySQL8ConnectionProvider.driverClass
-
- override def canHandle(providerClass: String): Boolean = {
- driverClass.equalsIgnoreCase(providerClass)
- }
-
}
object MySQL8ConnectionProvider {
diff --git
a/externals/kyuubi-jdbc-engine/src/main/scala/org/apache/kyuubi/engine/jdbc/operation/ExecuteStatement.scala
b/externals/kyuubi-jdbc-engine/src/main/scala/org/apache/kyuubi/engine/jdbc/operation/ExecuteStatement.scala
index 4292c320b..af9e9a102 100644
---
a/externals/kyuubi-jdbc-engine/src/main/scala/org/apache/kyuubi/engine/jdbc/operation/ExecuteStatement.scala
+++
b/externals/kyuubi-jdbc-engine/src/main/scala/org/apache/kyuubi/engine/jdbc/operation/ExecuteStatement.scala
@@ -76,8 +76,9 @@ class ExecuteStatement(
})
} else {
warn(s"Execute in full collect mode")
- jdbcStatement.closeOnCompletion()
- new ArrayFetchIterator(resultSetWrapper.toArray())
+ val arrayIter = new ArrayFetchIterator(resultSetWrapper.toArray())
+ jdbcStatement.close()
+ arrayIter
}
} else {
schema = Schema(List[Column](
diff --git
a/externals/kyuubi-jdbc-engine/src/main/scala/org/apache/kyuubi/engine/jdbc/phoenix/PhoenixConnectionProvider.scala
b/externals/kyuubi-jdbc-engine/src/main/scala/org/apache/kyuubi/engine/jdbc/phoenix/PhoenixConnectionProvider.scala
index 95c6f1c00..591ca4720 100644
---
a/externals/kyuubi-jdbc-engine/src/main/scala/org/apache/kyuubi/engine/jdbc/phoenix/PhoenixConnectionProvider.scala
+++
b/externals/kyuubi-jdbc-engine/src/main/scala/org/apache/kyuubi/engine/jdbc/phoenix/PhoenixConnectionProvider.scala
@@ -23,9 +23,4 @@ class PhoenixConnectionProvider extends
JdbcConnectionProvider {
override val name: String = classOf[PhoenixConnectionProvider].getName
override val driverClass: String =
"org.apache.phoenix.queryserver.client.Driver"
-
- override def canHandle(providerClass: String): Boolean = {
- driverClass.equalsIgnoreCase(providerClass)
- }
-
}
diff --git
a/externals/kyuubi-jdbc-engine/src/main/scala/org/apache/kyuubi/engine/jdbc/postgresql/PostgreSQLConnectionProvider.scala
b/externals/kyuubi-jdbc-engine/src/main/scala/org/apache/kyuubi/engine/jdbc/postgresql/PostgreSQLConnectionProvider.scala
index a11e57768..dcd8a8786 100644
---
a/externals/kyuubi-jdbc-engine/src/main/scala/org/apache/kyuubi/engine/jdbc/postgresql/PostgreSQLConnectionProvider.scala
+++
b/externals/kyuubi-jdbc-engine/src/main/scala/org/apache/kyuubi/engine/jdbc/postgresql/PostgreSQLConnectionProvider.scala
@@ -24,8 +24,4 @@ class PostgreSQLConnectionProvider extends
JdbcConnectionProvider {
override val driverClass: String = "org.postgresql.Driver"
- override def canHandle(providerClass: String): Boolean = {
- driverClass.equalsIgnoreCase(providerClass)
- }
-
}
diff --git
a/externals/kyuubi-jdbc-engine/src/main/scala/org/apache/kyuubi/engine/jdbc/schema/DefaultJdbcTRowSetGenerator.scala
b/externals/kyuubi-jdbc-engine/src/main/scala/org/apache/kyuubi/engine/jdbc/schema/DefaultJdbcTRowSetGenerator.scala
index 2c9ddd6da..ec5de3949 100644
---
a/externals/kyuubi-jdbc-engine/src/main/scala/org/apache/kyuubi/engine/jdbc/schema/DefaultJdbcTRowSetGenerator.scala
+++
b/externals/kyuubi-jdbc-engine/src/main/scala/org/apache/kyuubi/engine/jdbc/schema/DefaultJdbcTRowSetGenerator.scala
@@ -33,9 +33,11 @@ class DefaultJdbcTRowSetGenerator extends
JdbcTRowSetGenerator {
case INTEGER => toIntegerTColumn(rows, ordinal)
case BIGINT => toBigIntTColumn(rows, ordinal)
case REAL => toRealTColumn(rows, ordinal)
+ case FLOAT => toFloatTColumn(rows, ordinal)
case DOUBLE => toDoubleTColumn(rows, ordinal)
case CHAR => toCharTColumn(rows, ordinal)
case VARCHAR => toVarcharTColumn(rows, ordinal)
+ case BOOLEAN => toBooleanTColumn(rows, ordinal)
case _ => toDefaultTColumn(rows, ordinal, sqlType)
}
@@ -47,9 +49,11 @@ class DefaultJdbcTRowSetGenerator extends
JdbcTRowSetGenerator {
case INTEGER => toIntegerTColumnValue(row, ordinal)
case BIGINT => toBigIntTColumnValue(row, ordinal)
case REAL => toRealTColumnValue(row, ordinal)
+ case FLOAT => toFloatTColumnValue(row, ordinal)
case DOUBLE => toDoubleTColumnValue(row, ordinal)
case CHAR => toCharTColumnValue(row, ordinal)
case VARCHAR => toVarcharTColumnValue(row, ordinal)
+ case BOOLEAN => toBooleanTColumnValue(row, ordinal)
case otherType => toDefaultTColumnValue(row, ordinal, otherType)
}
}
@@ -63,6 +67,9 @@ class DefaultJdbcTRowSetGenerator extends
JdbcTRowSetGenerator {
def toBitTColumn(rows: Seq[Seq[_]], ordinal: Int): TColumn =
asBooleanTColumn(rows, ordinal)
+ def toBooleanTColumn(rows: Seq[Seq[_]], ordinal: Int): TColumn =
+ asBooleanTColumn(rows, ordinal)
+
def toTinyIntTColumn(rows: Seq[Seq[_]], ordinal: Int): TColumn =
asShortTColumn(rows, ordinal)
@@ -78,6 +85,9 @@ class DefaultJdbcTRowSetGenerator extends
JdbcTRowSetGenerator {
def toRealTColumn(rows: Seq[Seq[_]], ordinal: Int): TColumn =
asFloatTColumn(rows, ordinal)
+ def toFloatTColumn(rows: Seq[Seq[_]], ordinal: Int): TColumn =
+ asFloatTColumn(rows, ordinal)
+
def toDoubleTColumn(rows: Seq[Seq[_]], ordinal: Int): TColumn =
asDoubleTColumn(rows, ordinal)
@@ -92,6 +102,9 @@ class DefaultJdbcTRowSetGenerator extends
JdbcTRowSetGenerator {
def toBitTColumnValue(row: Seq[_], ordinal: Int): TColumnValue =
asBooleanTColumnValue(row, ordinal)
+ def toBooleanTColumnValue(row: Seq[_], ordinal: Int): TColumnValue =
+ asBooleanTColumnValue(row, ordinal)
+
def toTinyIntTColumnValue(row: Seq[_], ordinal: Int): TColumnValue =
asShortTColumnValue(row, ordinal)
@@ -107,6 +120,9 @@ class DefaultJdbcTRowSetGenerator extends
JdbcTRowSetGenerator {
def toRealTColumnValue(row: Seq[_], ordinal: Int): TColumnValue =
asFloatTColumnValue(row, ordinal)
+ def toFloatTColumnValue(row: Seq[_], ordinal: Int): TColumnValue =
+ asFloatTColumnValue(row, ordinal)
+
def toDoubleTColumnValue(row: Seq[_], ordinal: Int): TColumnValue =
asDoubleTColumnValue(row, ordinal)
diff --git
a/externals/kyuubi-jdbc-engine/src/main/scala/org/apache/kyuubi/engine/jdbc/schema/SchemaHelper.scala
b/externals/kyuubi-jdbc-engine/src/main/scala/org/apache/kyuubi/engine/jdbc/schema/SchemaHelper.scala
index 6b39bb3db..16d46fc36 100644
---
a/externals/kyuubi-jdbc-engine/src/main/scala/org/apache/kyuubi/engine/jdbc/schema/SchemaHelper.scala
+++
b/externals/kyuubi-jdbc-engine/src/main/scala/org/apache/kyuubi/engine/jdbc/schema/SchemaHelper.scala
@@ -100,6 +100,12 @@ abstract class SchemaHelper {
case Types.DECIMAL =>
decimalToTTypeId
+ case Types.FLOAT =>
+ floatToTTypeId
+
+ case Types.BOOLEAN =>
+ booleanToTTypeId
+
// TODO add more type support
case _ =>
defaultToTTypeId
@@ -109,6 +115,10 @@ abstract class SchemaHelper {
TTypeId.BOOLEAN_TYPE
}
+ protected def booleanToTTypeId: TTypeId = {
+ TTypeId.BOOLEAN_TYPE
+ }
+
protected def tinyIntToTTypeId: TTypeId = {
TTypeId.TINYINT_TYPE
}
@@ -129,6 +139,10 @@ abstract class SchemaHelper {
TTypeId.FLOAT_TYPE
}
+ protected def floatToTTypeId: TTypeId = {
+ TTypeId.FLOAT_TYPE
+ }
+
protected def doubleToTTypeId: TTypeId = {
TTypeId.DOUBLE_TYPE
}
diff --git a/externals/kyuubi-jdbc-engine/src/test/resources/impala-compose.yml
b/externals/kyuubi-jdbc-engine/src/test/resources/impala-compose.yml
new file mode 100644
index 000000000..4be34042b
--- /dev/null
+++ b/externals/kyuubi-jdbc-engine/src/test/resources/impala-compose.yml
@@ -0,0 +1,82 @@
+# 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.
+
+# modified compose file from Impala repo, see
+# https://github.com/apache/impala/blob/4.3.0/docker/quickstart.yml
+version: "3.5"
+services:
+ metastore:
+ image: apache/impala:4.0.0-impala_quickstart_hms
+ command: ["hms"]
+ ports:
+ - "9083"
+ volumes:
+ # Volume used to store Apache Derby database.
+ - impala-data:/var/lib/hive
+ # Warehouse directory. HMS does file operations so needs access to the
+ # shared volume.
+ - impala-data:/user/hive/warehouse
+ - ./impala_conf:/opt/hive/conf:ro
+
+ statestored:
+ image: apache/impala:4.0.0-statestored
+ ports:
+ - "25010"
+ command: ["-redirect_stdout_stderr=false", "-logtostderr", "-v=1"]
+ volumes:
+ - ./impala_conf:/opt/impala/conf:ro
+
+ catalogd:
+ depends_on:
+ - statestored
+ - metastore
+ image: apache/impala:4.0.0-catalogd
+ ports:
+ - "25020"
+ command: ["-redirect_stdout_stderr=false", "-logtostderr", "-v=1",
+ "-hms_event_polling_interval_s=1",
"-invalidate_tables_timeout_s=999999"]
+ volumes:
+ # Warehouse directory. Catalog does file operations so needs access to
the
+ # shared volume.
+ - impala-data:/user/hive/warehouse
+ - ./impala_conf:/opt/impala/conf:ro
+
+ impalad:
+ image: apache/impala:4.0.0-impalad_coord_exec
+ depends_on:
+ - statestored
+ - catalogd
+ ports:
+ - "21050:21050"
+ command: [ "-v=1",
+ "-redirect_stdout_stderr=false", "-logtostderr",
+ "-mt_dop_auto_fallback=true",
+
"-default_query_options=mt_dop=4,default_file_format=parquet,default_transactional_type=insert_only",
+ "-mem_limit=1500mb"]
+ environment:
+ # Keep the Java heap small to preserve memory for query execution.
+ - JAVA_TOOL_OPTIONS="-Xmx1g"
+ volumes:
+ - impala-data:/user/hive/warehouse
+ - ./impala_conf:/opt/impala/conf:ro
+
+volumes:
+ impala-data:
+
+networks:
+ default:
+ name: default-kyuubi-impala-test
diff --git
a/externals/kyuubi-jdbc-engine/src/test/resources/impala_conf/hive-site.xml
b/externals/kyuubi-jdbc-engine/src/test/resources/impala_conf/hive-site.xml
new file mode 100644
index 000000000..55fa54ef1
--- /dev/null
+++ b/externals/kyuubi-jdbc-engine/src/test/resources/impala_conf/hive-site.xml
@@ -0,0 +1,72 @@
+<?xml version="1.0"?>
+<?xml-stylesheet type="text/xsl" href="configuration.xsl"?>
+<!--
+ 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.
+-->
+<!-- Hive configuration for Impala quickstart docker cluster. -->
+<configuration>
+ <property>
+ <!-- Required for automatic metadata sync. -->
+ <name>hive.metastore.dml.events</name>
+ <value>true</value>
+ </property>
+ <property>
+ <!-- User impala is not authorized to consume notifications by default,
disable
+ authentication to work around this. -->
+ <name>hive.metastore.event.db.notification.api.auth</name>
+ <value>false</value>
+ </property>
+ <property>
+ <name>hive.metastore.uris</name>
+ <value>thrift://metastore:9083</value>
+ </property>
+ <!-- Managed and external tablespaces must live on the Docker volumes that we
+ configure for the quickstart cluster. -->
+ <property>
+ <name>hive.metastore.warehouse.dir</name>
+ <value>/user/hive/warehouse/managed</value>
+ </property>
+ <property>
+ <name>hive.metastore.warehouse.external.dir</name>
+ <value>/user/hive/warehouse/external</value>
+ </property>
+ <property>
+ <!-- Required to enable Hive transactions -->
+ <name>hive.support.concurrency</name>
+ <value>true</value>
+ </property>
+ <property>
+ <!-- Required to enable Hive transactions -->
+ <name>hive.txn.manager</name>
+ <value>org.apache.hadoop.hive.ql.lockmgr.DbTxnManager</value>
+ </property>
+ <property>
+ <!-- Use embedded Derby database -->
+ <name>javax.jdo.option.ConnectionDriverName</name>
+ <value>org.apache.derby.jdbc.EmbeddedDriver</value>
+ </property>
+ <property>
+ <!-- Use embedded Derby database -->
+ <name>javax.jdo.option.ConnectionURL</name>
+
<value>jdbc:derby:;databaseName=/var/lib/hive/metastore/metastore_db;create=true</value>
+ </property>
+ <!-- Hive stats autogathering negatively affects latency of DDL operations,
etc and
+ is not particularly useful for Impala -->
+ <property>
+ <name>hive.stats.autogather</name>
+ <value>false</value>
+ </property>
+</configuration>
diff --git
a/externals/kyuubi-jdbc-engine/src/test/scala/org/apache/kyuubi/engine/jdbc/impala/DialectSuite.scala
b/externals/kyuubi-jdbc-engine/src/test/scala/org/apache/kyuubi/engine/jdbc/impala/DialectSuite.scala
new file mode 100644
index 000000000..7f90a6094
--- /dev/null
+++
b/externals/kyuubi-jdbc-engine/src/test/scala/org/apache/kyuubi/engine/jdbc/impala/DialectSuite.scala
@@ -0,0 +1,106 @@
+/*
+ * 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.jdbc.impala
+
+import org.apache.kyuubi.{KyuubiFunSuite, KyuubiSQLException}
+import org.apache.kyuubi.engine.jdbc.dialect.ImpalaDialect
+import org.apache.kyuubi.engine.jdbc.impala.DialectSuite.{SCHEME_NAME,
TABLE_NAME}
+
+class DialectSuite extends KyuubiFunSuite {
+
+ private val dialect: ImpalaDialect = new ImpalaDialect()
+
+ test("impala dialect - get tables query") {
+ val expectedQuery = "show tables"
+ val actualQuery = dialect.getTablesQuery(null, null, null, null)
+
+ assert(expectedQuery == actualQuery.trim)
+ }
+
+ test("impala dialect - get tables query by scheme") {
+ val expectedQuery = s"show tables in $SCHEME_NAME"
+ val actualQuery = dialect.getTablesQuery(null, SCHEME_NAME, null, null)
+
+ assert(expectedQuery == actualQuery.trim)
+ }
+
+ test("impala dialect - get tables query by table name") {
+ val expectedQuery = s"show tables like '$TABLE_NAME'"
+ val queryWithTableName = dialect.getTablesQuery(null, null, TABLE_NAME,
null)
+
+ assert(expectedQuery == queryWithTableName.trim)
+
+ // kyuubi injects '%' in case if schema is null
+ val queryWithWildcardScheme = dialect.getTablesQuery(null, "%",
TABLE_NAME, null)
+
+ assert(expectedQuery == queryWithWildcardScheme.trim)
+ }
+
+ test("impala dialect - get tables query by scheme and table name") {
+ val expectedQuery = s"show tables in $SCHEME_NAME like 'test*'"
+ val actualQuery = dialect.getTablesQuery(null, SCHEME_NAME, "test*", null)
+
+ assert(expectedQuery == actualQuery.trim)
+ }
+
+ test("impala dialect - fail get tables if pattern-like scheme provided") {
+ val exception = intercept[KyuubiSQLException] {
+ dialect.getTablesQuery(null, "*scheme*", TABLE_NAME, null)
+ }
+ assert(exception.getMessage == "Pattern-like schema names not supported")
+ }
+
+ test("impala dialect - get columns query by table name") {
+ val expectedQuery = s"show column stats $TABLE_NAME"
+ val actualQuery = dialect.getColumnsQuery(null, null, null, TABLE_NAME,
null)
+
+ assert(expectedQuery == actualQuery.trim)
+ }
+
+ test("impala dialect - get columns query by scheme and table name") {
+ val expectedQuery = s"show column stats $SCHEME_NAME.$TABLE_NAME"
+ val actualQuery = dialect.getColumnsQuery(null, null, SCHEME_NAME,
TABLE_NAME, null)
+
+ assert(expectedQuery == actualQuery.trim)
+ }
+
+ test("impala dialect - fail get columns if pattern-like scheme provided") {
+ val exception = intercept[KyuubiSQLException] {
+ dialect.getColumnsQuery(null, null, "*scheme*", TABLE_NAME, null)
+ }
+ assert(exception.getMessage == "Pattern-like schema names not supported")
+ }
+
+ test("impala dialect - fail get columns if pattern-like table provided") {
+ val exception = intercept[KyuubiSQLException] {
+ dialect.getColumnsQuery(null, null, null, "*test*", null)
+ }
+ assert(exception.getMessage == "Pattern-like table names not supported")
+ }
+
+ test("impala dialect - fail get columns if table name not provided") {
+ val exception = intercept[KyuubiSQLException] {
+ dialect.getColumnsQuery(null, null, null, null, null)
+ }
+ assert(exception.getMessage == "Table name should not be empty")
+ }
+}
+
+object DialectSuite {
+ val TABLE_NAME = "test_table"
+ val SCHEME_NAME = "test_db"
+}
diff --git
a/externals/kyuubi-jdbc-engine/src/test/scala/org/apache/kyuubi/engine/jdbc/impala/ImpalaOperationSuite.scala
b/externals/kyuubi-jdbc-engine/src/test/scala/org/apache/kyuubi/engine/jdbc/impala/ImpalaOperationSuite.scala
new file mode 100644
index 000000000..ae3336d5a
--- /dev/null
+++
b/externals/kyuubi-jdbc-engine/src/test/scala/org/apache/kyuubi/engine/jdbc/impala/ImpalaOperationSuite.scala
@@ -0,0 +1,108 @@
+/*
+ * 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.jdbc.impala
+
+import java.sql.ResultSet
+
+import scala.collection.mutable.ArrayBuffer
+
+import org.apache.kyuubi.operation.HiveJDBCTestHelper
+
+abstract class ImpalaOperationSuite extends WithImpalaEngine with
HiveJDBCTestHelper {
+ test("impala - get tables") {
+ withJdbcStatement() { statement =>
+ val meta = statement.getConnection.getMetaData
+
+ statement.execute("create table test1(id bigint)")
+ statement.execute("create table test2(id bigint)")
+ statement.execute("create database db1")
+ statement.execute("create table db1.test3(id bigint)")
+
+ var tables = meta.getTables(null, null, "test1", null)
+ while (tables.next()) {
+ assert(tables.getString(1) == "test1")
+ }
+
+ tables = meta.getTables(null, null, "test2", null)
+ while (tables.next()) {
+ assert(tables.getString(1) == "test2")
+ }
+
+ tables = meta.getTables(null, null, "test*", null)
+
+ val actualTables = ArrayBuffer[String]()
+ while (tables.next()) {
+ actualTables += tables.getString(1)
+ }
+ assert(ArrayBuffer("test1", "test2") == actualTables)
+
+ tables = meta.getTables(null, "db1", "test*", null)
+ while (tables.next()) {
+ assert(tables.getString(1) == "test3")
+ }
+
+ statement.execute("drop table test1")
+ statement.execute("drop table test2")
+ statement.execute("drop table db1.test3")
+ statement.execute("drop database db1")
+ }
+ }
+
+ test("impala - get columns") {
+ case class Column(name: String, columnType: String)
+
+ def buildColumn(resultSet: ResultSet): Column = {
+ val columnName = resultSet.getString("Column")
+ val columnType = resultSet.getString("Type")
+ Column(columnName, columnType)
+ }
+
+ withJdbcStatement() { statement =>
+ val metadata = statement.getConnection.getMetaData
+ statement.execute("create table if not exists test1" +
+ "(id bigint, str1 string, str2 string, age int)")
+
+ statement.execute("create database db1")
+ statement.execute("create table if not exists db1.test2" +
+ "(id bigint, str1 string)")
+
+ val resultBuffer = ArrayBuffer[Column]()
+ val resultSet1 = metadata.getColumns(null, null, "test1", null)
+ while (resultSet1.next()) {
+ resultBuffer += buildColumn(resultSet1)
+ }
+
+ assert(resultBuffer.contains(Column("id", "BIGINT")))
+ assert(resultBuffer.contains(Column("str1", "STRING")))
+ assert(resultBuffer.contains(Column("str2", "STRING")))
+ assert(resultBuffer.contains(Column("age", "INT")))
+
+ resultBuffer.clear()
+
+ val resultSet2 = metadata.getColumns(null, "db1", "test2", null)
+ while (resultSet2.next()) {
+ resultBuffer += buildColumn(resultSet2)
+ }
+ assert(resultBuffer.contains(Column("id", "BIGINT")))
+ assert(resultBuffer.contains(Column("str1", "STRING")))
+
+ statement.execute("drop table test1")
+ statement.execute("drop table db1.test2")
+ statement.execute("drop database db1")
+ }
+ }
+}
diff --git
a/externals/kyuubi-jdbc-engine/src/test/scala/org/apache/kyuubi/engine/jdbc/impala/OperationWithImpalaEngineSuite.scala
b/externals/kyuubi-jdbc-engine/src/test/scala/org/apache/kyuubi/engine/jdbc/impala/OperationWithImpalaEngineSuite.scala
new file mode 100644
index 000000000..87fa49745
--- /dev/null
+++
b/externals/kyuubi-jdbc-engine/src/test/scala/org/apache/kyuubi/engine/jdbc/impala/OperationWithImpalaEngineSuite.scala
@@ -0,0 +1,51 @@
+/*
+ * 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.jdbc.impala
+
+import org.apache.kyuubi.config.KyuubiConf
+import org.apache.kyuubi.engine.jdbc.connection.ConnectionProvider
+import org.apache.kyuubi.operation.HiveJDBCTestHelper
+import org.apache.kyuubi.shaded.hive.service.rpc.thrift.{TGetInfoReq,
TGetInfoType}
+
+class OperationWithImpalaEngineSuite extends ImpalaOperationSuite with
HiveJDBCTestHelper {
+
+ override protected def jdbcUrl: String = jdbcConnectionUrl
+
+ test("impala - test for Jdbc engine getInfo") {
+ val metaData = ConnectionProvider.create(kyuubiConf).getMetaData
+
+ withSessionConf(Map(KyuubiConf.SERVER_INFO_PROVIDER.key -> "ENGINE"))()() {
+ withSessionHandle { (client, handle) =>
+ val req = new TGetInfoReq()
+ req.setSessionHandle(handle)
+ req.setInfoType(TGetInfoType.CLI_DBMS_NAME)
+ assert(client.GetInfo(req).getInfoValue.getStringValue ==
metaData.getDatabaseProductName)
+
+ val req2 = new TGetInfoReq()
+ req2.setSessionHandle(handle)
+ req2.setInfoType(TGetInfoType.CLI_DBMS_VER)
+ assert(
+ client.GetInfo(req2).getInfoValue.getStringValue ==
metaData.getDatabaseProductVersion)
+
+ val req3 = new TGetInfoReq()
+ req3.setSessionHandle(handle)
+ req3.setInfoType(TGetInfoType.CLI_MAX_COLUMN_NAME_LEN)
+ assert(client.GetInfo(req3).getInfoValue.getLenValue ==
metaData.getMaxColumnNameLength)
+ }
+ }
+ }
+}
diff --git
a/externals/kyuubi-jdbc-engine/src/main/scala/org/apache/kyuubi/engine/jdbc/phoenix/PhoenixConnectionProvider.scala
b/externals/kyuubi-jdbc-engine/src/test/scala/org/apache/kyuubi/engine/jdbc/impala/SessionSuite.scala
similarity index 55%
copy from
externals/kyuubi-jdbc-engine/src/main/scala/org/apache/kyuubi/engine/jdbc/phoenix/PhoenixConnectionProvider.scala
copy to
externals/kyuubi-jdbc-engine/src/test/scala/org/apache/kyuubi/engine/jdbc/impala/SessionSuite.scala
index 95c6f1c00..7154e9cea 100644
---
a/externals/kyuubi-jdbc-engine/src/main/scala/org/apache/kyuubi/engine/jdbc/phoenix/PhoenixConnectionProvider.scala
+++
b/externals/kyuubi-jdbc-engine/src/test/scala/org/apache/kyuubi/engine/jdbc/impala/SessionSuite.scala
@@ -14,18 +14,26 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-package org.apache.kyuubi.engine.jdbc.phoenix
+package org.apache.kyuubi.engine.jdbc.impala
-import org.apache.kyuubi.engine.jdbc.connection.JdbcConnectionProvider
+import org.apache.kyuubi.operation.HiveJDBCTestHelper
-class PhoenixConnectionProvider extends JdbcConnectionProvider {
+class SessionSuite extends WithImpalaEngine with HiveJDBCTestHelper {
- override val name: String = classOf[PhoenixConnectionProvider].getName
-
- override val driverClass: String =
"org.apache.phoenix.queryserver.client.Driver"
-
- override def canHandle(providerClass: String): Boolean = {
- driverClass.equalsIgnoreCase(providerClass)
+ test("impala - test session") {
+ withJdbcStatement() { statement =>
+ val resultSet = statement.executeQuery(
+ "select '1' as id")
+ val metadata = resultSet.getMetaData
+ for (i <- 1 to metadata.getColumnCount) {
+ assert(metadata.getColumnName(i) == "id")
+ }
+ while (resultSet.next()) {
+ val id = resultSet.getObject(1)
+ assert(id == "1")
+ }
+ }
}
+ override protected def jdbcUrl: String = jdbcConnectionUrl
}
diff --git
a/externals/kyuubi-jdbc-engine/src/test/scala/org/apache/kyuubi/engine/jdbc/impala/StatementSuite.scala
b/externals/kyuubi-jdbc-engine/src/test/scala/org/apache/kyuubi/engine/jdbc/impala/StatementSuite.scala
new file mode 100644
index 000000000..ed6d7e4f0
--- /dev/null
+++
b/externals/kyuubi-jdbc-engine/src/test/scala/org/apache/kyuubi/engine/jdbc/impala/StatementSuite.scala
@@ -0,0 +1,106 @@
+/*
+ * 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.jdbc.impala
+
+import java.sql.{Date, Timestamp}
+
+import org.apache.kyuubi.operation.HiveJDBCTestHelper
+
+class StatementSuite extends WithImpalaEngine with HiveJDBCTestHelper {
+
+ test("impala - test select") {
+ withJdbcStatement("test1") { statement =>
+ statement.execute("create table test1(id bigint, " +
+ "name string, age integer)")
+ statement.execute("insert into test1 values(1, 'a', 11)")
+
+ val resultSet1 = statement.executeQuery("select * from test1")
+ while (resultSet1.next()) {
+ val id = resultSet1.getObject(1)
+ assert(id == 1)
+ val name = resultSet1.getObject(2)
+ assert(name == "a")
+ val age = resultSet1.getObject(3)
+ assert(age == 11)
+ }
+ }
+ }
+
+ test("impala - test types") {
+ withJdbcStatement("type_test") { statement =>
+ statement.execute("create table type_test(" +
+ "id bigint, " +
+ "smallint_col smallint, " +
+ "int_col int, " +
+ "bigint_col bigint, " +
+ "date_col date, " +
+ "timestamp_col timestamp, " +
+ "char_col char(10), " +
+ "varchar_col varchar(255), " +
+ "boolean_col boolean, " +
+ "double_col double, " +
+ "real_col real, " +
+ "string_col STRING " +
+ ")")
+
+ statement.execute("insert into type_test" +
+ "(id, " +
+ "smallint_col, " +
+ "int_col, " +
+ "bigint_col, " +
+ "date_col, " +
+ "timestamp_col, " +
+ "char_col, " +
+ "varchar_col, " +
+ "boolean_col, " +
+ "double_col, " +
+ "real_col," +
+ "string_col) " +
+ "VALUES (1, " +
+ "2, " +
+ "3, " +
+ "4, " +
+ "'2022-05-08', " +
+ "'2022-05-08 17:47:45'," +
+ "CAST('a' AS char(10)), " +
+ "CAST('Hello' AS varchar(255)), " +
+ "true, " +
+ "8.8, " +
+ "9.9, " +
+ "'test_str' " +
+ ")")
+
+ val resultSet1 = statement.executeQuery("select * from type_test")
+ while (resultSet1.next()) {
+ assert(resultSet1.getObject(1) == 1)
+ assert(resultSet1.getObject(2) == 2)
+ assert(resultSet1.getObject(3) == 3)
+ assert(resultSet1.getObject(4) == 4)
+ assert(resultSet1.getObject(5) == Date.valueOf("2022-05-08"))
+ assert(resultSet1.getObject(6) == Timestamp.valueOf("2022-05-08
17:47:45"))
+ assert(resultSet1.getString(7).trim == "a")
+ assert(resultSet1.getObject(8) == "Hello")
+ assert(resultSet1.getObject(9) == true)
+ assert(resultSet1.getObject(10) == 8.8)
+ assert(resultSet1.getObject(11) == 9.9)
+ assert(resultSet1.getObject(12) == "test_str")
+ }
+ }
+ }
+
+ override protected def jdbcUrl: String = jdbcConnectionUrl
+}
diff --git
a/externals/kyuubi-jdbc-engine/src/test/scala/org/apache/kyuubi/engine/jdbc/impala/WithImpalaContainer.scala
b/externals/kyuubi-jdbc-engine/src/test/scala/org/apache/kyuubi/engine/jdbc/impala/WithImpalaContainer.scala
new file mode 100644
index 000000000..4aaa88711
--- /dev/null
+++
b/externals/kyuubi-jdbc-engine/src/test/scala/org/apache/kyuubi/engine/jdbc/impala/WithImpalaContainer.scala
@@ -0,0 +1,68 @@
+/*
+ * 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.jdbc.impala
+
+import java.io.File
+
+import com.dimafeng.testcontainers.{DockerComposeContainer, ExposedService}
+import org.testcontainers.containers.wait.strategy.Wait
+
+import org.apache.kyuubi.Utils
+import org.apache.kyuubi.engine.jdbc.WithJdbcServerContainer
+
+trait WithImpalaContainer extends WithJdbcServerContainer {
+ private val METASTORE_SERVICE_NAME = "metastore"
+ private val METASTORE_PORT = 9083
+
+ private val STATESTORE_SERVICE_NAME = "statestored"
+ private val STATESTORE_PORT = 25010
+
+ private val CATALOGD_SERVICE_NAME = "catalogd"
+ private val CATALOGD_PORT = 25020
+
+ private val IMPALAD_SERVICE_NAME = "impalad"
+ private val IMPALAD_PORT = 21050
+
+ override val containerDef: DockerComposeContainer.Def =
+ DockerComposeContainer
+ .Def(
+ composeFiles = new File(Utils.getContextOrKyuubiClassLoader
+ .getResource("impala-compose.yml").toURI),
+ exposedServices = Seq[ExposedService](
+ ExposedService(
+ METASTORE_SERVICE_NAME,
+ METASTORE_PORT,
+ waitStrategy = Wait.forListeningPort),
+ ExposedService(
+ STATESTORE_SERVICE_NAME,
+ STATESTORE_PORT,
+ waitStrategy = Wait.forListeningPort),
+ ExposedService(
+ CATALOGD_SERVICE_NAME,
+ CATALOGD_PORT,
+ waitStrategy = Wait.forListeningPort),
+ ExposedService(
+ IMPALAD_SERVICE_NAME,
+ IMPALAD_PORT,
+ waitStrategy = Wait.forListeningPort)))
+
+ protected def hiveServerJdbcUrl: String = withContainers { container =>
+ val feHost: String = container.getServiceHost(IMPALAD_SERVICE_NAME,
IMPALAD_PORT)
+ val fePort: Int = container.getServicePort(IMPALAD_SERVICE_NAME,
IMPALAD_PORT)
+ s"jdbc:kyuubi://$feHost:$fePort/;auth=noSasl"
+ }
+}
diff --git
a/externals/kyuubi-jdbc-engine/src/main/scala/org/apache/kyuubi/engine/jdbc/phoenix/PhoenixConnectionProvider.scala
b/externals/kyuubi-jdbc-engine/src/test/scala/org/apache/kyuubi/engine/jdbc/impala/WithImpalaEngine.scala
similarity index 60%
copy from
externals/kyuubi-jdbc-engine/src/main/scala/org/apache/kyuubi/engine/jdbc/phoenix/PhoenixConnectionProvider.scala
copy to
externals/kyuubi-jdbc-engine/src/test/scala/org/apache/kyuubi/engine/jdbc/impala/WithImpalaEngine.scala
index 95c6f1c00..9b31dd245 100644
---
a/externals/kyuubi-jdbc-engine/src/main/scala/org/apache/kyuubi/engine/jdbc/phoenix/PhoenixConnectionProvider.scala
+++
b/externals/kyuubi-jdbc-engine/src/test/scala/org/apache/kyuubi/engine/jdbc/impala/WithImpalaEngine.scala
@@ -14,18 +14,17 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-package org.apache.kyuubi.engine.jdbc.phoenix
+package org.apache.kyuubi.engine.jdbc.impala
-import org.apache.kyuubi.engine.jdbc.connection.JdbcConnectionProvider
+import org.apache.kyuubi.config.KyuubiConf._
+import org.apache.kyuubi.engine.jdbc.WithJdbcEngine
-class PhoenixConnectionProvider extends JdbcConnectionProvider {
-
- override val name: String = classOf[PhoenixConnectionProvider].getName
-
- override val driverClass: String =
"org.apache.phoenix.queryserver.client.Driver"
-
- override def canHandle(providerClass: String): Boolean = {
- driverClass.equalsIgnoreCase(providerClass)
- }
+trait WithImpalaEngine extends WithJdbcEngine with WithImpalaContainer {
+ override def withKyuubiConf: Map[String, String] = Map(
+ ENGINE_SHARE_LEVEL.key -> "SERVER",
+ ENGINE_JDBC_CONNECTION_URL.key -> hiveServerJdbcUrl,
+ ENGINE_TYPE.key -> "jdbc",
+ ENGINE_JDBC_SHORT_NAME.key -> "impala",
+ ENGINE_JDBC_DRIVER_CLASS.key -> ImpalaConnectionProvider.driverClass)
}
diff --git a/integration-tests/kyuubi-jdbc-it/pom.xml
b/integration-tests/kyuubi-jdbc-it/pom.xml
index 7921d94e2..5b4edbcbd 100644
--- a/integration-tests/kyuubi-jdbc-it/pom.xml
+++ b/integration-tests/kyuubi-jdbc-it/pom.xml
@@ -133,6 +133,13 @@
<overWrite>true</overWrite>
<outputDirectory>${project.build.directory}</outputDirectory>
</artifactItem>
+ <artifactItem>
+ <groupId>org.apache.kyuubi</groupId>
+
<artifactId>kyuubi-hive-jdbc-shaded</artifactId>
+ <version>${project.version}</version>
+ <overWrite>true</overWrite>
+
<outputDirectory>${project.build.directory}</outputDirectory>
+ </artifactItem>
</artifactItems>
</configuration>
</execution>
diff --git
a/integration-tests/kyuubi-jdbc-it/src/test/resources/impala-compose.yml
b/integration-tests/kyuubi-jdbc-it/src/test/resources/impala-compose.yml
new file mode 100644
index 000000000..4be34042b
--- /dev/null
+++ b/integration-tests/kyuubi-jdbc-it/src/test/resources/impala-compose.yml
@@ -0,0 +1,82 @@
+# 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.
+
+# modified compose file from Impala repo, see
+# https://github.com/apache/impala/blob/4.3.0/docker/quickstart.yml
+version: "3.5"
+services:
+ metastore:
+ image: apache/impala:4.0.0-impala_quickstart_hms
+ command: ["hms"]
+ ports:
+ - "9083"
+ volumes:
+ # Volume used to store Apache Derby database.
+ - impala-data:/var/lib/hive
+ # Warehouse directory. HMS does file operations so needs access to the
+ # shared volume.
+ - impala-data:/user/hive/warehouse
+ - ./impala_conf:/opt/hive/conf:ro
+
+ statestored:
+ image: apache/impala:4.0.0-statestored
+ ports:
+ - "25010"
+ command: ["-redirect_stdout_stderr=false", "-logtostderr", "-v=1"]
+ volumes:
+ - ./impala_conf:/opt/impala/conf:ro
+
+ catalogd:
+ depends_on:
+ - statestored
+ - metastore
+ image: apache/impala:4.0.0-catalogd
+ ports:
+ - "25020"
+ command: ["-redirect_stdout_stderr=false", "-logtostderr", "-v=1",
+ "-hms_event_polling_interval_s=1",
"-invalidate_tables_timeout_s=999999"]
+ volumes:
+ # Warehouse directory. Catalog does file operations so needs access to
the
+ # shared volume.
+ - impala-data:/user/hive/warehouse
+ - ./impala_conf:/opt/impala/conf:ro
+
+ impalad:
+ image: apache/impala:4.0.0-impalad_coord_exec
+ depends_on:
+ - statestored
+ - catalogd
+ ports:
+ - "21050:21050"
+ command: [ "-v=1",
+ "-redirect_stdout_stderr=false", "-logtostderr",
+ "-mt_dop_auto_fallback=true",
+
"-default_query_options=mt_dop=4,default_file_format=parquet,default_transactional_type=insert_only",
+ "-mem_limit=1500mb"]
+ environment:
+ # Keep the Java heap small to preserve memory for query execution.
+ - JAVA_TOOL_OPTIONS="-Xmx1g"
+ volumes:
+ - impala-data:/user/hive/warehouse
+ - ./impala_conf:/opt/impala/conf:ro
+
+volumes:
+ impala-data:
+
+networks:
+ default:
+ name: default-kyuubi-impala-test
diff --git
a/integration-tests/kyuubi-jdbc-it/src/test/resources/impala_conf/hive-site.xml
b/integration-tests/kyuubi-jdbc-it/src/test/resources/impala_conf/hive-site.xml
new file mode 100644
index 000000000..55fa54ef1
--- /dev/null
+++
b/integration-tests/kyuubi-jdbc-it/src/test/resources/impala_conf/hive-site.xml
@@ -0,0 +1,72 @@
+<?xml version="1.0"?>
+<?xml-stylesheet type="text/xsl" href="configuration.xsl"?>
+<!--
+ 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.
+-->
+<!-- Hive configuration for Impala quickstart docker cluster. -->
+<configuration>
+ <property>
+ <!-- Required for automatic metadata sync. -->
+ <name>hive.metastore.dml.events</name>
+ <value>true</value>
+ </property>
+ <property>
+ <!-- User impala is not authorized to consume notifications by default,
disable
+ authentication to work around this. -->
+ <name>hive.metastore.event.db.notification.api.auth</name>
+ <value>false</value>
+ </property>
+ <property>
+ <name>hive.metastore.uris</name>
+ <value>thrift://metastore:9083</value>
+ </property>
+ <!-- Managed and external tablespaces must live on the Docker volumes that we
+ configure for the quickstart cluster. -->
+ <property>
+ <name>hive.metastore.warehouse.dir</name>
+ <value>/user/hive/warehouse/managed</value>
+ </property>
+ <property>
+ <name>hive.metastore.warehouse.external.dir</name>
+ <value>/user/hive/warehouse/external</value>
+ </property>
+ <property>
+ <!-- Required to enable Hive transactions -->
+ <name>hive.support.concurrency</name>
+ <value>true</value>
+ </property>
+ <property>
+ <!-- Required to enable Hive transactions -->
+ <name>hive.txn.manager</name>
+ <value>org.apache.hadoop.hive.ql.lockmgr.DbTxnManager</value>
+ </property>
+ <property>
+ <!-- Use embedded Derby database -->
+ <name>javax.jdo.option.ConnectionDriverName</name>
+ <value>org.apache.derby.jdbc.EmbeddedDriver</value>
+ </property>
+ <property>
+ <!-- Use embedded Derby database -->
+ <name>javax.jdo.option.ConnectionURL</name>
+
<value>jdbc:derby:;databaseName=/var/lib/hive/metastore/metastore_db;create=true</value>
+ </property>
+ <!-- Hive stats autogathering negatively affects latency of DDL operations,
etc and
+ is not particularly useful for Impala -->
+ <property>
+ <name>hive.stats.autogather</name>
+ <value>false</value>
+ </property>
+</configuration>
diff --git
a/externals/kyuubi-jdbc-engine/src/main/scala/org/apache/kyuubi/engine/jdbc/postgresql/PostgreSQLConnectionProvider.scala
b/integration-tests/kyuubi-jdbc-it/src/test/scala/org/apache/kyuubi/it/jdbc/impala/OperationWithServerSuite.scala
similarity index 64%
copy from
externals/kyuubi-jdbc-engine/src/main/scala/org/apache/kyuubi/engine/jdbc/postgresql/PostgreSQLConnectionProvider.scala
copy to
integration-tests/kyuubi-jdbc-it/src/test/scala/org/apache/kyuubi/it/jdbc/impala/OperationWithServerSuite.scala
index a11e57768..8157d4d5c 100644
---
a/externals/kyuubi-jdbc-engine/src/main/scala/org/apache/kyuubi/engine/jdbc/postgresql/PostgreSQLConnectionProvider.scala
+++
b/integration-tests/kyuubi-jdbc-it/src/test/scala/org/apache/kyuubi/it/jdbc/impala/OperationWithServerSuite.scala
@@ -14,18 +14,14 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-package org.apache.kyuubi.engine.jdbc.postgresql
-import org.apache.kyuubi.engine.jdbc.connection.JdbcConnectionProvider
+package org.apache.kyuubi.it.jdbc.impala
-class PostgreSQLConnectionProvider extends JdbcConnectionProvider {
+import org.apache.kyuubi.engine.jdbc.impala.ImpalaOperationSuite
- override val name: String = classOf[PostgreSQLConnectionProvider].getName
+class OperationWithServerSuite extends ImpalaOperationSuite
+ with WithKyuubiServerAndImpalaContainer {
- override val driverClass: String = "org.postgresql.Driver"
-
- override def canHandle(providerClass: String): Boolean = {
- driverClass.equalsIgnoreCase(providerClass)
- }
+ override protected def jdbcUrl: String = getJdbcUrl
}
diff --git
a/externals/kyuubi-jdbc-engine/src/main/scala/org/apache/kyuubi/engine/jdbc/postgresql/PostgreSQLConnectionProvider.scala
b/integration-tests/kyuubi-jdbc-it/src/test/scala/org/apache/kyuubi/it/jdbc/impala/SessionWithServerSuite.scala
similarity index 64%
copy from
externals/kyuubi-jdbc-engine/src/main/scala/org/apache/kyuubi/engine/jdbc/postgresql/PostgreSQLConnectionProvider.scala
copy to
integration-tests/kyuubi-jdbc-it/src/test/scala/org/apache/kyuubi/it/jdbc/impala/SessionWithServerSuite.scala
index a11e57768..a8e8c3f9d 100644
---
a/externals/kyuubi-jdbc-engine/src/main/scala/org/apache/kyuubi/engine/jdbc/postgresql/PostgreSQLConnectionProvider.scala
+++
b/integration-tests/kyuubi-jdbc-it/src/test/scala/org/apache/kyuubi/it/jdbc/impala/SessionWithServerSuite.scala
@@ -14,18 +14,14 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-package org.apache.kyuubi.engine.jdbc.postgresql
-import org.apache.kyuubi.engine.jdbc.connection.JdbcConnectionProvider
+package org.apache.kyuubi.it.jdbc.impala
-class PostgreSQLConnectionProvider extends JdbcConnectionProvider {
+import org.apache.kyuubi.engine.jdbc.impala.SessionSuite
- override val name: String = classOf[PostgreSQLConnectionProvider].getName
+class SessionWithServerSuite extends SessionSuite
+ with WithKyuubiServerAndImpalaContainer {
- override val driverClass: String = "org.postgresql.Driver"
-
- override def canHandle(providerClass: String): Boolean = {
- driverClass.equalsIgnoreCase(providerClass)
- }
+ override protected def jdbcUrl: String = getJdbcUrl
}
diff --git
a/externals/kyuubi-jdbc-engine/src/main/scala/org/apache/kyuubi/engine/jdbc/postgresql/PostgreSQLConnectionProvider.scala
b/integration-tests/kyuubi-jdbc-it/src/test/scala/org/apache/kyuubi/it/jdbc/impala/StatementWithServerSuite.scala
similarity index 64%
copy from
externals/kyuubi-jdbc-engine/src/main/scala/org/apache/kyuubi/engine/jdbc/postgresql/PostgreSQLConnectionProvider.scala
copy to
integration-tests/kyuubi-jdbc-it/src/test/scala/org/apache/kyuubi/it/jdbc/impala/StatementWithServerSuite.scala
index a11e57768..d771ef847 100644
---
a/externals/kyuubi-jdbc-engine/src/main/scala/org/apache/kyuubi/engine/jdbc/postgresql/PostgreSQLConnectionProvider.scala
+++
b/integration-tests/kyuubi-jdbc-it/src/test/scala/org/apache/kyuubi/it/jdbc/impala/StatementWithServerSuite.scala
@@ -14,18 +14,14 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-package org.apache.kyuubi.engine.jdbc.postgresql
-import org.apache.kyuubi.engine.jdbc.connection.JdbcConnectionProvider
+package org.apache.kyuubi.it.jdbc.impala
-class PostgreSQLConnectionProvider extends JdbcConnectionProvider {
+import org.apache.kyuubi.engine.jdbc.impala.StatementSuite
- override val name: String = classOf[PostgreSQLConnectionProvider].getName
+class StatementWithServerSuite extends StatementSuite
+ with WithKyuubiServerAndImpalaContainer {
- override val driverClass: String = "org.postgresql.Driver"
-
- override def canHandle(providerClass: String): Boolean = {
- driverClass.equalsIgnoreCase(providerClass)
- }
+ override protected def jdbcUrl: String = getJdbcUrl
}
diff --git
a/integration-tests/kyuubi-jdbc-it/src/test/scala/org/apache/kyuubi/it/jdbc/impala/WithKyuubiServerAndImpalaContainer.scala
b/integration-tests/kyuubi-jdbc-it/src/test/scala/org/apache/kyuubi/it/jdbc/impala/WithKyuubiServerAndImpalaContainer.scala
new file mode 100644
index 000000000..e835d6fea
--- /dev/null
+++
b/integration-tests/kyuubi-jdbc-it/src/test/scala/org/apache/kyuubi/it/jdbc/impala/WithKyuubiServerAndImpalaContainer.scala
@@ -0,0 +1,59 @@
+/*
+ * 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.it.jdbc.impala
+
+import java.nio.file.{Files, Path, Paths}
+
+import org.apache.kyuubi.{Utils, WithKyuubiServer}
+import org.apache.kyuubi.config.KyuubiConf
+import org.apache.kyuubi.config.KyuubiConf.{ENGINE_JDBC_EXTRA_CLASSPATH,
KYUUBI_ENGINE_ENV_PREFIX, KYUUBI_HOME}
+import org.apache.kyuubi.engine.jdbc.impala.WithImpalaEngine
+
+trait WithKyuubiServerAndImpalaContainer extends WithKyuubiServer with
WithImpalaEngine {
+
+ private val kyuubiHome: String = Utils
+ .getCodeSourceLocation(getClass).split("integration-tests").head
+
+ private val hiveJdbcConnectorPath: String = {
+ val keyword = "kyuubi-hive-jdbc-shaded"
+
+ val jarsDir = Paths.get(kyuubiHome)
+ .resolve("integration-tests")
+ .resolve("kyuubi-jdbc-it")
+ .resolve("target")
+
+ Files.list(jarsDir)
+ .filter { p: Path => p.getFileName.toString contains keyword }
+ .findFirst
+ .orElseThrow { () => new IllegalStateException(s"Can not find $keyword
in $jarsDir.") }
+ .toAbsolutePath
+ .toString
+ }
+
+ override protected val conf: KyuubiConf = {
+ KyuubiConf()
+ .set(s"$KYUUBI_ENGINE_ENV_PREFIX.$KYUUBI_HOME", kyuubiHome)
+ .set(ENGINE_JDBC_EXTRA_CLASSPATH, hiveJdbcConnectorPath)
+ }
+
+ override def beforeAll(): Unit = {
+ val configs = withKyuubiConf
+ configs.foreach(config => conf.set(config._1, config._2))
+ super.beforeAll()
+ }
+}
diff --git
a/kyuubi-common/src/main/scala/org/apache/kyuubi/KyuubiSQLException.scala
b/kyuubi-common/src/main/scala/org/apache/kyuubi/KyuubiSQLException.scala
index 42579fb96..6153ac30e 100644
--- a/kyuubi-common/src/main/scala/org/apache/kyuubi/KyuubiSQLException.scala
+++ b/kyuubi-common/src/main/scala/org/apache/kyuubi/KyuubiSQLException.scala
@@ -82,8 +82,8 @@ object KyuubiSQLException {
}
}
- def featureNotSupported(): KyuubiSQLException = {
- KyuubiSQLException("feature not supported", sqlState = "0A000")
+ def featureNotSupported(message: String = "feature not supported"):
KyuubiSQLException = {
+ KyuubiSQLException(message, sqlState = "0A000")
}
def connectionDoesNotExist(): KyuubiSQLException = {