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

FlyingZC pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/shardingsphere.git


The following commit(s) were added to refs/heads/master by this push:
     new 55e764eadfe Use ShardingSphereResultSetMetaData to replace 
JDBCQueryResultMetaData in proxy to handle column type (#38710)
55e764eadfe is described below

commit 55e764eadfe6628ac011b1486e2565e5dd9ea1ea
Author: Zhengqiang Duan <[email protected]>
AuthorDate: Fri May 22 08:40:44 2026 +0800

    Use ShardingSphereResultSetMetaData to replace JDBCQueryResultMetaData in 
proxy to handle column type (#38710)
---
 .../execute/result/query/QueryResultMetaData.java  |   9 +
 .../jdbc/metadata/JDBCQueryResultMetaData.java     |   2 +
 .../impl/raw/metadata/RawQueryResultMetaData.java  |  15 +-
 .../impl/raw/metadata/RawResultSetMetaData.java    | 215 +++++++++++++++++++++
 .../jdbc/metadata/JDBCQueryResultMetaDataTest.java |  10 +-
 .../raw/metadata/RawQueryResultMetaDataTest.java   |  40 ++++
 .../raw/metadata/RawResultSetMetaDataTest.java     | 210 ++++++++++++++++++++
 .../resultset/ShardingSphereResultSetMetaData.java |   3 +-
 .../ShardingSphereResultSetMetaDataTest.java       |  56 ++++++
 .../connector/StandardDatabaseProxyConnector.java  |  16 +-
 .../DatabaseAdminQueryProxyBackendHandler.java     |   4 +-
 .../response/header/query/QueryHeaderBuilder.java  |   6 +-
 .../header/query/QueryHeaderBuilderEngine.java     |  33 ++--
 .../StandardDatabaseProxyConnectorTest.java        |  14 +-
 .../jdbc/fixture/QueryHeaderBuilderFixture.java    |   5 +-
 .../header/query/QueryHeaderBuilderEngineTest.java |  24 ++-
 .../header/query/FirebirdQueryHeaderBuilder.java   |  12 +-
 .../query/FirebirdQueryHeaderBuilderTest.java      |  12 +-
 .../header/query/MySQLQueryHeaderBuilder.java      |  49 ++---
 .../header/query/MySQLQueryHeaderBuilderTest.java  |  59 ++++--
 .../header/query/OpenGaussQueryHeaderBuilder.java  |   8 +-
 .../query/OpenGaussQueryHeaderBuilderTest.java     |  16 +-
 .../header/query/PostgreSQLQueryHeaderBuilder.java |  12 +-
 .../query/PostgreSQLQueryHeaderBuilderTest.java    |  14 +-
 .../prepare/MySQLProjectionMetadataResolver.java   |  13 +-
 25 files changed, 717 insertions(+), 140 deletions(-)

diff --git 
a/infra/executor/src/main/java/org/apache/shardingsphere/infra/executor/sql/execute/result/query/QueryResultMetaData.java
 
b/infra/executor/src/main/java/org/apache/shardingsphere/infra/executor/sql/execute/result/query/QueryResultMetaData.java
index 20813c5a41e..cfcf4b1fcf2 100644
--- 
a/infra/executor/src/main/java/org/apache/shardingsphere/infra/executor/sql/execute/result/query/QueryResultMetaData.java
+++ 
b/infra/executor/src/main/java/org/apache/shardingsphere/infra/executor/sql/execute/result/query/QueryResultMetaData.java
@@ -17,6 +17,7 @@
 
 package org.apache.shardingsphere.infra.executor.sql.execute.result.query;
 
+import java.sql.ResultSetMetaData;
 import java.sql.SQLException;
 
 /**
@@ -121,4 +122,12 @@ public interface QueryResultMetaData {
      * @throws SQLException SQL exception
      */
     boolean isAutoIncrement(int columnIndex) throws SQLException;
+    
+    /**
+     * Get result set meta data.
+     *
+     * @return result set meta data
+     * @throws SQLException SQL exception
+     */
+    ResultSetMetaData getResultSetMetaData() throws SQLException;
 }
diff --git 
a/infra/executor/src/main/java/org/apache/shardingsphere/infra/executor/sql/execute/result/query/impl/driver/jdbc/metadata/JDBCQueryResultMetaData.java
 
b/infra/executor/src/main/java/org/apache/shardingsphere/infra/executor/sql/execute/result/query/impl/driver/jdbc/metadata/JDBCQueryResultMetaData.java
index b6745f66430..4a12b922e24 100644
--- 
a/infra/executor/src/main/java/org/apache/shardingsphere/infra/executor/sql/execute/result/query/impl/driver/jdbc/metadata/JDBCQueryResultMetaData.java
+++ 
b/infra/executor/src/main/java/org/apache/shardingsphere/infra/executor/sql/execute/result/query/impl/driver/jdbc/metadata/JDBCQueryResultMetaData.java
@@ -17,6 +17,7 @@
 
 package 
org.apache.shardingsphere.infra.executor.sql.execute.result.query.impl.driver.jdbc.metadata;
 
+import lombok.Getter;
 import lombok.RequiredArgsConstructor;
 import 
org.apache.shardingsphere.infra.executor.sql.execute.result.query.QueryResultMetaData;
 
@@ -30,6 +31,7 @@ import java.sql.SQLFeatureNotSupportedException;
 @RequiredArgsConstructor
 public final class JDBCQueryResultMetaData implements QueryResultMetaData {
     
+    @Getter
     private final ResultSetMetaData resultSetMetaData;
     
     @Override
diff --git 
a/infra/executor/src/main/java/org/apache/shardingsphere/infra/executor/sql/execute/result/query/impl/raw/metadata/RawQueryResultMetaData.java
 
b/infra/executor/src/main/java/org/apache/shardingsphere/infra/executor/sql/execute/result/query/impl/raw/metadata/RawQueryResultMetaData.java
index 580a66febed..e3d1a8e46cc 100644
--- 
a/infra/executor/src/main/java/org/apache/shardingsphere/infra/executor/sql/execute/result/query/impl/raw/metadata/RawQueryResultMetaData.java
+++ 
b/infra/executor/src/main/java/org/apache/shardingsphere/infra/executor/sql/execute/result/query/impl/raw/metadata/RawQueryResultMetaData.java
@@ -17,19 +17,25 @@
 
 package 
org.apache.shardingsphere.infra.executor.sql.execute.result.query.impl.raw.metadata;
 
-import lombok.RequiredArgsConstructor;
 import 
org.apache.shardingsphere.infra.executor.sql.execute.result.query.QueryResultMetaData;
 
+import java.sql.ResultSetMetaData;
 import java.util.List;
 
 /**
  * Raw query result meta data.
  */
-@RequiredArgsConstructor
 public final class RawQueryResultMetaData implements QueryResultMetaData {
     
     private final List<RawQueryResultColumnMetaData> columns;
     
+    private final ResultSetMetaData resultSetMetaData;
+    
+    public RawQueryResultMetaData(final List<RawQueryResultColumnMetaData> 
columns) {
+        this.columns = columns;
+        resultSetMetaData = new RawResultSetMetaData(columns);
+    }
+    
     @Override
     public int getColumnCount() {
         return columns.size();
@@ -84,4 +90,9 @@ public final class RawQueryResultMetaData implements 
QueryResultMetaData {
     public boolean isAutoIncrement(final int columnIndex) {
         return columns.get(columnIndex - 1).isAutoIncrement();
     }
+    
+    @Override
+    public ResultSetMetaData getResultSetMetaData() {
+        return resultSetMetaData;
+    }
 }
diff --git 
a/infra/executor/src/main/java/org/apache/shardingsphere/infra/executor/sql/execute/result/query/impl/raw/metadata/RawResultSetMetaData.java
 
b/infra/executor/src/main/java/org/apache/shardingsphere/infra/executor/sql/execute/result/query/impl/raw/metadata/RawResultSetMetaData.java
new file mode 100644
index 00000000000..80bf5f9341e
--- /dev/null
+++ 
b/infra/executor/src/main/java/org/apache/shardingsphere/infra/executor/sql/execute/result/query/impl/raw/metadata/RawResultSetMetaData.java
@@ -0,0 +1,215 @@
+/*
+ * 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.shardingsphere.infra.executor.sql.execute.result.query.impl.raw.metadata;
+
+import lombok.RequiredArgsConstructor;
+
+import java.math.BigDecimal;
+import java.sql.Date;
+import java.sql.ResultSetMetaData;
+import java.sql.SQLException;
+import java.sql.SQLFeatureNotSupportedException;
+import java.sql.Time;
+import java.sql.Timestamp;
+import java.sql.Types;
+import java.util.List;
+
+/**
+ * Raw result set meta data.
+ */
+@RequiredArgsConstructor
+public final class RawResultSetMetaData implements ResultSetMetaData {
+    
+    private final List<RawQueryResultColumnMetaData> columns;
+    
+    @Override
+    public int getColumnCount() {
+        return columns.size();
+    }
+    
+    @Override
+    public boolean isAutoIncrement(final int column) throws SQLException {
+        return getColumnMetaData(column).isAutoIncrement();
+    }
+    
+    @Override
+    public boolean isCaseSensitive(final int column) throws SQLException {
+        getColumnMetaData(column);
+        return true;
+    }
+    
+    @Override
+    public boolean isSearchable(final int column) throws SQLException {
+        getColumnMetaData(column);
+        return true;
+    }
+    
+    @Override
+    public boolean isCurrency(final int column) throws SQLException {
+        getColumnMetaData(column);
+        return false;
+    }
+    
+    @Override
+    public int isNullable(final int column) throws SQLException {
+        return getColumnMetaData(column).isNotNull() ? 
ResultSetMetaData.columnNoNulls : ResultSetMetaData.columnNullable;
+    }
+    
+    @Override
+    public boolean isSigned(final int column) throws SQLException {
+        return getColumnMetaData(column).isSigned();
+    }
+    
+    @Override
+    public int getColumnDisplaySize(final int column) throws SQLException {
+        return getColumnMetaData(column).getLength();
+    }
+    
+    @Override
+    public String getColumnLabel(final int column) throws SQLException {
+        return getColumnMetaData(column).getLabel();
+    }
+    
+    @Override
+    public String getColumnName(final int column) throws SQLException {
+        return getColumnMetaData(column).getName();
+    }
+    
+    @Override
+    public String getSchemaName(final int column) throws SQLException {
+        getColumnMetaData(column);
+        return "";
+    }
+    
+    @Override
+    public int getPrecision(final int column) throws SQLException {
+        return getColumnMetaData(column).getLength();
+    }
+    
+    @Override
+    public int getScale(final int column) throws SQLException {
+        return getColumnMetaData(column).getDecimals();
+    }
+    
+    @Override
+    public String getTableName(final int column) throws SQLException {
+        return getColumnMetaData(column).getTableName();
+    }
+    
+    @Override
+    public String getCatalogName(final int column) throws SQLException {
+        getColumnMetaData(column);
+        return "";
+    }
+    
+    @Override
+    public int getColumnType(final int column) throws SQLException {
+        return getColumnMetaData(column).getType();
+    }
+    
+    @Override
+    public String getColumnTypeName(final int column) throws SQLException {
+        return getColumnMetaData(column).getTypeName();
+    }
+    
+    @Override
+    public boolean isReadOnly(final int column) throws SQLException {
+        getColumnMetaData(column);
+        return false;
+    }
+    
+    @Override
+    public boolean isWritable(final int column) throws SQLException {
+        getColumnMetaData(column);
+        return true;
+    }
+    
+    @Override
+    public boolean isDefinitelyWritable(final int column) throws SQLException {
+        getColumnMetaData(column);
+        return false;
+    }
+    
+    @Override
+    public String getColumnClassName(final int column) throws SQLException {
+        return getColumnClassNameByType(getColumnMetaData(column).getType());
+    }
+    
+    private String getColumnClassNameByType(final int columnType) {
+        switch (columnType) {
+            case Types.BOOLEAN:
+            case Types.BIT:
+                return Boolean.class.getName();
+            case Types.TINYINT:
+            case Types.SMALLINT:
+            case Types.INTEGER:
+                return Integer.class.getName();
+            case Types.BIGINT:
+                return Long.class.getName();
+            case Types.FLOAT:
+            case Types.REAL:
+                return Float.class.getName();
+            case Types.DOUBLE:
+                return Double.class.getName();
+            case Types.NUMERIC:
+            case Types.DECIMAL:
+                return BigDecimal.class.getName();
+            case Types.DATE:
+                return Date.class.getName();
+            case Types.TIME:
+            case Types.TIME_WITH_TIMEZONE:
+                return Time.class.getName();
+            case Types.TIMESTAMP:
+            case Types.TIMESTAMP_WITH_TIMEZONE:
+                return Timestamp.class.getName();
+            case Types.BINARY:
+            case Types.VARBINARY:
+            case Types.LONGVARBINARY:
+                return byte[].class.getName();
+            case Types.CHAR:
+            case Types.VARCHAR:
+            case Types.LONGVARCHAR:
+            case Types.NCHAR:
+            case Types.NVARCHAR:
+            case Types.LONGNVARCHAR:
+                return String.class.getName();
+            default:
+                return Object.class.getName();
+        }
+    }
+    
+    private RawQueryResultColumnMetaData getColumnMetaData(final int column) 
throws SQLException {
+        if (column < 1 || column > columns.size()) {
+            throw new SQLException(String.format("Column index out of range: 
%s", column));
+        }
+        return columns.get(column - 1);
+    }
+    
+    @Override
+    public <T> T unwrap(final Class<T> iface) throws SQLException {
+        if (isWrapperFor(iface)) {
+            return iface.cast(this);
+        }
+        throw new SQLFeatureNotSupportedException(String.format("`%s` cannot 
be unwrapped as `%s`", getClass().getName(), iface.getName()));
+    }
+    
+    @Override
+    public boolean isWrapperFor(final Class<?> iface) {
+        return iface.isInstance(this);
+    }
+}
diff --git 
a/infra/executor/src/test/java/org/apache/shardingsphere/infra/executor/sql/execute/result/query/impl/driver/jdbc/metadata/JDBCQueryResultMetaDataTest.java
 
b/infra/executor/src/test/java/org/apache/shardingsphere/infra/executor/sql/execute/result/query/impl/driver/jdbc/metadata/JDBCQueryResultMetaDataTest.java
index 37ddc79f016..ed018e57898 100644
--- 
a/infra/executor/src/test/java/org/apache/shardingsphere/infra/executor/sql/execute/result/query/impl/driver/jdbc/metadata/JDBCQueryResultMetaDataTest.java
+++ 
b/infra/executor/src/test/java/org/apache/shardingsphere/infra/executor/sql/execute/result/query/impl/driver/jdbc/metadata/JDBCQueryResultMetaDataTest.java
@@ -34,11 +34,14 @@ import static org.mockito.Mockito.when;
 
 class JDBCQueryResultMetaDataTest {
     
+    private ResultSetMetaData resultSetMetaData;
+    
     private JDBCQueryResultMetaData queryResultMetaData;
     
     @BeforeEach
     void setUp() throws SQLException {
-        queryResultMetaData = new 
JDBCQueryResultMetaData(mockResultSetMetaData());
+        resultSetMetaData = mockResultSetMetaData();
+        queryResultMetaData = new JDBCQueryResultMetaData(resultSetMetaData);
     }
     
     private ResultSetMetaData mockResultSetMetaData() throws SQLException {
@@ -57,6 +60,11 @@ class JDBCQueryResultMetaDataTest {
         return result;
     }
     
+    @Test
+    void assertGetResultSetMetaData() throws SQLException {
+        assertThat(queryResultMetaData.getResultSetMetaData(), 
is(resultSetMetaData));
+    }
+    
     @Test
     void assertGetColumnCount() throws SQLException {
         assertThat(queryResultMetaData.getColumnCount(), is(1));
diff --git 
a/infra/executor/src/test/java/org/apache/shardingsphere/infra/executor/sql/execute/result/query/impl/raw/metadata/RawQueryResultMetaDataTest.java
 
b/infra/executor/src/test/java/org/apache/shardingsphere/infra/executor/sql/execute/result/query/impl/raw/metadata/RawQueryResultMetaDataTest.java
new file mode 100644
index 00000000000..f8ab96d17e0
--- /dev/null
+++ 
b/infra/executor/src/test/java/org/apache/shardingsphere/infra/executor/sql/execute/result/query/impl/raw/metadata/RawQueryResultMetaDataTest.java
@@ -0,0 +1,40 @@
+/*
+ * 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.shardingsphere.infra.executor.sql.execute.result.query.impl.raw.metadata;
+
+import org.junit.jupiter.api.Test;
+
+import java.sql.ResultSetMetaData;
+import java.sql.Types;
+import java.util.Collections;
+
+import static org.hamcrest.MatcherAssert.assertThat;
+import static org.hamcrest.Matchers.is;
+import static org.hamcrest.Matchers.isA;
+
+class RawQueryResultMetaDataTest {
+    
+    @Test
+    void assertGetResultSetMetaData() {
+        RawQueryResultMetaData queryResultMetaData = new 
RawQueryResultMetaData(Collections.singletonList(new 
RawQueryResultColumnMetaData("foo_table", "foo_column", "foo_label",
+                Types.VARCHAR, "VARCHAR", 100, 2, true, true, true)));
+        ResultSetMetaData actual = queryResultMetaData.getResultSetMetaData();
+        assertThat(actual, isA(RawResultSetMetaData.class));
+        assertThat(queryResultMetaData.getResultSetMetaData(), is(actual));
+    }
+}
diff --git 
a/infra/executor/src/test/java/org/apache/shardingsphere/infra/executor/sql/execute/result/query/impl/raw/metadata/RawResultSetMetaDataTest.java
 
b/infra/executor/src/test/java/org/apache/shardingsphere/infra/executor/sql/execute/result/query/impl/raw/metadata/RawResultSetMetaDataTest.java
new file mode 100644
index 00000000000..767e1236507
--- /dev/null
+++ 
b/infra/executor/src/test/java/org/apache/shardingsphere/infra/executor/sql/execute/result/query/impl/raw/metadata/RawResultSetMetaDataTest.java
@@ -0,0 +1,210 @@
+/*
+ * 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.shardingsphere.infra.executor.sql.execute.result.query.impl.raw.metadata;
+
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.params.ParameterizedTest;
+import org.junit.jupiter.params.provider.Arguments;
+import org.junit.jupiter.params.provider.MethodSource;
+
+import java.math.BigDecimal;
+import java.sql.Date;
+import java.sql.ResultSetMetaData;
+import java.sql.SQLException;
+import java.sql.SQLFeatureNotSupportedException;
+import java.sql.Time;
+import java.sql.Timestamp;
+import java.sql.Types;
+import java.util.Collections;
+import java.util.stream.Stream;
+
+import static org.hamcrest.MatcherAssert.assertThat;
+import static org.hamcrest.Matchers.is;
+import static org.junit.jupiter.api.Assertions.assertFalse;
+import static org.junit.jupiter.api.Assertions.assertThrows;
+import static org.junit.jupiter.api.Assertions.assertTrue;
+
+class RawResultSetMetaDataTest {
+    
+    @Test
+    void assertGetColumnCount() {
+        assertThat(createMetaData().getColumnCount(), is(1));
+    }
+    
+    @Test
+    void assertIsAutoIncrement() throws SQLException {
+        assertTrue(createMetaData().isAutoIncrement(1));
+    }
+    
+    @Test
+    void assertIsCaseSensitive() throws SQLException {
+        assertTrue(createMetaData().isCaseSensitive(1));
+    }
+    
+    @Test
+    void assertIsSearchable() throws SQLException {
+        assertTrue(createMetaData().isSearchable(1));
+    }
+    
+    @Test
+    void assertIsCurrency() throws SQLException {
+        assertFalse(createMetaData().isCurrency(1));
+    }
+    
+    @Test
+    void assertIsNullable() throws SQLException {
+        assertThat(createMetaData().isNullable(1), 
is(ResultSetMetaData.columnNoNulls));
+    }
+    
+    @Test
+    void assertIsNullableWithNullableColumn() throws SQLException {
+        assertThat(new RawResultSetMetaData(Collections.singletonList(new 
RawQueryResultColumnMetaData("foo_table", "foo_column", "foo_label", 
Types.VARCHAR, "VARCHAR", 100, 2,
+                true, false, true))).isNullable(1), 
is(ResultSetMetaData.columnNullable));
+    }
+    
+    @Test
+    void assertIsSigned() throws SQLException {
+        assertTrue(createMetaData().isSigned(1));
+    }
+    
+    @Test
+    void assertGetColumnDisplaySize() throws SQLException {
+        assertThat(createMetaData().getColumnDisplaySize(1), is(100));
+    }
+    
+    @Test
+    void assertGetColumnLabel() throws SQLException {
+        assertThat(createMetaData().getColumnLabel(1), is("foo_label"));
+    }
+    
+    @Test
+    void assertGetColumnName() throws SQLException {
+        assertThat(createMetaData().getColumnName(1), is("foo_column"));
+    }
+    
+    @Test
+    void assertGetColumnNameWithTooSmallColumnIndex() {
+        assertThrows(SQLException.class, () -> 
createMetaData().getColumnName(0));
+    }
+    
+    @Test
+    void assertGetColumnNameWithTooLargeColumnIndex() {
+        assertThrows(SQLException.class, () -> 
createMetaData().getColumnName(2));
+    }
+    
+    @Test
+    void assertGetSchemaName() throws SQLException {
+        assertThat(createMetaData().getSchemaName(1), is(""));
+    }
+    
+    @Test
+    void assertGetPrecision() throws SQLException {
+        assertThat(createMetaData().getPrecision(1), is(100));
+    }
+    
+    @Test
+    void assertGetScale() throws SQLException {
+        assertThat(createMetaData().getScale(1), is(2));
+    }
+    
+    @Test
+    void assertGetTableName() throws SQLException {
+        assertThat(createMetaData().getTableName(1), is("foo_table"));
+    }
+    
+    @Test
+    void assertGetCatalogName() throws SQLException {
+        assertThat(createMetaData().getCatalogName(1), is(""));
+    }
+    
+    @Test
+    void assertGetColumnType() throws SQLException {
+        assertThat(createMetaData().getColumnType(1), is(Types.VARCHAR));
+    }
+    
+    @Test
+    void assertGetColumnTypeName() throws SQLException {
+        assertThat(createMetaData().getColumnTypeName(1), is("VARCHAR"));
+    }
+    
+    @Test
+    void assertIsReadOnly() throws SQLException {
+        assertFalse(createMetaData().isReadOnly(1));
+    }
+    
+    @Test
+    void assertIsWritable() throws SQLException {
+        assertTrue(createMetaData().isWritable(1));
+    }
+    
+    @Test
+    void assertIsDefinitelyWritable() throws SQLException {
+        assertFalse(createMetaData().isDefinitelyWritable(1));
+    }
+    
+    @ParameterizedTest(name = "{0}")
+    @MethodSource("getColumnClassNameArguments")
+    void assertGetColumnClassName(final String name, final int columnType, 
final String expected) throws SQLException {
+        assertThat(createMetaData(columnType).getColumnClassName(1), 
is(expected));
+    }
+    
+    private static Stream<Arguments> getColumnClassNameArguments() {
+        return Stream.of(
+                Arguments.of("boolean", Types.BOOLEAN, 
Boolean.class.getName()),
+                Arguments.of("integer", Types.INTEGER, 
Integer.class.getName()),
+                Arguments.of("bigint", Types.BIGINT, Long.class.getName()),
+                Arguments.of("float", Types.FLOAT, Float.class.getName()),
+                Arguments.of("double", Types.DOUBLE, Double.class.getName()),
+                Arguments.of("decimal", Types.DECIMAL, 
BigDecimal.class.getName()),
+                Arguments.of("date", Types.DATE, Date.class.getName()),
+                Arguments.of("time", Types.TIME, Time.class.getName()),
+                Arguments.of("timestamp", Types.TIMESTAMP, 
Timestamp.class.getName()),
+                Arguments.of("binary", Types.BINARY, byte[].class.getName()),
+                Arguments.of("varchar", Types.VARCHAR, String.class.getName()),
+                Arguments.of("other", Types.OTHER, Object.class.getName()));
+    }
+    
+    @Test
+    void assertUnwrap() throws SQLException {
+        RawResultSetMetaData metaData = createMetaData();
+        assertThat(metaData.unwrap(RawResultSetMetaData.class), is(metaData));
+    }
+    
+    @Test
+    void assertUnwrapWithUnsupportedClass() {
+        assertThrows(SQLFeatureNotSupportedException.class, () -> 
createMetaData().unwrap(String.class));
+    }
+    
+    @Test
+    void assertIsWrapperFor() {
+        assertTrue(createMetaData().isWrapperFor(RawResultSetMetaData.class));
+    }
+    
+    @Test
+    void assertIsWrapperForWithUnsupportedClass() {
+        assertFalse(createMetaData().isWrapperFor(String.class));
+    }
+    
+    private RawResultSetMetaData createMetaData() {
+        return createMetaData(Types.VARCHAR);
+    }
+    
+    private RawResultSetMetaData createMetaData(final int columnType) {
+        return new RawResultSetMetaData(Collections.singletonList(new 
RawQueryResultColumnMetaData("foo_table", "foo_column", "foo_label", 
columnType, "VARCHAR", 100, 2, true, true, true)));
+    }
+}
diff --git 
a/jdbc/src/main/java/org/apache/shardingsphere/driver/jdbc/core/resultset/ShardingSphereResultSetMetaData.java
 
b/jdbc/src/main/java/org/apache/shardingsphere/driver/jdbc/core/resultset/ShardingSphereResultSetMetaData.java
index 6d1a2ac4ef3..e4d068b2383 100644
--- 
a/jdbc/src/main/java/org/apache/shardingsphere/driver/jdbc/core/resultset/ShardingSphereResultSetMetaData.java
+++ 
b/jdbc/src/main/java/org/apache/shardingsphere/driver/jdbc/core/resultset/ShardingSphereResultSetMetaData.java
@@ -128,7 +128,8 @@ public final class ShardingSphereResultSetMetaData extends 
WrapperAdapter implem
     
     @Override
     public String getTableName(final int column) throws SQLException {
-        return 
decorateTableName(database.getRuleMetaData().getAttributes(DataNodeRuleAttribute.class),
 resultSetMetaData.getTableName(column));
+        String actualTableName = resultSetMetaData.getTableName(column);
+        return null == database ? actualTableName : 
decorateTableName(database.getRuleMetaData().getAttributes(DataNodeRuleAttribute.class),
 actualTableName);
     }
     
     private String decorateTableName(final Collection<DataNodeRuleAttribute> 
ruleAttributes, final String actualTableName) {
diff --git 
a/jdbc/src/test/java/org/apache/shardingsphere/driver/jdbc/core/resultset/ShardingSphereResultSetMetaDataTest.java
 
b/jdbc/src/test/java/org/apache/shardingsphere/driver/jdbc/core/resultset/ShardingSphereResultSetMetaDataTest.java
new file mode 100644
index 00000000000..eafa9232b80
--- /dev/null
+++ 
b/jdbc/src/test/java/org/apache/shardingsphere/driver/jdbc/core/resultset/ShardingSphereResultSetMetaDataTest.java
@@ -0,0 +1,56 @@
+/*
+ * 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.shardingsphere.driver.jdbc.core.resultset;
+
+import 
org.apache.shardingsphere.infra.metadata.database.ShardingSphereDatabase;
+import 
org.apache.shardingsphere.infra.rule.attribute.datanode.DataNodeRuleAttribute;
+import org.junit.jupiter.api.Test;
+
+import java.sql.ResultSetMetaData;
+import java.sql.SQLException;
+import java.util.Collections;
+import java.util.Optional;
+
+import static org.hamcrest.MatcherAssert.assertThat;
+import static org.hamcrest.Matchers.is;
+import static org.mockito.Mockito.RETURNS_DEEP_STUBS;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.when;
+
+class ShardingSphereResultSetMetaDataTest {
+    
+    @Test
+    void assertGetTableNameWithNullDatabase() throws SQLException {
+        ResultSetMetaData resultSetMetaData = mock(ResultSetMetaData.class);
+        when(resultSetMetaData.getTableName(1)).thenReturn("t_order");
+        String actualTableName = new 
ShardingSphereResultSetMetaData(resultSetMetaData, null, null).getTableName(1);
+        assertThat(actualTableName, is("t_order"));
+    }
+    
+    @Test
+    void assertGetTableNameWithDataNodeRuleAttribute() throws SQLException {
+        ResultSetMetaData resultSetMetaData = mock(ResultSetMetaData.class);
+        when(resultSetMetaData.getTableName(1)).thenReturn("t_order_0");
+        DataNodeRuleAttribute ruleAttribute = 
mock(DataNodeRuleAttribute.class);
+        
when(ruleAttribute.findLogicTableByActualTable("t_order_0")).thenReturn(Optional.of("t_order"));
+        ShardingSphereDatabase database = mock(ShardingSphereDatabase.class, 
RETURNS_DEEP_STUBS);
+        
when(database.getRuleMetaData().getAttributes(DataNodeRuleAttribute.class)).thenReturn(Collections.singleton(ruleAttribute));
+        String actualTableName = new 
ShardingSphereResultSetMetaData(resultSetMetaData, database, 
null).getTableName(1);
+        assertThat(actualTableName, is("t_order"));
+    }
+}
diff --git 
a/proxy/backend/core/src/main/java/org/apache/shardingsphere/proxy/backend/connector/StandardDatabaseProxyConnector.java
 
b/proxy/backend/core/src/main/java/org/apache/shardingsphere/proxy/backend/connector/StandardDatabaseProxyConnector.java
index 7cf6aff54c5..3ad376a8aae 100644
--- 
a/proxy/backend/core/src/main/java/org/apache/shardingsphere/proxy/backend/connector/StandardDatabaseProxyConnector.java
+++ 
b/proxy/backend/core/src/main/java/org/apache/shardingsphere/proxy/backend/connector/StandardDatabaseProxyConnector.java
@@ -22,6 +22,7 @@ import 
org.apache.shardingsphere.database.connector.core.metadata.database.metad
 import org.apache.shardingsphere.database.connector.core.type.DatabaseType;
 import 
org.apache.shardingsphere.database.connector.core.type.DatabaseTypeRegistry;
 import 
org.apache.shardingsphere.database.exception.core.SQLExceptionTransformEngine;
+import 
org.apache.shardingsphere.driver.jdbc.core.resultset.ShardingSphereResultSetMetaData;
 import 
org.apache.shardingsphere.infra.binder.context.segment.insert.keygen.GeneratedKeyContext;
 import 
org.apache.shardingsphere.infra.binder.context.statement.SQLStatementContext;
 import 
org.apache.shardingsphere.infra.binder.context.statement.type.ddl.CursorHeldSQLStatementContext;
@@ -38,7 +39,6 @@ import 
org.apache.shardingsphere.infra.executor.sql.execute.engine.SQLExecutorEx
 import 
org.apache.shardingsphere.infra.executor.sql.execute.engine.driver.jdbc.JDBCExecutionUnit;
 import 
org.apache.shardingsphere.infra.executor.sql.execute.result.ExecuteResult;
 import 
org.apache.shardingsphere.infra.executor.sql.execute.result.query.QueryResult;
-import 
org.apache.shardingsphere.infra.executor.sql.execute.result.query.impl.driver.jdbc.metadata.JDBCQueryResultMetaData;
 import 
org.apache.shardingsphere.infra.executor.sql.execute.result.query.impl.driver.jdbc.type.stream.JDBCStreamQueryResult;
 import 
org.apache.shardingsphere.infra.executor.sql.execute.result.update.UpdateResult;
 import 
org.apache.shardingsphere.infra.executor.sql.prepare.driver.DriverExecutionPrepareEngine;
@@ -278,11 +278,12 @@ public final class StandardDatabaseProxyConnector 
implements DatabaseProxyConnec
     }
     
     private ResponseHeader processExecuteQueryFederation(final ResultSet 
resultSet) throws SQLException {
-        int columnCount = resultSet.getMetaData().getColumnCount();
+        ShardingSphereResultSetMetaData resultSetMetaData = new 
ShardingSphereResultSetMetaData(resultSet.getMetaData(), database, 
queryContext.getSqlStatementContext());
+        int columnCount = resultSetMetaData.getColumnCount();
         queryHeaders = new ArrayList<>(columnCount);
         QueryHeaderBuilderEngine queryHeaderBuilderEngine = new 
QueryHeaderBuilderEngine(null == database ? null : database.getProtocolType());
         for (int columnIndex = 1; columnIndex <= columnCount; columnIndex++) {
-            queryHeaders.add(queryHeaderBuilderEngine.build(new 
JDBCQueryResultMetaData(resultSet.getMetaData()), database, columnIndex));
+            queryHeaders.add(queryHeaderBuilderEngine.build(resultSetMetaData, 
database, columnIndex));
         }
         mergedResult = new 
IteratorStreamMergedResult(Collections.singletonList(new 
JDBCStreamQueryResult(resultSet)));
         return new QueryResponseHeader(queryHeaders);
@@ -298,8 +299,9 @@ public final class StandardDatabaseProxyConnector 
implements DatabaseProxyConnec
         int columnCount = getColumnCount(sqlStatementContext, 
queryResultSample);
         List<QueryHeader> result = new ArrayList<>(columnCount);
         QueryHeaderBuilderEngine queryHeaderBuilderEngine = new 
QueryHeaderBuilderEngine(database.getProtocolType());
+        ShardingSphereResultSetMetaData resultSetMetaData = new 
ShardingSphereResultSetMetaData(queryResultSample.getMetaData().getResultSetMetaData(),
 database, sqlStatementContext);
         for (int columnIndex = 1; columnIndex <= columnCount; columnIndex++) {
-            result.add(createQueryHeader(queryHeaderBuilderEngine, 
sqlStatementContext, queryResultSample, database, columnIndex));
+            result.add(createQueryHeader(queryHeaderBuilderEngine, 
sqlStatementContext, resultSetMetaData, database, columnIndex));
         }
         return result;
     }
@@ -311,10 +313,10 @@ public final class StandardDatabaseProxyConnector 
implements DatabaseProxyConnec
     }
     
     private QueryHeader createQueryHeader(final QueryHeaderBuilderEngine 
queryHeaderBuilderEngine, final SQLStatementContext sqlStatementContext,
-                                          final QueryResult queryResultSample, 
final ShardingSphereDatabase database, final int columnIndex) throws 
SQLException {
+                                          final 
ShardingSphereResultSetMetaData resultSetMetaData, final ShardingSphereDatabase 
database, final int columnIndex) throws SQLException {
         return containsDerivedProjections
-                ? queryHeaderBuilderEngine.build(((SelectStatementContext) 
sqlStatementContext).getProjectionsContext(), queryResultSample.getMetaData(), 
database, columnIndex)
-                : 
queryHeaderBuilderEngine.build(queryResultSample.getMetaData(), database, 
columnIndex);
+                ? queryHeaderBuilderEngine.build(((SelectStatementContext) 
sqlStatementContext).getProjectionsContext(), resultSetMetaData, database, 
columnIndex)
+                : queryHeaderBuilderEngine.build(resultSetMetaData, database, 
columnIndex);
     }
     
     private MergedResult mergeQuery(final List<QueryResult> queryResults) 
throws SQLException {
diff --git 
a/proxy/backend/core/src/main/java/org/apache/shardingsphere/proxy/backend/handler/admin/DatabaseAdminQueryProxyBackendHandler.java
 
b/proxy/backend/core/src/main/java/org/apache/shardingsphere/proxy/backend/handler/admin/DatabaseAdminQueryProxyBackendHandler.java
index 9be54edadfc..958168e1a19 100644
--- 
a/proxy/backend/core/src/main/java/org/apache/shardingsphere/proxy/backend/handler/admin/DatabaseAdminQueryProxyBackendHandler.java
+++ 
b/proxy/backend/core/src/main/java/org/apache/shardingsphere/proxy/backend/handler/admin/DatabaseAdminQueryProxyBackendHandler.java
@@ -19,6 +19,7 @@ package org.apache.shardingsphere.proxy.backend.handler.admin;
 
 import lombok.RequiredArgsConstructor;
 import org.apache.shardingsphere.database.connector.core.type.DatabaseType;
+import 
org.apache.shardingsphere.driver.jdbc.core.resultset.ShardingSphereResultSetMetaData;
 import 
org.apache.shardingsphere.infra.executor.sql.execute.result.query.QueryResultMetaData;
 import org.apache.shardingsphere.infra.merge.result.MergedResult;
 import 
org.apache.shardingsphere.infra.metadata.database.ShardingSphereDatabase;
@@ -66,8 +67,9 @@ public final class DatabaseAdminQueryProxyBackendHandler 
implements ProxyBackend
         ShardingSphereDatabase database = null == 
connectionSession.getUsedDatabaseName() ? null : 
contextManager.getDatabase(connectionSession.getUsedDatabaseName());
         DatabaseType databaseType = null == database ? 
connectionSession.getProtocolType() : database.getProtocolType();
         QueryHeaderBuilderEngine queryHeaderBuilderEngine = new 
QueryHeaderBuilderEngine(databaseType);
+        ShardingSphereResultSetMetaData resultSetMetaData = new 
ShardingSphereResultSetMetaData(queryResultMetaData.getResultSetMetaData(), 
database, null);
         for (int columnIndex = 1; columnIndex <= 
queryResultMetaData.getColumnCount(); columnIndex++) {
-            result.add(queryHeaderBuilderEngine.build(queryResultMetaData, 
database, columnIndex));
+            result.add(queryHeaderBuilderEngine.build(resultSetMetaData, 
database, columnIndex));
         }
         return result;
     }
diff --git 
a/proxy/backend/core/src/main/java/org/apache/shardingsphere/proxy/backend/response/header/query/QueryHeaderBuilder.java
 
b/proxy/backend/core/src/main/java/org/apache/shardingsphere/proxy/backend/response/header/query/QueryHeaderBuilder.java
index f5ce47e89ca..0eeeab6658b 100644
--- 
a/proxy/backend/core/src/main/java/org/apache/shardingsphere/proxy/backend/response/header/query/QueryHeaderBuilder.java
+++ 
b/proxy/backend/core/src/main/java/org/apache/shardingsphere/proxy/backend/response/header/query/QueryHeaderBuilder.java
@@ -18,7 +18,7 @@
 package org.apache.shardingsphere.proxy.backend.response.header.query;
 
 import org.apache.shardingsphere.database.connector.core.spi.DatabaseTypedSPI;
-import 
org.apache.shardingsphere.infra.executor.sql.execute.result.query.QueryResultMetaData;
+import 
org.apache.shardingsphere.driver.jdbc.core.resultset.ShardingSphereResultSetMetaData;
 import 
org.apache.shardingsphere.infra.metadata.database.ShardingSphereDatabase;
 import org.apache.shardingsphere.infra.spi.annotation.SingletonSPI;
 
@@ -33,7 +33,7 @@ public interface QueryHeaderBuilder extends DatabaseTypedSPI {
     /**
      * Build query header.
      *
-     * @param queryResultMetaData query result meta data
+     * @param resultSetMetaData result set meta data
      * @param database database
      * @param columnName column name
      * @param columnLabel column label
@@ -41,5 +41,5 @@ public interface QueryHeaderBuilder extends DatabaseTypedSPI {
      * @return query header
      * @throws SQLException SQL exception
      */
-    QueryHeader build(QueryResultMetaData queryResultMetaData, 
ShardingSphereDatabase database, String columnName, String columnLabel, int 
columnIndex) throws SQLException;
+    QueryHeader build(ShardingSphereResultSetMetaData resultSetMetaData, 
ShardingSphereDatabase database, String columnName, String columnLabel, int 
columnIndex) throws SQLException;
 }
diff --git 
a/proxy/backend/core/src/main/java/org/apache/shardingsphere/proxy/backend/response/header/query/QueryHeaderBuilderEngine.java
 
b/proxy/backend/core/src/main/java/org/apache/shardingsphere/proxy/backend/response/header/query/QueryHeaderBuilderEngine.java
index 9fb51157c2c..ac0761b2eda 100644
--- 
a/proxy/backend/core/src/main/java/org/apache/shardingsphere/proxy/backend/response/header/query/QueryHeaderBuilderEngine.java
+++ 
b/proxy/backend/core/src/main/java/org/apache/shardingsphere/proxy/backend/response/header/query/QueryHeaderBuilderEngine.java
@@ -17,14 +17,13 @@
 
 package org.apache.shardingsphere.proxy.backend.response.header.query;
 
-import lombok.RequiredArgsConstructor;
 import 
org.apache.shardingsphere.database.connector.core.spi.DatabaseTypedSPILoader;
 import org.apache.shardingsphere.database.connector.core.type.DatabaseType;
+import 
org.apache.shardingsphere.driver.jdbc.core.resultset.ShardingSphereResultSetMetaData;
 import 
org.apache.shardingsphere.infra.binder.context.segment.select.projection.Projection;
 import 
org.apache.shardingsphere.infra.binder.context.segment.select.projection.ProjectionsContext;
 import org.apache.shardingsphere.infra.exception.ShardingSpherePreconditions;
 import 
org.apache.shardingsphere.infra.exception.kernel.syntax.ColumnIndexOutOfRangeException;
-import 
org.apache.shardingsphere.infra.executor.sql.execute.result.query.QueryResultMetaData;
 import 
org.apache.shardingsphere.infra.metadata.database.ShardingSphereDatabase;
 
 import java.sql.SQLException;
@@ -32,40 +31,48 @@ import java.sql.SQLException;
 /**
  * Query header builder engine.
  */
-@RequiredArgsConstructor
 public final class QueryHeaderBuilderEngine {
     
-    private final DatabaseType databaseType;
+    private final QueryHeaderBuilder queryHeaderBuilder;
+    
+    /**
+     * Create query header builder engine.
+     *
+     * @param databaseType database type
+     */
+    public QueryHeaderBuilderEngine(final DatabaseType databaseType) {
+        queryHeaderBuilder = 
DatabaseTypedSPILoader.getService(QueryHeaderBuilder.class, databaseType);
+    }
     
     /**
      * Build query header builder.
      *
-     * @param queryResultMetaData query result meta data
+     * @param resultSetMetaData result set meta data
      * @param database database
      * @param columnIndex column index
      * @return query header
      * @throws SQLException SQL exception
      */
-    public QueryHeader build(final QueryResultMetaData queryResultMetaData, 
final ShardingSphereDatabase database, final int columnIndex) throws 
SQLException {
-        String columnName = queryResultMetaData.getColumnName(columnIndex);
-        String columnLabel = queryResultMetaData.getColumnLabel(columnIndex);
-        return DatabaseTypedSPILoader.getService(QueryHeaderBuilder.class, 
databaseType).build(queryResultMetaData, database, columnName, columnLabel, 
columnIndex);
+    public QueryHeader build(final ShardingSphereResultSetMetaData 
resultSetMetaData, final ShardingSphereDatabase database, final int 
columnIndex) throws SQLException {
+        String columnName = resultSetMetaData.getColumnName(columnIndex);
+        String columnLabel = resultSetMetaData.getColumnLabel(columnIndex);
+        return queryHeaderBuilder.build(resultSetMetaData, database, 
columnName, columnLabel, columnIndex);
     }
     
     /**
      * Build query header builder.
      *
      * @param projectionsContext projections context
-     * @param queryResultMetaData query result meta data
+     * @param resultSetMetaData result set meta data
      * @param database database
      * @param columnIndex column index
      * @return query header
      * @throws SQLException SQL exception
      */
-    public QueryHeader build(final ProjectionsContext projectionsContext,
-                             final QueryResultMetaData queryResultMetaData, 
final ShardingSphereDatabase database, final int columnIndex) throws 
SQLException {
+    public QueryHeader build(final ProjectionsContext projectionsContext, 
final ShardingSphereResultSetMetaData resultSetMetaData, final 
ShardingSphereDatabase database,
+                             final int columnIndex) throws SQLException {
         ShardingSpherePreconditions.checkState(columnIndex <= 
projectionsContext.getExpandProjections().size(), () -> new 
ColumnIndexOutOfRangeException(columnIndex));
         Projection projection = 
projectionsContext.getExpandProjections().get(columnIndex - 1);
-        return DatabaseTypedSPILoader.getService(QueryHeaderBuilder.class, 
databaseType).build(queryResultMetaData, database, projection.getColumnName(), 
projection.getColumnLabel(), columnIndex);
+        return queryHeaderBuilder.build(resultSetMetaData, database, 
projection.getColumnName(), projection.getColumnLabel(), columnIndex);
     }
 }
diff --git 
a/proxy/backend/core/src/test/java/org/apache/shardingsphere/proxy/backend/connector/StandardDatabaseProxyConnectorTest.java
 
b/proxy/backend/core/src/test/java/org/apache/shardingsphere/proxy/backend/connector/StandardDatabaseProxyConnectorTest.java
index 4a859280afb..d7e2c9e0ad9 100644
--- 
a/proxy/backend/core/src/test/java/org/apache/shardingsphere/proxy/backend/connector/StandardDatabaseProxyConnectorTest.java
+++ 
b/proxy/backend/core/src/test/java/org/apache/shardingsphere/proxy/backend/connector/StandardDatabaseProxyConnectorTest.java
@@ -23,6 +23,7 @@ import 
org.apache.shardingsphere.database.connector.core.metadata.database.metad
 import 
org.apache.shardingsphere.database.connector.core.spi.DatabaseTypedSPILoader;
 import org.apache.shardingsphere.database.connector.core.type.DatabaseType;
 import 
org.apache.shardingsphere.database.connector.core.type.DatabaseTypeRegistry;
+import 
org.apache.shardingsphere.driver.jdbc.core.resultset.ShardingSphereResultSetMetaData;
 import 
org.apache.shardingsphere.infra.binder.context.segment.insert.keygen.GeneratedKeyContext;
 import 
org.apache.shardingsphere.infra.binder.context.segment.select.projection.Projection;
 import 
org.apache.shardingsphere.infra.binder.context.segment.select.projection.ProjectionsContext;
@@ -107,6 +108,7 @@ import org.mockito.quality.Strictness;
 
 import java.lang.reflect.Field;
 import java.sql.ResultSet;
+import java.sql.ResultSetMetaData;
 import java.sql.SQLException;
 import java.sql.Statement;
 import java.sql.Types;
@@ -202,7 +204,7 @@ class StandardDatabaseProxyConnectorTest {
         ShardingSphereDatabase database = createDatabaseMetaData();
         try (MockedStatic<DatabaseTypedSPILoader> spiLoader = 
mockStatic(DatabaseTypedSPILoader.class)) {
             spiLoader.when(() -> 
DatabaseTypedSPILoader.getService(QueryHeaderBuilder.class, 
databaseType)).thenReturn(new QueryHeaderBuilderFixture());
-            Plugins.getMemberAccessor().set(queryHeadersField, engine, 
Collections.singletonList(new 
QueryHeaderBuilderEngine(databaseType).build(createQueryResultMetaData(), 
database, 1)));
+            Plugins.getMemberAccessor().set(queryHeadersField, engine, 
Collections.singletonList(new 
QueryHeaderBuilderEngine(databaseType).build(createResultSetMetaData(), 
database, 1)));
             Field mergedResultField = 
StandardDatabaseProxyConnector.class.getDeclaredField("mergedResult");
             Plugins.getMemberAccessor().set(mergedResultField, engine, new 
MemoryMergedResult<ShardingSphereRule>(null, null, null, 
Collections.emptyList()) {
                 
@@ -507,9 +509,11 @@ class StandardDatabaseProxyConnectorTest {
         
when(executionContext.getSqlStatementContext()).thenReturn(sqlStatementContext);
         QueryResult queryResult = mock(QueryResult.class);
         QueryResultMetaData queryResultMetaData = 
mock(QueryResultMetaData.class);
+        ResultSetMetaData resultSetMetaData = mock(ResultSetMetaData.class);
         when(queryResultMetaData.getColumnCount()).thenReturn(1);
-        when(queryResultMetaData.getColumnName(1)).thenReturn("order_id");
-        when(queryResultMetaData.getColumnLabel(1)).thenReturn("order_id");
+        
when(queryResultMetaData.getResultSetMetaData()).thenReturn(resultSetMetaData);
+        when(resultSetMetaData.getColumnName(1)).thenReturn("order_id");
+        when(resultSetMetaData.getColumnLabel(1)).thenReturn("order_id");
         when(queryResult.getMetaData()).thenReturn(queryResultMetaData);
         
when(proxySQLExecutor.execute(executionContext)).thenReturn(Collections.singletonList(queryResult));
         MergedResult mergedResult = mock(MergedResult.class);
@@ -722,8 +726,8 @@ class StandardDatabaseProxyConnectorTest {
         return result;
     }
     
-    private QueryResultMetaData createQueryResultMetaData() throws 
SQLException {
-        QueryResultMetaData result = mock(QueryResultMetaData.class);
+    private ShardingSphereResultSetMetaData createResultSetMetaData() throws 
SQLException {
+        ShardingSphereResultSetMetaData result = 
mock(ShardingSphereResultSetMetaData.class);
         when(result.getColumnLabel(1)).thenReturn("order_id");
         when(result.getColumnName(1)).thenReturn("order_id");
         return result;
diff --git 
a/proxy/backend/core/src/test/java/org/apache/shardingsphere/proxy/backend/connector/jdbc/fixture/QueryHeaderBuilderFixture.java
 
b/proxy/backend/core/src/test/java/org/apache/shardingsphere/proxy/backend/connector/jdbc/fixture/QueryHeaderBuilderFixture.java
index a6174c06922..652a319428c 100644
--- 
a/proxy/backend/core/src/test/java/org/apache/shardingsphere/proxy/backend/connector/jdbc/fixture/QueryHeaderBuilderFixture.java
+++ 
b/proxy/backend/core/src/test/java/org/apache/shardingsphere/proxy/backend/connector/jdbc/fixture/QueryHeaderBuilderFixture.java
@@ -17,7 +17,7 @@
 
 package org.apache.shardingsphere.proxy.backend.connector.jdbc.fixture;
 
-import 
org.apache.shardingsphere.infra.executor.sql.execute.result.query.QueryResultMetaData;
+import 
org.apache.shardingsphere.driver.jdbc.core.resultset.ShardingSphereResultSetMetaData;
 import 
org.apache.shardingsphere.infra.metadata.database.ShardingSphereDatabase;
 import 
org.apache.shardingsphere.proxy.backend.response.header.query.QueryHeader;
 import 
org.apache.shardingsphere.proxy.backend.response.header.query.QueryHeaderBuilder;
@@ -27,8 +27,7 @@ import java.sql.Types;
 public final class QueryHeaderBuilderFixture implements QueryHeaderBuilder {
     
     @Override
-    public QueryHeader build(final QueryResultMetaData queryResultMetaData,
-                             final ShardingSphereDatabase database, final 
String columnName, final String columnLabel, final int columnIndex) {
+    public QueryHeader build(final ShardingSphereResultSetMetaData 
resultSetMetaData, final ShardingSphereDatabase database, final String 
columnName, final String columnLabel, final int columnIndex) {
         return new QueryHeader(null, null, null, null, Types.INTEGER, null, 0, 
0, false, false, false, false);
     }
     
diff --git 
a/proxy/backend/core/src/test/java/org/apache/shardingsphere/proxy/backend/response/header/query/QueryHeaderBuilderEngineTest.java
 
b/proxy/backend/core/src/test/java/org/apache/shardingsphere/proxy/backend/response/header/query/QueryHeaderBuilderEngineTest.java
index b0f73e81970..bf99744d57d 100644
--- 
a/proxy/backend/core/src/test/java/org/apache/shardingsphere/proxy/backend/response/header/query/QueryHeaderBuilderEngineTest.java
+++ 
b/proxy/backend/core/src/test/java/org/apache/shardingsphere/proxy/backend/response/header/query/QueryHeaderBuilderEngineTest.java
@@ -19,10 +19,10 @@ package 
org.apache.shardingsphere.proxy.backend.response.header.query;
 
 import 
org.apache.shardingsphere.database.connector.core.spi.DatabaseTypedSPILoader;
 import org.apache.shardingsphere.database.connector.core.type.DatabaseType;
+import 
org.apache.shardingsphere.driver.jdbc.core.resultset.ShardingSphereResultSetMetaData;
 import 
org.apache.shardingsphere.infra.binder.context.segment.select.projection.Projection;
 import 
org.apache.shardingsphere.infra.binder.context.segment.select.projection.ProjectionsContext;
 import 
org.apache.shardingsphere.infra.exception.kernel.syntax.ColumnIndexOutOfRangeException;
-import 
org.apache.shardingsphere.infra.executor.sql.execute.result.query.QueryResultMetaData;
 import 
org.apache.shardingsphere.infra.metadata.database.ShardingSphereDatabase;
 import org.apache.shardingsphere.infra.spi.type.typed.TypedSPILoader;
 import org.junit.jupiter.api.Test;
@@ -44,16 +44,16 @@ class QueryHeaderBuilderEngineTest {
     
     @Test
     void assertBuildWithoutProjections() throws SQLException {
-        QueryResultMetaData queryResultMetaData = 
mock(QueryResultMetaData.class);
-        when(queryResultMetaData.getColumnName(1)).thenReturn("col_name");
-        when(queryResultMetaData.getColumnLabel(1)).thenReturn("col_label");
+        ShardingSphereResultSetMetaData resultSetMetaData = 
mock(ShardingSphereResultSetMetaData.class);
+        when(resultSetMetaData.getColumnName(1)).thenReturn("col_name");
+        when(resultSetMetaData.getColumnLabel(1)).thenReturn("col_label");
         ShardingSphereDatabase database = mock(ShardingSphereDatabase.class);
         QueryHeader expectedQueryHeader = mock(QueryHeader.class);
         try (MockedStatic<DatabaseTypedSPILoader> spiLoader = 
mockStatic(DatabaseTypedSPILoader.class)) {
             QueryHeaderBuilder queryHeaderBuilder = 
mock(QueryHeaderBuilder.class);
-            when(queryHeaderBuilder.build(queryResultMetaData, database, 
"col_name", "col_label", 1)).thenReturn(expectedQueryHeader);
+            when(queryHeaderBuilder.build(resultSetMetaData, database, 
"col_name", "col_label", 1)).thenReturn(expectedQueryHeader);
             spiLoader.when(() -> 
DatabaseTypedSPILoader.getService(QueryHeaderBuilder.class, 
databaseType)).thenReturn(queryHeaderBuilder);
-            QueryHeader actualQueryHeader = new 
QueryHeaderBuilderEngine(databaseType).build(queryResultMetaData, database, 1);
+            QueryHeader actualQueryHeader = new 
QueryHeaderBuilderEngine(databaseType).build(resultSetMetaData, database, 1);
             assertThat(actualQueryHeader, is(expectedQueryHeader));
         }
     }
@@ -65,14 +65,14 @@ class QueryHeaderBuilderEngineTest {
         when(projection.getColumnLabel()).thenReturn("l1");
         when(projection.getExpression()).thenReturn("c1");
         ProjectionsContext projectionsContext = new ProjectionsContext(0, 0, 
false, Collections.singleton(projection));
-        QueryResultMetaData queryResultMetaData = 
mock(QueryResultMetaData.class);
+        ShardingSphereResultSetMetaData resultSetMetaData = 
mock(ShardingSphereResultSetMetaData.class);
         ShardingSphereDatabase database = mock(ShardingSphereDatabase.class);
         QueryHeader expectedQueryHeader = mock(QueryHeader.class);
         try (MockedStatic<DatabaseTypedSPILoader> spiLoader = 
mockStatic(DatabaseTypedSPILoader.class)) {
             QueryHeaderBuilder queryHeaderBuilder = 
mock(QueryHeaderBuilder.class);
-            when(queryHeaderBuilder.build(queryResultMetaData, database, "c1", 
"l1", 1)).thenReturn(expectedQueryHeader);
+            when(queryHeaderBuilder.build(resultSetMetaData, database, "c1", 
"l1", 1)).thenReturn(expectedQueryHeader);
             spiLoader.when(() -> 
DatabaseTypedSPILoader.getService(QueryHeaderBuilder.class, 
databaseType)).thenReturn(queryHeaderBuilder);
-            QueryHeader actualQueryHeader = new 
QueryHeaderBuilderEngine(databaseType).build(projectionsContext, 
queryResultMetaData, database, 1);
+            QueryHeader actualQueryHeader = new 
QueryHeaderBuilderEngine(databaseType).build(projectionsContext, 
resultSetMetaData, database, 1);
             assertThat(actualQueryHeader, is(expectedQueryHeader));
         }
     }
@@ -84,6 +84,10 @@ class QueryHeaderBuilderEngineTest {
         when(projection.getColumnName()).thenReturn("column");
         when(projection.getExpression()).thenReturn("column");
         ProjectionsContext projectionsContext = new ProjectionsContext(0, 0, 
false, Collections.singleton(projection));
-        assertThrows(ColumnIndexOutOfRangeException.class, () -> new 
QueryHeaderBuilderEngine(databaseType).build(projectionsContext, mock(), 
mock(), 2));
+        try (MockedStatic<DatabaseTypedSPILoader> spiLoader = 
mockStatic(DatabaseTypedSPILoader.class)) {
+            spiLoader.when(() -> 
DatabaseTypedSPILoader.getService(QueryHeaderBuilder.class, 
databaseType)).thenReturn(mock(QueryHeaderBuilder.class));
+            assertThrows(ColumnIndexOutOfRangeException.class,
+                    () -> new 
QueryHeaderBuilderEngine(databaseType).build(projectionsContext, 
mock(ShardingSphereResultSetMetaData.class), mock(), 2));
+        }
     }
 }
diff --git 
a/proxy/backend/dialect/firebird/src/main/java/org/apache/shardingsphere/proxy/backend/firebird/response/header/query/FirebirdQueryHeaderBuilder.java
 
b/proxy/backend/dialect/firebird/src/main/java/org/apache/shardingsphere/proxy/backend/firebird/response/header/query/FirebirdQueryHeaderBuilder.java
index 4f362e17e84..4a3efc29cf0 100644
--- 
a/proxy/backend/dialect/firebird/src/main/java/org/apache/shardingsphere/proxy/backend/firebird/response/header/query/FirebirdQueryHeaderBuilder.java
+++ 
b/proxy/backend/dialect/firebird/src/main/java/org/apache/shardingsphere/proxy/backend/firebird/response/header/query/FirebirdQueryHeaderBuilder.java
@@ -17,7 +17,7 @@
 
 package org.apache.shardingsphere.proxy.backend.firebird.response.header.query;
 
-import 
org.apache.shardingsphere.infra.executor.sql.execute.result.query.QueryResultMetaData;
+import 
org.apache.shardingsphere.driver.jdbc.core.resultset.ShardingSphereResultSetMetaData;
 import 
org.apache.shardingsphere.infra.metadata.database.ShardingSphereDatabase;
 import 
org.apache.shardingsphere.proxy.backend.response.header.query.QueryHeader;
 import 
org.apache.shardingsphere.proxy.backend.response.header.query.QueryHeaderBuilder;
@@ -36,11 +36,11 @@ public final class FirebirdQueryHeaderBuilder implements 
QueryHeaderBuilder {
     private static final boolean UNUSED_BOOLEAN_FIELD = false;
     
     @Override
-    public QueryHeader build(final QueryResultMetaData queryResultMetaData,
-                             final ShardingSphereDatabase database, final 
String columnName, final String columnLabel, final int columnIndex) throws 
SQLException {
-        int columnType = queryResultMetaData.getColumnType(columnIndex);
-        String columnTypeName = 
queryResultMetaData.getColumnTypeName(columnIndex);
-        int columnLength = queryResultMetaData.getColumnLength(columnIndex);
+    public QueryHeader build(final ShardingSphereResultSetMetaData 
resultSetMetaData, final ShardingSphereDatabase database, final String 
columnName, final String columnLabel,
+                             final int columnIndex) throws SQLException {
+        int columnType = resultSetMetaData.getColumnType(columnIndex);
+        String columnTypeName = 
resultSetMetaData.getColumnTypeName(columnIndex);
+        int columnLength = resultSetMetaData.getColumnDisplaySize(columnIndex);
         return new QueryHeader(UNUSED_STRING_FIELD, UNUSED_STRING_FIELD, 
columnLabel, UNUSED_STRING_FIELD, columnType, columnTypeName, columnLength,
                 UNUSED_INT_FIELD, UNUSED_BOOLEAN_FIELD, UNUSED_BOOLEAN_FIELD, 
UNUSED_BOOLEAN_FIELD, UNUSED_BOOLEAN_FIELD);
     }
diff --git 
a/proxy/backend/dialect/firebird/src/test/java/org/apache/shardingsphere/proxy/backend/firebird/response/header/query/FirebirdQueryHeaderBuilderTest.java
 
b/proxy/backend/dialect/firebird/src/test/java/org/apache/shardingsphere/proxy/backend/firebird/response/header/query/FirebirdQueryHeaderBuilderTest.java
index daa012be364..72e4087ceee 100644
--- 
a/proxy/backend/dialect/firebird/src/test/java/org/apache/shardingsphere/proxy/backend/firebird/response/header/query/FirebirdQueryHeaderBuilderTest.java
+++ 
b/proxy/backend/dialect/firebird/src/test/java/org/apache/shardingsphere/proxy/backend/firebird/response/header/query/FirebirdQueryHeaderBuilderTest.java
@@ -19,7 +19,7 @@ package 
org.apache.shardingsphere.proxy.backend.firebird.response.header.query;
 
 import 
org.apache.shardingsphere.database.connector.core.spi.DatabaseTypedSPILoader;
 import org.apache.shardingsphere.database.connector.core.type.DatabaseType;
-import 
org.apache.shardingsphere.infra.executor.sql.execute.result.query.QueryResultMetaData;
+import 
org.apache.shardingsphere.driver.jdbc.core.resultset.ShardingSphereResultSetMetaData;
 import org.apache.shardingsphere.infra.spi.type.typed.TypedSPILoader;
 import 
org.apache.shardingsphere.proxy.backend.response.header.query.QueryHeader;
 import 
org.apache.shardingsphere.proxy.backend.response.header.query.QueryHeaderBuilder;
@@ -41,11 +41,11 @@ class FirebirdQueryHeaderBuilderTest {
     
     @Test
     void assertBuild() throws SQLException {
-        QueryResultMetaData queryResultMetaData = 
mock(QueryResultMetaData.class);
-        when(queryResultMetaData.getColumnType(1)).thenReturn(Types.INTEGER);
-        when(queryResultMetaData.getColumnTypeName(1)).thenReturn("int");
-        when(queryResultMetaData.getColumnLength(1)).thenReturn(11);
-        QueryHeader actual = queryHeaderBuilder.build(queryResultMetaData, 
null, null, "foo_label", 1);
+        ShardingSphereResultSetMetaData resultSetMetaData = 
mock(ShardingSphereResultSetMetaData.class);
+        when(resultSetMetaData.getColumnType(1)).thenReturn(Types.INTEGER);
+        when(resultSetMetaData.getColumnTypeName(1)).thenReturn("int");
+        when(resultSetMetaData.getColumnDisplaySize(1)).thenReturn(11);
+        QueryHeader actual = queryHeaderBuilder.build(resultSetMetaData, null, 
null, "foo_label", 1);
         assertThat(actual.getSchema(), is(""));
         assertThat(actual.getTable(), is(""));
         assertThat(actual.getColumnLabel(), is("foo_label"));
diff --git 
a/proxy/backend/dialect/mysql/src/main/java/org/apache/shardingsphere/proxy/backend/mysql/response/header/query/MySQLQueryHeaderBuilder.java
 
b/proxy/backend/dialect/mysql/src/main/java/org/apache/shardingsphere/proxy/backend/mysql/response/header/query/MySQLQueryHeaderBuilder.java
index 6362376f9c9..570c06c81f0 100644
--- 
a/proxy/backend/dialect/mysql/src/main/java/org/apache/shardingsphere/proxy/backend/mysql/response/header/query/MySQLQueryHeaderBuilder.java
+++ 
b/proxy/backend/dialect/mysql/src/main/java/org/apache/shardingsphere/proxy/backend/mysql/response/header/query/MySQLQueryHeaderBuilder.java
@@ -17,14 +17,14 @@
 
 package org.apache.shardingsphere.proxy.backend.mysql.response.header.query;
 
-import 
org.apache.shardingsphere.infra.executor.sql.execute.result.query.QueryResultMetaData;
+import 
org.apache.shardingsphere.driver.jdbc.core.resultset.ShardingSphereResultSetMetaData;
 import 
org.apache.shardingsphere.infra.metadata.database.ShardingSphereDatabase;
 import 
org.apache.shardingsphere.infra.metadata.database.schema.model.ShardingSphereColumn;
 import 
org.apache.shardingsphere.infra.metadata.database.schema.model.ShardingSphereSchema;
-import 
org.apache.shardingsphere.infra.rule.attribute.datanode.DataNodeRuleAttribute;
 import 
org.apache.shardingsphere.proxy.backend.response.header.query.QueryHeader;
 import 
org.apache.shardingsphere.proxy.backend.response.header.query.QueryHeaderBuilder;
 
+import java.sql.ResultSetMetaData;
 import java.sql.SQLException;
 import java.util.Optional;
 
@@ -34,39 +34,28 @@ import java.util.Optional;
 public final class MySQLQueryHeaderBuilder implements QueryHeaderBuilder {
     
     @Override
-    public QueryHeader build(final QueryResultMetaData queryResultMetaData,
-                             final ShardingSphereDatabase database, final 
String columnName, final String columnLabel, final int columnIndex) throws 
SQLException {
+    public QueryHeader build(final ShardingSphereResultSetMetaData 
resultSetMetaData, final ShardingSphereDatabase database, final String 
columnName, final String columnLabel,
+                             final int columnIndex) throws SQLException {
         String schemaName = null == database ? "" : database.getName();
-        String actualTableName = queryResultMetaData.getTableName(columnIndex);
-        String tableName;
-        boolean primaryKey;
-        if (null == actualTableName || null == database) {
-            tableName = actualTableName;
-            primaryKey = false;
-        } else {
-            tableName = getLogicTableName(database, actualTableName);
-            ShardingSphereSchema schema = database.getSchema(schemaName);
-            primaryKey = isPrimaryKey(schema, tableName, columnName)
-                    || isPrimaryKey(schema, tableName, 
queryResultMetaData.getColumnName(columnIndex));
-        }
-        int columnType = queryResultMetaData.getColumnType(columnIndex);
-        String columnTypeName = 
queryResultMetaData.getColumnTypeName(columnIndex);
-        int columnLength = queryResultMetaData.getColumnLength(columnIndex);
-        int decimals = queryResultMetaData.getDecimals(columnIndex);
-        boolean signed = queryResultMetaData.isSigned(columnIndex);
-        boolean notNull = queryResultMetaData.isNotNull(columnIndex);
-        boolean autoIncrement = 
queryResultMetaData.isAutoIncrement(columnIndex);
+        String tableName = resultSetMetaData.getTableName(columnIndex);
+        boolean primaryKey = isPrimaryKey(database, schemaName, tableName, 
columnName, resultSetMetaData, columnIndex);
+        int columnType = resultSetMetaData.getColumnType(columnIndex);
+        String columnTypeName = 
resultSetMetaData.getColumnTypeName(columnIndex);
+        int columnLength = resultSetMetaData.getColumnDisplaySize(columnIndex);
+        int decimals = resultSetMetaData.getScale(columnIndex);
+        boolean signed = resultSetMetaData.isSigned(columnIndex);
+        boolean notNull = ResultSetMetaData.columnNoNulls == 
resultSetMetaData.isNullable(columnIndex);
+        boolean autoIncrement = resultSetMetaData.isAutoIncrement(columnIndex);
         return new QueryHeader(schemaName, tableName, columnLabel, columnName, 
columnType, columnTypeName, columnLength, decimals, signed, primaryKey, 
notNull, autoIncrement);
     }
     
-    private String getLogicTableName(final ShardingSphereDatabase database, 
final String actualTableName) {
-        for (DataNodeRuleAttribute each : 
database.getRuleMetaData().getAttributes(DataNodeRuleAttribute.class)) {
-            Optional<String> logicTable = 
each.findLogicTableByActualTable(actualTableName);
-            if (logicTable.isPresent()) {
-                return logicTable.get();
-            }
+    private boolean isPrimaryKey(final ShardingSphereDatabase database, final 
String schemaName, final String tableName, final String columnName,
+                                 final ShardingSphereResultSetMetaData 
resultSetMetaData, final int columnIndex) throws SQLException {
+        if (null == database || null == tableName) {
+            return false;
         }
-        return actualTableName;
+        ShardingSphereSchema schema = database.getSchema(schemaName);
+        return isPrimaryKey(schema, tableName, columnName) || 
isPrimaryKey(schema, tableName, resultSetMetaData.getColumnName(columnIndex));
     }
     
     private boolean isPrimaryKey(final ShardingSphereSchema schema, final 
String tableName, final String columnName) {
diff --git 
a/proxy/backend/dialect/mysql/src/test/java/org/apache/shardingsphere/proxy/backend/mysql/response/header/query/MySQLQueryHeaderBuilderTest.java
 
b/proxy/backend/dialect/mysql/src/test/java/org/apache/shardingsphere/proxy/backend/mysql/response/header/query/MySQLQueryHeaderBuilderTest.java
index 8a0086d3f42..9e1004e4209 100644
--- 
a/proxy/backend/dialect/mysql/src/test/java/org/apache/shardingsphere/proxy/backend/mysql/response/header/query/MySQLQueryHeaderBuilderTest.java
+++ 
b/proxy/backend/dialect/mysql/src/test/java/org/apache/shardingsphere/proxy/backend/mysql/response/header/query/MySQLQueryHeaderBuilderTest.java
@@ -17,7 +17,7 @@
 
 package org.apache.shardingsphere.proxy.backend.mysql.response.header.query;
 
-import 
org.apache.shardingsphere.infra.executor.sql.execute.result.query.QueryResultMetaData;
+import 
org.apache.shardingsphere.driver.jdbc.core.resultset.ShardingSphereResultSetMetaData;
 import 
org.apache.shardingsphere.infra.metadata.database.ShardingSphereDatabase;
 import 
org.apache.shardingsphere.infra.metadata.database.schema.model.ShardingSphereColumn;
 import 
org.apache.shardingsphere.infra.metadata.database.schema.model.ShardingSphereIndex;
@@ -27,6 +27,7 @@ import 
org.apache.shardingsphere.infra.rule.attribute.datanode.DataNodeRuleAttri
 import 
org.apache.shardingsphere.proxy.backend.response.header.query.QueryHeader;
 import org.junit.jupiter.api.Test;
 
+import java.sql.ResultSetMetaData;
 import java.sql.SQLException;
 import java.sql.Types;
 import java.util.Collections;
@@ -44,8 +45,8 @@ class MySQLQueryHeaderBuilderTest {
     
     @Test
     void assertBuild() throws SQLException {
-        QueryResultMetaData queryResultMetaData = createQueryResultMetaData();
-        QueryHeader actual = new 
MySQLQueryHeaderBuilder().build(queryResultMetaData, createDatabase(), 
queryResultMetaData.getColumnName(1), queryResultMetaData.getColumnLabel(1), 1);
+        ShardingSphereResultSetMetaData resultSetMetaData = 
createResultSetMetaData();
+        QueryHeader actual = new 
MySQLQueryHeaderBuilder().build(resultSetMetaData, createDatabase(), 
resultSetMetaData.getColumnName(1), resultSetMetaData.getColumnLabel(1), 1);
         assertThat(actual.getSchema(), is("foo_db"));
         assertThat(actual.getTable(), is("t_logic_order"));
         assertThat(actual.getColumnLabel(), is("order_id"));
@@ -61,21 +62,21 @@ class MySQLQueryHeaderBuilderTest {
     
     @Test
     void assertBuildWithoutPrimaryKeyColumn() throws SQLException {
-        QueryResultMetaData queryResultMetaData = createQueryResultMetaData();
-        assertFalse(new MySQLQueryHeaderBuilder().build(queryResultMetaData, 
createDatabase(), queryResultMetaData.getColumnName(2), 
queryResultMetaData.getColumnLabel(2), 2).isPrimaryKey());
+        ShardingSphereResultSetMetaData resultSetMetaData = 
createResultSetMetaData();
+        assertFalse(new MySQLQueryHeaderBuilder().build(resultSetMetaData, 
createDatabase(), resultSetMetaData.getColumnName(2), 
resultSetMetaData.getColumnLabel(2), 2).isPrimaryKey());
     }
     
     @Test
     void assertBuildWithAliasColumnAndOriginalPrimaryKey() throws SQLException 
{
-        QueryResultMetaData queryResultMetaData = createQueryResultMetaData();
-        QueryHeader actual = new 
MySQLQueryHeaderBuilder().build(queryResultMetaData, createDatabase(), 
"order_id_alias", "order_id_alias", 1);
+        ShardingSphereResultSetMetaData resultSetMetaData = 
createResultSetMetaData();
+        QueryHeader actual = new 
MySQLQueryHeaderBuilder().build(resultSetMetaData, createDatabase(), 
"order_id_alias", "order_id_alias", 1);
         assertTrue(actual.isPrimaryKey());
     }
     
     @Test
     void assertBuildWithNullDatabase() throws SQLException {
-        QueryResultMetaData queryResultMetaData = createQueryResultMetaData();
-        QueryHeader actual = new 
MySQLQueryHeaderBuilder().build(queryResultMetaData, null, 
queryResultMetaData.getColumnName(1), queryResultMetaData.getColumnLabel(1), 1);
+        ShardingSphereResultSetMetaData resultSetMetaData = 
createActualResultSetMetaData("t_order");
+        QueryHeader actual = new 
MySQLQueryHeaderBuilder().build(resultSetMetaData, null, 
resultSetMetaData.getColumnName(1), resultSetMetaData.getColumnLabel(1), 1);
         assertFalse(actual.isPrimaryKey());
         assertThat(actual.getTable(), is("t_order"));
     }
@@ -87,17 +88,17 @@ class MySQLQueryHeaderBuilderTest {
         DataNodeRuleAttribute ruleAttribute = 
mock(DataNodeRuleAttribute.class);
         
when(ruleAttribute.findLogicTableByActualTable("t_order")).thenReturn(Optional.of("t_order"));
         
when(database.getRuleMetaData().getAttributes(DataNodeRuleAttribute.class)).thenReturn(Collections.singleton(ruleAttribute));
-        QueryResultMetaData queryResultMetaData = createQueryResultMetaData();
-        QueryHeader actual = new 
MySQLQueryHeaderBuilder().build(queryResultMetaData, database, 
queryResultMetaData.getColumnName(1), queryResultMetaData.getColumnLabel(1), 1);
+        ShardingSphereResultSetMetaData resultSetMetaData = 
createResultSetMetaData("t_order");
+        QueryHeader actual = new 
MySQLQueryHeaderBuilder().build(resultSetMetaData, database, 
resultSetMetaData.getColumnName(1), resultSetMetaData.getColumnLabel(1), 1);
         assertFalse(actual.isPrimaryKey());
         assertThat(actual.getTable(), is("t_order"));
     }
     
     @Test
     void assertBuildWithoutDataNodeContainedRule() throws SQLException {
-        QueryResultMetaData queryResultMetaData = createQueryResultMetaData();
+        ShardingSphereResultSetMetaData resultSetMetaData = 
createResultSetMetaData();
         QueryHeader actual = new MySQLQueryHeaderBuilder().build(
-                queryResultMetaData, mock(ShardingSphereDatabase.class, 
RETURNS_DEEP_STUBS), queryResultMetaData.getColumnName(1), 
queryResultMetaData.getColumnLabel(1), 1);
+                resultSetMetaData, mock(ShardingSphereDatabase.class, 
RETURNS_DEEP_STUBS), resultSetMetaData.getColumnName(1), 
resultSetMetaData.getColumnLabel(1), 1);
         assertFalse(actual.isPrimaryKey());
         assertThat(actual.getTable(), is(actual.getTable()));
     }
@@ -116,19 +117,37 @@ class MySQLQueryHeaderBuilderTest {
         return result;
     }
     
-    private QueryResultMetaData createQueryResultMetaData() throws 
SQLException {
-        QueryResultMetaData result = mock(QueryResultMetaData.class);
-        when(result.getTableName(1)).thenReturn("t_order");
-        when(result.getTableName(2)).thenReturn("t_order");
+    private ShardingSphereResultSetMetaData createResultSetMetaData() throws 
SQLException {
+        return createResultSetMetaData("t_logic_order");
+    }
+    
+    private ShardingSphereResultSetMetaData createResultSetMetaData(final 
String tableName) throws SQLException {
+        ShardingSphereResultSetMetaData result = 
mock(ShardingSphereResultSetMetaData.class);
+        when(result.getTableName(1)).thenReturn(tableName);
+        when(result.getTableName(2)).thenReturn(tableName);
         when(result.getColumnLabel(1)).thenReturn("order_id");
         when(result.getColumnName(1)).thenReturn("order_id");
         when(result.getColumnName(2)).thenReturn("expr");
         when(result.getColumnType(1)).thenReturn(Types.INTEGER);
         when(result.isSigned(1)).thenReturn(true);
         when(result.isAutoIncrement(1)).thenReturn(true);
-        when(result.getColumnLength(1)).thenReturn(1);
-        when(result.getDecimals(1)).thenReturn(1);
-        when(result.isNotNull(1)).thenReturn(true);
+        when(result.getColumnDisplaySize(1)).thenReturn(1);
+        when(result.getScale(1)).thenReturn(1);
+        when(result.isNullable(1)).thenReturn(ResultSetMetaData.columnNoNulls);
         return result;
     }
+    
+    private ShardingSphereResultSetMetaData 
createActualResultSetMetaData(final String tableName) throws SQLException {
+        ResultSetMetaData result = mock(ResultSetMetaData.class);
+        when(result.getTableName(1)).thenReturn(tableName);
+        when(result.getColumnLabel(1)).thenReturn("order_id");
+        when(result.getColumnName(1)).thenReturn("order_id");
+        when(result.getColumnType(1)).thenReturn(Types.INTEGER);
+        when(result.isSigned(1)).thenReturn(true);
+        when(result.isAutoIncrement(1)).thenReturn(true);
+        when(result.getColumnDisplaySize(1)).thenReturn(1);
+        when(result.getScale(1)).thenReturn(1);
+        when(result.isNullable(1)).thenReturn(ResultSetMetaData.columnNoNulls);
+        return new ShardingSphereResultSetMetaData(result, null, null);
+    }
 }
diff --git 
a/proxy/backend/dialect/opengauss/src/main/java/org/apache/shardingsphere/proxy/backend/opengauss/response/header/query/OpenGaussQueryHeaderBuilder.java
 
b/proxy/backend/dialect/opengauss/src/main/java/org/apache/shardingsphere/proxy/backend/opengauss/response/header/query/OpenGaussQueryHeaderBuilder.java
index 93ba258073e..47687e75805 100644
--- 
a/proxy/backend/dialect/opengauss/src/main/java/org/apache/shardingsphere/proxy/backend/opengauss/response/header/query/OpenGaussQueryHeaderBuilder.java
+++ 
b/proxy/backend/dialect/opengauss/src/main/java/org/apache/shardingsphere/proxy/backend/opengauss/response/header/query/OpenGaussQueryHeaderBuilder.java
@@ -17,7 +17,7 @@
 
 package 
org.apache.shardingsphere.proxy.backend.opengauss.response.header.query;
 
-import 
org.apache.shardingsphere.infra.executor.sql.execute.result.query.QueryResultMetaData;
+import 
org.apache.shardingsphere.driver.jdbc.core.resultset.ShardingSphereResultSetMetaData;
 import 
org.apache.shardingsphere.infra.metadata.database.ShardingSphereDatabase;
 import 
org.apache.shardingsphere.proxy.backend.postgresql.response.header.query.PostgreSQLQueryHeaderBuilder;
 import 
org.apache.shardingsphere.proxy.backend.response.header.query.QueryHeader;
@@ -33,9 +33,9 @@ public final class OpenGaussQueryHeaderBuilder implements 
QueryHeaderBuilder {
     private final PostgreSQLQueryHeaderBuilder delegate = new 
PostgreSQLQueryHeaderBuilder();
     
     @Override
-    public QueryHeader build(final QueryResultMetaData queryResultMetaData,
-                             final ShardingSphereDatabase database, final 
String columnName, final String columnLabel, final int columnIndex) throws 
SQLException {
-        return delegate.build(queryResultMetaData, database, columnName, 
columnLabel, columnIndex);
+    public QueryHeader build(final ShardingSphereResultSetMetaData 
resultSetMetaData, final ShardingSphereDatabase database, final String 
columnName, final String columnLabel,
+                             final int columnIndex) throws SQLException {
+        return delegate.build(resultSetMetaData, database, columnName, 
columnLabel, columnIndex);
     }
     
     @Override
diff --git 
a/proxy/backend/dialect/opengauss/src/test/java/org/apache/shardingsphere/proxy/backend/opengauss/response/header/query/OpenGaussQueryHeaderBuilderTest.java
 
b/proxy/backend/dialect/opengauss/src/test/java/org/apache/shardingsphere/proxy/backend/opengauss/response/header/query/OpenGaussQueryHeaderBuilderTest.java
index 2327cb22ae3..20cf4f2608d 100644
--- 
a/proxy/backend/dialect/opengauss/src/test/java/org/apache/shardingsphere/proxy/backend/opengauss/response/header/query/OpenGaussQueryHeaderBuilderTest.java
+++ 
b/proxy/backend/dialect/opengauss/src/test/java/org/apache/shardingsphere/proxy/backend/opengauss/response/header/query/OpenGaussQueryHeaderBuilderTest.java
@@ -17,7 +17,7 @@
 
 package 
org.apache.shardingsphere.proxy.backend.opengauss.response.header.query;
 
-import 
org.apache.shardingsphere.infra.executor.sql.execute.result.query.QueryResultMetaData;
+import 
org.apache.shardingsphere.driver.jdbc.core.resultset.ShardingSphereResultSetMetaData;
 import 
org.apache.shardingsphere.proxy.backend.postgresql.response.header.query.PostgreSQLQueryHeaderBuilder;
 import 
org.apache.shardingsphere.proxy.backend.response.header.query.QueryHeader;
 import org.junit.jupiter.api.Test;
@@ -35,13 +35,13 @@ class OpenGaussQueryHeaderBuilderTest {
     @Test
     void assertBuildOpenGaussQueryHeader() throws SQLException {
         final int columnIndex = 1;
-        QueryResultMetaData queryResultMetaData = 
mock(QueryResultMetaData.class);
-        
when(queryResultMetaData.getColumnLabel(columnIndex)).thenReturn("label");
-        
when(queryResultMetaData.getColumnType(columnIndex)).thenReturn(Types.INTEGER);
-        
when(queryResultMetaData.getColumnTypeName(columnIndex)).thenReturn("int");
-        when(queryResultMetaData.getColumnLength(columnIndex)).thenReturn(11);
-        QueryHeader expected = new 
PostgreSQLQueryHeaderBuilder().build(queryResultMetaData, null, null, 
queryResultMetaData.getColumnLabel(columnIndex), columnIndex);
-        QueryHeader actual = new 
OpenGaussQueryHeaderBuilder().build(queryResultMetaData, null, null, 
queryResultMetaData.getColumnLabel(columnIndex), columnIndex);
+        ShardingSphereResultSetMetaData resultSetMetaData = 
mock(ShardingSphereResultSetMetaData.class);
+        
when(resultSetMetaData.getColumnLabel(columnIndex)).thenReturn("label");
+        
when(resultSetMetaData.getColumnType(columnIndex)).thenReturn(Types.INTEGER);
+        
when(resultSetMetaData.getColumnTypeName(columnIndex)).thenReturn("int");
+        
when(resultSetMetaData.getColumnDisplaySize(columnIndex)).thenReturn(11);
+        QueryHeader expected = new 
PostgreSQLQueryHeaderBuilder().build(resultSetMetaData, null, null, 
resultSetMetaData.getColumnLabel(columnIndex), columnIndex);
+        QueryHeader actual = new 
OpenGaussQueryHeaderBuilder().build(resultSetMetaData, null, null, 
resultSetMetaData.getColumnLabel(columnIndex), columnIndex);
         assertThat(actual.getColumnLabel(), is(expected.getColumnLabel()));
         assertThat(actual.getColumnType(), is(expected.getColumnType()));
         assertThat(actual.getColumnTypeName(), 
is(expected.getColumnTypeName()));
diff --git 
a/proxy/backend/dialect/postgresql/src/main/java/org/apache/shardingsphere/proxy/backend/postgresql/response/header/query/PostgreSQLQueryHeaderBuilder.java
 
b/proxy/backend/dialect/postgresql/src/main/java/org/apache/shardingsphere/proxy/backend/postgresql/response/header/query/PostgreSQLQueryHeaderBuilder.java
index b8606709dde..1f61a07f488 100644
--- 
a/proxy/backend/dialect/postgresql/src/main/java/org/apache/shardingsphere/proxy/backend/postgresql/response/header/query/PostgreSQLQueryHeaderBuilder.java
+++ 
b/proxy/backend/dialect/postgresql/src/main/java/org/apache/shardingsphere/proxy/backend/postgresql/response/header/query/PostgreSQLQueryHeaderBuilder.java
@@ -17,7 +17,7 @@
 
 package 
org.apache.shardingsphere.proxy.backend.postgresql.response.header.query;
 
-import 
org.apache.shardingsphere.infra.executor.sql.execute.result.query.QueryResultMetaData;
+import 
org.apache.shardingsphere.driver.jdbc.core.resultset.ShardingSphereResultSetMetaData;
 import 
org.apache.shardingsphere.infra.metadata.database.ShardingSphereDatabase;
 import 
org.apache.shardingsphere.proxy.backend.response.header.query.QueryHeader;
 import 
org.apache.shardingsphere.proxy.backend.response.header.query.QueryHeaderBuilder;
@@ -36,11 +36,11 @@ public final class PostgreSQLQueryHeaderBuilder implements 
QueryHeaderBuilder {
     private static final boolean UNUSED_BOOLEAN_FIELD = false;
     
     @Override
-    public QueryHeader build(final QueryResultMetaData queryResultMetaData,
-                             final ShardingSphereDatabase database, final 
String columnName, final String columnLabel, final int columnIndex) throws 
SQLException {
-        int columnType = queryResultMetaData.getColumnType(columnIndex);
-        String columnTypeName = 
queryResultMetaData.getColumnTypeName(columnIndex);
-        int columnLength = queryResultMetaData.getColumnLength(columnIndex);
+    public QueryHeader build(final ShardingSphereResultSetMetaData 
resultSetMetaData, final ShardingSphereDatabase database, final String 
columnName, final String columnLabel,
+                             final int columnIndex) throws SQLException {
+        int columnType = resultSetMetaData.getColumnType(columnIndex);
+        String columnTypeName = 
resultSetMetaData.getColumnTypeName(columnIndex);
+        int columnLength = resultSetMetaData.getColumnDisplaySize(columnIndex);
         return new QueryHeader(UNUSED_STRING_FIELD, UNUSED_STRING_FIELD, 
columnLabel, UNUSED_STRING_FIELD, columnType, columnTypeName, columnLength,
                 UNUSED_INT_FIELD, UNUSED_BOOLEAN_FIELD, UNUSED_BOOLEAN_FIELD, 
UNUSED_BOOLEAN_FIELD, UNUSED_BOOLEAN_FIELD);
     }
diff --git 
a/proxy/backend/dialect/postgresql/src/test/java/org/apache/shardingsphere/proxy/backend/postgresql/response/header/query/PostgreSQLQueryHeaderBuilderTest.java
 
b/proxy/backend/dialect/postgresql/src/test/java/org/apache/shardingsphere/proxy/backend/postgresql/response/header/query/PostgreSQLQueryHeaderBuilderTest.java
index 4859314f887..718de3d1ec6 100644
--- 
a/proxy/backend/dialect/postgresql/src/test/java/org/apache/shardingsphere/proxy/backend/postgresql/response/header/query/PostgreSQLQueryHeaderBuilderTest.java
+++ 
b/proxy/backend/dialect/postgresql/src/test/java/org/apache/shardingsphere/proxy/backend/postgresql/response/header/query/PostgreSQLQueryHeaderBuilderTest.java
@@ -17,7 +17,7 @@
 
 package 
org.apache.shardingsphere.proxy.backend.postgresql.response.header.query;
 
-import 
org.apache.shardingsphere.infra.executor.sql.execute.result.query.QueryResultMetaData;
+import 
org.apache.shardingsphere.driver.jdbc.core.resultset.ShardingSphereResultSetMetaData;
 import 
org.apache.shardingsphere.proxy.backend.response.header.query.QueryHeader;
 import org.junit.jupiter.api.Test;
 
@@ -34,12 +34,12 @@ class PostgreSQLQueryHeaderBuilderTest {
     @Test
     void assertBuildPostgreSQLQueryHeader() throws SQLException {
         final int columnIndex = 1;
-        QueryResultMetaData queryResultMetaData = 
mock(QueryResultMetaData.class);
-        
when(queryResultMetaData.getColumnLabel(columnIndex)).thenReturn("label");
-        
when(queryResultMetaData.getColumnType(columnIndex)).thenReturn(Types.INTEGER);
-        
when(queryResultMetaData.getColumnTypeName(columnIndex)).thenReturn("int");
-        when(queryResultMetaData.getColumnLength(columnIndex)).thenReturn(11);
-        QueryHeader actual = new 
PostgreSQLQueryHeaderBuilder().build(queryResultMetaData, null, null, 
queryResultMetaData.getColumnLabel(columnIndex), columnIndex);
+        ShardingSphereResultSetMetaData resultSetMetaData = 
mock(ShardingSphereResultSetMetaData.class);
+        
when(resultSetMetaData.getColumnLabel(columnIndex)).thenReturn("label");
+        
when(resultSetMetaData.getColumnType(columnIndex)).thenReturn(Types.INTEGER);
+        
when(resultSetMetaData.getColumnTypeName(columnIndex)).thenReturn("int");
+        
when(resultSetMetaData.getColumnDisplaySize(columnIndex)).thenReturn(11);
+        QueryHeader actual = new 
PostgreSQLQueryHeaderBuilder().build(resultSetMetaData, null, null, 
resultSetMetaData.getColumnLabel(columnIndex), columnIndex);
         assertThat(actual.getColumnLabel(), is("label"));
         assertThat(actual.getColumnType(), is(Types.INTEGER));
         assertThat(actual.getColumnTypeName(), is("int"));
diff --git 
a/proxy/frontend/dialect/mysql/src/main/java/org/apache/shardingsphere/proxy/frontend/mysql/command/query/binary/prepare/MySQLProjectionMetadataResolver.java
 
b/proxy/frontend/dialect/mysql/src/main/java/org/apache/shardingsphere/proxy/frontend/mysql/command/query/binary/prepare/MySQLProjectionMetadataResolver.java
index ec053eebb55..9c6e417c078 100644
--- 
a/proxy/frontend/dialect/mysql/src/main/java/org/apache/shardingsphere/proxy/frontend/mysql/command/query/binary/prepare/MySQLProjectionMetadataResolver.java
+++ 
b/proxy/frontend/dialect/mysql/src/main/java/org/apache/shardingsphere/proxy/frontend/mysql/command/query/binary/prepare/MySQLProjectionMetadataResolver.java
@@ -24,14 +24,13 @@ import 
org.apache.shardingsphere.database.protocol.mysql.constant.MySQLCharacter
 import org.apache.shardingsphere.database.protocol.mysql.packet.MySQLPacket;
 import 
org.apache.shardingsphere.database.protocol.mysql.packet.command.query.MySQLColumnDefinition41Packet;
 import 
org.apache.shardingsphere.database.protocol.mysql.packet.command.query.MySQLColumnDefinitionFlag;
-import 
org.apache.shardingsphere.infra.executor.sql.execute.result.query.QueryResultMetaData;
-import 
org.apache.shardingsphere.infra.executor.sql.execute.result.query.impl.driver.jdbc.metadata.JDBCQueryResultMetaData;
+import 
org.apache.shardingsphere.driver.jdbc.core.resultset.ShardingSphereResultSetMetaData;
+import 
org.apache.shardingsphere.infra.binder.context.statement.type.dml.SelectStatementContext;
 import 
org.apache.shardingsphere.infra.metadata.database.ShardingSphereDatabase;
 import org.apache.shardingsphere.proxy.backend.context.ProxyContext;
 import 
org.apache.shardingsphere.proxy.backend.response.header.query.QueryHeader;
 import 
org.apache.shardingsphere.proxy.backend.response.header.query.QueryHeaderBuilderEngine;
 import org.apache.shardingsphere.proxy.backend.session.ConnectionSession;
-import 
org.apache.shardingsphere.infra.binder.context.statement.type.dml.SelectStatementContext;
 import 
org.apache.shardingsphere.proxy.frontend.mysql.command.query.binary.MySQLServerPreparedStatement;
 
 import java.sql.PreparedStatement;
@@ -68,17 +67,17 @@ public final class MySQLProjectionMetadataResolver {
     public static Collection<MySQLPacket> resolveProjectionPackets(final 
ConnectionSession connectionSession, final MySQLServerPreparedStatement 
preparedStatement,
                                                                    final 
SelectStatementContext selectStatementContext, final int characterSet) throws 
SQLException {
         try (PreparedStatement actualPreparedStatement = 
MySQLPreparedStatementMetadataFactory.load(connectionSession, 
preparedStatement)) {
-            ResultSetMetaData resultSetMetaData = 
actualPreparedStatement.getMetaData();
-            if (null == resultSetMetaData) {
+            ResultSetMetaData actualResultSetMetaData = 
actualPreparedStatement.getMetaData();
+            if (null == actualResultSetMetaData) {
                 return createDefaultPackets(selectStatementContext, 
characterSet);
             }
-            QueryResultMetaData queryResultMetaData = new 
JDBCQueryResultMetaData(resultSetMetaData);
             String databaseName = 
selectStatementContext.getTablesContext().getDatabaseName().orElseGet(connectionSession::getCurrentDatabaseName);
             ShardingSphereDatabase database = 
ProxyContext.getInstance().getContextManager().getMetaDataContexts().getMetaData().getDatabase(databaseName);
+            ShardingSphereResultSetMetaData resultSetMetaData = new 
ShardingSphereResultSetMetaData(actualResultSetMetaData, database, 
selectStatementContext);
             QueryHeaderBuilderEngine queryHeaderBuilderEngine = new 
QueryHeaderBuilderEngine(database.getProtocolType());
             Collection<MySQLPacket> result = new 
ArrayList<>(selectStatementContext.getProjectionsContext().getExpandProjections().size());
             for (int columnIndex = 1; columnIndex <= 
selectStatementContext.getProjectionsContext().getExpandProjections().size(); 
columnIndex++) {
-                QueryHeader queryHeader = 
queryHeaderBuilderEngine.build(selectStatementContext.getProjectionsContext(), 
queryResultMetaData, database, columnIndex);
+                QueryHeader queryHeader = 
queryHeaderBuilderEngine.build(selectStatementContext.getProjectionsContext(), 
resultSetMetaData, database, columnIndex);
                 result.add(createMySQLColumnDefinition41Packet(queryHeader, 
characterSet));
             }
             return result;


Reply via email to