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 = {

Reply via email to