You are viewing a plain text version of this content. The canonical link for it is here.
Posted to notifications@skywalking.apache.org by wu...@apache.org on 2023/02/12 14:50:24 UTC

[skywalking-java] branch main updated: Add plugin to support clickhouse jdbc (#455)

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

wusheng pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/skywalking-java.git


The following commit(s) were added to refs/heads/main by this push:
     new 9cb5a13d44 Add plugin to support clickhouse jdbc (#455)
9cb5a13d44 is described below

commit 9cb5a13d447bfabaf7740628121ba0d8d6eb5f47
Author: 空青 <42...@users.noreply.github.com>
AuthorDate: Sun Feb 12 22:50:19 2023 +0800

    Add plugin to support clickhouse jdbc (#455)
    
    * Add plugin to support clickhouse-jdbc-0.3.2.*
    * Rename clickhouse-0.3.x-plugin to clickhouse-0.3.1-plugin
---
 .github/workflows/plugins-test.3.yaml              |   3 +-
 CHANGES.md                                         |   1 +
 .../pom.xml                                        |   4 +-
 .../ClickHouseStatementMethodInterceptor.java      |   0
 .../ClickHouseStatementTracingWrapper.java         |   0
 .../InitConnectionMethodInterceptor.java           |   0
 .../jdbc/clickhouse/TracedClickHouseStatement.java |   0
 .../define/ConnectionInstrumentation.java          |   0
 .../src/main/resources/skywalking-plugin.def       |   2 +-
 .../ClickHouseStatementMethodInterceptorTest.java  |   0
 .../InitConnectionMethodInterceptorTest.java       |   0
 .../pom.xml                                        |  10 +-
 ...ickHousePrepareStatementMethodInterceptor.java} |  27 +-
 .../v32/ClickHousePrepareStatementTracing.java}    |  10 +-
 .../v32/ClickHouseStatementInterceptor.java}       |  29 +-
 .../v32/InitConnectionConstructorInterceptor.java  |  53 ++
 .../v32/SWClickHousePreparedStatement.java         | 690 +++++++++++++++++++++
 .../jdbc/clickhouse/v32/SWClickHouseStatement.java | 390 ++++++++++++
 .../v32}/define/ConnectionInstrumentation.java     |  72 +--
 .../src/main/resources/skywalking-plugin.def       |   2 +-
 .../jdbc/clickhouse/AbstractStatementTest.java     |  62 ++
 .../InitConnectionConstructorInterceptorTest.java} |  25 +-
 .../SWClickHousePreparedStatementTest.java         | 560 +++++++++++++++++
 .../jdbc/clickhouse/SWClickHouseStatementTest.java | 264 ++++++++
 .../jdbc/clickhouse/SWClickhouseConnection.java    | 370 +++++++++++
 apm-sniffer/apm-sdk-plugin/pom.xml                 |   3 +-
 .../setup/service-agent/java-agent/Plugin-list.md  |   3 +-
 .../bin/startup.sh                                 |   2 +-
 .../config/expectedData.yaml                       |   2 +-
 .../configuration.yml                              |   2 +-
 .../pom.xml                                        |   6 +-
 .../src/main/assembly/assembly.xml                 |   2 +-
 .../skywalking/apm/testcase/neo4j/Application.java |   0
 .../testcase/neo4j/controller/CaseController.java  |   0
 .../src/main/resources/application.yaml            |   0
 .../src/main/resources/log4j2.xml                  |   0
 .../support-version.list                           |   0
 .../bin/startup.sh                                 |   2 +-
 .../config/expectedData.yaml                       |  78 +--
 .../configuration.yml                              |   2 +-
 .../pom.xml                                        |  10 +-
 .../src/main/assembly/assembly.xml                 |   2 +-
 .../skywalking/apm/testcase/neo4j/Application.java |  14 +-
 .../testcase/neo4j/controller/CaseController.java  |  11 +-
 .../src/main/resources/application.yaml            |   0
 .../src/main/resources/log4j2.xml                  |   0
 .../support-version.list                           |   3 +-
 47 files changed, 2523 insertions(+), 193 deletions(-)

diff --git a/.github/workflows/plugins-test.3.yaml b/.github/workflows/plugins-test.3.yaml
index 932429d166..3127472d31 100644
--- a/.github/workflows/plugins-test.3.yaml
+++ b/.github/workflows/plugins-test.3.yaml
@@ -93,7 +93,8 @@ jobs:
           - oracle-scenario
           - druid-1.x-scenario
           - hikaricp-scenario
-          - clickhouse-0.3.x-scenario
+          - clickhouse-0.3.1-scenario
+          - clickhouse-0.3.2.x-scenario
           - kylin-jdbc-2.6.x-3.x-4.x-scenario
           - undertow-worker-thread-pool-scenario
           - tomcat-thread-pool-scenario
diff --git a/CHANGES.md b/CHANGES.md
index cb56e7f0fd..9f95405d75 100644
--- a/CHANGES.md
+++ b/CHANGES.md
@@ -13,6 +13,7 @@ Release Notes.
 * Fix H2 instrumentation point
 * Refactor pipeline in jedis-plugin.
 * Enhance kotlin coroutine plugin for stack tracing.
+* Add plugin to support ClickHouse JDBC driver (0.3.2.*).
 
 #### Documentation
 * Update docs of Tracing APIs, reorganize the API docs into six parts.
diff --git a/apm-sniffer/apm-sdk-plugin/clickhouse-0.3.x-plugin/pom.xml b/apm-sniffer/apm-sdk-plugin/clickhouse-0.3.1-plugin/pom.xml
similarity index 95%
copy from apm-sniffer/apm-sdk-plugin/clickhouse-0.3.x-plugin/pom.xml
copy to apm-sniffer/apm-sdk-plugin/clickhouse-0.3.1-plugin/pom.xml
index 6a9a97ec62..69509fc6af 100755
--- a/apm-sniffer/apm-sdk-plugin/clickhouse-0.3.x-plugin/pom.xml
+++ b/apm-sniffer/apm-sdk-plugin/clickhouse-0.3.1-plugin/pom.xml
@@ -24,10 +24,10 @@
     </parent>
     <modelVersion>4.0.0</modelVersion>
 
-    <artifactId>apm-clickhouse-0.3.x-plugin</artifactId>
+    <artifactId>apm-clickhouse-0.3.1-plugin</artifactId>
     <packaging>jar</packaging>
 
-    <name>clickhouse-0.3.x-plugin</name>
+    <name>clickhouse-0.3.1-plugin</name>
 
     <properties>
         <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
diff --git a/apm-sniffer/apm-sdk-plugin/clickhouse-0.3.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/jdbc/clickhouse/ClickHouseStatementMethodInterceptor.java b/apm-sniffer/apm-sdk-plugin/clickhouse-0.3.1-plugin/src/main/java/org/apache/skywalking/apm/plugin/jdbc/clickhouse/ClickHouseStatementMethodInterceptor.java
similarity index 100%
copy from apm-sniffer/apm-sdk-plugin/clickhouse-0.3.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/jdbc/clickhouse/ClickHouseStatementMethodInterceptor.java
copy to apm-sniffer/apm-sdk-plugin/clickhouse-0.3.1-plugin/src/main/java/org/apache/skywalking/apm/plugin/jdbc/clickhouse/ClickHouseStatementMethodInterceptor.java
diff --git a/apm-sniffer/apm-sdk-plugin/clickhouse-0.3.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/jdbc/clickhouse/ClickHouseStatementTracingWrapper.java b/apm-sniffer/apm-sdk-plugin/clickhouse-0.3.1-plugin/src/main/java/org/apache/skywalking/apm/plugin/jdbc/clickhouse/ClickHouseStatementTracingWrapper.java
similarity index 100%
copy from apm-sniffer/apm-sdk-plugin/clickhouse-0.3.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/jdbc/clickhouse/ClickHouseStatementTracingWrapper.java
copy to apm-sniffer/apm-sdk-plugin/clickhouse-0.3.1-plugin/src/main/java/org/apache/skywalking/apm/plugin/jdbc/clickhouse/ClickHouseStatementTracingWrapper.java
diff --git a/apm-sniffer/apm-sdk-plugin/clickhouse-0.3.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/jdbc/clickhouse/InitConnectionMethodInterceptor.java b/apm-sniffer/apm-sdk-plugin/clickhouse-0.3.1-plugin/src/main/java/org/apache/skywalking/apm/plugin/jdbc/clickhouse/InitConnectionMethodInterceptor.java
similarity index 100%
rename from apm-sniffer/apm-sdk-plugin/clickhouse-0.3.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/jdbc/clickhouse/InitConnectionMethodInterceptor.java
rename to apm-sniffer/apm-sdk-plugin/clickhouse-0.3.1-plugin/src/main/java/org/apache/skywalking/apm/plugin/jdbc/clickhouse/InitConnectionMethodInterceptor.java
diff --git a/apm-sniffer/apm-sdk-plugin/clickhouse-0.3.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/jdbc/clickhouse/TracedClickHouseStatement.java b/apm-sniffer/apm-sdk-plugin/clickhouse-0.3.1-plugin/src/main/java/org/apache/skywalking/apm/plugin/jdbc/clickhouse/TracedClickHouseStatement.java
similarity index 100%
rename from apm-sniffer/apm-sdk-plugin/clickhouse-0.3.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/jdbc/clickhouse/TracedClickHouseStatement.java
rename to apm-sniffer/apm-sdk-plugin/clickhouse-0.3.1-plugin/src/main/java/org/apache/skywalking/apm/plugin/jdbc/clickhouse/TracedClickHouseStatement.java
diff --git a/apm-sniffer/apm-sdk-plugin/clickhouse-0.3.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/jdbc/clickhouse/define/ConnectionInstrumentation.java b/apm-sniffer/apm-sdk-plugin/clickhouse-0.3.1-plugin/src/main/java/org/apache/skywalking/apm/plugin/jdbc/clickhouse/define/ConnectionInstrumentation.java
similarity index 100%
copy from apm-sniffer/apm-sdk-plugin/clickhouse-0.3.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/jdbc/clickhouse/define/ConnectionInstrumentation.java
copy to apm-sniffer/apm-sdk-plugin/clickhouse-0.3.1-plugin/src/main/java/org/apache/skywalking/apm/plugin/jdbc/clickhouse/define/ConnectionInstrumentation.java
diff --git a/apm-sniffer/apm-sdk-plugin/clickhouse-0.3.x-plugin/src/main/resources/skywalking-plugin.def b/apm-sniffer/apm-sdk-plugin/clickhouse-0.3.1-plugin/src/main/resources/skywalking-plugin.def
similarity index 92%
copy from apm-sniffer/apm-sdk-plugin/clickhouse-0.3.x-plugin/src/main/resources/skywalking-plugin.def
copy to apm-sniffer/apm-sdk-plugin/clickhouse-0.3.1-plugin/src/main/resources/skywalking-plugin.def
index ea2f8f85be..75705a6187 100644
--- a/apm-sniffer/apm-sdk-plugin/clickhouse-0.3.x-plugin/src/main/resources/skywalking-plugin.def
+++ b/apm-sniffer/apm-sdk-plugin/clickhouse-0.3.1-plugin/src/main/resources/skywalking-plugin.def
@@ -14,4 +14,4 @@
 # See the License for the specific language governing permissions and
 # limitations under the License.
 
-clickhouse-0.3.x=org.apache.skywalking.apm.plugin.jdbc.clickhouse.define.ConnectionInstrumentation
+clickhouse-0.3.1=org.apache.skywalking.apm.plugin.jdbc.clickhouse.define.ConnectionInstrumentation
diff --git a/apm-sniffer/apm-sdk-plugin/clickhouse-0.3.x-plugin/src/test/java/org/apache/skywalking/apm/plugin/jdbc/clickhouse/ClickHouseStatementMethodInterceptorTest.java b/apm-sniffer/apm-sdk-plugin/clickhouse-0.3.1-plugin/src/test/java/org/apache/skywalking/apm/plugin/jdbc/clickhouse/ClickHouseStatementMethodInterceptorTest.java
similarity index 100%
rename from apm-sniffer/apm-sdk-plugin/clickhouse-0.3.x-plugin/src/test/java/org/apache/skywalking/apm/plugin/jdbc/clickhouse/ClickHouseStatementMethodInterceptorTest.java
rename to apm-sniffer/apm-sdk-plugin/clickhouse-0.3.1-plugin/src/test/java/org/apache/skywalking/apm/plugin/jdbc/clickhouse/ClickHouseStatementMethodInterceptorTest.java
diff --git a/apm-sniffer/apm-sdk-plugin/clickhouse-0.3.x-plugin/src/test/java/org/apache/skywalking/apm/plugin/jdbc/clickhouse/InitConnectionMethodInterceptorTest.java b/apm-sniffer/apm-sdk-plugin/clickhouse-0.3.1-plugin/src/test/java/org/apache/skywalking/apm/plugin/jdbc/clickhouse/InitConnectionMethodInterceptorTest.java
similarity index 100%
copy from apm-sniffer/apm-sdk-plugin/clickhouse-0.3.x-plugin/src/test/java/org/apache/skywalking/apm/plugin/jdbc/clickhouse/InitConnectionMethodInterceptorTest.java
copy to apm-sniffer/apm-sdk-plugin/clickhouse-0.3.1-plugin/src/test/java/org/apache/skywalking/apm/plugin/jdbc/clickhouse/InitConnectionMethodInterceptorTest.java
diff --git a/apm-sniffer/apm-sdk-plugin/clickhouse-0.3.x-plugin/pom.xml b/apm-sniffer/apm-sdk-plugin/clickhouse-0.3.2.x-plugin/pom.xml
similarity index 87%
rename from apm-sniffer/apm-sdk-plugin/clickhouse-0.3.x-plugin/pom.xml
rename to apm-sniffer/apm-sdk-plugin/clickhouse-0.3.2.x-plugin/pom.xml
index 6a9a97ec62..b1afa13a29 100755
--- a/apm-sniffer/apm-sdk-plugin/clickhouse-0.3.x-plugin/pom.xml
+++ b/apm-sniffer/apm-sdk-plugin/clickhouse-0.3.2.x-plugin/pom.xml
@@ -24,21 +24,21 @@
     </parent>
     <modelVersion>4.0.0</modelVersion>
 
-    <artifactId>apm-clickhouse-0.3.x-plugin</artifactId>
+    <artifactId>apm-clickhouse-0.3.2.x-plugin</artifactId>
     <packaging>jar</packaging>
 
-    <name>clickhouse-0.3.x-plugin</name>
+    <name>clickhouse-0.3.2.x-plugin</name>
 
     <properties>
         <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
-        <clickhouse.jdbc.version>0.3.1-patch</clickhouse.jdbc.version>
+        <clickhouse.jdbc.version>0.3.2-patch11</clickhouse.jdbc.version>
     </properties>
 
     <dependencies>
         <dependency>
-            <groupId>ru.yandex.clickhouse</groupId>
+            <groupId>com.clickhouse</groupId>
             <artifactId>clickhouse-jdbc</artifactId>
-            <version>${clickhouse.jdbc.version}</version>
+            <version>0.3.2-patch11</version>
             <scope>provided</scope>
         </dependency>
         <dependency>
diff --git a/apm-sniffer/apm-sdk-plugin/clickhouse-0.3.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/jdbc/clickhouse/ClickHouseStatementMethodInterceptor.java b/apm-sniffer/apm-sdk-plugin/clickhouse-0.3.2.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/jdbc/clickhouse/v32/ClickHousePrepareStatementMethodInterceptor.java
similarity index 67%
copy from apm-sniffer/apm-sdk-plugin/clickhouse-0.3.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/jdbc/clickhouse/ClickHouseStatementMethodInterceptor.java
copy to apm-sniffer/apm-sdk-plugin/clickhouse-0.3.2.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/jdbc/clickhouse/v32/ClickHousePrepareStatementMethodInterceptor.java
index e706dbb66b..66658b8075 100644
--- a/apm-sniffer/apm-sdk-plugin/clickhouse-0.3.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/jdbc/clickhouse/ClickHouseStatementMethodInterceptor.java
+++ b/apm-sniffer/apm-sdk-plugin/clickhouse-0.3.2.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/jdbc/clickhouse/v32/ClickHousePrepareStatementMethodInterceptor.java
@@ -16,43 +16,44 @@
  *
  */
 
-package org.apache.skywalking.apm.plugin.jdbc.clickhouse;
+package org.apache.skywalking.apm.plugin.jdbc.clickhouse.v32;
 
-import java.lang.reflect.Method;
+import com.clickhouse.jdbc.ClickHousePreparedStatement;
 import org.apache.skywalking.apm.agent.core.plugin.interceptor.enhance.EnhancedInstance;
 import org.apache.skywalking.apm.agent.core.plugin.interceptor.enhance.InstanceMethodsAroundInterceptor;
 import org.apache.skywalking.apm.agent.core.plugin.interceptor.enhance.MethodInterceptResult;
 import org.apache.skywalking.apm.plugin.jdbc.trace.ConnectionInfo;
-import ru.yandex.clickhouse.ClickHouseConnectionImpl;
-import ru.yandex.clickhouse.ClickHouseStatement;
+
+import java.lang.reflect.Method;
+import java.sql.Connection;
+import java.sql.PreparedStatement;
 
 /**
- * This interceptor is used to replace {@link org.apache.skywalking.apm.plugin.jdbc.JDBCStatementInterceptor}.
- * Because return value type of {@link ClickHouseConnectionImpl#createStatement()} method is {@link
- * ru.yandex.clickhouse.ClickHouseStatement} instead of {@link java.sql.Statement}.
+ * This interceptor is used to replace {@link org.apache.skywalking.apm.plugin.jdbc.JDBCPrepareStatementInterceptor}.
+ * Because 0.3.2 added implementation {@link ClickHousePreparedStatement#executeLargeUpdate()}
+ * and {@link ClickHousePreparedStatement#executeLargeBatch()}
  */
-public class ClickHouseStatementMethodInterceptor implements InstanceMethodsAroundInterceptor {
+public class ClickHousePrepareStatementMethodInterceptor implements InstanceMethodsAroundInterceptor {
 
     @Override
     public void beforeMethod(EnhancedInstance objInst, Method method, Object[] allArguments, Class<?>[] argumentsTypes,
-            MethodInterceptResult result) throws Throwable {
+                             MethodInterceptResult result) throws Throwable {
 
     }
 
     @Override
     public Object afterMethod(EnhancedInstance objInst, Method method, Object[] allArguments, Class<?>[] argumentsTypes,
-            Object ret) throws Throwable {
+                              Object ret) throws Throwable {
         final Object connectionInfo = objInst.getSkyWalkingDynamicField();
         if (connectionInfo == null) {
             return ret;
         }
-
-        return new TracedClickHouseStatement((ClickHouseStatement) ret, (ConnectionInfo) connectionInfo);
+        return new SWClickHousePreparedStatement((Connection) objInst, (PreparedStatement) ret, (ConnectionInfo) objInst.getSkyWalkingDynamicField(), (String) allArguments[0]);
     }
 
     @Override
     public void handleMethodException(EnhancedInstance objInst, Method method, Object[] allArguments,
-            Class<?>[] argumentsTypes, Throwable t) {
+                                      Class<?>[] argumentsTypes, Throwable t) {
 
     }
 }
diff --git a/apm-sniffer/apm-sdk-plugin/clickhouse-0.3.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/jdbc/clickhouse/ClickHouseStatementTracingWrapper.java b/apm-sniffer/apm-sdk-plugin/clickhouse-0.3.2.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/jdbc/clickhouse/v32/ClickHousePrepareStatementTracing.java
similarity index 88%
rename from apm-sniffer/apm-sdk-plugin/clickhouse-0.3.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/jdbc/clickhouse/ClickHouseStatementTracingWrapper.java
rename to apm-sniffer/apm-sdk-plugin/clickhouse-0.3.2.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/jdbc/clickhouse/v32/ClickHousePrepareStatementTracing.java
index 6f2e9bcaa0..292dd413a7 100644
--- a/apm-sniffer/apm-sdk-plugin/clickhouse-0.3.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/jdbc/clickhouse/ClickHouseStatementTracingWrapper.java
+++ b/apm-sniffer/apm-sdk-plugin/clickhouse-0.3.2.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/jdbc/clickhouse/v32/ClickHousePrepareStatementTracing.java
@@ -16,19 +16,21 @@
  *
  */
 
-package org.apache.skywalking.apm.plugin.jdbc.clickhouse;
+package org.apache.skywalking.apm.plugin.jdbc.clickhouse.v32;
 
-import java.sql.SQLException;
 import org.apache.skywalking.apm.agent.core.context.ContextManager;
 import org.apache.skywalking.apm.agent.core.context.tag.Tags;
 import org.apache.skywalking.apm.agent.core.context.trace.AbstractSpan;
 import org.apache.skywalking.apm.agent.core.context.trace.SpanLayer;
 import org.apache.skywalking.apm.plugin.jdbc.trace.ConnectionInfo;
 
+import java.sql.SQLException;
+
 /**
- *
+ * {@link ClickHousePrepareStatementTracing} create an exit span when the client call the method in the class that extend {@link
+ * java.sql.PreparedStatement}.
  */
-public class ClickHouseStatementTracingWrapper {
+public class ClickHousePrepareStatementTracing {
 
     public static <T> T of(ConnectionInfo connectionInfo, String methodName, String sql,
             SupplierWithException<T> supplier) throws SQLException {
diff --git a/apm-sniffer/apm-sdk-plugin/clickhouse-0.3.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/jdbc/clickhouse/ClickHouseStatementMethodInterceptor.java b/apm-sniffer/apm-sdk-plugin/clickhouse-0.3.2.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/jdbc/clickhouse/v32/ClickHouseStatementInterceptor.java
similarity index 62%
rename from apm-sniffer/apm-sdk-plugin/clickhouse-0.3.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/jdbc/clickhouse/ClickHouseStatementMethodInterceptor.java
rename to apm-sniffer/apm-sdk-plugin/clickhouse-0.3.2.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/jdbc/clickhouse/v32/ClickHouseStatementInterceptor.java
index e706dbb66b..36821839d5 100644
--- a/apm-sniffer/apm-sdk-plugin/clickhouse-0.3.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/jdbc/clickhouse/ClickHouseStatementMethodInterceptor.java
+++ b/apm-sniffer/apm-sdk-plugin/clickhouse-0.3.2.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/jdbc/clickhouse/v32/ClickHouseStatementInterceptor.java
@@ -16,43 +16,42 @@
  *
  */
 
-package org.apache.skywalking.apm.plugin.jdbc.clickhouse;
+package org.apache.skywalking.apm.plugin.jdbc.clickhouse.v32;
 
 import java.lang.reflect.Method;
+
+import com.clickhouse.jdbc.ClickHouseConnection;
+import com.clickhouse.jdbc.ClickHouseStatement;
 import org.apache.skywalking.apm.agent.core.plugin.interceptor.enhance.EnhancedInstance;
 import org.apache.skywalking.apm.agent.core.plugin.interceptor.enhance.InstanceMethodsAroundInterceptor;
 import org.apache.skywalking.apm.agent.core.plugin.interceptor.enhance.MethodInterceptResult;
+import org.apache.skywalking.apm.plugin.jdbc.JDBCStatementInterceptor;
 import org.apache.skywalking.apm.plugin.jdbc.trace.ConnectionInfo;
-import ru.yandex.clickhouse.ClickHouseConnectionImpl;
-import ru.yandex.clickhouse.ClickHouseStatement;
+import org.apache.skywalking.apm.plugin.jdbc.trace.SWStatement;
 
 /**
- * This interceptor is used to replace {@link org.apache.skywalking.apm.plugin.jdbc.JDBCStatementInterceptor}.
- * Because return value type of {@link ClickHouseConnectionImpl#createStatement()} method is {@link
- * ru.yandex.clickhouse.ClickHouseStatement} instead of {@link java.sql.Statement}.
+ * {@link JDBCStatementInterceptor} return {@link SWStatement} instance that wrapper the real Statement instance when
+ * the client call <code>createStatement</code> method.
  */
-public class ClickHouseStatementMethodInterceptor implements InstanceMethodsAroundInterceptor {
-
+public class ClickHouseStatementInterceptor implements InstanceMethodsAroundInterceptor {
     @Override
     public void beforeMethod(EnhancedInstance objInst, Method method, Object[] allArguments, Class<?>[] argumentsTypes,
-            MethodInterceptResult result) throws Throwable {
+                             MethodInterceptResult result) throws Throwable {
 
     }
 
     @Override
     public Object afterMethod(EnhancedInstance objInst, Method method, Object[] allArguments, Class<?>[] argumentsTypes,
-            Object ret) throws Throwable {
-        final Object connectionInfo = objInst.getSkyWalkingDynamicField();
-        if (connectionInfo == null) {
+                              Object ret) throws Throwable {
+        if (objInst.getSkyWalkingDynamicField() == null) {
             return ret;
         }
-
-        return new TracedClickHouseStatement((ClickHouseStatement) ret, (ConnectionInfo) connectionInfo);
+        return new SWClickHouseStatement((ClickHouseConnection) objInst, (ClickHouseStatement) ret, (ConnectionInfo) objInst.getSkyWalkingDynamicField());
     }
 
     @Override
     public void handleMethodException(EnhancedInstance objInst, Method method, Object[] allArguments,
-            Class<?>[] argumentsTypes, Throwable t) {
+                                      Class<?>[] argumentsTypes, Throwable t) {
 
     }
 }
diff --git a/apm-sniffer/apm-sdk-plugin/clickhouse-0.3.2.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/jdbc/clickhouse/v32/InitConnectionConstructorInterceptor.java b/apm-sniffer/apm-sdk-plugin/clickhouse-0.3.2.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/jdbc/clickhouse/v32/InitConnectionConstructorInterceptor.java
new file mode 100644
index 0000000000..6298ea9ecb
--- /dev/null
+++ b/apm-sniffer/apm-sdk-plugin/clickhouse-0.3.2.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/jdbc/clickhouse/v32/InitConnectionConstructorInterceptor.java
@@ -0,0 +1,53 @@
+/*
+ * 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.skywalking.apm.plugin.jdbc.clickhouse.v32;
+
+import com.clickhouse.client.ClickHouseNode;
+import com.clickhouse.jdbc.internal.ClickHouseConnectionImpl;
+import com.clickhouse.jdbc.internal.ClickHouseJdbcUrlParser;
+import org.apache.skywalking.apm.agent.core.plugin.interceptor.enhance.EnhancedInstance;
+import org.apache.skywalking.apm.agent.core.plugin.interceptor.enhance.InstanceConstructorInterceptor;
+import org.apache.skywalking.apm.network.trace.component.ComponentsDefine;
+import org.apache.skywalking.apm.plugin.jdbc.trace.ConnectionInfo;
+
+/**
+ * Enhance {@link ClickHouseConnectionImpl#ClickHouseConnectionImpl(ClickHouseJdbcUrlParser.ConnectionInfo)} method.
+ * <p>
+ * ClickHouse JDBC Driver uses this method to simulate the action of connecting database in JDBC protocol.
+ * So this method is enhanced to prevent the generation of exit span of http type.
+ * </p>
+ * <p>
+ * This interceptor is used to replace {@link org.apache.skywalking.apm.plugin.jdbc.JDBCDriverInterceptor}.
+ * </p>
+ */
+public class InitConnectionConstructorInterceptor implements InstanceConstructorInterceptor {
+
+    @Override
+    public void onConstruct(EnhancedInstance objInst, Object[] allArguments) throws Throwable {
+        ClickHouseJdbcUrlParser.ConnectionInfo clickhouseConnectionInfo = (ClickHouseJdbcUrlParser.ConnectionInfo) allArguments[0];
+
+        for (ClickHouseNode node : clickhouseConnectionInfo.getNodes().getNodes()) {
+            final ConnectionInfo connectionInfo = new ConnectionInfo(ComponentsDefine.CLICKHOUSE_JDBC_DRIVER,
+                    "ClickHouse", node.getHost(), node.getPort(),
+                    node.getDatabase().orElse(""));
+            objInst.setSkyWalkingDynamicField(connectionInfo);
+        }
+    }
+
+}
diff --git a/apm-sniffer/apm-sdk-plugin/clickhouse-0.3.2.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/jdbc/clickhouse/v32/SWClickHousePreparedStatement.java b/apm-sniffer/apm-sdk-plugin/clickhouse-0.3.2.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/jdbc/clickhouse/v32/SWClickHousePreparedStatement.java
new file mode 100644
index 0000000000..b09e4d89b7
--- /dev/null
+++ b/apm-sniffer/apm-sdk-plugin/clickhouse-0.3.2.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/jdbc/clickhouse/v32/SWClickHousePreparedStatement.java
@@ -0,0 +1,690 @@
+/*
+ * 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.skywalking.apm.plugin.jdbc.clickhouse.v32;
+
+import org.apache.skywalking.apm.plugin.jdbc.trace.ConnectionInfo;
+import org.apache.skywalking.apm.plugin.jdbc.trace.PreparedStatementTracing;
+
+import java.io.InputStream;
+import java.io.Reader;
+import java.math.BigDecimal;
+import java.net.URL;
+import java.sql.Array;
+import java.sql.Blob;
+import java.sql.Clob;
+import java.sql.Connection;
+import java.sql.Date;
+import java.sql.NClob;
+import java.sql.ParameterMetaData;
+import java.sql.PreparedStatement;
+import java.sql.Ref;
+import java.sql.ResultSet;
+import java.sql.ResultSetMetaData;
+import java.sql.RowId;
+import java.sql.SQLException;
+import java.sql.SQLWarning;
+import java.sql.SQLXML;
+import java.sql.SQLType;
+import java.sql.Time;
+import java.sql.Timestamp;
+import java.util.Calendar;
+
+/**
+ * Enhance based {@link org.apache.skywalking.apm.plugin.jdbc.trace.SWPreparedStatement}
+ * {@link SWClickHousePreparedStatement} wrapper the {@link PreparedStatement} created by client. and it will interceptor the
+ * following methods for trace. 1. {@link #execute()} 2. {@link #execute(String)} 3. {@link #execute(String, int[])} 4.
+ * {@link #execute(String, String[])} 5. {@link #execute(String, int)} 6. {@link #executeQuery()} 7. {@link
+ * #executeQuery(String)} 8. {@link #executeUpdate()} 9. {@link #executeUpdate(String)} 10. {@link
+ * #executeUpdate(String, int[])} 11. {@link #executeUpdate(String, String[])} 12. {@link #executeUpdate(String, int)}
+ * 13. {@link #addBatch()} 14. {@link #addBatch(String)} ()
+ * <p>
+ * Next comes the extension method
+ * 15. {@link #executeLargeUpdate()} 16. {@link #executeLargeBatch()} ()}
+ */
+public class SWClickHousePreparedStatement implements PreparedStatement {
+    private Connection realConnection;
+    private PreparedStatement realStatement;
+    private ConnectionInfo connectInfo;
+    private String sql;
+
+    public SWClickHousePreparedStatement(Connection realConnection, PreparedStatement realStatement, ConnectionInfo connectInfo,
+                                         String sql) {
+        this.realConnection = realConnection;
+        this.realStatement = realStatement;
+        this.connectInfo = connectInfo;
+        this.sql = sql;
+    }
+
+    @Override
+    public void setObject(int parameterIndex, Object x, SQLType targetSqlType, int scaleOrLength) throws SQLException {
+        realStatement.setObject(parameterIndex, x, targetSqlType, scaleOrLength);
+    }
+
+    @Override
+    public void setObject(int parameterIndex, Object x, SQLType targetSqlType) throws SQLException {
+        realStatement.setObject(parameterIndex, x, targetSqlType);
+    }
+
+    @Override
+    public long executeLargeUpdate() throws SQLException {
+        return ClickHousePrepareStatementTracing.of(connectInfo, "executeLargeUpdate", "", realStatement::executeLargeUpdate);
+    }
+
+    @Override
+    public long getLargeUpdateCount() throws SQLException {
+        return realStatement.getLargeUpdateCount();
+    }
+
+    @Override
+    public void setLargeMaxRows(long max) throws SQLException {
+        realStatement.setLargeMaxRows(max);
+    }
+
+    @Override
+    public long getLargeMaxRows() throws SQLException {
+        return realStatement.getLargeMaxRows();
+    }
+
+    @Override
+    public long[] executeLargeBatch() throws SQLException {
+        return ClickHousePrepareStatementTracing.of(connectInfo, "executeLargeBatch", "", realStatement::executeLargeBatch);
+    }
+
+    @Override
+    public long executeLargeUpdate(String sql) throws SQLException {
+        return realStatement.executeLargeUpdate(sql);
+    }
+
+    @Override
+    public long executeLargeUpdate(String sql, int autoGeneratedKeys) throws SQLException {
+        return realStatement.executeLargeUpdate(sql, autoGeneratedKeys);
+    }
+
+    @Override
+    public long executeLargeUpdate(String sql, int[] columnIndexes) throws SQLException {
+        return realStatement.executeLargeUpdate(sql, columnIndexes);
+    }
+
+    @Override
+    public long executeLargeUpdate(String sql, String[] columnNames) throws SQLException {
+        return realStatement.executeLargeUpdate(sql, columnNames);
+    }
+
+    @Override
+    public ResultSet executeQuery(String sql) throws SQLException {
+        return PreparedStatementTracing.execute(realStatement, connectInfo, "executeQuery", sql, new PreparedStatementTracing.Executable<ResultSet>() {
+            @Override
+            public ResultSet exe(PreparedStatement realStatement, String sql) throws SQLException {
+                return realStatement.executeQuery(sql);
+            }
+        });
+    }
+
+    @Override
+    public int executeUpdate(String sql) throws SQLException {
+        return PreparedStatementTracing.execute(realStatement, connectInfo, "executeUpdate", sql, new PreparedStatementTracing.Executable<Integer>() {
+            @Override
+            public Integer exe(PreparedStatement realStatement, String sql) throws SQLException {
+                return realStatement.executeUpdate(sql);
+            }
+        });
+    }
+
+    @Override
+    public void close() throws SQLException {
+        realStatement.close();
+    }
+
+    @Override
+    public int getMaxFieldSize() throws SQLException {
+        return realStatement.getMaxFieldSize();
+    }
+
+    @Override
+    public void setMaxFieldSize(int max) throws SQLException {
+        realStatement.setMaxFieldSize(max);
+    }
+
+    @Override
+    public int getMaxRows() throws SQLException {
+        return realStatement.getMaxRows();
+    }
+
+    @Override
+    public void setMaxRows(int max) throws SQLException {
+        realStatement.setMaxRows(max);
+    }
+
+    @Override
+    public void setEscapeProcessing(boolean enable) throws SQLException {
+        realStatement.setEscapeProcessing(enable);
+    }
+
+    @Override
+    public int getQueryTimeout() throws SQLException {
+        return realStatement.getQueryTimeout();
+    }
+
+    @Override
+    public void setQueryTimeout(int seconds) throws SQLException {
+        realStatement.setQueryTimeout(seconds);
+    }
+
+    @Override
+    public void cancel() throws SQLException {
+        realStatement.cancel();
+    }
+
+    @Override
+    public SQLWarning getWarnings() throws SQLException {
+        return realStatement.getWarnings();
+    }
+
+    @Override
+    public void clearWarnings() throws SQLException {
+        realStatement.clearWarnings();
+    }
+
+    @Override
+    public void setCursorName(String name) throws SQLException {
+        realStatement.setCursorName(name);
+    }
+
+    @Override
+    public boolean execute(String sql) throws SQLException {
+        return PreparedStatementTracing.execute(realStatement, connectInfo, "execute", sql, new PreparedStatementTracing.Executable<Boolean>() {
+            @Override
+            public Boolean exe(PreparedStatement realStatement, String sql) throws SQLException {
+                return realStatement.execute(sql);
+            }
+        });
+    }
+
+    @Override
+    public ResultSet getResultSet() throws SQLException {
+        return realStatement.getResultSet();
+    }
+
+    @Override
+    public int getUpdateCount() throws SQLException {
+        return realStatement.getUpdateCount();
+    }
+
+    @Override
+    public boolean getMoreResults() throws SQLException {
+        return realStatement.getMoreResults();
+    }
+
+    @Override
+    public void setFetchDirection(int direction) throws SQLException {
+        realStatement.setFetchDirection(direction);
+    }
+
+    @Override
+    public int getFetchDirection() throws SQLException {
+        return realStatement.getFetchDirection();
+    }
+
+    @Override
+    public void setFetchSize(int rows) throws SQLException {
+        realStatement.setFetchSize(rows);
+    }
+
+    @Override
+    public int getFetchSize() throws SQLException {
+        return realStatement.getFetchSize();
+    }
+
+    @Override
+    public int getResultSetConcurrency() throws SQLException {
+        return realStatement.getResultSetConcurrency();
+    }
+
+    @Override
+    public int getResultSetType() throws SQLException {
+        return realStatement.getResultSetType();
+    }
+
+    @Override
+    public void addBatch(String sql) throws SQLException {
+        realStatement.addBatch(sql);
+    }
+
+    @Override
+    public void clearBatch() throws SQLException {
+        realStatement.clearBatch();
+    }
+
+    @Override
+    public int[] executeBatch() throws SQLException {
+        return PreparedStatementTracing.execute(realStatement, connectInfo, "executeBatch", "", new PreparedStatementTracing.Executable<int[]>() {
+            @Override
+            public int[] exe(PreparedStatement realStatement, String sql) throws SQLException {
+                return realStatement.executeBatch();
+            }
+        });
+    }
+
+    @Override
+    public Connection getConnection() throws SQLException {
+        return realConnection;
+    }
+
+    @Override
+    public boolean getMoreResults(int current) throws SQLException {
+        return realStatement.getMoreResults(current);
+    }
+
+    @Override
+    public ResultSet getGeneratedKeys() throws SQLException {
+        return realStatement.getGeneratedKeys();
+    }
+
+    @Override
+    public int executeUpdate(String sql, final int autoGeneratedKeys) throws SQLException {
+        return PreparedStatementTracing.execute(realStatement, connectInfo, "executeUpdate", sql, new PreparedStatementTracing.Executable<Integer>() {
+            @Override
+            public Integer exe(PreparedStatement realStatement, String sql) throws SQLException {
+                return realStatement.executeUpdate(sql, autoGeneratedKeys);
+            }
+        });
+    }
+
+    @Override
+    public int executeUpdate(String sql, final int[] columnIndexes) throws SQLException {
+        return PreparedStatementTracing.execute(realStatement, connectInfo, "executeUpdate", sql, new PreparedStatementTracing.Executable<Integer>() {
+            @Override
+            public Integer exe(PreparedStatement realStatement, String sql) throws SQLException {
+                return realStatement.executeUpdate(sql, columnIndexes);
+            }
+        });
+    }
+
+    @Override
+    public int executeUpdate(String sql, final String[] columnNames) throws SQLException {
+        return PreparedStatementTracing.execute(realStatement, connectInfo, "executeUpdate", sql, new PreparedStatementTracing.Executable<Integer>() {
+            @Override
+            public Integer exe(PreparedStatement realStatement, String sql) throws SQLException {
+                return realStatement.executeUpdate(sql, columnNames);
+            }
+        });
+    }
+
+    @Override
+    public boolean execute(String sql, final int autoGeneratedKeys) throws SQLException {
+        return PreparedStatementTracing.execute(realStatement, connectInfo, "execute", sql, new PreparedStatementTracing.Executable<Boolean>() {
+            @Override
+            public Boolean exe(PreparedStatement realStatement, String sql) throws SQLException {
+                return realStatement.execute(sql, autoGeneratedKeys);
+            }
+        });
+    }
+
+    @Override
+    public boolean execute(String sql, final int[] columnIndexes) throws SQLException {
+        return PreparedStatementTracing.execute(realStatement, connectInfo, "execute", sql, new PreparedStatementTracing.Executable<Boolean>() {
+            @Override
+            public Boolean exe(PreparedStatement realStatement, String sql) throws SQLException {
+                return realStatement.execute(sql, columnIndexes);
+            }
+        });
+    }
+
+    @Override
+    public boolean execute(String sql, final String[] columnNames) throws SQLException {
+        return PreparedStatementTracing.execute(realStatement, connectInfo, "execute", sql, new PreparedStatementTracing.Executable<Boolean>() {
+            @Override
+            public Boolean exe(PreparedStatement realStatement, String sql) throws SQLException {
+                return realStatement.execute(sql, columnNames);
+            }
+        });
+    }
+
+    @Override
+    public int getResultSetHoldability() throws SQLException {
+        return realStatement.getResultSetHoldability();
+    }
+
+    @Override
+    public boolean isClosed() throws SQLException {
+        return realStatement.isClosed();
+    }
+
+    @Override
+    public void setPoolable(boolean poolable) throws SQLException {
+        realStatement.setPoolable(poolable);
+    }
+
+    @Override
+    public boolean isPoolable() throws SQLException {
+        return realStatement.isPoolable();
+    }
+
+    @Override
+    public void closeOnCompletion() throws SQLException {
+        realStatement.closeOnCompletion();
+    }
+
+    @Override
+    public boolean isCloseOnCompletion() throws SQLException {
+        return realStatement.isCloseOnCompletion();
+    }
+
+    @Override
+    public <T> T unwrap(Class<T> iface) throws SQLException {
+        return realStatement.unwrap(iface);
+    }
+
+    @Override
+    public boolean isWrapperFor(Class<?> iface) throws SQLException {
+        return realStatement.isWrapperFor(iface);
+    }
+
+    @Override
+    public ResultSet executeQuery() throws SQLException {
+        return PreparedStatementTracing.execute(realStatement, connectInfo, "executeQuery", sql, new PreparedStatementTracing.Executable<ResultSet>() {
+            @Override
+            public ResultSet exe(PreparedStatement realStatement, String sql) throws SQLException {
+                return realStatement.executeQuery();
+            }
+        });
+    }
+
+    @Override
+    public int executeUpdate() throws SQLException {
+        return PreparedStatementTracing.execute(realStatement, connectInfo, "executeUpdate", sql, new PreparedStatementTracing.Executable<Integer>() {
+            @Override
+            public Integer exe(PreparedStatement realStatement, String sql) throws SQLException {
+                return realStatement.executeUpdate();
+            }
+        });
+    }
+
+    @Override
+    public void setNull(int parameterIndex, int sqlType) throws SQLException {
+        realStatement.setNull(parameterIndex, sqlType);
+    }
+
+    @Override
+    public void setBoolean(int parameterIndex, boolean x) throws SQLException {
+        realStatement.setBoolean(parameterIndex, x);
+    }
+
+    @Override
+    public void setByte(int parameterIndex, byte x) throws SQLException {
+        realStatement.setByte(parameterIndex, x);
+    }
+
+    @Override
+    public void setShort(int parameterIndex, short x) throws SQLException {
+        realStatement.setShort(parameterIndex, x);
+    }
+
+    @Override
+    public void setInt(int parameterIndex, int x) throws SQLException {
+        realStatement.setInt(parameterIndex, x);
+    }
+
+    @Override
+    public void setLong(int parameterIndex, long x) throws SQLException {
+        realStatement.setLong(parameterIndex, x);
+    }
+
+    @Override
+    public void setFloat(int parameterIndex, float x) throws SQLException {
+        realStatement.setFloat(parameterIndex, x);
+    }
+
+    @Override
+    public void setDouble(int parameterIndex, double x) throws SQLException {
+        realStatement.setDouble(parameterIndex, x);
+    }
+
+    @Override
+    public void setBigDecimal(int parameterIndex, BigDecimal x) throws SQLException {
+        realStatement.setBigDecimal(parameterIndex, x);
+    }
+
+    @Override
+    public void setString(int parameterIndex, String x) throws SQLException {
+        realStatement.setString(parameterIndex, x);
+    }
+
+    @Override
+    public void setBytes(int parameterIndex, byte[] x) throws SQLException {
+        realStatement.setBytes(parameterIndex, x);
+    }
+
+    @Override
+    public void setDate(int parameterIndex, Date x) throws SQLException {
+        realStatement.setDate(parameterIndex, x);
+    }
+
+    @Override
+    public void setTime(int parameterIndex, Time x) throws SQLException {
+        realStatement.setTime(parameterIndex, x);
+    }
+
+    @Override
+    public void setTimestamp(int parameterIndex, Timestamp x) throws SQLException {
+        realStatement.setTimestamp(parameterIndex, x);
+    }
+
+    @Override
+    public void setAsciiStream(int parameterIndex, InputStream x, int length) throws SQLException {
+        realStatement.setAsciiStream(parameterIndex, x, length);
+    }
+
+    @Override
+    @Deprecated
+    public void setUnicodeStream(int parameterIndex, InputStream x, int length) throws SQLException {
+        realStatement.setUnicodeStream(parameterIndex, x, length);
+    }
+
+    @Override
+    public void setBinaryStream(int parameterIndex, InputStream x, int length) throws SQLException {
+        realStatement.setBinaryStream(parameterIndex, x, length);
+    }
+
+    @Override
+    public void clearParameters() throws SQLException {
+        realStatement.clearParameters();
+    }
+
+    @Override
+    public void setObject(int parameterIndex, Object x, int targetSqlType) throws SQLException {
+        realStatement.setObject(parameterIndex, x, targetSqlType);
+    }
+
+    @Override
+    public void setObject(int parameterIndex, Object x) throws SQLException {
+        realStatement.setObject(parameterIndex, x);
+    }
+
+    @Override
+    public boolean execute() throws SQLException {
+        return PreparedStatementTracing.execute(realStatement, connectInfo, "execute", sql, new PreparedStatementTracing.Executable<Boolean>() {
+            @Override
+            public Boolean exe(PreparedStatement realStatement, String sql) throws SQLException {
+                return realStatement.execute();
+            }
+        });
+    }
+
+    @Override
+    public void addBatch() throws SQLException {
+        realStatement.addBatch();
+    }
+
+    @Override
+    public void setCharacterStream(int parameterIndex, Reader reader, int length) throws SQLException {
+        realStatement.setCharacterStream(parameterIndex, reader, length);
+    }
+
+    @Override
+    public void setRef(int parameterIndex, Ref x) throws SQLException {
+        realStatement.setRef(parameterIndex, x);
+    }
+
+    @Override
+    public void setBlob(int parameterIndex, Blob x) throws SQLException {
+        realStatement.setBlob(parameterIndex, x);
+    }
+
+    @Override
+    public void setClob(int parameterIndex, Clob x) throws SQLException {
+        realStatement.setClob(parameterIndex, x);
+    }
+
+    @Override
+    public void setArray(int parameterIndex, Array x) throws SQLException {
+        realStatement.setArray(parameterIndex, x);
+    }
+
+    @Override
+    public ResultSetMetaData getMetaData() throws SQLException {
+        return realStatement.getMetaData();
+    }
+
+    @Override
+    public void setDate(int parameterIndex, Date x, Calendar cal) throws SQLException {
+        realStatement.setDate(parameterIndex, x, cal);
+    }
+
+    @Override
+    public void setTime(int parameterIndex, Time x, Calendar cal) throws SQLException {
+        realStatement.setTime(parameterIndex, x, cal);
+    }
+
+    @Override
+    public void setTimestamp(int parameterIndex, Timestamp x, Calendar cal) throws SQLException {
+        realStatement.setTimestamp(parameterIndex, x, cal);
+    }
+
+    @Override
+    public void setNull(int parameterIndex, int sqlType, String typeName) throws SQLException {
+        realStatement.setNull(parameterIndex, sqlType, typeName);
+    }
+
+    @Override
+    public void setURL(int parameterIndex, URL x) throws SQLException {
+        realStatement.setURL(parameterIndex, x);
+    }
+
+    @Override
+    public ParameterMetaData getParameterMetaData() throws SQLException {
+        return realStatement.getParameterMetaData();
+    }
+
+    @Override
+    public void setRowId(int parameterIndex, RowId x) throws SQLException {
+        realStatement.setRowId(parameterIndex, x);
+    }
+
+    @Override
+    public void setNString(int parameterIndex, String value) throws SQLException {
+        realStatement.setNString(parameterIndex, value);
+    }
+
+    @Override
+    public void setNCharacterStream(int parameterIndex, Reader value, long length) throws SQLException {
+        realStatement.setNCharacterStream(parameterIndex, value, length);
+    }
+
+    @Override
+    public void setNClob(int parameterIndex, NClob value) throws SQLException {
+        realStatement.setNClob(parameterIndex, value);
+    }
+
+    @Override
+    public void setClob(int parameterIndex, Reader reader, long length) throws SQLException {
+        realStatement.setClob(parameterIndex, reader, length);
+    }
+
+    @Override
+    public void setBlob(int parameterIndex, InputStream inputStream, long length) throws SQLException {
+        realStatement.setBlob(parameterIndex, inputStream, length);
+    }
+
+    @Override
+    public void setNClob(int parameterIndex, Reader reader, long length) throws SQLException {
+        realStatement.setNClob(parameterIndex, reader, length);
+    }
+
+    @Override
+    public void setSQLXML(int parameterIndex, SQLXML xmlObject) throws SQLException {
+        realStatement.setSQLXML(parameterIndex, xmlObject);
+    }
+
+    @Override
+    public void setObject(int parameterIndex, Object x, int targetSqlType, int scaleOrLength) throws SQLException {
+        realStatement.setObject(parameterIndex, x, targetSqlType, scaleOrLength);
+    }
+
+    @Override
+    public void setAsciiStream(int parameterIndex, InputStream x, long length) throws SQLException {
+        realStatement.setAsciiStream(parameterIndex, x, length);
+    }
+
+    @Override
+    public void setBinaryStream(int parameterIndex, InputStream x, long length) throws SQLException {
+        realStatement.setBinaryStream(parameterIndex, x, length);
+    }
+
+    @Override
+    public void setCharacterStream(int parameterIndex, Reader reader, long length) throws SQLException {
+        realStatement.setCharacterStream(parameterIndex, reader, length);
+    }
+
+    @Override
+    public void setAsciiStream(int parameterIndex, InputStream x) throws SQLException {
+        realStatement.setAsciiStream(parameterIndex, x);
+    }
+
+    @Override
+    public void setBinaryStream(int parameterIndex, InputStream x) throws SQLException {
+        realStatement.setBinaryStream(parameterIndex, x);
+    }
+
+    @Override
+    public void setCharacterStream(int parameterIndex, Reader reader) throws SQLException {
+        realStatement.setCharacterStream(parameterIndex, reader);
+    }
+
+    @Override
+    public void setNCharacterStream(int parameterIndex, Reader value) throws SQLException {
+        realStatement.setNCharacterStream(parameterIndex, value);
+    }
+
+    @Override
+    public void setClob(int parameterIndex, Reader reader) throws SQLException {
+        realStatement.setClob(parameterIndex, reader);
+    }
+
+    @Override
+    public void setBlob(int parameterIndex, InputStream inputStream) throws SQLException {
+        realStatement.setBlob(parameterIndex, inputStream);
+    }
+
+    @Override
+    public void setNClob(int parameterIndex, Reader reader) throws SQLException {
+        realStatement.setNClob(parameterIndex, reader);
+    }
+
+}
diff --git a/apm-sniffer/apm-sdk-plugin/clickhouse-0.3.2.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/jdbc/clickhouse/v32/SWClickHouseStatement.java b/apm-sniffer/apm-sdk-plugin/clickhouse-0.3.2.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/jdbc/clickhouse/v32/SWClickHouseStatement.java
new file mode 100644
index 0000000000..0334cb7b11
--- /dev/null
+++ b/apm-sniffer/apm-sdk-plugin/clickhouse-0.3.2.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/jdbc/clickhouse/v32/SWClickHouseStatement.java
@@ -0,0 +1,390 @@
+/*
+ * 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.skywalking.apm.plugin.jdbc.clickhouse.v32;
+
+import com.clickhouse.client.ClickHouseConfig;
+import com.clickhouse.client.ClickHouseRequest;
+import com.clickhouse.jdbc.ClickHouseConnection;
+import com.clickhouse.jdbc.ClickHouseStatement;
+import org.apache.skywalking.apm.plugin.jdbc.trace.ConnectionInfo;
+import org.apache.skywalking.apm.plugin.jdbc.trace.StatementTracing;
+
+import java.sql.ResultSet;
+import java.sql.SQLException;
+import java.sql.SQLWarning;
+
+/**
+ * Enhance based {@link org.apache.skywalking.apm.plugin.jdbc.trace.SWStatement}
+ * {@link SWClickHouseStatement} wrapper the {@link java.sql.Statement} created by client. and it will interceptor the following
+ * methods for trace. 1. {@link #execute(String)} 2. {@link #execute(String, int[])} 3. {@link #execute(String,
+ * String[])} 4. {@link #execute(String, int)} 5. {@link #executeQuery(String)} 6. {@link #executeUpdate(String)} 7.
+ * {@link #executeUpdate(String, int[])} 8. {@link #executeUpdate(String, String[])} 9. {@link #executeUpdate(String,
+ * int)} 10. {@link #addBatch(String)} ()}
+ * <p>
+ * Next comes the extension method
+ * * 11. {@link #executeLargeUpdate(String)} ()} 12. {@link #executeLargeBatch()} ()}
+ */
+
+public class SWClickHouseStatement implements ClickHouseStatement {
+    private ClickHouseConnection realConnection;
+    private ClickHouseStatement realStatement;
+    private ConnectionInfo connectInfo;
+
+    public SWClickHouseStatement(ClickHouseConnection realConnection, ClickHouseStatement realStatement, ConnectionInfo connectInfo) {
+        this.realConnection = realConnection;
+        this.realStatement = realStatement;
+        this.connectInfo = connectInfo;
+    }
+
+    @Override
+    public ClickHouseConfig getConfig() {
+        return realStatement.getConfig();
+    }
+
+    @Override
+    public int getNullAsDefault() {
+        return realStatement.getNullAsDefault();
+    }
+
+    @Override
+    public void setNullAsDefault(int level) {
+        realStatement.setNullAsDefault(level);
+    }
+
+    @Override
+    public ClickHouseRequest<?> getRequest() {
+        return realStatement.getRequest();
+    }
+
+    @Override
+    public ClickHouseRequest.Mutation write() {
+        return realStatement.write();
+    }
+
+    @Override
+    public long getLargeUpdateCount() throws SQLException {
+        return realStatement.getLargeUpdateCount();
+    }
+
+    @Override
+    public void setLargeMaxRows(long max) throws SQLException {
+        realStatement.setLargeMaxRows(max);
+    }
+
+    @Override
+    public long getLargeMaxRows() throws SQLException {
+        return realStatement.getLargeMaxRows();
+    }
+
+    @Override
+    public long[] executeLargeBatch() throws SQLException {
+        return realStatement.executeLargeBatch();
+    }
+
+    @Override
+    public long executeLargeUpdate(String sql) throws SQLException {
+        return realStatement.executeLargeUpdate(sql);
+    }
+
+    @Override
+    public long executeLargeUpdate(String sql, int autoGeneratedKeys) throws SQLException {
+        return realStatement.executeLargeUpdate(sql, autoGeneratedKeys);
+    }
+
+    @Override
+    public long executeLargeUpdate(String sql, int[] columnIndexes) throws SQLException {
+        return realStatement.executeLargeUpdate(sql, columnIndexes);
+    }
+
+    @Override
+    public long executeLargeUpdate(String sql, String[] columnNames) throws SQLException {
+        return realStatement.executeLargeUpdate(sql, columnNames);
+    }
+
+    @Override
+    public <T> T unwrap(Class<T> iface) throws SQLException {
+        return realStatement.unwrap(iface);
+    }
+
+    @Override
+    public boolean isWrapperFor(Class<?> iface) throws SQLException {
+        return realStatement.isWrapperFor(iface);
+    }
+
+    @Override
+    public ResultSet executeQuery(String sql) throws SQLException {
+        return StatementTracing.execute(realStatement, connectInfo, "executeQuery", sql, new StatementTracing.Executable<ResultSet>() {
+            @Override
+            public ResultSet exe(java.sql.Statement realStatement, String sql) throws SQLException {
+                return realStatement.executeQuery(sql);
+            }
+        });
+    }
+
+    @Override
+    public int executeUpdate(String sql) throws SQLException {
+        return StatementTracing.execute(realStatement, connectInfo, "executeUpdate", sql, new StatementTracing.Executable<Integer>() {
+            @Override
+            public Integer exe(java.sql.Statement realStatement, String sql) throws SQLException {
+                return realStatement.executeUpdate(sql);
+            }
+        });
+    }
+
+    @Override
+    public void close() throws SQLException {
+        realStatement.close();
+    }
+
+    @Override
+    public int getMaxFieldSize() throws SQLException {
+        return realStatement.getMaxFieldSize();
+    }
+
+    @Override
+    public void setMaxFieldSize(int max) throws SQLException {
+        realStatement.setMaxFieldSize(max);
+    }
+
+    @Override
+    public int getMaxRows() throws SQLException {
+        return realStatement.getMaxRows();
+    }
+
+    @Override
+    public void setMaxRows(int max) throws SQLException {
+        realStatement.setMaxRows(max);
+    }
+
+    @Override
+    public void setEscapeProcessing(boolean enable) throws SQLException {
+        realStatement.setEscapeProcessing(enable);
+    }
+
+    @Override
+    public int getQueryTimeout() throws SQLException {
+        return realStatement.getQueryTimeout();
+    }
+
+    @Override
+    public void setQueryTimeout(int seconds) throws SQLException {
+        realStatement.setQueryTimeout(seconds);
+    }
+
+    @Override
+    public void cancel() throws SQLException {
+        realStatement.cancel();
+    }
+
+    @Override
+    public SQLWarning getWarnings() throws SQLException {
+        return realStatement.getWarnings();
+    }
+
+    @Override
+    public void clearWarnings() throws SQLException {
+        realStatement.clearWarnings();
+    }
+
+    @Override
+    public void setCursorName(String name) throws SQLException {
+        realStatement.setCursorName(name);
+    }
+
+    @Override
+    public boolean execute(String sql) throws SQLException {
+        return StatementTracing.execute(realStatement, connectInfo, "execute", sql, new StatementTracing.Executable<Boolean>() {
+            @Override
+            public Boolean exe(java.sql.Statement realStatement, String sql) throws SQLException {
+                return realStatement.execute(sql);
+            }
+        });
+    }
+
+    @Override
+    public ResultSet getResultSet() throws SQLException {
+        return realStatement.getResultSet();
+    }
+
+    @Override
+    public int getUpdateCount() throws SQLException {
+        return realStatement.getUpdateCount();
+    }
+
+    @Override
+    public boolean getMoreResults() throws SQLException {
+        return realStatement.getMoreResults();
+    }
+
+    @Override
+    public void setFetchDirection(int direction) throws SQLException {
+        realStatement.setFetchDirection(direction);
+    }
+
+    @Override
+    public int getFetchDirection() throws SQLException {
+        return realStatement.getFetchDirection();
+    }
+
+    @Override
+    public void setFetchSize(int rows) throws SQLException {
+        realStatement.setFetchSize(rows);
+    }
+
+    @Override
+    public int getFetchSize() throws SQLException {
+        return realStatement.getFetchSize();
+    }
+
+    @Override
+    public int getResultSetConcurrency() throws SQLException {
+        return realStatement.getResultSetConcurrency();
+    }
+
+    @Override
+    public int getResultSetType() throws SQLException {
+        return realStatement.getResultSetType();
+    }
+
+    @Override
+    public void addBatch(String sql) throws SQLException {
+        realStatement.addBatch(sql);
+    }
+
+    @Override
+    public void clearBatch() throws SQLException {
+        realStatement.clearBatch();
+    }
+
+    @Override
+    public int[] executeBatch() throws SQLException {
+        return StatementTracing.execute(realStatement, connectInfo, "executeBatch", "", new StatementTracing.Executable<int[]>() {
+            @Override
+            public int[] exe(java.sql.Statement realStatement, String sql) throws SQLException {
+                return realStatement.executeBatch();
+            }
+        });
+    }
+
+    @Override
+    public ClickHouseConnection getConnection() throws SQLException {
+        return this.realConnection;
+    }
+
+    @Override
+    public boolean getMoreResults(int current) throws SQLException {
+        return realStatement.getMoreResults(current);
+    }
+
+    @Override
+    public ResultSet getGeneratedKeys() throws SQLException {
+        return realStatement.getGeneratedKeys();
+    }
+
+    @Override
+    public int executeUpdate(String sql, final int autoGeneratedKeys) throws SQLException {
+        return StatementTracing.execute(realStatement, connectInfo, "executeUpdate", sql, new StatementTracing.Executable<Integer>() {
+            @Override
+            public Integer exe(java.sql.Statement realStatement, String sql) throws SQLException {
+                return realStatement.executeUpdate(sql, autoGeneratedKeys);
+            }
+        });
+    }
+
+    @Override
+    public int executeUpdate(String sql, final int[] columnIndexes) throws SQLException {
+        return StatementTracing.execute(realStatement, connectInfo, "executeUpdate", sql, new StatementTracing.Executable<Integer>() {
+            @Override
+            public Integer exe(java.sql.Statement realStatement, String sql) throws SQLException {
+                return realStatement.executeUpdate(sql, columnIndexes);
+            }
+        });
+    }
+
+    @Override
+    public int executeUpdate(String sql, final String[] columnNames) throws SQLException {
+        return StatementTracing.execute(realStatement, connectInfo, "executeUpdate", sql, new StatementTracing.Executable<Integer>() {
+            @Override
+            public Integer exe(java.sql.Statement realStatement, String sql) throws SQLException {
+                return realStatement.executeUpdate(sql, columnNames);
+            }
+        });
+    }
+
+    @Override
+    public boolean execute(String sql, final int autoGeneratedKeys) throws SQLException {
+        return StatementTracing.execute(realStatement, connectInfo, "execute", sql, new StatementTracing.Executable<Boolean>() {
+            @Override
+            public Boolean exe(java.sql.Statement realStatement, String sql) throws SQLException {
+                return realStatement.execute(sql, autoGeneratedKeys);
+            }
+        });
+    }
+
+    @Override
+    public boolean execute(String sql, final int[] columnIndexes) throws SQLException {
+        return StatementTracing.execute(realStatement, connectInfo, "execute", sql, new StatementTracing.Executable<Boolean>() {
+            @Override
+            public Boolean exe(java.sql.Statement realStatement, String sql) throws SQLException {
+                return realStatement.execute(sql, columnIndexes);
+            }
+        });
+    }
+
+    @Override
+    public boolean execute(String sql, final String[] columnNames) throws SQLException {
+        return StatementTracing.execute(realStatement, connectInfo, "execute", sql, new StatementTracing.Executable<Boolean>() {
+            @Override
+            public Boolean exe(java.sql.Statement realStatement, String sql) throws SQLException {
+                return realStatement.execute(sql, columnNames);
+            }
+        });
+    }
+
+    @Override
+    public int getResultSetHoldability() throws SQLException {
+        return realStatement.getResultSetHoldability();
+    }
+
+    @Override
+    public boolean isClosed() throws SQLException {
+        return realStatement.isClosed();
+    }
+
+    @Override
+    public void setPoolable(boolean poolable) throws SQLException {
+        realStatement.setPoolable(poolable);
+    }
+
+    @Override
+    public boolean isPoolable() throws SQLException {
+        return realStatement.isPoolable();
+    }
+
+    @Override
+    public void closeOnCompletion() throws SQLException {
+        realStatement.closeOnCompletion();
+    }
+
+    @Override
+    public boolean isCloseOnCompletion() throws SQLException {
+        return realStatement.isCloseOnCompletion();
+    }
+
+}
diff --git a/apm-sniffer/apm-sdk-plugin/clickhouse-0.3.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/jdbc/clickhouse/define/ConnectionInstrumentation.java b/apm-sniffer/apm-sdk-plugin/clickhouse-0.3.2.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/jdbc/clickhouse/v32/define/ConnectionInstrumentation.java
similarity index 70%
rename from apm-sniffer/apm-sdk-plugin/clickhouse-0.3.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/jdbc/clickhouse/define/ConnectionInstrumentation.java
rename to apm-sniffer/apm-sdk-plugin/clickhouse-0.3.2.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/jdbc/clickhouse/v32/define/ConnectionInstrumentation.java
index d7fd1f2b14..5c63598a0f 100644
--- a/apm-sniffer/apm-sdk-plugin/clickhouse-0.3.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/jdbc/clickhouse/define/ConnectionInstrumentation.java
+++ b/apm-sniffer/apm-sdk-plugin/clickhouse-0.3.2.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/jdbc/clickhouse/v32/define/ConnectionInstrumentation.java
@@ -16,70 +16,73 @@
  *
  */
 
-package org.apache.skywalking.apm.plugin.jdbc.clickhouse.define;
-
-import static net.bytebuddy.matcher.ElementMatchers.named;
-import static org.apache.skywalking.apm.agent.core.plugin.match.NameMatch.byName;
+package org.apache.skywalking.apm.plugin.jdbc.clickhouse.v32.define;
 
 import net.bytebuddy.description.method.MethodDescription;
 import net.bytebuddy.matcher.ElementMatcher;
-import net.bytebuddy.matcher.ElementMatchers;
 import org.apache.skywalking.apm.agent.core.plugin.interceptor.ConstructorInterceptPoint;
 import org.apache.skywalking.apm.agent.core.plugin.interceptor.InstanceMethodsInterceptPoint;
 import org.apache.skywalking.apm.agent.core.plugin.interceptor.enhance.ClassInstanceMethodsEnhancePluginDefine;
 import org.apache.skywalking.apm.agent.core.plugin.match.ClassMatch;
 import org.apache.skywalking.apm.plugin.jdbc.define.Constants;
 
+import static net.bytebuddy.matcher.ElementMatchers.named;
+import static net.bytebuddy.matcher.ElementMatchers.takesArguments;
+import static org.apache.skywalking.apm.agent.core.plugin.bytebuddy.ArgumentTypeNameMatch.takesArgumentWithType;
+import static org.apache.skywalking.apm.agent.core.plugin.match.NameMatch.byName;
+
 /**
- * Intercept {@link ru.yandex.clickhouse.ClickHouseConnectionImpl} class.
+ * Intercept {@link com.clickhouse.jdbc.internal.ClickHouseConnectionImpl} class.
  */
 public class ConnectionInstrumentation extends ClassInstanceMethodsEnhancePluginDefine {
 
-    private final static String ENHANCE_CLASS = "ru.yandex.clickhouse.ClickHouseConnectionImpl";
-    private final static String INIT_CONNECTION_METHOD_NAME = "initConnection";
-    private final static String INIT_CONNECTION_METHOD_INTERCEPTOR = "org.apache.skywalking.apm.plugin.jdbc.clickhouse.InitConnectionMethodInterceptor";
-    private final static String CREATE_CLICKHOUSE_STATEMENT_METHOD_NAME = "createClickHouseStatement";
-    private final static String CREATE_CLICKHOUSE_STATEMENT_INTERCEPTOR = "org.apache.skywalking.apm.plugin.jdbc.clickhouse.ClickHouseStatementMethodInterceptor";
+    private final static String ENHANCE_CLASS = "com.clickhouse.jdbc.internal.ClickHouseConnectionImpl";
+
+    private final static String ENHANCE_INIT_CONNECTION_METHOD = "com.clickhouse.jdbc.internal.ClickHouseJdbcUrlParser$ConnectionInfo";
+    private final static String INIT_CONNECTION_METHOD_INTERCEPTOR_CLASS = "org.apache.skywalking.apm.plugin.jdbc.clickhouse.v32.InitConnectionConstructorInterceptor";
+
+    private final static String STATEMENT_INTERCEPT_CLASS = "org.apache.skywalking.apm.plugin.jdbc.clickhouse.v32.ClickHouseStatementInterceptor";
+    private final static String PREPARE_STATEMENT_INTERCEPT_CLASS = "org.apache.skywalking.apm.plugin.jdbc.clickhouse.v32.ClickHousePrepareStatementMethodInterceptor";
 
     @Override
-    protected ClassMatch enhanceClass() {
-        return byName(ENHANCE_CLASS);
+    protected final String[] witnessClasses() {
+        return new String[]{ENHANCE_CLASS};
     }
 
     @Override
-    public ConstructorInterceptPoint[] getConstructorsInterceptPoints() {
-        return new ConstructorInterceptPoint[0];
+    protected ClassMatch enhanceClass() {
+        return byName(ENHANCE_CLASS);
     }
 
     @Override
-    public InstanceMethodsInterceptPoint[] getInstanceMethodsInterceptPoints() {
-        return new InstanceMethodsInterceptPoint[] {
-                new InstanceMethodsInterceptPoint() {
+    public ConstructorInterceptPoint[] getConstructorsInterceptPoints() {
+        return new ConstructorInterceptPoint[]{
+                new ConstructorInterceptPoint() {
                     @Override
-                    public ElementMatcher<MethodDescription> getMethodsMatcher() {
-                        return named(Constants.CREATE_STATEMENT_METHOD_NAME).or(
-                                named(CREATE_CLICKHOUSE_STATEMENT_METHOD_NAME));
+                    public ElementMatcher<MethodDescription> getConstructorMatcher() {
+                        return takesArgumentWithType(0, ENHANCE_INIT_CONNECTION_METHOD);
                     }
 
                     @Override
-                    public String getMethodsInterceptor() {
-                        return CREATE_CLICKHOUSE_STATEMENT_INTERCEPTOR;
+                    public String getConstructorInterceptor() {
+                        return INIT_CONNECTION_METHOD_INTERCEPTOR_CLASS;
                     }
+                }
+        };
+    }
 
-                    @Override
-                    public boolean isOverrideArgs() {
-                        return false;
-                    }
-                },
+    @Override
+    public InstanceMethodsInterceptPoint[] getInstanceMethodsInterceptPoints() {
+        return new InstanceMethodsInterceptPoint[]{
                 new InstanceMethodsInterceptPoint() {
                     @Override
                     public ElementMatcher<MethodDescription> getMethodsMatcher() {
-                        return named(Constants.PREPARE_STATEMENT_METHOD_NAME);
+                        return named(Constants.CREATE_STATEMENT_METHOD_NAME);
                     }
 
                     @Override
                     public String getMethodsInterceptor() {
-                        return Constants.PREPARE_STATEMENT_INTERCEPT_CLASS;
+                        return STATEMENT_INTERCEPT_CLASS;
                     }
 
                     @Override
@@ -90,12 +93,12 @@ public class ConnectionInstrumentation extends ClassInstanceMethodsEnhancePlugin
                 new InstanceMethodsInterceptPoint() {
                     @Override
                     public ElementMatcher<MethodDescription> getMethodsMatcher() {
-                        return named(Constants.CLOSE_METHOD_NAME);
+                        return named(Constants.PREPARE_STATEMENT_METHOD_NAME).and(takesArguments(4));
                     }
 
                     @Override
                     public String getMethodsInterceptor() {
-                        return Constants.SERVICE_METHOD_INTERCEPT_CLASS;
+                        return PREPARE_STATEMENT_INTERCEPT_CLASS;
                     }
 
                     @Override
@@ -106,13 +109,12 @@ public class ConnectionInstrumentation extends ClassInstanceMethodsEnhancePlugin
                 new InstanceMethodsInterceptPoint() {
                     @Override
                     public ElementMatcher<MethodDescription> getMethodsMatcher() {
-                        return named(INIT_CONNECTION_METHOD_NAME).and(ElementMatchers.takesArgument(0,
-                                named("ru.yandex.clickhouse.settings.ClickHouseProperties")));
+                        return named(Constants.CLOSE_METHOD_NAME);
                     }
 
                     @Override
                     public String getMethodsInterceptor() {
-                        return INIT_CONNECTION_METHOD_INTERCEPTOR;
+                        return Constants.SERVICE_METHOD_INTERCEPT_CLASS;
                     }
 
                     @Override
diff --git a/apm-sniffer/apm-sdk-plugin/clickhouse-0.3.x-plugin/src/main/resources/skywalking-plugin.def b/apm-sniffer/apm-sdk-plugin/clickhouse-0.3.2.x-plugin/src/main/resources/skywalking-plugin.def
similarity index 88%
rename from apm-sniffer/apm-sdk-plugin/clickhouse-0.3.x-plugin/src/main/resources/skywalking-plugin.def
rename to apm-sniffer/apm-sdk-plugin/clickhouse-0.3.2.x-plugin/src/main/resources/skywalking-plugin.def
index ea2f8f85be..241641077c 100644
--- a/apm-sniffer/apm-sdk-plugin/clickhouse-0.3.x-plugin/src/main/resources/skywalking-plugin.def
+++ b/apm-sniffer/apm-sdk-plugin/clickhouse-0.3.2.x-plugin/src/main/resources/skywalking-plugin.def
@@ -14,4 +14,4 @@
 # See the License for the specific language governing permissions and
 # limitations under the License.
 
-clickhouse-0.3.x=org.apache.skywalking.apm.plugin.jdbc.clickhouse.define.ConnectionInstrumentation
+clickhouse-0.3.2.x=org.apache.skywalking.apm.plugin.jdbc.clickhouse.v32.define.ConnectionInstrumentation
diff --git a/apm-sniffer/apm-sdk-plugin/clickhouse-0.3.2.x-plugin/src/test/java/org/apache/skywalking/apm/plugin/jdbc/clickhouse/AbstractStatementTest.java b/apm-sniffer/apm-sdk-plugin/clickhouse-0.3.2.x-plugin/src/test/java/org/apache/skywalking/apm/plugin/jdbc/clickhouse/AbstractStatementTest.java
new file mode 100644
index 0000000000..0d44e6d4fc
--- /dev/null
+++ b/apm-sniffer/apm-sdk-plugin/clickhouse-0.3.2.x-plugin/src/test/java/org/apache/skywalking/apm/plugin/jdbc/clickhouse/AbstractStatementTest.java
@@ -0,0 +1,62 @@
+/*
+ * 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.skywalking.apm.plugin.jdbc.clickhouse;
+
+import org.apache.skywalking.apm.agent.core.context.trace.AbstractTracingSpan;
+import org.apache.skywalking.apm.agent.core.context.trace.LogDataEntity;
+import org.apache.skywalking.apm.agent.core.context.trace.SpanLayer;
+import org.apache.skywalking.apm.agent.core.context.util.TagValuePair;
+import org.apache.skywalking.apm.agent.test.helper.SpanHelper;
+import org.hamcrest.CoreMatchers;
+import org.junit.Assert;
+
+import java.sql.SQLException;
+import java.util.List;
+
+import static junit.framework.TestCase.assertNotNull;
+import static org.hamcrest.CoreMatchers.is;
+import static org.hamcrest.MatcherAssert.assertThat;
+
+public abstract class AbstractStatementTest {
+
+    protected void assertDBSpanLog(LogDataEntity logData) {
+        Assert.assertThat(logData.getLogs().size(), is(4));
+        Assert.assertThat(logData.getLogs().get(0).getValue(), CoreMatchers.<Object>is("error"));
+        Assert.assertThat(logData.getLogs().get(1).getValue(), CoreMatchers.<Object>is(SQLException.class.getName()));
+        Assert.assertNull(logData.getLogs().get(2).getValue());
+        assertNotNull(logData.getLogs().get(3).getValue());
+    }
+
+    protected void assertDBSpan(AbstractTracingSpan span, String exceptOperationName, String exceptDBStatement) {
+        assertDBSpan(span, exceptOperationName);
+        assertThat(span.isExit(), is(true));
+        List<TagValuePair> tags = SpanHelper.getTags(span);
+        assertThat(tags.get(2).getValue(), is(exceptDBStatement));
+    }
+
+    protected void assertDBSpan(AbstractTracingSpan span, String exceptOperationName) {
+        assertThat(span.getOperationName(), is(exceptOperationName));
+        assertThat(SpanHelper.getComponentId(span), is(119));
+        List<TagValuePair> tags = SpanHelper.getTags(span);
+        assertThat(tags.get(0).getValue(), is("ClickHouse"));
+        assertThat(tags.get(1).getValue(), is("test"));
+        assertThat(SpanHelper.getLayer(span), CoreMatchers.is(SpanLayer.DB));
+    }
+
+}
diff --git a/apm-sniffer/apm-sdk-plugin/clickhouse-0.3.x-plugin/src/test/java/org/apache/skywalking/apm/plugin/jdbc/clickhouse/InitConnectionMethodInterceptorTest.java b/apm-sniffer/apm-sdk-plugin/clickhouse-0.3.2.x-plugin/src/test/java/org/apache/skywalking/apm/plugin/jdbc/clickhouse/InitConnectionConstructorInterceptorTest.java
similarity index 77%
rename from apm-sniffer/apm-sdk-plugin/clickhouse-0.3.x-plugin/src/test/java/org/apache/skywalking/apm/plugin/jdbc/clickhouse/InitConnectionMethodInterceptorTest.java
rename to apm-sniffer/apm-sdk-plugin/clickhouse-0.3.2.x-plugin/src/test/java/org/apache/skywalking/apm/plugin/jdbc/clickhouse/InitConnectionConstructorInterceptorTest.java
index 6aef6ae42d..9d9987aaca 100644
--- a/apm-sniffer/apm-sdk-plugin/clickhouse-0.3.x-plugin/src/test/java/org/apache/skywalking/apm/plugin/jdbc/clickhouse/InitConnectionMethodInterceptorTest.java
+++ b/apm-sniffer/apm-sdk-plugin/clickhouse-0.3.2.x-plugin/src/test/java/org/apache/skywalking/apm/plugin/jdbc/clickhouse/InitConnectionConstructorInterceptorTest.java
@@ -18,20 +18,23 @@
 
 package org.apache.skywalking.apm.plugin.jdbc.clickhouse;
 
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertNotNull;
-import static org.mockito.Mockito.when;
+import com.clickhouse.client.ClickHouseNodes;
+import com.clickhouse.jdbc.internal.ClickHouseJdbcUrlParser;
 import org.apache.skywalking.apm.agent.core.plugin.interceptor.enhance.EnhancedInstance;
+import org.apache.skywalking.apm.plugin.jdbc.clickhouse.v32.InitConnectionConstructorInterceptor;
 import org.apache.skywalking.apm.plugin.jdbc.trace.ConnectionInfo;
 import org.junit.Before;
 import org.junit.Test;
 import org.junit.runner.RunWith;
 import org.mockito.Mock;
 import org.mockito.junit.MockitoJUnitRunner;
-import ru.yandex.clickhouse.settings.ClickHouseProperties;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+import static org.mockito.Mockito.when;
 
 @RunWith(MockitoJUnitRunner.class)
-public class InitConnectionMethodInterceptorTest {
+public class InitConnectionConstructorInterceptorTest {
 
     private final EnhancedInstance enhancedInstance = new EnhancedInstance() {
         private Object value;
@@ -46,21 +49,19 @@ public class InitConnectionMethodInterceptorTest {
             this.value = value;
         }
     };
-    private InitConnectionMethodInterceptor targetInterceptor;
+    private InitConnectionConstructorInterceptor targetInterceptor;
     @Mock
-    private ClickHouseProperties clickHouseProperties;
+    private ClickHouseJdbcUrlParser.ConnectionInfo connectionInfo;
 
     @Before
     public void setUp() throws Exception {
-        targetInterceptor = new InitConnectionMethodInterceptor();
-        when(clickHouseProperties.getHost()).thenReturn("127.0.0.1");
-        when(clickHouseProperties.getPort()).thenReturn(8123);
-        when(clickHouseProperties.getDatabase()).thenReturn("default");
+        targetInterceptor = new InitConnectionConstructorInterceptor();
+        when(connectionInfo.getNodes()).thenReturn(ClickHouseNodes.of("http://127.0.0.1:8123/default"));
     }
 
     @Test
     public void test() throws Throwable {
-        targetInterceptor.beforeMethod(enhancedInstance, null, new Object[] {clickHouseProperties}, new Class[0], null);
+        targetInterceptor.onConstruct(enhancedInstance, new Object[]{connectionInfo});
         final ConnectionInfo connectionInfo = (ConnectionInfo) enhancedInstance.getSkyWalkingDynamicField();
         assertNotNull(connectionInfo);
         assertEquals("ClickHouse-jdbc-driver", connectionInfo.getComponent().getName());
diff --git a/apm-sniffer/apm-sdk-plugin/clickhouse-0.3.2.x-plugin/src/test/java/org/apache/skywalking/apm/plugin/jdbc/clickhouse/SWClickHousePreparedStatementTest.java b/apm-sniffer/apm-sdk-plugin/clickhouse-0.3.2.x-plugin/src/test/java/org/apache/skywalking/apm/plugin/jdbc/clickhouse/SWClickHousePreparedStatementTest.java
new file mode 100644
index 0000000000..54ade27107
--- /dev/null
+++ b/apm-sniffer/apm-sdk-plugin/clickhouse-0.3.2.x-plugin/src/test/java/org/apache/skywalking/apm/plugin/jdbc/clickhouse/SWClickHousePreparedStatementTest.java
@@ -0,0 +1,560 @@
+/*
+ * 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.skywalking.apm.plugin.jdbc.clickhouse;
+
+import com.clickhouse.jdbc.ClickHousePreparedStatement;
+import com.clickhouse.jdbc.internal.ClickHouseConnectionImpl;
+import org.apache.skywalking.apm.agent.core.context.trace.AbstractTracingSpan;
+import org.apache.skywalking.apm.agent.core.context.trace.LogDataEntity;
+import org.apache.skywalking.apm.agent.core.context.trace.TraceSegment;
+import org.apache.skywalking.apm.agent.test.helper.SegmentHelper;
+import org.apache.skywalking.apm.agent.test.helper.SpanHelper;
+import org.apache.skywalking.apm.agent.test.tools.AgentServiceRule;
+import org.apache.skywalking.apm.agent.test.tools.SegmentStorage;
+import org.apache.skywalking.apm.agent.test.tools.SegmentStoragePoint;
+import org.apache.skywalking.apm.agent.test.tools.TracingSegmentRunner;
+import org.apache.skywalking.apm.network.trace.component.ComponentsDefine;
+import org.apache.skywalking.apm.plugin.jdbc.trace.ConnectionInfo;
+import org.hamcrest.CoreMatchers;
+import org.junit.Assert;
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.Mock;
+import org.mockito.junit.MockitoJUnit;
+import org.mockito.junit.MockitoRule;
+
+import java.io.InputStream;
+import java.io.Reader;
+import java.math.BigDecimal;
+import java.net.MalformedURLException;
+import java.net.URL;
+import java.sql.Array;
+import java.sql.Blob;
+import java.sql.Connection;
+import java.sql.Clob;
+import java.sql.Date;
+import java.sql.NClob;
+import java.sql.PreparedStatement;
+import java.sql.Ref;
+import java.sql.ResultSet;
+import java.sql.RowId;
+import java.sql.SQLException;
+import java.sql.SQLXML;
+import java.sql.Time;
+import java.sql.Timestamp;
+import java.util.Calendar;
+import java.util.List;
+import java.util.Properties;
+
+import static org.hamcrest.CoreMatchers.is;
+import static org.hamcrest.MatcherAssert.assertThat;
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.ArgumentMatchers.anyBoolean;
+import static org.mockito.ArgumentMatchers.anyByte;
+import static org.mockito.ArgumentMatchers.anyDouble;
+import static org.mockito.ArgumentMatchers.anyFloat;
+import static org.mockito.ArgumentMatchers.anyInt;
+import static org.mockito.ArgumentMatchers.anyLong;
+import static org.mockito.ArgumentMatchers.anyShort;
+import static org.mockito.ArgumentMatchers.anyString;
+import static org.mockito.Mockito.times;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+
+@RunWith(TracingSegmentRunner.class)
+public class SWClickHousePreparedStatementTest extends AbstractStatementTest {
+    @SegmentStoragePoint
+    private SegmentStorage segmentStorage;
+
+    @Rule
+    public AgentServiceRule serviceRule = new AgentServiceRule();
+    @Rule
+    public MockitoRule rule = MockitoJUnit.rule();
+
+    @Mock
+    private Array array;
+    @Mock
+    private SQLXML sqlxml;
+    @Mock
+    private RowId rowId;
+    @Mock
+    private Ref ref;
+    @Mock
+    private Clob clob;
+    @Mock
+    private NClob nClob;
+    @Mock
+    private Reader reader;
+    @Mock
+    private InputStream inputStream;
+    @Mock
+    private Blob blob;
+    @Mock
+    private ClickHousePreparedStatement clickHousePreparedStatement;
+    @Mock
+    private ClickHouseConnectionImpl jdbcConnection;
+    private ConnectionInfo connectionInfo;
+    private SWClickhouseConnection swClickhouseConnection;
+    private byte[] bytesParam = new byte[]{1, 2};
+
+    @Before
+    public void setUp() throws Exception {
+        connectionInfo = new ConnectionInfo(ComponentsDefine.CLICKHOUSE_JDBC_DRIVER, "ClickHouse", "127.0.0.1", 8123, "test");
+        swClickhouseConnection = new SWClickhouseConnection("jdbc:clickhouse://127.0.0.1:8123/test", new Properties(), jdbcConnection, connectionInfo);
+        when(jdbcConnection.prepareStatement(anyString())).thenReturn(clickHousePreparedStatement);
+        when(jdbcConnection.prepareStatement(anyString(), anyInt(), anyInt(), anyInt())).thenReturn(clickHousePreparedStatement);
+        when(jdbcConnection.prepareStatement(anyString(), anyInt(), anyInt())).thenReturn(clickHousePreparedStatement);
+        when(jdbcConnection.prepareStatement(anyString(), anyInt())).thenReturn(clickHousePreparedStatement);
+    }
+
+    @Test
+    public void testSetParam() throws SQLException, MalformedURLException {
+        PreparedStatement preparedStatement = swClickhouseConnection.prepareStatement("SELECT * FROM test WHERE a = ? or b = ? or c=? or d = ? or e = ?" + " or e = ? or f = ? or g = ? or h = ? or i = ? or j = ? or k = ? or l = ? or m = ?  or n = ? or o = ? or p = ? " + " or r = ?  or s = ? or t = ?  or u = ?  or v = ?  or w = ?  or x = ?  or y = ? or z = ? or a1 = ? or a2 = ? or a3 = ?" + " or a4 = ? or a5 = ? or a6 = ?  or a7 = ?  or a8 = ?  or a9 = ? or b1 = ? or b2 = ? or b3 = ? or b4 [...]
+        preparedStatement.clearParameters();
+        preparedStatement.setAsciiStream(1, inputStream);
+        preparedStatement.setAsciiStream(2, inputStream, 10);
+        preparedStatement.setAsciiStream(3, inputStream, 1000000L);
+        preparedStatement.setCharacterStream(4, reader);
+        preparedStatement.setCharacterStream(4, reader, 10);
+        preparedStatement.setCharacterStream(5, reader, 10L);
+        preparedStatement.setShort(6, (short) 12);
+        preparedStatement.setInt(7, 1);
+        preparedStatement.setString(8, "test");
+        preparedStatement.setBoolean(9, true);
+        preparedStatement.setLong(10, 100L);
+        preparedStatement.setDouble(11, 12.0);
+        preparedStatement.setFloat(12, 12.0f);
+        preparedStatement.setByte(13, (byte) 1);
+        preparedStatement.setBytes(14, bytesParam);
+        preparedStatement.setDate(15, new Date(System.currentTimeMillis()));
+        preparedStatement.setNull(16, 1);
+        preparedStatement.setNull(17, 1, "test");
+        preparedStatement.setBigDecimal(18, new BigDecimal(10000));
+        preparedStatement.setBlob(19, inputStream);
+        preparedStatement.setBlob(20, inputStream, 1000000L);
+        preparedStatement.setClob(21, clob);
+        preparedStatement.setClob(22, reader);
+        preparedStatement.setClob(23, reader, 100L);
+        preparedStatement.setNString(24, "test");
+        preparedStatement.setNCharacterStream(25, reader);
+        preparedStatement.setNCharacterStream(26, reader, 1);
+        preparedStatement.setNClob(27, nClob);
+        preparedStatement.setNClob(28, reader, 1);
+        preparedStatement.setObject(29, new Object());
+        preparedStatement.setObject(30, new Object(), 1);
+        preparedStatement.setObject(31, new Object(), 1, 1);
+        preparedStatement.setRef(32, ref);
+        preparedStatement.setRowId(33, rowId);
+        preparedStatement.setSQLXML(34, sqlxml);
+        preparedStatement.setTime(35, new Time(System.currentTimeMillis()));
+        preparedStatement.setTimestamp(36, new Timestamp(System.currentTimeMillis()));
+        preparedStatement.setTimestamp(37, new Timestamp(System.currentTimeMillis()), Calendar.getInstance());
+        preparedStatement.setURL(38, new URL("http", "127.0.0.1", "test"));
+        preparedStatement.setBinaryStream(39, inputStream);
+        preparedStatement.setBinaryStream(40, inputStream, 1);
+        preparedStatement.setBinaryStream(41, inputStream, 1L);
+        preparedStatement.setNClob(42, reader);
+        preparedStatement.setTime(43, new Time(System.currentTimeMillis()), Calendar.getInstance());
+        preparedStatement.setArray(45, array);
+        preparedStatement.setBlob(46, blob);
+        preparedStatement.setDate(47, new Date(System.currentTimeMillis()), Calendar.getInstance());
+
+        ResultSet resultSet = preparedStatement.executeQuery();
+        preparedStatement.close();
+
+        verify(clickHousePreparedStatement).clearParameters();
+        verify(clickHousePreparedStatement).executeQuery();
+        verify(clickHousePreparedStatement).close();
+        verify(clickHousePreparedStatement).setAsciiStream(anyInt(), any(InputStream.class));
+        verify(clickHousePreparedStatement).setAsciiStream(anyInt(), any(InputStream.class), anyInt());
+        verify(clickHousePreparedStatement).setAsciiStream(anyInt(), any(InputStream.class), anyLong());
+        verify(clickHousePreparedStatement).setCharacterStream(anyInt(), any(Reader.class));
+        verify(clickHousePreparedStatement).setCharacterStream(anyInt(), any(Reader.class), anyInt());
+        verify(clickHousePreparedStatement).setCharacterStream(anyInt(), any(Reader.class), anyLong());
+        verify(clickHousePreparedStatement).setShort(anyInt(), anyShort());
+        verify(clickHousePreparedStatement).setInt(anyInt(), anyInt());
+        verify(clickHousePreparedStatement).setString(anyInt(), anyString());
+        verify(clickHousePreparedStatement).setBoolean(anyInt(), anyBoolean());
+        verify(clickHousePreparedStatement).setLong(anyInt(), anyLong());
+        verify(clickHousePreparedStatement).setDouble(anyInt(), anyDouble());
+        verify(clickHousePreparedStatement).setFloat(anyInt(), anyFloat());
+        verify(clickHousePreparedStatement).setByte(anyInt(), anyByte());
+        verify(clickHousePreparedStatement).setBytes(14, bytesParam);
+        verify(clickHousePreparedStatement).setDate(anyInt(), any(Date.class));
+        verify(clickHousePreparedStatement).setNull(anyInt(), anyInt());
+        verify(clickHousePreparedStatement).setNull(anyInt(), anyInt(), anyString());
+        verify(clickHousePreparedStatement).setBigDecimal(anyInt(), any(BigDecimal.class));
+        verify(clickHousePreparedStatement).setBlob(anyInt(), any(InputStream.class));
+        verify(clickHousePreparedStatement).setBlob(anyInt(), any(InputStream.class), anyLong());
+        verify(clickHousePreparedStatement).setClob(anyInt(), any(Clob.class));
+        verify(clickHousePreparedStatement).setClob(anyInt(), any(Reader.class));
+        verify(clickHousePreparedStatement).setClob(anyInt(), any(Reader.class), anyLong());
+        verify(clickHousePreparedStatement).setNString(anyInt(), anyString());
+        verify(clickHousePreparedStatement).setNCharacterStream(anyInt(), any(Reader.class));
+        verify(clickHousePreparedStatement).setNCharacterStream(anyInt(), any(Reader.class), anyLong());
+        verify(clickHousePreparedStatement).setNClob(27, nClob);
+        verify(clickHousePreparedStatement).setNClob(28, reader, 1);
+        verify(clickHousePreparedStatement).setObject(anyInt(), any());
+        verify(clickHousePreparedStatement).setObject(anyInt(), any(), anyInt());
+        verify(clickHousePreparedStatement).setObject(anyInt(), any(), anyInt(), anyInt());
+        verify(clickHousePreparedStatement).setRef(anyInt(), any(Ref.class));
+        verify(clickHousePreparedStatement).setRowId(anyInt(), any(RowId.class));
+        verify(clickHousePreparedStatement).setSQLXML(anyInt(), any(SQLXML.class));
+        verify(clickHousePreparedStatement).setTime(anyInt(), any(Time.class));
+        verify(clickHousePreparedStatement).setTimestamp(anyInt(), any(Timestamp.class));
+        verify(clickHousePreparedStatement).setTimestamp(anyInt(), any(Timestamp.class), any(Calendar.class));
+        verify(clickHousePreparedStatement).setURL(anyInt(), any(URL.class));
+        verify(clickHousePreparedStatement).setBinaryStream(anyInt(), any(InputStream.class));
+        verify(clickHousePreparedStatement).setBinaryStream(anyInt(), any(InputStream.class), anyInt());
+        verify(clickHousePreparedStatement).setBinaryStream(anyInt(), any(InputStream.class), anyLong());
+        verify(clickHousePreparedStatement).setNClob(42, reader);
+        verify(clickHousePreparedStatement).setTime(anyInt(), any(Time.class), any(Calendar.class));
+        verify(clickHousePreparedStatement).setTimestamp(anyInt(), any(Timestamp.class), any(Calendar.class));
+        verify(clickHousePreparedStatement).setArray(anyInt(), any(Array.class));
+        verify(clickHousePreparedStatement).setBlob(anyInt(), any(Blob.class));
+        verify(clickHousePreparedStatement).setDate(anyInt(), any(Date.class), any(Calendar.class));
+    }
+
+    @Test
+    public void testPreparedStatementConfig() throws SQLException {
+        PreparedStatement preparedStatement = swClickhouseConnection.prepareStatement("INSERT INTO test VALUES( ? , ?)", 1);
+        preparedStatement.setInt(1, 1);
+        preparedStatement.setString(2, "a");
+        preparedStatement.getUpdateCount();
+        preparedStatement.setFetchDirection(1);
+        preparedStatement.getFetchDirection();
+        preparedStatement.getResultSetConcurrency();
+        preparedStatement.getResultSetType();
+        preparedStatement.isClosed();
+        preparedStatement.setPoolable(false);
+        preparedStatement.isPoolable();
+        preparedStatement.getWarnings();
+        preparedStatement.clearWarnings();
+        preparedStatement.setCursorName("test");
+        preparedStatement.setMaxFieldSize(11);
+        preparedStatement.getMaxFieldSize();
+        preparedStatement.setMaxRows(10);
+        preparedStatement.getMaxRows();
+        preparedStatement.getParameterMetaData();
+        preparedStatement.setEscapeProcessing(true);
+        preparedStatement.setFetchSize(1);
+        preparedStatement.getFetchSize();
+        preparedStatement.setQueryTimeout(1);
+        preparedStatement.getQueryTimeout();
+        Connection connection = preparedStatement.getConnection();
+
+        preparedStatement.execute();
+
+        preparedStatement.getMoreResults();
+        preparedStatement.getMoreResults(1);
+        preparedStatement.getResultSetHoldability();
+        preparedStatement.getMetaData();
+        preparedStatement.getResultSet();
+
+        preparedStatement.close();
+        verify(clickHousePreparedStatement).getUpdateCount();
+        verify(clickHousePreparedStatement).getMoreResults();
+        verify(clickHousePreparedStatement).setFetchDirection(anyInt());
+        verify(clickHousePreparedStatement).getFetchDirection();
+        verify(clickHousePreparedStatement).getResultSetType();
+        verify(clickHousePreparedStatement).isClosed();
+        verify(clickHousePreparedStatement).setPoolable(anyBoolean());
+        verify(clickHousePreparedStatement).getWarnings();
+        verify(clickHousePreparedStatement).clearWarnings();
+        verify(clickHousePreparedStatement).setCursorName(anyString());
+        verify(clickHousePreparedStatement).setMaxFieldSize(anyInt());
+        verify(clickHousePreparedStatement).getMaxFieldSize();
+        verify(clickHousePreparedStatement).setMaxRows(anyInt());
+        verify(clickHousePreparedStatement).getMaxRows();
+        verify(clickHousePreparedStatement).setEscapeProcessing(anyBoolean());
+        verify(clickHousePreparedStatement).getResultSetConcurrency();
+        verify(clickHousePreparedStatement).getResultSetConcurrency();
+        verify(clickHousePreparedStatement).getResultSetType();
+        verify(clickHousePreparedStatement).getMetaData();
+        verify(clickHousePreparedStatement).getParameterMetaData();
+        verify(clickHousePreparedStatement).getMoreResults(anyInt());
+        verify(clickHousePreparedStatement).setFetchSize(anyInt());
+        verify(clickHousePreparedStatement).getFetchSize();
+        verify(clickHousePreparedStatement).getQueryTimeout();
+        verify(clickHousePreparedStatement).setQueryTimeout(anyInt());
+        verify(clickHousePreparedStatement).getResultSet();
+        assertThat(connection, CoreMatchers.<Connection>is(swClickhouseConnection));
+    }
+
+    @Test
+    public void testExecuteQuery() throws SQLException {
+        PreparedStatement preparedStatement = swClickhouseConnection.prepareStatement("SELECT * FROM test", 1, 1, 1);
+        ResultSet resultSet = preparedStatement.executeQuery();
+
+        preparedStatement.close();
+
+        verify(clickHousePreparedStatement).executeQuery();
+        verify(clickHousePreparedStatement).close();
+        TraceSegment traceSegment = segmentStorage.getTraceSegments().get(0);
+        List<AbstractTracingSpan> spans = SegmentHelper.getSpans(traceSegment);
+        assertThat(spans.size(), is(1));
+        assertDBSpan(spans.get(0), "ClickHouse/JDBC/PreparedStatement/executeQuery", "SELECT * FROM test");
+    }
+
+    @Test
+    public void testExecute() throws SQLException {
+        PreparedStatement preparedStatement = swClickhouseConnection.prepareStatement("SELECT * FROM test", 1, 1, 1);
+        preparedStatement.execute();
+
+        preparedStatement.close();
+
+        verify(clickHousePreparedStatement).execute();
+        verify(clickHousePreparedStatement).close();
+        TraceSegment traceSegment = segmentStorage.getTraceSegments().get(0);
+        List<AbstractTracingSpan> spans = SegmentHelper.getSpans(traceSegment);
+        assertThat(spans.size(), is(1));
+        assertDBSpan(spans.get(0), "ClickHouse/JDBC/PreparedStatement/execute", "SELECT * FROM test");
+    }
+
+    @Test
+    public void testQuerySqlWithSql() throws SQLException {
+        PreparedStatement preparedStatement = swClickhouseConnection.prepareStatement("SELECT * FROM test", 1);
+        ResultSet resultSet = preparedStatement.executeQuery("SELECT * FROM test");
+
+        preparedStatement.getGeneratedKeys();
+        preparedStatement.close();
+
+        verify(clickHousePreparedStatement).executeQuery(anyString());
+        verify(clickHousePreparedStatement).close();
+        TraceSegment traceSegment = segmentStorage.getTraceSegments().get(0);
+        List<AbstractTracingSpan> spans = SegmentHelper.getSpans(traceSegment);
+        assertThat(spans.size(), is(1));
+        assertDBSpan(spans.get(0), "ClickHouse/JDBC/PreparedStatement/executeQuery", "SELECT * FROM test");
+
+    }
+
+    @Test
+    public void testInsertWithAutoGeneratedKey() throws SQLException {
+        PreparedStatement preparedStatement = swClickhouseConnection.prepareStatement("INSERT INTO test VALUES(?)", 1);
+        boolean insertCount = preparedStatement.execute("INSERT INTO test VALUES(1)", 1);
+        preparedStatement.close();
+
+        verify(clickHousePreparedStatement).execute(anyString(), anyInt());
+        verify(clickHousePreparedStatement).close();
+        TraceSegment traceSegment = segmentStorage.getTraceSegments().get(0);
+        List<AbstractTracingSpan> spans = SegmentHelper.getSpans(traceSegment);
+        assertThat(spans.size(), is(1));
+        assertDBSpan(spans.get(0), "ClickHouse/JDBC/PreparedStatement/execute", "INSERT INTO test VALUES(1)");
+
+    }
+
+    @Test
+    public void testInsertWithIntColumnIndexes() throws SQLException {
+        PreparedStatement preparedStatement = swClickhouseConnection.prepareStatement("INSERT INTO test VALUES(?)", 1);
+        boolean insertCount = preparedStatement.execute("INSERT INTO test VALUES(1)", new int[]{1, 2});
+        preparedStatement.close();
+
+        verify(clickHousePreparedStatement).close();
+        TraceSegment traceSegment = segmentStorage.getTraceSegments().get(0);
+        List<AbstractTracingSpan> spans = SegmentHelper.getSpans(traceSegment);
+        assertThat(spans.size(), is(1));
+        assertDBSpan(spans.get(0), "ClickHouse/JDBC/PreparedStatement/execute", "INSERT INTO test VALUES(1)");
+
+    }
+
+    @Test
+    public void testInsertWithStringColumnIndexes() throws SQLException {
+        PreparedStatement preparedStatement = swClickhouseConnection.prepareStatement("INSERT INTO test VALUES(?)", 1);
+        boolean insertCount = preparedStatement.execute("INSERT INTO test VALUES(1)", new String[]{"1", "2"});
+        preparedStatement.close();
+
+        verify(clickHousePreparedStatement).close();
+        TraceSegment traceSegment = segmentStorage.getTraceSegments().get(0);
+        List<AbstractTracingSpan> spans = SegmentHelper.getSpans(traceSegment);
+        assertThat(spans.size(), is(1));
+        assertDBSpan(spans.get(0), "ClickHouse/JDBC/PreparedStatement/execute", "INSERT INTO test VALUES(1)");
+
+    }
+
+    @Test
+    public void testExecuteWithSQL() throws SQLException {
+        PreparedStatement preparedStatement = swClickhouseConnection.prepareStatement("UPDATE test SET  a = ?");
+        preparedStatement.setString(1, "a");
+        boolean updateCount = preparedStatement.execute("UPDATE test SET  a = 1");
+        preparedStatement.cancel();
+        preparedStatement.close();
+
+        verify(clickHousePreparedStatement).execute(anyString());
+        verify(clickHousePreparedStatement).close();
+        TraceSegment traceSegment = segmentStorage.getTraceSegments().get(0);
+        List<AbstractTracingSpan> spans = SegmentHelper.getSpans(traceSegment);
+        assertThat(spans.size(), is(1));
+        assertDBSpan(spans.get(0), "ClickHouse/JDBC/PreparedStatement/execute", "UPDATE test SET  a = 1");
+
+    }
+
+    @Test
+    public void testExecuteUpdate() throws SQLException {
+        PreparedStatement preparedStatement = swClickhouseConnection.prepareStatement("UPDATE test SET  a = ?");
+        preparedStatement.setString(1, "a");
+        int updateCount = preparedStatement.executeUpdate();
+        preparedStatement.cancel();
+        preparedStatement.close();
+
+        verify(clickHousePreparedStatement).executeUpdate();
+        verify(clickHousePreparedStatement).close();
+        TraceSegment traceSegment = segmentStorage.getTraceSegments().get(0);
+        List<AbstractTracingSpan> spans = SegmentHelper.getSpans(traceSegment);
+        assertThat(spans.size(), is(1));
+        assertDBSpan(spans.get(0), "ClickHouse/JDBC/PreparedStatement/executeUpdate", "UPDATE test SET  a = ?");
+
+    }
+
+    @Test
+    public void testUpdateSql() throws SQLException {
+        PreparedStatement preparedStatement = swClickhouseConnection.prepareStatement("UPDATE test SET  a = ?");
+
+        int updateCount = preparedStatement.executeUpdate("UPDATE test SET  a = 1");
+        preparedStatement.cancel();
+        preparedStatement.close();
+
+        verify(clickHousePreparedStatement).executeUpdate(anyString());
+        verify(clickHousePreparedStatement).close();
+        TraceSegment traceSegment = segmentStorage.getTraceSegments().get(0);
+        List<AbstractTracingSpan> spans = SegmentHelper.getSpans(traceSegment);
+        assertThat(spans.size(), is(1));
+        assertDBSpan(spans.get(0), "ClickHouse/JDBC/PreparedStatement/executeUpdate", "UPDATE test SET  a = 1");
+
+    }
+
+    @Test
+    public void testUpdateWithAutoGeneratedKey() throws SQLException {
+        PreparedStatement preparedStatement = swClickhouseConnection.prepareStatement("UPDATE test SET  a = ?");
+
+        int updateCount = preparedStatement.executeUpdate("UPDATE test SET  a = 1", 1);
+        preparedStatement.cancel();
+        preparedStatement.close();
+
+        verify(clickHousePreparedStatement).close();
+        TraceSegment traceSegment = segmentStorage.getTraceSegments().get(0);
+        List<AbstractTracingSpan> spans = SegmentHelper.getSpans(traceSegment);
+        assertThat(spans.size(), is(1));
+        assertDBSpan(spans.get(0), "ClickHouse/JDBC/PreparedStatement/executeUpdate", "UPDATE test SET  a = 1");
+    }
+
+    @Test
+    public void testUpdateWithIntColumnIndexes() throws SQLException {
+        PreparedStatement preparedStatement = swClickhouseConnection.prepareStatement("UPDATE test SET  a = ?");
+
+        int updateCount = preparedStatement.executeUpdate("UPDATE test SET  a = 1", new int[]{1});
+        preparedStatement.cancel();
+        preparedStatement.close();
+
+        verify(clickHousePreparedStatement).close();
+        TraceSegment traceSegment = segmentStorage.getTraceSegments().get(0);
+        List<AbstractTracingSpan> spans = SegmentHelper.getSpans(traceSegment);
+        assertThat(spans.size(), is(1));
+        assertDBSpan(spans.get(0), "ClickHouse/JDBC/PreparedStatement/executeUpdate", "UPDATE test SET  a = 1");
+
+    }
+
+    @Test
+    public void testUpdateWithStringColumnIndexes() throws SQLException {
+        PreparedStatement preparedStatement = swClickhouseConnection.prepareStatement("UPDATE test SET  a = ?");
+
+        int updateCount = preparedStatement.executeUpdate("UPDATE test SET  a = 1", new String[]{"1"});
+        preparedStatement.cancel();
+        preparedStatement.close();
+
+        verify(clickHousePreparedStatement).close();
+        TraceSegment traceSegment = segmentStorage.getTraceSegments().get(0);
+        List<AbstractTracingSpan> spans = SegmentHelper.getSpans(traceSegment);
+        assertThat(spans.size(), is(1));
+        assertDBSpan(spans.get(0), "ClickHouse/JDBC/PreparedStatement/executeUpdate", "UPDATE test SET  a = 1");
+    }
+
+    @Test
+    public void testBatch() throws SQLException, MalformedURLException {
+        PreparedStatement preparedStatement = swClickhouseConnection.prepareStatement("UPDATE test SET a = ? WHERE b = ?");
+        preparedStatement.setShort(1, (short) 12);
+        preparedStatement.setTime(2, new Time(System.currentTimeMillis()));
+        preparedStatement.addBatch();
+        int[] resultSet = preparedStatement.executeBatch();
+        preparedStatement.clearBatch();
+
+        verify(clickHousePreparedStatement).executeBatch();
+        verify(clickHousePreparedStatement).addBatch();
+        verify(clickHousePreparedStatement).clearBatch();
+
+        TraceSegment traceSegment = segmentStorage.getTraceSegments().get(0);
+        List<AbstractTracingSpan> spans = SegmentHelper.getSpans(traceSegment);
+        assertThat(spans.size(), is(1));
+        assertDBSpan(spans.get(0), "ClickHouse/JDBC/PreparedStatement/executeBatch", "");
+
+    }
+
+    @Test
+    public void testQueryWithMultiHost() throws SQLException {
+        PreparedStatement preparedStatement = swClickhouseConnection.prepareStatement("SELECT * FROM test WHERE a = ? or b = ? or c=? or d = ?", 1, 1);
+        preparedStatement.setAsciiStream(1, inputStream);
+        preparedStatement.setAsciiStream(2, inputStream, 10);
+        preparedStatement.setAsciiStream(3, inputStream, 1000000L);
+        preparedStatement.setCharacterStream(4, reader);
+        ResultSet resultSet = preparedStatement.executeQuery();
+
+        preparedStatement.close();
+
+        verify(clickHousePreparedStatement).executeQuery();
+        verify(clickHousePreparedStatement).close();
+    }
+
+    @Test(expected = SQLException.class)
+    public void testMultiHostWithException() throws SQLException {
+        when(clickHousePreparedStatement.executeQuery()).thenThrow(new SQLException());
+        try {
+            PreparedStatement preparedStatement = swClickhouseConnection.prepareStatement("SELECT * FROM test WHERE a = ? or b = ? or c=? or d = ? or e=?");
+            preparedStatement.setBigDecimal(1, new BigDecimal(10000));
+            preparedStatement.setBlob(2, inputStream);
+            preparedStatement.setBlob(3, inputStream, 1000000L);
+            preparedStatement.setByte(3, (byte) 1);
+            preparedStatement.setBytes(4, new byte[]{1, 2});
+            preparedStatement.setLong(5, 100L);
+
+            ResultSet resultSet = preparedStatement.executeQuery();
+
+            preparedStatement.close();
+        } finally {
+            verify(clickHousePreparedStatement).executeQuery();
+            verify(clickHousePreparedStatement, times(0)).close();
+            verify(clickHousePreparedStatement).setBigDecimal(anyInt(), any(BigDecimal.class));
+            verify(clickHousePreparedStatement).setBlob(anyInt(), any(InputStream.class));
+            verify(clickHousePreparedStatement).setBlob(anyInt(), any(InputStream.class), anyLong());
+            verify(clickHousePreparedStatement).setByte(anyInt(), anyByte());
+
+            TraceSegment traceSegment = segmentStorage.getTraceSegments().get(0);
+            List<AbstractTracingSpan> spans = SegmentHelper.getSpans(traceSegment);
+            assertThat(spans.size(), is(1));
+            assertDBSpan(spans.get(0), "ClickHouse/JDBC/PreparedStatement/executeQuery", "SELECT * FROM test WHERE a = ? or b = ? or c=? or d = ? or e=?");
+
+            List<LogDataEntity> logData = SpanHelper.getLogs(spans.get(0));
+            Assert.assertThat(logData.size(), is(1));
+            assertThat(logData.size(), is(1));
+            assertDBSpanLog(logData.get(0));
+        }
+
+    }
+
+}
diff --git a/apm-sniffer/apm-sdk-plugin/clickhouse-0.3.2.x-plugin/src/test/java/org/apache/skywalking/apm/plugin/jdbc/clickhouse/SWClickHouseStatementTest.java b/apm-sniffer/apm-sdk-plugin/clickhouse-0.3.2.x-plugin/src/test/java/org/apache/skywalking/apm/plugin/jdbc/clickhouse/SWClickHouseStatementTest.java
new file mode 100644
index 0000000000..a0ad75b313
--- /dev/null
+++ b/apm-sniffer/apm-sdk-plugin/clickhouse-0.3.2.x-plugin/src/test/java/org/apache/skywalking/apm/plugin/jdbc/clickhouse/SWClickHouseStatementTest.java
@@ -0,0 +1,264 @@
+/*
+ * 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.skywalking.apm.plugin.jdbc.clickhouse;
+
+import com.clickhouse.jdbc.internal.ClickHouseConnectionImpl;
+import com.clickhouse.jdbc.internal.ClickHouseStatementImpl;
+import org.apache.skywalking.apm.agent.core.context.trace.AbstractTracingSpan;
+import org.apache.skywalking.apm.agent.core.context.trace.TraceSegment;
+import org.apache.skywalking.apm.agent.test.helper.SegmentHelper;
+import org.apache.skywalking.apm.agent.test.tools.AgentServiceRule;
+import org.apache.skywalking.apm.agent.test.tools.SegmentStorage;
+import org.apache.skywalking.apm.agent.test.tools.SegmentStoragePoint;
+import org.apache.skywalking.apm.agent.test.tools.TracingSegmentRunner;
+import org.apache.skywalking.apm.network.trace.component.ComponentsDefine;
+import org.apache.skywalking.apm.plugin.jdbc.trace.ConnectionInfo;
+import org.hamcrest.CoreMatchers;
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.Mock;
+import org.mockito.junit.MockitoJUnit;
+import org.mockito.junit.MockitoRule;
+
+import java.net.MalformedURLException;
+import java.sql.Connection;
+import java.sql.ResultSet;
+import java.sql.SQLException;
+import java.sql.Statement;
+import java.util.List;
+import java.util.Properties;
+
+import static org.hamcrest.CoreMatchers.is;
+import static org.hamcrest.MatcherAssert.assertThat;
+import static org.mockito.ArgumentMatchers.anyBoolean;
+import static org.mockito.ArgumentMatchers.anyInt;
+import static org.mockito.ArgumentMatchers.anyString;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+
+@RunWith(TracingSegmentRunner.class)
+public class SWClickHouseStatementTest extends AbstractStatementTest {
+
+    @SegmentStoragePoint
+    private SegmentStorage segmentStorage;
+
+    @Rule
+    public AgentServiceRule serviceRule = new AgentServiceRule();
+    @Rule
+    public MockitoRule rule = MockitoJUnit.rule();
+
+    @Mock
+    private ClickHouseStatementImpl clickHouseStatement;
+    @Mock
+    private ClickHouseConnectionImpl jdbcConnection;
+    private ConnectionInfo connectionInfo;
+    SWClickhouseConnection swClickhouseConnection;
+
+    @Before
+    public void setUp() throws Exception {
+        connectionInfo = new ConnectionInfo(ComponentsDefine.CLICKHOUSE_JDBC_DRIVER, "ClickHouse", "127.0.0.1", 8123, "test");
+        swClickhouseConnection = new SWClickhouseConnection("jdbc:clickhouse://127.0.0.1:8123/test", new Properties(), jdbcConnection, connectionInfo);
+        when(jdbcConnection.createStatement()).thenReturn(clickHouseStatement);
+        when(jdbcConnection.createStatement(anyInt(), anyInt())).thenReturn(clickHouseStatement);
+        when(jdbcConnection.createStatement(anyInt(), anyInt(), anyInt())).thenReturn(clickHouseStatement);
+    }
+
+    @Test
+    public void testPreparedStatementConfig() throws SQLException {
+        Statement statement = swClickhouseConnection.createStatement();
+        statement.cancel();
+        statement.getUpdateCount();
+        statement.setFetchDirection(1);
+        statement.getFetchDirection();
+        statement.getResultSetConcurrency();
+        statement.getResultSetType();
+        statement.isClosed();
+        statement.setPoolable(false);
+        statement.isPoolable();
+        statement.getWarnings();
+        statement.clearWarnings();
+        statement.setCursorName("test");
+        statement.setMaxFieldSize(11);
+        statement.getMaxFieldSize();
+        statement.setMaxRows(10);
+        statement.getMaxRows();
+        statement.setEscapeProcessing(true);
+        statement.setFetchSize(1);
+        statement.getFetchSize();
+        statement.setQueryTimeout(1);
+        statement.getQueryTimeout();
+        Connection connection = statement.getConnection();
+
+        statement.execute("SELECT * FROM test");
+        statement.getMoreResults();
+        statement.getMoreResults(1);
+        statement.getResultSetHoldability();
+        statement.getResultSet();
+
+        statement.close();
+        verify(clickHouseStatement).getUpdateCount();
+        verify(clickHouseStatement).getMoreResults();
+        verify(clickHouseStatement).setFetchDirection(anyInt());
+        verify(clickHouseStatement).getFetchDirection();
+        verify(clickHouseStatement).getResultSetType();
+        verify(clickHouseStatement).isClosed();
+        verify(clickHouseStatement).setPoolable(anyBoolean());
+        verify(clickHouseStatement).getWarnings();
+        verify(clickHouseStatement).clearWarnings();
+        verify(clickHouseStatement).setCursorName(anyString());
+        verify(clickHouseStatement).setMaxFieldSize(anyInt());
+        verify(clickHouseStatement).getMaxFieldSize();
+        verify(clickHouseStatement).setMaxRows(anyInt());
+        verify(clickHouseStatement).getMaxRows();
+        verify(clickHouseStatement).setEscapeProcessing(anyBoolean());
+        verify(clickHouseStatement).getResultSetConcurrency();
+        verify(clickHouseStatement).getResultSetConcurrency();
+        verify(clickHouseStatement).getResultSetType();
+        verify(clickHouseStatement).getMoreResults(anyInt());
+        verify(clickHouseStatement).setFetchSize(anyInt());
+        verify(clickHouseStatement).getFetchSize();
+        verify(clickHouseStatement).getQueryTimeout();
+        verify(clickHouseStatement).setQueryTimeout(anyInt());
+        verify(clickHouseStatement).getResultSet();
+        assertThat(connection, CoreMatchers.<Connection>is(swClickhouseConnection));
+
+        TraceSegment traceSegment = segmentStorage.getTraceSegments().get(0);
+        List<AbstractTracingSpan> spans = SegmentHelper.getSpans(traceSegment);
+        assertThat(spans.size(), is(1));
+        assertDBSpan(spans.get(0), "ClickHouse/JDBC/Statement/execute", "SELECT * FROM test");
+    }
+
+    @Test
+    public void testExecuteWithAutoGeneratedKey() throws SQLException {
+        Statement statement = swClickhouseConnection.createStatement(1, 1);
+        boolean executeSuccess = statement.execute("SELECT * FROM test", 1);
+
+        TraceSegment traceSegment = segmentStorage.getTraceSegments().get(0);
+        List<AbstractTracingSpan> spans = SegmentHelper.getSpans(traceSegment);
+        assertThat(spans.size(), is(1));
+        assertDBSpan(spans.get(0), "ClickHouse/JDBC/Statement/execute", "SELECT * FROM test");
+
+    }
+
+    @Test
+    public void testExecuteQuery() throws SQLException {
+        Statement statement = swClickhouseConnection.createStatement(1, 1, 1);
+        ResultSet executeSuccess = statement.executeQuery("SELECT * FROM test");
+
+        TraceSegment traceSegment = segmentStorage.getTraceSegments().get(0);
+        List<AbstractTracingSpan> spans = SegmentHelper.getSpans(traceSegment);
+        assertThat(spans.size(), is(1));
+        assertDBSpan(spans.get(0), "ClickHouse/JDBC/Statement/executeQuery", "SELECT * FROM test");
+
+    }
+
+    @Test
+    public void testExecuteUpdate() throws SQLException {
+        Statement statement = swClickhouseConnection.createStatement(1, 1, 1);
+        int executeSuccess = statement.executeUpdate("UPDATE test SET a = 1");
+
+        TraceSegment traceSegment = segmentStorage.getTraceSegments().get(0);
+        List<AbstractTracingSpan> spans = SegmentHelper.getSpans(traceSegment);
+        assertThat(spans.size(), is(1));
+        assertDBSpan(spans.get(0), "ClickHouse/JDBC/Statement/executeUpdate", "UPDATE test SET a = 1");
+
+    }
+
+    @Test
+    public void testExecuteUpdateWithAutoGeneratedKey() throws SQLException {
+        Statement statement = swClickhouseConnection.createStatement(1, 1, 1);
+        int executeSuccess = statement.executeUpdate("UPDATE test SET a = 1", 1);
+        statement.getGeneratedKeys();
+
+        verify(clickHouseStatement).getGeneratedKeys();
+        TraceSegment traceSegment = segmentStorage.getTraceSegments().get(0);
+        List<AbstractTracingSpan> spans = SegmentHelper.getSpans(traceSegment);
+        assertThat(spans.size(), is(1));
+        assertDBSpan(spans.get(0), "ClickHouse/JDBC/Statement/executeUpdate", "UPDATE test SET a = 1");
+
+    }
+
+    @Test
+    public void testExecuteUpdateWithColumnIndexes() throws SQLException {
+        Statement statement = swClickhouseConnection.createStatement(1, 1, 1);
+        int executeSuccess = statement.executeUpdate("UPDATE test SET a = 1", new int[]{1});
+
+        TraceSegment traceSegment = segmentStorage.getTraceSegments().get(0);
+        List<AbstractTracingSpan> spans = SegmentHelper.getSpans(traceSegment);
+        assertThat(spans.size(), is(1));
+        assertDBSpan(spans.get(0), "ClickHouse/JDBC/Statement/executeUpdate", "UPDATE test SET a = 1");
+
+    }
+
+    @Test
+    public void testExecuteUpdateWithColumnStringIndexes() throws SQLException {
+        Statement statement = swClickhouseConnection.createStatement(1, 1, 1);
+        int executeSuccess = statement.executeUpdate("UPDATE test SET a = 1", new String[]{"1"});
+
+        TraceSegment traceSegment = segmentStorage.getTraceSegments().get(0);
+        List<AbstractTracingSpan> spans = SegmentHelper.getSpans(traceSegment);
+        assertThat(spans.size(), is(1));
+        assertDBSpan(spans.get(0), "ClickHouse/JDBC/Statement/executeUpdate", "UPDATE test SET a = 1");
+
+    }
+
+    @Test
+    public void testExecuteWithColumnIndexes() throws SQLException {
+        Statement statement = swClickhouseConnection.createStatement(1, 1, 1);
+        boolean executeSuccess = statement.execute("UPDATE test SET a = 1", new int[]{1});
+
+        TraceSegment traceSegment = segmentStorage.getTraceSegments().get(0);
+        List<AbstractTracingSpan> spans = SegmentHelper.getSpans(traceSegment);
+        assertThat(spans.size(), is(1));
+        assertDBSpan(spans.get(0), "ClickHouse/JDBC/Statement/execute", "UPDATE test SET a = 1");
+
+    }
+
+    @Test
+    public void testExecuteWithColumnStringIndexes() throws SQLException {
+        Statement statement = swClickhouseConnection.createStatement(1, 1, 1);
+        boolean executeSuccess = statement.execute("UPDATE test SET a = 1", new String[]{"1"});
+
+        TraceSegment traceSegment = segmentStorage.getTraceSegments().get(0);
+        List<AbstractTracingSpan> spans = SegmentHelper.getSpans(traceSegment);
+        assertThat(spans.size(), is(1));
+        assertDBSpan(spans.get(0), "ClickHouse/JDBC/Statement/execute", "UPDATE test SET a = 1");
+    }
+
+    @Test
+    public void testBatch() throws SQLException, MalformedURLException {
+        Statement statement = swClickhouseConnection.createStatement();
+        statement.addBatch("UPDATE test SET a = 1 WHERE b = 2");
+        int[] resultSet = statement.executeBatch();
+        statement.clearBatch();
+
+        verify(clickHouseStatement).executeBatch();
+        verify(clickHouseStatement).addBatch(anyString());
+        verify(clickHouseStatement).clearBatch();
+
+        TraceSegment traceSegment = segmentStorage.getTraceSegments().get(0);
+        List<AbstractTracingSpan> spans = SegmentHelper.getSpans(traceSegment);
+        assertThat(spans.size(), is(1));
+        assertDBSpan(spans.get(0), "ClickHouse/JDBC/Statement/executeBatch", "");
+
+    }
+
+}
diff --git a/apm-sniffer/apm-sdk-plugin/clickhouse-0.3.2.x-plugin/src/test/java/org/apache/skywalking/apm/plugin/jdbc/clickhouse/SWClickhouseConnection.java b/apm-sniffer/apm-sdk-plugin/clickhouse-0.3.2.x-plugin/src/test/java/org/apache/skywalking/apm/plugin/jdbc/clickhouse/SWClickhouseConnection.java
new file mode 100644
index 0000000000..09db26530e
--- /dev/null
+++ b/apm-sniffer/apm-sdk-plugin/clickhouse-0.3.2.x-plugin/src/test/java/org/apache/skywalking/apm/plugin/jdbc/clickhouse/SWClickhouseConnection.java
@@ -0,0 +1,370 @@
+/*
+ * 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.skywalking.apm.plugin.jdbc.clickhouse;
+
+import java.net.URI;
+import java.sql.CallableStatement;
+import java.sql.DatabaseMetaData;
+import java.sql.NClob;
+import java.sql.PreparedStatement;
+import java.sql.SQLClientInfoException;
+import java.sql.SQLException;
+import java.sql.SQLWarning;
+import java.sql.Savepoint;
+import java.util.Calendar;
+import java.util.Map;
+import java.util.Optional;
+import java.util.Properties;
+import java.util.TimeZone;
+import java.util.concurrent.Executor;
+
+import com.clickhouse.client.ClickHouseConfig;
+import com.clickhouse.client.ClickHouseTransaction;
+import com.clickhouse.client.ClickHouseVersion;
+import com.clickhouse.jdbc.ClickHouseConnection;
+import com.clickhouse.jdbc.ClickHouseArray;
+import com.clickhouse.jdbc.ClickHouseBlob;
+import com.clickhouse.jdbc.ClickHouseClob;
+import com.clickhouse.jdbc.ClickHouseXml;
+import com.clickhouse.jdbc.ClickHouseStruct;
+import com.clickhouse.jdbc.ClickHouseStatement;
+import com.clickhouse.jdbc.JdbcConfig;
+import com.clickhouse.jdbc.parser.ClickHouseSqlStatement;
+import org.apache.skywalking.apm.plugin.jdbc.clickhouse.v32.SWClickHousePreparedStatement;
+import org.apache.skywalking.apm.plugin.jdbc.clickhouse.v32.SWClickHouseStatement;
+import org.apache.skywalking.apm.plugin.jdbc.trace.ConnectionInfo;
+
+/**
+ * for test
+ */
+public class SWClickhouseConnection implements ClickHouseConnection {
+    private ConnectionInfo connectInfo;
+    private final ClickHouseConnection realConnection;
+
+    public SWClickhouseConnection(String url, Properties info, ClickHouseConnection realConnection, ConnectionInfo connectInfo) {
+        super();
+        this.connectInfo = connectInfo;
+        this.realConnection = realConnection;
+    }
+
+    public <T> T unwrap(Class<T> iface) throws SQLException {
+        return realConnection.unwrap(iface);
+    }
+
+    public boolean isWrapperFor(Class<?> iface) throws SQLException {
+        return realConnection.isWrapperFor(iface);
+    }
+
+    public ClickHouseStatement createStatement() throws SQLException {
+        return new SWClickHouseStatement(this, realConnection.createStatement(), this.connectInfo);
+    }
+
+    public PreparedStatement prepareStatement(String sql) throws SQLException {
+        return new SWClickHousePreparedStatement(this, realConnection.prepareStatement(sql), this.connectInfo, sql);
+    }
+
+    @Deprecated
+    public CallableStatement prepareCall(String sql) throws SQLException {
+        return null;
+    }
+
+    public String nativeSQL(String sql) throws SQLException {
+        return realConnection.nativeSQL(sql);
+    }
+
+    public void setAutoCommit(boolean autoCommit) throws SQLException {
+        realConnection.setAutoCommit(autoCommit);
+    }
+
+    public boolean getAutoCommit() throws SQLException {
+        return realConnection.getAutoCommit();
+    }
+
+    public void commit() throws SQLException {
+        realConnection.commit();
+    }
+
+    public void rollback() throws SQLException {
+        realConnection.rollback();
+    }
+
+    public void close() throws SQLException {
+        realConnection.close();
+    }
+
+    public boolean isClosed() throws SQLException {
+        return realConnection.isClosed();
+    }
+
+    public DatabaseMetaData getMetaData() throws SQLException {
+        return realConnection.getMetaData();
+    }
+
+    public void setReadOnly(boolean readOnly) throws SQLException {
+        realConnection.setReadOnly(readOnly);
+    }
+
+    public boolean isReadOnly() throws SQLException {
+        return realConnection.isReadOnly();
+    }
+
+    public void setCatalog(String catalog) throws SQLException {
+        realConnection.setCatalog(catalog);
+    }
+
+    public String getCatalog() throws SQLException {
+        return realConnection.getCatalog();
+    }
+
+    public void setTransactionIsolation(int level) throws SQLException {
+        realConnection.setTransactionIsolation(level);
+    }
+
+    public int getTransactionIsolation() throws SQLException {
+        return realConnection.getTransactionIsolation();
+    }
+
+    public SQLWarning getWarnings() throws SQLException {
+        return realConnection.getWarnings();
+    }
+
+    public void clearWarnings() throws SQLException {
+        realConnection.clearWarnings();
+    }
+
+    public ClickHouseStatement createStatement(int resultSetType, int resultSetConcurrency) throws SQLException {
+        return new SWClickHouseStatement(this, realConnection.createStatement(resultSetType, resultSetConcurrency), this.connectInfo);
+    }
+
+    public PreparedStatement prepareStatement(String sql, int resultSetType,
+                                              int resultSetConcurrency) throws SQLException {
+        return new SWClickHousePreparedStatement(this, realConnection.prepareStatement(sql, resultSetType, resultSetConcurrency), this.connectInfo, sql);
+    }
+
+    @Override
+    public ClickHouseConfig getConfig() {
+        return realConnection.getConfig();
+    }
+
+    @Override
+    public boolean allowCustomSetting() {
+        return realConnection.allowCustomSetting();
+    }
+
+    @Override
+    public String getCurrentDatabase() {
+        return realConnection.getCurrentDatabase();
+    }
+
+    @Override
+    public String getCurrentUser() {
+        return realConnection.getCurrentUser();
+    }
+
+    @Override
+    public Calendar getDefaultCalendar() {
+        return realConnection.getDefaultCalendar();
+    }
+
+    @Override
+    public Optional<TimeZone> getEffectiveTimeZone() {
+        return realConnection.getEffectiveTimeZone();
+    }
+
+    @Override
+    public TimeZone getJvmTimeZone() {
+        return realConnection.getJvmTimeZone();
+    }
+
+    @Override
+    public TimeZone getServerTimeZone() {
+        return realConnection.getServerTimeZone();
+    }
+
+    @Override
+    public ClickHouseVersion getServerVersion() {
+        return realConnection.getServerVersion();
+    }
+
+    @Override
+    public ClickHouseTransaction getTransaction() {
+        return realConnection.getTransaction();
+    }
+
+    @Override
+    public URI getUri() {
+        return realConnection.getUri();
+    }
+
+    @Override
+    public JdbcConfig getJdbcConfig() {
+        return realConnection.getJdbcConfig();
+    }
+
+    @Override
+    public boolean isTransactionSupported() {
+        return realConnection.isTransactionSupported();
+    }
+
+    @Override
+    public boolean isImplicitTransactionSupported() {
+        return realConnection.isImplicitTransactionSupported();
+    }
+
+    @Override
+    public String newQueryId() {
+        return realConnection.newQueryId();
+    }
+
+    @Override
+    public ClickHouseSqlStatement[] parse(String sql, ClickHouseConfig config) {
+        return new ClickHouseSqlStatement[0];
+    }
+
+    @Deprecated
+    public CallableStatement prepareCall(String sql, int resultSetType, int resultSetConcurrency) throws SQLException {
+        return null;
+    }
+
+    public Map<String, Class<?>> getTypeMap() throws SQLException {
+        return realConnection.getTypeMap();
+    }
+
+    public void setTypeMap(Map<String, Class<?>> map) throws SQLException {
+        realConnection.setTypeMap(map);
+    }
+
+    public void setHoldability(int holdability) throws SQLException {
+        realConnection.setHoldability(holdability);
+    }
+
+    public int getHoldability() throws SQLException {
+        return realConnection.getHoldability();
+    }
+
+    public Savepoint setSavepoint() throws SQLException {
+        return realConnection.setSavepoint();
+    }
+
+    public Savepoint setSavepoint(String name) throws SQLException {
+        return realConnection.setSavepoint(name);
+    }
+
+    public void rollback(final Savepoint savepoint) throws SQLException {
+        realConnection.rollback(savepoint);
+    }
+
+    public void releaseSavepoint(final Savepoint savepoint) throws SQLException {
+        realConnection.releaseSavepoint(savepoint);
+    }
+
+    @Deprecated
+    public ClickHouseStatement createStatement(int resultSetType, int resultSetConcurrency,
+                                               int resultSetHoldability) throws SQLException {
+        return new SWClickHouseStatement(this, realConnection.createStatement(resultSetType, resultSetConcurrency, resultSetHoldability), this.connectInfo);
+    }
+
+    public PreparedStatement prepareStatement(String sql, int resultSetType, int resultSetConcurrency,
+                                              int resultSetHoldability) throws SQLException {
+        return new SWClickHousePreparedStatement(this, realConnection.prepareStatement(sql, resultSetType, resultSetConcurrency, resultSetHoldability), this.connectInfo, sql);
+    }
+
+    @Deprecated
+    public CallableStatement prepareCall(String sql, int resultSetType, int resultSetConcurrency,
+                                         int resultSetHoldability) throws SQLException {
+        return null;
+    }
+
+    public PreparedStatement prepareStatement(String sql, int autoGeneratedKeys) throws SQLException {
+        return new SWClickHousePreparedStatement(this, realConnection.prepareStatement(sql, autoGeneratedKeys), this.connectInfo, sql);
+    }
+
+    public PreparedStatement prepareStatement(String sql, int[] columnIndexes) throws SQLException {
+        return new SWClickHousePreparedStatement(this, realConnection.prepareStatement(sql, columnIndexes), this.connectInfo, sql);
+    }
+
+    public PreparedStatement prepareStatement(String sql, String[] columnNames) throws SQLException {
+        return new SWClickHousePreparedStatement(this, realConnection.prepareStatement(sql, columnNames), this.connectInfo, sql);
+    }
+
+    public ClickHouseClob createClob() throws SQLException {
+        return realConnection.createClob();
+    }
+
+    public ClickHouseBlob createBlob() throws SQLException {
+        return realConnection.createBlob();
+    }
+
+    public NClob createNClob() throws SQLException {
+        return realConnection.createNClob();
+    }
+
+    public ClickHouseXml createSQLXML() throws SQLException {
+        return realConnection.createSQLXML();
+    }
+
+    public boolean isValid(int timeout) throws SQLException {
+        return realConnection.isValid(timeout);
+    }
+
+    public void setClientInfo(String name, String value) throws SQLClientInfoException {
+        realConnection.setClientInfo(name, value);
+    }
+
+    public void setClientInfo(Properties properties) throws SQLClientInfoException {
+        realConnection.setClientInfo(properties);
+    }
+
+    public String getClientInfo(String name) throws SQLException {
+        return realConnection.getClientInfo(name);
+    }
+
+    public Properties getClientInfo() throws SQLException {
+        return realConnection.getClientInfo();
+    }
+
+    public ClickHouseArray createArrayOf(String typeName, Object[] elements) throws SQLException {
+        return realConnection.createArrayOf(typeName, elements);
+    }
+
+    public ClickHouseStruct createStruct(String typeName, Object[] attributes) throws SQLException {
+        return realConnection.createStruct(typeName, attributes);
+    }
+
+    public void setSchema(String schema) throws SQLException {
+        realConnection.setSchema(schema);
+    }
+
+    public String getSchema() throws SQLException {
+        return realConnection.getSchema();
+    }
+
+    public void abort(Executor executor) throws SQLException {
+        realConnection.abort(executor);
+    }
+
+    public void setNetworkTimeout(Executor executor, int milliseconds) throws SQLException {
+        realConnection.setNetworkTimeout(executor, milliseconds);
+    }
+
+    public int getNetworkTimeout() throws SQLException {
+        return realConnection.getNetworkTimeout();
+    }
+
+}
diff --git a/apm-sniffer/apm-sdk-plugin/pom.xml b/apm-sniffer/apm-sdk-plugin/pom.xml
index 958369e21c..e5cddd3abd 100644
--- a/apm-sniffer/apm-sdk-plugin/pom.xml
+++ b/apm-sniffer/apm-sdk-plugin/pom.xml
@@ -113,7 +113,8 @@
         <module>druid-1.x-plugin</module>
         <module>hikaricp-3.x-4.x-plugin</module>
         <module>httpclient-5.x-plugin</module>
-        <module>clickhouse-0.3.x-plugin</module>
+        <module>clickhouse-0.3.2.x-plugin</module>
+        <module>clickhouse-0.3.1-plugin</module>
         <module>kylin-jdbc-2.6.x-3.x-4.x-plugin</module>
         <module>okhttp-2.x-plugin</module>
         <module>pulsar-common</module>
diff --git a/docs/en/setup/service-agent/java-agent/Plugin-list.md b/docs/en/setup/service-agent/java-agent/Plugin-list.md
index 651b15f2ff..e99b67b090 100644
--- a/docs/en/setup/service-agent/java-agent/Plugin-list.md
+++ b/docs/en/setup/service-agent/java-agent/Plugin-list.md
@@ -140,7 +140,8 @@
 - jsonrpc4j
 - spring-cloud-gateway-3.x
 - neo4j-4.x
-- clickhouse-0.3.x
+- clickhouse-0.3.1
+- clickhouse-0.3.2.x
 - kylin-jdbc-2.6.x-3.x-4.x
 - okhttp-2.x
 - pulsar-2.8.x
diff --git a/test/plugin/scenarios/clickhouse-0.3.x-scenario/bin/startup.sh b/test/plugin/scenarios/clickhouse-0.3.1-scenario/bin/startup.sh
similarity index 93%
copy from test/plugin/scenarios/clickhouse-0.3.x-scenario/bin/startup.sh
copy to test/plugin/scenarios/clickhouse-0.3.1-scenario/bin/startup.sh
index b21584064d..332b5dec12 100644
--- a/test/plugin/scenarios/clickhouse-0.3.x-scenario/bin/startup.sh
+++ b/test/plugin/scenarios/clickhouse-0.3.1-scenario/bin/startup.sh
@@ -21,4 +21,4 @@ home="$(
   pwd
 )"
 
-java -jar ${agent_opts} "-Dskywalking.plugin.neo4j.trace_cypher_parameters=true" ${home}/../libs/clickhouse-0.3.x-scenario.jar &
+java -jar ${agent_opts} "-Dskywalking.plugin.neo4j.trace_cypher_parameters=true" ${home}/../libs/clickhouse-0.3.1-scenario.jar &
diff --git a/test/plugin/scenarios/clickhouse-0.3.x-scenario/config/expectedData.yaml b/test/plugin/scenarios/clickhouse-0.3.1-scenario/config/expectedData.yaml
similarity index 99%
copy from test/plugin/scenarios/clickhouse-0.3.x-scenario/config/expectedData.yaml
copy to test/plugin/scenarios/clickhouse-0.3.1-scenario/config/expectedData.yaml
index d3062dc8a5..338578558b 100644
--- a/test/plugin/scenarios/clickhouse-0.3.x-scenario/config/expectedData.yaml
+++ b/test/plugin/scenarios/clickhouse-0.3.1-scenario/config/expectedData.yaml
@@ -14,7 +14,7 @@
 # See the License for the specific language governing permissions and
 # limitations under the License.
 segmentItems:
-  - serviceName: clickhouse-0.3.x-scenario
+  - serviceName: clickhouse-0.3.1-scenario
     segmentSize: ge 2
     segments:
       - segmentId: not null
diff --git a/test/plugin/scenarios/clickhouse-0.3.x-scenario/configuration.yml b/test/plugin/scenarios/clickhouse-0.3.1-scenario/configuration.yml
similarity index 95%
copy from test/plugin/scenarios/clickhouse-0.3.x-scenario/configuration.yml
copy to test/plugin/scenarios/clickhouse-0.3.1-scenario/configuration.yml
index e3befa24d5..6b8bd1f7f7 100644
--- a/test/plugin/scenarios/clickhouse-0.3.x-scenario/configuration.yml
+++ b/test/plugin/scenarios/clickhouse-0.3.1-scenario/configuration.yml
@@ -23,7 +23,7 @@ depends_on:
   - clickhouse-server
 dependencies:
   clickhouse-server:
-    image: yandex/clickhouse-server:21.8.8.29
+    image: yandex/clickhouse-server:22.1.2.2
     hostname: clickhouse-server
     expose:
       - 8123
\ No newline at end of file
diff --git a/test/plugin/scenarios/clickhouse-0.3.x-scenario/pom.xml b/test/plugin/scenarios/clickhouse-0.3.1-scenario/pom.xml
similarity index 96%
copy from test/plugin/scenarios/clickhouse-0.3.x-scenario/pom.xml
copy to test/plugin/scenarios/clickhouse-0.3.1-scenario/pom.xml
index d4e9a3cf6f..1cfb5a99a0 100644
--- a/test/plugin/scenarios/clickhouse-0.3.x-scenario/pom.xml
+++ b/test/plugin/scenarios/clickhouse-0.3.1-scenario/pom.xml
@@ -21,7 +21,7 @@
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
 
     <groupId>org.apache.skywalking.apm.testcase</groupId>
-    <artifactId>clickhouse-0.3.x-scenario</artifactId>
+    <artifactId>clickhouse-0.3.1-scenario</artifactId>
     <version>1.0.0</version>
     <packaging>jar</packaging>
 
@@ -35,7 +35,7 @@
         <spring.boot.version>2.5.1</spring.boot.version>
     </properties>
 
-    <name>skywalking-clickhouse-0.3.x-scenario</name>
+    <name>skywalking-clickhouse-0.3.1-scenario</name>
 
     <dependencyManagement>
         <dependencies>
@@ -73,7 +73,7 @@
     </dependencies>
 
     <build>
-        <finalName>clickhouse-0.3.x-scenario</finalName>
+        <finalName>clickhouse-0.3.1-scenario</finalName>
         <plugins>
             <plugin>
                 <groupId>org.springframework.boot</groupId>
diff --git a/test/plugin/scenarios/clickhouse-0.3.x-scenario/src/main/assembly/assembly.xml b/test/plugin/scenarios/clickhouse-0.3.1-scenario/src/main/assembly/assembly.xml
similarity index 96%
copy from test/plugin/scenarios/clickhouse-0.3.x-scenario/src/main/assembly/assembly.xml
copy to test/plugin/scenarios/clickhouse-0.3.1-scenario/src/main/assembly/assembly.xml
index 89ea092402..725c8abdbb 100644
--- a/test/plugin/scenarios/clickhouse-0.3.x-scenario/src/main/assembly/assembly.xml
+++ b/test/plugin/scenarios/clickhouse-0.3.1-scenario/src/main/assembly/assembly.xml
@@ -33,7 +33,7 @@
 
     <files>
         <file>
-            <source>${project.build.directory}/clickhouse-0.3.x-scenario.jar</source>
+            <source>${project.build.directory}/clickhouse-0.3.1-scenario.jar</source>
             <outputDirectory>./libs</outputDirectory>
             <fileMode>0775</fileMode>
         </file>
diff --git a/test/plugin/scenarios/clickhouse-0.3.x-scenario/src/main/java/org/apache/skywalking/apm/testcase/neo4j/Application.java b/test/plugin/scenarios/clickhouse-0.3.1-scenario/src/main/java/org/apache/skywalking/apm/testcase/neo4j/Application.java
similarity index 100%
copy from test/plugin/scenarios/clickhouse-0.3.x-scenario/src/main/java/org/apache/skywalking/apm/testcase/neo4j/Application.java
copy to test/plugin/scenarios/clickhouse-0.3.1-scenario/src/main/java/org/apache/skywalking/apm/testcase/neo4j/Application.java
diff --git a/test/plugin/scenarios/clickhouse-0.3.x-scenario/src/main/java/org/apache/skywalking/apm/testcase/neo4j/controller/CaseController.java b/test/plugin/scenarios/clickhouse-0.3.1-scenario/src/main/java/org/apache/skywalking/apm/testcase/neo4j/controller/CaseController.java
similarity index 100%
copy from test/plugin/scenarios/clickhouse-0.3.x-scenario/src/main/java/org/apache/skywalking/apm/testcase/neo4j/controller/CaseController.java
copy to test/plugin/scenarios/clickhouse-0.3.1-scenario/src/main/java/org/apache/skywalking/apm/testcase/neo4j/controller/CaseController.java
diff --git a/test/plugin/scenarios/clickhouse-0.3.x-scenario/src/main/resources/application.yaml b/test/plugin/scenarios/clickhouse-0.3.1-scenario/src/main/resources/application.yaml
similarity index 100%
copy from test/plugin/scenarios/clickhouse-0.3.x-scenario/src/main/resources/application.yaml
copy to test/plugin/scenarios/clickhouse-0.3.1-scenario/src/main/resources/application.yaml
diff --git a/test/plugin/scenarios/clickhouse-0.3.x-scenario/src/main/resources/log4j2.xml b/test/plugin/scenarios/clickhouse-0.3.1-scenario/src/main/resources/log4j2.xml
similarity index 100%
copy from test/plugin/scenarios/clickhouse-0.3.x-scenario/src/main/resources/log4j2.xml
copy to test/plugin/scenarios/clickhouse-0.3.1-scenario/src/main/resources/log4j2.xml
diff --git a/test/plugin/scenarios/clickhouse-0.3.x-scenario/support-version.list b/test/plugin/scenarios/clickhouse-0.3.1-scenario/support-version.list
similarity index 100%
copy from test/plugin/scenarios/clickhouse-0.3.x-scenario/support-version.list
copy to test/plugin/scenarios/clickhouse-0.3.1-scenario/support-version.list
diff --git a/test/plugin/scenarios/clickhouse-0.3.x-scenario/bin/startup.sh b/test/plugin/scenarios/clickhouse-0.3.2.x-scenario/bin/startup.sh
similarity index 93%
rename from test/plugin/scenarios/clickhouse-0.3.x-scenario/bin/startup.sh
rename to test/plugin/scenarios/clickhouse-0.3.2.x-scenario/bin/startup.sh
index b21584064d..f765620156 100644
--- a/test/plugin/scenarios/clickhouse-0.3.x-scenario/bin/startup.sh
+++ b/test/plugin/scenarios/clickhouse-0.3.2.x-scenario/bin/startup.sh
@@ -21,4 +21,4 @@ home="$(
   pwd
 )"
 
-java -jar ${agent_opts} "-Dskywalking.plugin.neo4j.trace_cypher_parameters=true" ${home}/../libs/clickhouse-0.3.x-scenario.jar &
+java -jar ${agent_opts} "-Dskywalking.plugin.neo4j.trace_cypher_parameters=true" ${home}/../libs/clickhouse-0.3.2.x-scenario.jar &
diff --git a/test/plugin/scenarios/clickhouse-0.3.x-scenario/config/expectedData.yaml b/test/plugin/scenarios/clickhouse-0.3.2.x-scenario/config/expectedData.yaml
similarity index 62%
rename from test/plugin/scenarios/clickhouse-0.3.x-scenario/config/expectedData.yaml
rename to test/plugin/scenarios/clickhouse-0.3.2.x-scenario/config/expectedData.yaml
index d3062dc8a5..7626468796 100644
--- a/test/plugin/scenarios/clickhouse-0.3.x-scenario/config/expectedData.yaml
+++ b/test/plugin/scenarios/clickhouse-0.3.2.x-scenario/config/expectedData.yaml
@@ -14,7 +14,7 @@
 # See the License for the specific language governing permissions and
 # limitations under the License.
 segmentItems:
-  - serviceName: clickhouse-0.3.x-scenario
+  - serviceName: clickhouse-0.3.2.x-scenario
     segmentSize: ge 2
     segments:
       - segmentId: not null
@@ -49,49 +49,14 @@ segmentItems:
             spanType: Exit
             peer: not null
             skipAnalysis: false
-            tags:
-              - {key: db.type, value: ClickHouse}
-              - {key: db.instance, value: system}
-              - {key: db.statement, value: 'select timezone(), version()'}
-              - {key: http.status_code, value: '200'}
-          - operationName: ClickHouse/JDBC/Statement/executeQuery
-            operationId: 0
-            parentSpanId: 0
-            spanId: 2
-            spanLayer: Database
-            startTime: nq 0
-            endTime: nq 0
-            componentId: 119
-            isError: false
-            spanType: Exit
-            peer: not null
-            skipAnalysis: false
             tags:
               - {key: db.type, value: ClickHouse}
               - {key: db.instance, value: system}
               - {key: db.statement, value: SELECT * FROM clusters}
-              - {key: http.status_code, value: '200'}
-          - operationName: ClickHouse/JDBC/Statement/execute
-            operationId: 0
-            parentSpanId: 0
-            spanId: 3
-            spanLayer: Database
-            startTime: nq 0
-            endTime: nq 0
-            componentId: 119
-            isError: false
-            spanType: Exit
-            peer: not null
-            skipAnalysis: false
-            tags:
-              - {key: db.type, value: ClickHouse}
-              - {key: db.instance, value: system}
-              - {key: db.statement, value: SELECT 1}
-              - {key: http.status_code, value: '200'}
           - operationName: ClickHouse/JDBC/Connection/close
             operationId: 0
             parentSpanId: 0
-            spanId: 4
+            spanId: 2
             spanLayer: Database
             startTime: nq 0
             endTime: nq 0
@@ -104,27 +69,10 @@ segmentItems:
               - {key: db.type, value: ClickHouse}
               - {key: db.instance, value: system}
               - {key: db.statement, value: ''}
-          - operationName: ClickHouse/JDBC/Statement/executeQuery
-            operationId: 0
-            parentSpanId: 0
-            spanId: 5
-            spanLayer: Database
-            startTime: nq 0
-            endTime: nq 0
-            componentId: 119
-            isError: false
-            spanType: Exit
-            peer: not null
-            skipAnalysis: false
-            tags:
-              - {key: db.type, value: ClickHouse}
-              - {key: db.instance, value: system}
-              - {key: db.statement, value: 'select timezone(), version()'}
-              - {key: http.status_code, value: '200'}
           - operationName: ClickHouse/JDBC/PreparedStatement/executeQuery
             operationId: 0
             parentSpanId: 0
-            spanId: 6
+            spanId: 3
             spanLayer: Database
             startTime: nq 0
             endTime: nq 0
@@ -137,28 +85,10 @@ segmentItems:
               - {key: db.type, value: ClickHouse}
               - {key: db.instance, value: system}
               - {key: db.statement, value: SELECT * FROM clusters}
-              - {key: http.status_code, value: '200'}
-          - operationName: ClickHouse/JDBC/Statement/execute
-            operationId: 0
-            parentSpanId: 0
-            spanId: 7
-            spanLayer: Database
-            startTime: nq 0
-            endTime: nq 0
-            componentId: 119
-            isError: false
-            spanType: Exit
-            peer: not null
-            skipAnalysis: false
-            tags:
-              - {key: db.type, value: ClickHouse}
-              - {key: db.instance, value: system}
-              - {key: db.statement, value: SELECT 1}
-              - {key: http.status_code, value: '200'}
           - operationName: ClickHouse/JDBC/Connection/close
             operationId: 0
             parentSpanId: 0
-            spanId: 8
+            spanId: 4
             spanLayer: Database
             startTime: nq 0
             endTime: nq 0
diff --git a/test/plugin/scenarios/clickhouse-0.3.x-scenario/configuration.yml b/test/plugin/scenarios/clickhouse-0.3.2.x-scenario/configuration.yml
similarity index 95%
rename from test/plugin/scenarios/clickhouse-0.3.x-scenario/configuration.yml
rename to test/plugin/scenarios/clickhouse-0.3.2.x-scenario/configuration.yml
index e3befa24d5..6b8bd1f7f7 100644
--- a/test/plugin/scenarios/clickhouse-0.3.x-scenario/configuration.yml
+++ b/test/plugin/scenarios/clickhouse-0.3.2.x-scenario/configuration.yml
@@ -23,7 +23,7 @@ depends_on:
   - clickhouse-server
 dependencies:
   clickhouse-server:
-    image: yandex/clickhouse-server:21.8.8.29
+    image: yandex/clickhouse-server:22.1.2.2
     hostname: clickhouse-server
     expose:
       - 8123
\ No newline at end of file
diff --git a/test/plugin/scenarios/clickhouse-0.3.x-scenario/pom.xml b/test/plugin/scenarios/clickhouse-0.3.2.x-scenario/pom.xml
similarity index 93%
rename from test/plugin/scenarios/clickhouse-0.3.x-scenario/pom.xml
rename to test/plugin/scenarios/clickhouse-0.3.2.x-scenario/pom.xml
index d4e9a3cf6f..94af1347f9 100644
--- a/test/plugin/scenarios/clickhouse-0.3.x-scenario/pom.xml
+++ b/test/plugin/scenarios/clickhouse-0.3.2.x-scenario/pom.xml
@@ -21,7 +21,7 @@
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
 
     <groupId>org.apache.skywalking.apm.testcase</groupId>
-    <artifactId>clickhouse-0.3.x-scenario</artifactId>
+    <artifactId>clickhouse-0.3.2.x-scenario</artifactId>
     <version>1.0.0</version>
     <packaging>jar</packaging>
 
@@ -31,11 +31,11 @@
         <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
         <compiler.version>1.8</compiler.version>
         <maven-compiler-plugin.version>3.8.1</maven-compiler-plugin.version>
-        <test.framework.version>0.3.1-patch</test.framework.version>
+        <test.framework.version>0.3.2-patch11</test.framework.version>
         <spring.boot.version>2.5.1</spring.boot.version>
     </properties>
 
-    <name>skywalking-clickhouse-0.3.x-scenario</name>
+    <name>skywalking-clickhouse-0.3.2.x-scenario</name>
 
     <dependencyManagement>
         <dependencies>
@@ -66,14 +66,14 @@
         </dependency>
 
         <dependency>
-            <groupId>ru.yandex.clickhouse</groupId>
+            <groupId>com.clickhouse</groupId>
             <artifactId>clickhouse-jdbc</artifactId>
             <version>${test.framework.version}</version>
         </dependency>
     </dependencies>
 
     <build>
-        <finalName>clickhouse-0.3.x-scenario</finalName>
+        <finalName>clickhouse-0.3.2.x-scenario</finalName>
         <plugins>
             <plugin>
                 <groupId>org.springframework.boot</groupId>
diff --git a/test/plugin/scenarios/clickhouse-0.3.x-scenario/src/main/assembly/assembly.xml b/test/plugin/scenarios/clickhouse-0.3.2.x-scenario/src/main/assembly/assembly.xml
similarity index 94%
rename from test/plugin/scenarios/clickhouse-0.3.x-scenario/src/main/assembly/assembly.xml
rename to test/plugin/scenarios/clickhouse-0.3.2.x-scenario/src/main/assembly/assembly.xml
index 89ea092402..fb949776c7 100644
--- a/test/plugin/scenarios/clickhouse-0.3.x-scenario/src/main/assembly/assembly.xml
+++ b/test/plugin/scenarios/clickhouse-0.3.2.x-scenario/src/main/assembly/assembly.xml
@@ -33,7 +33,7 @@
 
     <files>
         <file>
-            <source>${project.build.directory}/clickhouse-0.3.x-scenario.jar</source>
+            <source>${project.build.directory}/clickhouse-0.3.2.x-scenario.jar</source>
             <outputDirectory>./libs</outputDirectory>
             <fileMode>0775</fileMode>
         </file>
diff --git a/test/plugin/scenarios/clickhouse-0.3.x-scenario/src/main/java/org/apache/skywalking/apm/testcase/neo4j/Application.java b/test/plugin/scenarios/clickhouse-0.3.2.x-scenario/src/main/java/org/apache/skywalking/apm/testcase/neo4j/Application.java
similarity index 82%
rename from test/plugin/scenarios/clickhouse-0.3.x-scenario/src/main/java/org/apache/skywalking/apm/testcase/neo4j/Application.java
rename to test/plugin/scenarios/clickhouse-0.3.2.x-scenario/src/main/java/org/apache/skywalking/apm/testcase/neo4j/Application.java
index b9e907f0d0..19b8e06408 100644
--- a/test/plugin/scenarios/clickhouse-0.3.x-scenario/src/main/java/org/apache/skywalking/apm/testcase/neo4j/Application.java
+++ b/test/plugin/scenarios/clickhouse-0.3.2.x-scenario/src/main/java/org/apache/skywalking/apm/testcase/neo4j/Application.java
@@ -18,12 +18,14 @@
 
 package org.apache.skywalking.apm.testcase.neo4j;
 
+import com.clickhouse.jdbc.ClickHouseDataSource;
 import org.springframework.beans.factory.annotation.Value;
 import org.springframework.boot.SpringApplication;
 import org.springframework.boot.autoconfigure.SpringBootApplication;
 import org.springframework.context.annotation.Bean;
-import ru.yandex.clickhouse.ClickHouseDataSource;
-import ru.yandex.clickhouse.settings.ClickHouseProperties;
+
+import java.sql.SQLException;
+import java.util.Properties;
 
 @SpringBootApplication
 public class Application {
@@ -40,10 +42,10 @@ public class Application {
     }
 
     @Bean
-    public ClickHouseDataSource dataSource() {
-        ClickHouseProperties properties = new ClickHouseProperties();
-        properties.setClientName("Agent #1");
-        properties.setSessionId("default-session-id");
+    public ClickHouseDataSource dataSource() throws SQLException {
+        Properties properties = new Properties();
+        properties.put("clientName", "Agent #1");
+        properties.put("sessionId", "default-session-id");
 
         return new ClickHouseDataSource(clickhouseJdbcUrl, properties);
     }
diff --git a/test/plugin/scenarios/clickhouse-0.3.x-scenario/src/main/java/org/apache/skywalking/apm/testcase/neo4j/controller/CaseController.java b/test/plugin/scenarios/clickhouse-0.3.2.x-scenario/src/main/java/org/apache/skywalking/apm/testcase/neo4j/controller/CaseController.java
similarity index 88%
rename from test/plugin/scenarios/clickhouse-0.3.x-scenario/src/main/java/org/apache/skywalking/apm/testcase/neo4j/controller/CaseController.java
rename to test/plugin/scenarios/clickhouse-0.3.2.x-scenario/src/main/java/org/apache/skywalking/apm/testcase/neo4j/controller/CaseController.java
index c561c56d87..2dc26c4a98 100644
--- a/test/plugin/scenarios/clickhouse-0.3.x-scenario/src/main/java/org/apache/skywalking/apm/testcase/neo4j/controller/CaseController.java
+++ b/test/plugin/scenarios/clickhouse-0.3.2.x-scenario/src/main/java/org/apache/skywalking/apm/testcase/neo4j/controller/CaseController.java
@@ -21,12 +21,13 @@ package org.apache.skywalking.apm.testcase.neo4j.controller;
 import java.sql.PreparedStatement;
 import java.sql.ResultSet;
 import javax.annotation.Resource;
+
+import com.clickhouse.jdbc.ClickHouseConnection;
+import com.clickhouse.jdbc.ClickHouseDataSource;
+import com.clickhouse.jdbc.ClickHouseStatement;
 import org.springframework.web.bind.annotation.RequestMapping;
 import org.springframework.web.bind.annotation.ResponseBody;
 import org.springframework.web.bind.annotation.RestController;
-import ru.yandex.clickhouse.ClickHouseConnection;
-import ru.yandex.clickhouse.ClickHouseDataSource;
-import ru.yandex.clickhouse.ClickHouseStatement;
 
 @RestController
 @RequestMapping("/case")
@@ -41,8 +42,8 @@ public class CaseController {
     @ResponseBody
     public String testcase() throws Exception {
         try (ClickHouseConnection conn = dataSource.getConnection();
-                ClickHouseStatement stmt = conn.createStatement();
-                ResultSet ignored = stmt.executeQuery(SQL)) {
+             ClickHouseStatement stmt = conn.createStatement();
+             ResultSet ignored = stmt.executeQuery(SQL)) {
             conn.isValid(3);
         }
 
diff --git a/test/plugin/scenarios/clickhouse-0.3.x-scenario/src/main/resources/application.yaml b/test/plugin/scenarios/clickhouse-0.3.2.x-scenario/src/main/resources/application.yaml
similarity index 100%
rename from test/plugin/scenarios/clickhouse-0.3.x-scenario/src/main/resources/application.yaml
rename to test/plugin/scenarios/clickhouse-0.3.2.x-scenario/src/main/resources/application.yaml
diff --git a/test/plugin/scenarios/clickhouse-0.3.x-scenario/src/main/resources/log4j2.xml b/test/plugin/scenarios/clickhouse-0.3.2.x-scenario/src/main/resources/log4j2.xml
similarity index 100%
rename from test/plugin/scenarios/clickhouse-0.3.x-scenario/src/main/resources/log4j2.xml
rename to test/plugin/scenarios/clickhouse-0.3.2.x-scenario/src/main/resources/log4j2.xml
diff --git a/test/plugin/scenarios/clickhouse-0.3.x-scenario/support-version.list b/test/plugin/scenarios/clickhouse-0.3.2.x-scenario/support-version.list
similarity index 98%
rename from test/plugin/scenarios/clickhouse-0.3.x-scenario/support-version.list
rename to test/plugin/scenarios/clickhouse-0.3.2.x-scenario/support-version.list
index dd3def8245..b219a1ca2a 100644
--- a/test/plugin/scenarios/clickhouse-0.3.x-scenario/support-version.list
+++ b/test/plugin/scenarios/clickhouse-0.3.2.x-scenario/support-version.list
@@ -14,5 +14,4 @@
 # See the License for the specific language governing permissions and
 # limitations under the License.
 
-0.3.0
-0.3.1
+0.3.2-patch11