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

terrymanu 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 bb8df05f99d Support openGauss composite type OID resolution (#39253)
bb8df05f99d is described below

commit bb8df05f99db28ecd9f8c416bafd4e04902b182a
Author: Liang Zhang <[email protected]>
AuthorDate: Tue Jul 28 16:45:52 2026 +0800

    Support openGauss composite type OID resolution (#39253)
    
    * Refactor AGENTS.md without changing policy behavior
    
    * Support openGauss composite type OID resolution
    
    * Support openGauss composite type OID resolution
---
 RELEASE-NOTES.md                                   |  1 +
 .../type/OpenGaussColumnTypeOIDResolver.java       | 41 ++++++++++++++++
 .../type/OpenGaussColumnTypeOIDResolverTest.java}  | 39 +++++----------
 ...TypeOIDLoader.java => ColumnTypeOIDLoader.java} | 37 +++-----------
 .../postgresql/type/ColumnTypeOIDResolver.java     | 39 +++++++++++++++
 .../type/PostgreSQLColumnTypeOIDResolver.java      | 40 ++++++++++++++++
 .../postgresql/type/ColumnTypeOIDLoaderTest.java   | 56 ++++++++++++++++++++++
 ...va => PostgreSQLColumnTypeOIDResolverTest.java} | 30 +++---------
 .../header/query/OpenGaussQueryHeaderBuilder.java  | 14 ++++++
 .../query/OpenGaussQueryHeaderBuilderTest.java     | 31 +++++++++++-
 .../header/query/PostgreSQLQueryHeaderBuilder.java |  7 ++-
 .../query/PostgreSQLQueryHeaderBuilderTest.java    | 25 +++++-----
 .../command/OpenGaussCommandExecutorFactory.java   |  6 ++-
 .../query/simple/OpenGaussComQueryExecutor.java    |  8 +++-
 .../simple/OpenGaussComQueryExecutorTest.java      | 14 ++++--
 .../command/PostgreSQLCommandExecutorFactory.java  |  6 ++-
 .../describe/PostgreSQLComDescribeExecutor.java    |  9 ++--
 .../PostgreSQLComDescribeExecutorTest.java         | 12 +++--
 18 files changed, 303 insertions(+), 112 deletions(-)

diff --git a/RELEASE-NOTES.md b/RELEASE-NOTES.md
index 6235a2df527..534ac59d851 100644
--- a/RELEASE-NOTES.md
+++ b/RELEASE-NOTES.md
@@ -38,6 +38,7 @@
 1. Proxy: Fix MySQL prepared statement parameter signedness decoding - 
[#39204](https://github.com/apache/shardingsphere/pull/39204)
 1. Proxy: Fix Proxy Native Docker image failing to start due to unexpanded 
LOCAL_PATH in ENTRYPOINT - 
[#39146](https://github.com/apache/shardingsphere/pull/39146)
 1. Proxy: Fix incorrect PostgreSQL composite column type OIDs in simple and 
extended query row descriptions - 
[#39241](https://github.com/apache/shardingsphere/pull/39241)
+1. Proxy: Fix incorrect openGauss composite column type OIDs in simple and 
extended query row descriptions - 
[#39253](https://github.com/apache/shardingsphere/pull/39253)
 1. JDBC & Proxy: Remove default MySQL prepared statement query properties when 
creating data sources - 
[#38593](https://github.com/apache/shardingsphere/pull/38593)
 1. Mode: Fix rule metadata not removed from memory after dropping rules in 
Etcd cluster mode - 
[#38561](https://github.com/apache/shardingsphere/pull/38561)
 1. Agent: Fix wrong target class name in StaticMethodAdviceExecutor error logs 
- [#39077](https://github.com/apache/shardingsphere/pull/39077)
diff --git 
a/database/protocol/dialect/opengauss/src/main/java/org/apache/shardingsphere/database/protocol/opengauss/type/OpenGaussColumnTypeOIDResolver.java
 
b/database/protocol/dialect/opengauss/src/main/java/org/apache/shardingsphere/database/protocol/opengauss/type/OpenGaussColumnTypeOIDResolver.java
new file mode 100644
index 00000000000..2974ed681b4
--- /dev/null
+++ 
b/database/protocol/dialect/opengauss/src/main/java/org/apache/shardingsphere/database/protocol/opengauss/type/OpenGaussColumnTypeOIDResolver.java
@@ -0,0 +1,41 @@
+/*
+ * 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.database.protocol.opengauss.type;
+
+import 
org.apache.shardingsphere.database.protocol.postgresql.type.ColumnTypeOIDResolver;
+import org.opengauss.core.BaseConnection;
+import org.opengauss.core.Oid;
+
+import java.sql.Connection;
+import java.sql.SQLException;
+import java.util.Optional;
+
+/**
+ * Column type OID resolver for openGauss.
+ */
+public final class OpenGaussColumnTypeOIDResolver implements 
ColumnTypeOIDResolver {
+    
+    @Override
+    public Optional<Integer> findTypeOID(final Connection connection, final 
String columnTypeName) throws SQLException {
+        if (!connection.isWrapperFor(BaseConnection.class)) {
+            return Optional.empty();
+        }
+        int typeOID = 
connection.unwrap(BaseConnection.class).getTypeInfo().getPGType(columnTypeName);
+        return Oid.UNSPECIFIED == typeOID ? Optional.empty() : 
Optional.of(typeOID);
+    }
+}
diff --git 
a/database/protocol/dialect/postgresql/src/test/java/org/apache/shardingsphere/database/protocol/postgresql/type/PostgreSQLColumnTypeOIDLoaderTest.java
 
b/database/protocol/dialect/opengauss/src/test/java/org/apache/shardingsphere/database/protocol/opengauss/type/OpenGaussColumnTypeOIDResolverTest.java
similarity index 56%
copy from 
database/protocol/dialect/postgresql/src/test/java/org/apache/shardingsphere/database/protocol/postgresql/type/PostgreSQLColumnTypeOIDLoaderTest.java
copy to 
database/protocol/dialect/opengauss/src/test/java/org/apache/shardingsphere/database/protocol/opengauss/type/OpenGaussColumnTypeOIDResolverTest.java
index 9d0cfb6b2e4..15b303dfb82 100644
--- 
a/database/protocol/dialect/postgresql/src/test/java/org/apache/shardingsphere/database/protocol/postgresql/type/PostgreSQLColumnTypeOIDLoaderTest.java
+++ 
b/database/protocol/dialect/opengauss/src/test/java/org/apache/shardingsphere/database/protocol/opengauss/type/OpenGaussColumnTypeOIDResolverTest.java
@@ -15,61 +15,44 @@
  * limitations under the License.
  */
 
-package org.apache.shardingsphere.database.protocol.postgresql.type;
+package org.apache.shardingsphere.database.protocol.opengauss.type;
 
+import 
org.apache.shardingsphere.database.protocol.postgresql.type.ColumnTypeOIDResolver;
 import org.junit.jupiter.api.Test;
-import org.postgresql.core.BaseConnection;
-import org.postgresql.core.Oid;
-import org.postgresql.core.TypeInfo;
+import org.opengauss.core.BaseConnection;
+import org.opengauss.core.Oid;
+import org.opengauss.core.TypeInfo;
 
 import java.sql.Connection;
-import java.sql.ResultSetMetaData;
 import java.sql.SQLException;
-import java.sql.Types;
-import java.util.Collections;
-import java.util.Map;
 import java.util.Optional;
 
 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.assertTrue;
 import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.never;
-import static org.mockito.Mockito.verify;
 import static org.mockito.Mockito.when;
 
-class PostgreSQLColumnTypeOIDLoaderTest {
+class OpenGaussColumnTypeOIDResolverTest {
     
-    @Test
-    void assertLoadFromResultSetMetaData() throws SQLException {
-        BaseConnection connection = mockConnection("record_type", 2249);
-        ResultSetMetaData metaData = mock(ResultSetMetaData.class);
-        when(metaData.getColumnCount()).thenReturn(2);
-        when(metaData.getColumnType(1)).thenReturn(Types.STRUCT);
-        when(metaData.getColumnType(2)).thenReturn(Types.VARCHAR);
-        when(metaData.getColumnTypeName(1)).thenReturn("record_type");
-        Map<Integer, Integer> actual = 
PostgreSQLColumnTypeOIDLoader.load(connection, metaData);
-        assertThat(actual, is(Collections.singletonMap(1, 2249)));
-        verify(metaData, never()).getColumnTypeName(2);
-    }
+    private final ColumnTypeOIDResolver resolver = new 
OpenGaussColumnTypeOIDResolver();
     
     @Test
-    void assertLoadFromNonPostgreSQLConnection() throws SQLException {
+    void assertFindTypeOIDFromNonOpenGaussConnection() throws SQLException {
         Connection connection = mock(Connection.class);
-        assertTrue(PostgreSQLColumnTypeOIDLoader.load(connection, 
mock(ResultSetMetaData.class)).isEmpty());
+        assertFalse(resolver.findTypeOID(connection, 
"record_type").isPresent());
     }
     
     @Test
     void assertFindUnspecifiedTypeOID() throws SQLException {
         BaseConnection connection = mockConnection("unknown_type", 
Oid.UNSPECIFIED);
-        assertFalse(PostgreSQLColumnTypeOIDLoader.findTypeOID(connection, 
"unknown_type").isPresent());
+        assertFalse(resolver.findTypeOID(connection, 
"unknown_type").isPresent());
     }
     
     @Test
     void assertFindTypeOID() throws SQLException {
         BaseConnection connection = mockConnection("record_type", 2249);
-        assertThat(PostgreSQLColumnTypeOIDLoader.findTypeOID(connection, 
"record_type"), is(Optional.of(2249)));
+        assertThat(resolver.findTypeOID(connection, "record_type"), 
is(Optional.of(2249)));
     }
     
     private BaseConnection mockConnection(final String columnTypeName, final 
int typeOID) throws SQLException {
diff --git 
a/database/protocol/dialect/postgresql/src/main/java/org/apache/shardingsphere/database/protocol/postgresql/type/PostgreSQLColumnTypeOIDLoader.java
 
b/database/protocol/dialect/postgresql/src/main/java/org/apache/shardingsphere/database/protocol/postgresql/type/ColumnTypeOIDLoader.java
similarity index 56%
rename from 
database/protocol/dialect/postgresql/src/main/java/org/apache/shardingsphere/database/protocol/postgresql/type/PostgreSQLColumnTypeOIDLoader.java
rename to 
database/protocol/dialect/postgresql/src/main/java/org/apache/shardingsphere/database/protocol/postgresql/type/ColumnTypeOIDLoader.java
index 07f1a6ba7e6..42d29713f71 100644
--- 
a/database/protocol/dialect/postgresql/src/main/java/org/apache/shardingsphere/database/protocol/postgresql/type/PostgreSQLColumnTypeOIDLoader.java
+++ 
b/database/protocol/dialect/postgresql/src/main/java/org/apache/shardingsphere/database/protocol/postgresql/type/ColumnTypeOIDLoader.java
@@ -19,63 +19,38 @@ package 
org.apache.shardingsphere.database.protocol.postgresql.type;
 
 import lombok.AccessLevel;
 import lombok.NoArgsConstructor;
-import org.postgresql.core.BaseConnection;
-import org.postgresql.core.Oid;
 
 import java.sql.Connection;
 import java.sql.ResultSetMetaData;
 import java.sql.SQLException;
 import java.sql.Types;
-import java.util.Collections;
 import java.util.HashMap;
 import java.util.Map;
-import java.util.Optional;
 
 /**
- * Loader for PostgreSQL column type OIDs.
+ * Loader for column type OIDs.
  */
 @NoArgsConstructor(access = AccessLevel.PRIVATE)
-public final class PostgreSQLColumnTypeOIDLoader {
+public final class ColumnTypeOIDLoader {
     
     /**
      * Load composite column type OIDs from result set metadata.
      *
      * @param connection database connection
      * @param metaData result set metadata
+     * @param typeOIDResolver column type OID resolver
      * @return column indexes to type OIDs, or an empty map if no composite 
column type can be resolved
      * @throws SQLException SQL exception
      */
-    public static Map<Integer, Integer> load(final Connection connection, 
final ResultSetMetaData metaData) throws SQLException {
-        return connection.isWrapperFor(BaseConnection.class) ? 
load(connection.unwrap(BaseConnection.class), metaData) : 
Collections.emptyMap();
-    }
-    
-    private static Map<Integer, Integer> load(final BaseConnection connection, 
final ResultSetMetaData metaData) throws SQLException {
+    public static Map<Integer, Integer> load(final Connection connection, 
final ResultSetMetaData metaData, final ColumnTypeOIDResolver typeOIDResolver) 
throws SQLException {
         int columnCount = metaData.getColumnCount();
         Map<Integer, Integer> result = new HashMap<>();
         for (int columnIndex = 1; columnIndex <= columnCount; columnIndex++) {
             if (Types.STRUCT == metaData.getColumnType(columnIndex)) {
-                int typeOID = 
connection.getTypeInfo().getPGType(metaData.getColumnTypeName(columnIndex));
-                if (Oid.UNSPECIFIED != typeOID) {
-                    result.put(columnIndex, typeOID);
-                }
+                int currentColumnIndex = columnIndex;
+                typeOIDResolver.findTypeOID(connection, 
metaData.getColumnTypeName(columnIndex)).ifPresent(typeOID -> 
result.put(currentColumnIndex, typeOID));
             }
         }
         return result;
     }
-    
-    /**
-     * Find type OID.
-     *
-     * @param connection database connection
-     * @param columnTypeName column type name
-     * @return type OID
-     * @throws SQLException SQL exception
-     */
-    public static Optional<Integer> findTypeOID(final Connection connection, 
final String columnTypeName) throws SQLException {
-        if (!connection.isWrapperFor(BaseConnection.class)) {
-            return Optional.empty();
-        }
-        int typeOID = 
connection.unwrap(BaseConnection.class).getTypeInfo().getPGType(columnTypeName);
-        return Oid.UNSPECIFIED == typeOID ? Optional.empty() : 
Optional.of(typeOID);
-    }
 }
diff --git 
a/database/protocol/dialect/postgresql/src/main/java/org/apache/shardingsphere/database/protocol/postgresql/type/ColumnTypeOIDResolver.java
 
b/database/protocol/dialect/postgresql/src/main/java/org/apache/shardingsphere/database/protocol/postgresql/type/ColumnTypeOIDResolver.java
new file mode 100644
index 00000000000..376a3fd9b89
--- /dev/null
+++ 
b/database/protocol/dialect/postgresql/src/main/java/org/apache/shardingsphere/database/protocol/postgresql/type/ColumnTypeOIDResolver.java
@@ -0,0 +1,39 @@
+/*
+ * 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.database.protocol.postgresql.type;
+
+import java.sql.Connection;
+import java.sql.SQLException;
+import java.util.Optional;
+
+/**
+ * Column type OID resolver.
+ */
+@FunctionalInterface
+public interface ColumnTypeOIDResolver {
+    
+    /**
+     * Find type OID.
+     *
+     * @param connection database connection
+     * @param columnTypeName column type name
+     * @return type OID
+     * @throws SQLException SQL exception
+     */
+    Optional<Integer> findTypeOID(Connection connection, String 
columnTypeName) throws SQLException;
+}
diff --git 
a/database/protocol/dialect/postgresql/src/main/java/org/apache/shardingsphere/database/protocol/postgresql/type/PostgreSQLColumnTypeOIDResolver.java
 
b/database/protocol/dialect/postgresql/src/main/java/org/apache/shardingsphere/database/protocol/postgresql/type/PostgreSQLColumnTypeOIDResolver.java
new file mode 100644
index 00000000000..fab0dead1b6
--- /dev/null
+++ 
b/database/protocol/dialect/postgresql/src/main/java/org/apache/shardingsphere/database/protocol/postgresql/type/PostgreSQLColumnTypeOIDResolver.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.database.protocol.postgresql.type;
+
+import org.postgresql.core.BaseConnection;
+import org.postgresql.core.Oid;
+
+import java.sql.Connection;
+import java.sql.SQLException;
+import java.util.Optional;
+
+/**
+ * Column type OID resolver for PostgreSQL.
+ */
+public final class PostgreSQLColumnTypeOIDResolver implements 
ColumnTypeOIDResolver {
+    
+    @Override
+    public Optional<Integer> findTypeOID(final Connection connection, final 
String columnTypeName) throws SQLException {
+        if (!connection.isWrapperFor(BaseConnection.class)) {
+            return Optional.empty();
+        }
+        int typeOID = 
connection.unwrap(BaseConnection.class).getTypeInfo().getPGType(columnTypeName);
+        return Oid.UNSPECIFIED == typeOID ? Optional.empty() : 
Optional.of(typeOID);
+    }
+}
diff --git 
a/database/protocol/dialect/postgresql/src/test/java/org/apache/shardingsphere/database/protocol/postgresql/type/ColumnTypeOIDLoaderTest.java
 
b/database/protocol/dialect/postgresql/src/test/java/org/apache/shardingsphere/database/protocol/postgresql/type/ColumnTypeOIDLoaderTest.java
new file mode 100644
index 00000000000..0e455e76fb1
--- /dev/null
+++ 
b/database/protocol/dialect/postgresql/src/test/java/org/apache/shardingsphere/database/protocol/postgresql/type/ColumnTypeOIDLoaderTest.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.database.protocol.postgresql.type;
+
+import org.junit.jupiter.api.Test;
+
+import java.sql.Connection;
+import java.sql.ResultSetMetaData;
+import java.sql.SQLException;
+import java.sql.Types;
+import java.util.Collections;
+import java.util.Map;
+import java.util.Optional;
+
+import static org.hamcrest.MatcherAssert.assertThat;
+import static org.hamcrest.Matchers.is;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.never;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+
+class ColumnTypeOIDLoaderTest {
+    
+    @Test
+    void assertLoadFromResultSetMetaData() throws SQLException {
+        Connection connection = mock(Connection.class);
+        ResultSetMetaData metaData = mock(ResultSetMetaData.class);
+        when(metaData.getColumnCount()).thenReturn(3);
+        when(metaData.getColumnType(1)).thenReturn(Types.STRUCT);
+        when(metaData.getColumnType(2)).thenReturn(Types.STRUCT);
+        when(metaData.getColumnType(3)).thenReturn(Types.VARCHAR);
+        when(metaData.getColumnTypeName(1)).thenReturn("record_type");
+        when(metaData.getColumnTypeName(2)).thenReturn("unknown_type");
+        ColumnTypeOIDResolver resolver = mock(ColumnTypeOIDResolver.class);
+        when(resolver.findTypeOID(connection, 
"record_type")).thenReturn(Optional.of(2249));
+        when(resolver.findTypeOID(connection, 
"unknown_type")).thenReturn(Optional.empty());
+        Map<Integer, Integer> actual = ColumnTypeOIDLoader.load(connection, 
metaData, resolver);
+        assertThat(actual, is(Collections.singletonMap(1, 2249)));
+        verify(metaData, never()).getColumnTypeName(3);
+    }
+}
diff --git 
a/database/protocol/dialect/postgresql/src/test/java/org/apache/shardingsphere/database/protocol/postgresql/type/PostgreSQLColumnTypeOIDLoaderTest.java
 
b/database/protocol/dialect/postgresql/src/test/java/org/apache/shardingsphere/database/protocol/postgresql/type/PostgreSQLColumnTypeOIDResolverTest.java
similarity index 61%
rename from 
database/protocol/dialect/postgresql/src/test/java/org/apache/shardingsphere/database/protocol/postgresql/type/PostgreSQLColumnTypeOIDLoaderTest.java
rename to 
database/protocol/dialect/postgresql/src/test/java/org/apache/shardingsphere/database/protocol/postgresql/type/PostgreSQLColumnTypeOIDResolverTest.java
index 9d0cfb6b2e4..76ea84dcfed 100644
--- 
a/database/protocol/dialect/postgresql/src/test/java/org/apache/shardingsphere/database/protocol/postgresql/type/PostgreSQLColumnTypeOIDLoaderTest.java
+++ 
b/database/protocol/dialect/postgresql/src/test/java/org/apache/shardingsphere/database/protocol/postgresql/type/PostgreSQLColumnTypeOIDResolverTest.java
@@ -23,53 +23,35 @@ import org.postgresql.core.Oid;
 import org.postgresql.core.TypeInfo;
 
 import java.sql.Connection;
-import java.sql.ResultSetMetaData;
 import java.sql.SQLException;
-import java.sql.Types;
-import java.util.Collections;
-import java.util.Map;
 import java.util.Optional;
 
 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.assertTrue;
 import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.never;
-import static org.mockito.Mockito.verify;
 import static org.mockito.Mockito.when;
 
-class PostgreSQLColumnTypeOIDLoaderTest {
+class PostgreSQLColumnTypeOIDResolverTest {
     
-    @Test
-    void assertLoadFromResultSetMetaData() throws SQLException {
-        BaseConnection connection = mockConnection("record_type", 2249);
-        ResultSetMetaData metaData = mock(ResultSetMetaData.class);
-        when(metaData.getColumnCount()).thenReturn(2);
-        when(metaData.getColumnType(1)).thenReturn(Types.STRUCT);
-        when(metaData.getColumnType(2)).thenReturn(Types.VARCHAR);
-        when(metaData.getColumnTypeName(1)).thenReturn("record_type");
-        Map<Integer, Integer> actual = 
PostgreSQLColumnTypeOIDLoader.load(connection, metaData);
-        assertThat(actual, is(Collections.singletonMap(1, 2249)));
-        verify(metaData, never()).getColumnTypeName(2);
-    }
+    private final ColumnTypeOIDResolver resolver = new 
PostgreSQLColumnTypeOIDResolver();
     
     @Test
-    void assertLoadFromNonPostgreSQLConnection() throws SQLException {
+    void assertFindTypeOIDFromNonPostgreSQLConnection() throws SQLException {
         Connection connection = mock(Connection.class);
-        assertTrue(PostgreSQLColumnTypeOIDLoader.load(connection, 
mock(ResultSetMetaData.class)).isEmpty());
+        assertFalse(resolver.findTypeOID(connection, 
"record_type").isPresent());
     }
     
     @Test
     void assertFindUnspecifiedTypeOID() throws SQLException {
         BaseConnection connection = mockConnection("unknown_type", 
Oid.UNSPECIFIED);
-        assertFalse(PostgreSQLColumnTypeOIDLoader.findTypeOID(connection, 
"unknown_type").isPresent());
+        assertFalse(resolver.findTypeOID(connection, 
"unknown_type").isPresent());
     }
     
     @Test
     void assertFindTypeOID() throws SQLException {
         BaseConnection connection = mockConnection("record_type", 2249);
-        assertThat(PostgreSQLColumnTypeOIDLoader.findTypeOID(connection, 
"record_type"), is(Optional.of(2249)));
+        assertThat(resolver.findTypeOID(connection, "record_type"), 
is(Optional.of(2249)));
     }
     
     private BaseConnection mockConnection(final String columnTypeName, final 
int typeOID) throws SQLException {
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 47687e75805..95b0a716717 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,13 +17,17 @@
 
 package 
org.apache.shardingsphere.proxy.backend.opengauss.response.header.query;
 
+import 
org.apache.shardingsphere.database.protocol.opengauss.type.OpenGaussColumnTypeOIDResolver;
+import 
org.apache.shardingsphere.database.protocol.postgresql.type.ColumnTypeOIDResolver;
 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;
 import 
org.apache.shardingsphere.proxy.backend.response.header.query.QueryHeaderBuilder;
 
+import java.sql.ResultSet;
 import java.sql.SQLException;
+import java.sql.Types;
 
 /**
  * Query header builder for openGauss.
@@ -32,12 +36,22 @@ public final class OpenGaussQueryHeaderBuilder implements 
QueryHeaderBuilder {
     
     private final PostgreSQLQueryHeaderBuilder delegate = new 
PostgreSQLQueryHeaderBuilder();
     
+    private final ColumnTypeOIDResolver columnTypeOIDResolver = new 
OpenGaussColumnTypeOIDResolver();
+    
     @Override
     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
+    public void appendProtocolAttributes(final QueryHeader queryHeader, final 
ResultSet resultSet) throws SQLException {
+        if (Types.STRUCT == queryHeader.getColumnType()) {
+            
columnTypeOIDResolver.findTypeOID(resultSet.getStatement().getConnection(), 
queryHeader.getColumnTypeName())
+                    .ifPresent(optional -> 
queryHeader.getProtocolAttributes().put(PostgreSQLQueryHeaderBuilder.TYPE_OID, 
optional));
+        }
+    }
+    
     @Override
     public String getDatabaseType() {
         return "openGauss";
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 821b3bd9fcb..38ca801400e 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,17 +17,24 @@
 
 package 
org.apache.shardingsphere.proxy.backend.opengauss.response.header.query;
 
+import 
org.apache.shardingsphere.database.protocol.opengauss.type.OpenGaussColumnTypeOIDResolver;
 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;
+import org.mockito.MockedConstruction;
 
+import java.sql.Connection;
+import java.sql.ResultSet;
 import java.sql.SQLException;
+import java.sql.Statement;
 import java.sql.Types;
+import java.util.Optional;
 
-import static org.hamcrest.Matchers.is;
 import static org.hamcrest.MatcherAssert.assertThat;
+import static org.hamcrest.Matchers.is;
 import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.mockConstruction;
 import static org.mockito.Mockito.when;
 
 class OpenGaussQueryHeaderBuilderTest {
@@ -47,4 +54,26 @@ class OpenGaussQueryHeaderBuilderTest {
         assertThat(actual.getColumnTypeName(), 
is(expected.getColumnTypeName()));
         assertThat(actual.getColumnLength(), is(expected.getColumnLength()));
     }
+    
+    @Test
+    void assertAppendProtocolAttributes() throws SQLException {
+        int columnIndex = 1;
+        ShardingSphereResultSetMetaData resultSetMetaData = 
mock(ShardingSphereResultSetMetaData.class);
+        
when(resultSetMetaData.getColumnType(columnIndex)).thenReturn(Types.STRUCT);
+        
when(resultSetMetaData.getColumnTypeName(columnIndex)).thenReturn("record_type");
+        ResultSet resultSet = mock(ResultSet.class);
+        Statement statement = mock(Statement.class);
+        Connection connection = mock(Connection.class);
+        when(resultSet.getStatement()).thenReturn(statement);
+        when(statement.getConnection()).thenReturn(connection);
+        // AutoMockExtension cannot configure constructed mocks, while this 
scenario requires a non-empty resolver result.
+        try (
+                MockedConstruction<OpenGaussColumnTypeOIDResolver> ignored = 
mockConstruction(
+                        OpenGaussColumnTypeOIDResolver.class, (mock, context) 
-> when(mock.findTypeOID(connection, 
"record_type")).thenReturn(Optional.of(2249)))) {
+            OpenGaussQueryHeaderBuilder builder = new 
OpenGaussQueryHeaderBuilder();
+            QueryHeader actual = builder.build(resultSetMetaData, null, null, 
"record", columnIndex);
+            builder.appendProtocolAttributes(actual, resultSet);
+            
assertThat(actual.getProtocolAttributes().get(PostgreSQLQueryHeaderBuilder.TYPE_OID),
 is(2249));
+        }
+    }
 }
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 eb5754cd647..1cea73b69c0 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,8 @@
 
 package 
org.apache.shardingsphere.proxy.backend.postgresql.response.header.query;
 
-import 
org.apache.shardingsphere.database.protocol.postgresql.type.PostgreSQLColumnTypeOIDLoader;
+import 
org.apache.shardingsphere.database.protocol.postgresql.type.ColumnTypeOIDResolver;
+import 
org.apache.shardingsphere.database.protocol.postgresql.type.PostgreSQLColumnTypeOIDResolver;
 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;
@@ -40,6 +41,8 @@ public final class PostgreSQLQueryHeaderBuilder implements 
QueryHeaderBuilder {
     
     private static final boolean UNUSED_BOOLEAN_FIELD = false;
     
+    private final ColumnTypeOIDResolver columnTypeOIDResolver = new 
PostgreSQLColumnTypeOIDResolver();
+    
     @Override
     public QueryHeader build(final ShardingSphereResultSetMetaData 
resultSetMetaData, final ShardingSphereDatabase database, final String 
columnName, final String columnLabel,
                              final int columnIndex) throws SQLException {
@@ -52,7 +55,7 @@ public final class PostgreSQLQueryHeaderBuilder implements 
QueryHeaderBuilder {
     @Override
     public void appendProtocolAttributes(final QueryHeader queryHeader, final 
ResultSet resultSet) throws SQLException {
         if (Types.STRUCT == queryHeader.getColumnType()) {
-            
PostgreSQLColumnTypeOIDLoader.findTypeOID(resultSet.getStatement().getConnection(),
 queryHeader.getColumnTypeName())
+            
columnTypeOIDResolver.findTypeOID(resultSet.getStatement().getConnection(), 
queryHeader.getColumnTypeName())
                     .ifPresent(optional -> 
queryHeader.getProtocolAttributes().put(TYPE_OID, optional));
         }
     }
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 14251dd4c82..665dd2ca7eb 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,24 +17,21 @@
 
 package 
org.apache.shardingsphere.proxy.backend.postgresql.response.header.query;
 
-import 
org.apache.shardingsphere.database.protocol.postgresql.type.PostgreSQLColumnTypeOIDLoader;
 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;
-import org.mockito.MockedStatic;
+import org.postgresql.core.BaseConnection;
+import org.postgresql.core.TypeInfo;
 
-import java.sql.Connection;
 import java.sql.ResultSet;
 import java.sql.SQLException;
 import java.sql.Statement;
 import java.sql.Types;
-import java.util.Optional;
 
 import static org.hamcrest.Matchers.is;
 import static org.hamcrest.MatcherAssert.assertThat;
 import static org.junit.jupiter.api.Assertions.assertTrue;
 import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.mockStatic;
 import static org.mockito.Mockito.verifyNoInteractions;
 import static org.mockito.Mockito.when;
 
@@ -63,16 +60,18 @@ class PostgreSQLQueryHeaderBuilderTest {
         
when(resultSetMetaData.getColumnTypeName(columnIndex)).thenReturn("record_type");
         ResultSet resultSet = mock(ResultSet.class);
         Statement statement = mock(Statement.class);
-        Connection connection = mock(Connection.class);
+        BaseConnection connection = mock(BaseConnection.class);
+        TypeInfo typeInfo = mock(TypeInfo.class);
         when(resultSet.getStatement()).thenReturn(statement);
         when(statement.getConnection()).thenReturn(connection);
-        try (MockedStatic<PostgreSQLColumnTypeOIDLoader> loader = 
mockStatic(PostgreSQLColumnTypeOIDLoader.class)) {
-            loader.when(() -> 
PostgreSQLColumnTypeOIDLoader.findTypeOID(connection, 
"record_type")).thenReturn(Optional.of(2249));
-            PostgreSQLQueryHeaderBuilder builder = new 
PostgreSQLQueryHeaderBuilder();
-            QueryHeader actual = builder.build(resultSetMetaData, null, null, 
"record", columnIndex);
-            builder.appendProtocolAttributes(actual, resultSet);
-            
assertThat(actual.getProtocolAttributes().get(PostgreSQLQueryHeaderBuilder.TYPE_OID),
 is(2249));
-        }
+        when(connection.isWrapperFor(BaseConnection.class)).thenReturn(true);
+        when(connection.unwrap(BaseConnection.class)).thenReturn(connection);
+        when(connection.getTypeInfo()).thenReturn(typeInfo);
+        when(typeInfo.getPGType("record_type")).thenReturn(2249);
+        PostgreSQLQueryHeaderBuilder builder = new 
PostgreSQLQueryHeaderBuilder();
+        QueryHeader actual = builder.build(resultSetMetaData, null, null, 
"record", columnIndex);
+        builder.appendProtocolAttributes(actual, resultSet);
+        
assertThat(actual.getProtocolAttributes().get(PostgreSQLQueryHeaderBuilder.TYPE_OID),
 is(2249));
     }
     
     @Test
diff --git 
a/proxy/frontend/dialect/opengauss/src/main/java/org/apache/shardingsphere/proxy/frontend/opengauss/command/OpenGaussCommandExecutorFactory.java
 
b/proxy/frontend/dialect/opengauss/src/main/java/org/apache/shardingsphere/proxy/frontend/opengauss/command/OpenGaussCommandExecutorFactory.java
index 071412b9f91..7f57f8d82d9 100644
--- 
a/proxy/frontend/dialect/opengauss/src/main/java/org/apache/shardingsphere/proxy/frontend/opengauss/command/OpenGaussCommandExecutorFactory.java
+++ 
b/proxy/frontend/dialect/opengauss/src/main/java/org/apache/shardingsphere/proxy/frontend/opengauss/command/OpenGaussCommandExecutorFactory.java
@@ -22,6 +22,7 @@ import lombok.NoArgsConstructor;
 import lombok.extern.slf4j.Slf4j;
 import 
org.apache.shardingsphere.database.protocol.opengauss.packet.command.OpenGaussCommandPacketType;
 import 
org.apache.shardingsphere.database.protocol.opengauss.packet.command.bind.OpenGaussComBatchBindPacket;
+import 
org.apache.shardingsphere.database.protocol.opengauss.type.OpenGaussColumnTypeOIDResolver;
 import 
org.apache.shardingsphere.database.protocol.packet.command.CommandPacketType;
 import 
org.apache.shardingsphere.database.protocol.packet.sql.SQLReceivedPacket;
 import 
org.apache.shardingsphere.database.protocol.postgresql.packet.command.PostgreSQLCommandPacket;
@@ -33,6 +34,7 @@ import 
org.apache.shardingsphere.database.protocol.postgresql.packet.command.que
 import 
org.apache.shardingsphere.database.protocol.postgresql.packet.command.query.extended.execute.PostgreSQLComExecutePacket;
 import 
org.apache.shardingsphere.database.protocol.postgresql.packet.command.query.extended.parse.PostgreSQLComParsePacket;
 import 
org.apache.shardingsphere.database.protocol.postgresql.packet.command.query.simple.PostgreSQLComQueryPacket;
+import 
org.apache.shardingsphere.database.protocol.postgresql.type.ColumnTypeOIDResolver;
 import org.apache.shardingsphere.proxy.backend.session.ConnectionSession;
 import 
org.apache.shardingsphere.proxy.frontend.command.executor.CommandExecutor;
 import 
org.apache.shardingsphere.proxy.frontend.opengauss.command.query.extended.bind.OpenGaussComBatchBindExecutor;
@@ -61,6 +63,8 @@ import java.util.List;
 @Slf4j
 public final class OpenGaussCommandExecutorFactory {
     
+    private static final ColumnTypeOIDResolver COLUMN_TYPE_OID_RESOLVER = new 
OpenGaussColumnTypeOIDResolver();
+    
     /**
      * Create new instance of command executor.
      *
@@ -123,7 +127,7 @@ public final class OpenGaussCommandExecutorFactory {
             case BIND_COMMAND:
                 return new PostgreSQLComBindExecutor(portalContext, 
(PostgreSQLComBindPacket) commandPacket, connectionSession);
             case DESCRIBE_COMMAND:
-                return new PostgreSQLComDescribeExecutor(portalContext, 
(PostgreSQLComDescribePacket) commandPacket, connectionSession);
+                return new PostgreSQLComDescribeExecutor(portalContext, 
(PostgreSQLComDescribePacket) commandPacket, connectionSession, 
COLUMN_TYPE_OID_RESOLVER);
             case EXECUTE_COMMAND:
                 return new PostgreSQLComExecuteExecutor(portalContext, 
(PostgreSQLComExecutePacket) commandPacket);
             case SYNC_COMMAND:
diff --git 
a/proxy/frontend/dialect/opengauss/src/main/java/org/apache/shardingsphere/proxy/frontend/opengauss/command/query/simple/OpenGaussComQueryExecutor.java
 
b/proxy/frontend/dialect/opengauss/src/main/java/org/apache/shardingsphere/proxy/frontend/opengauss/command/query/simple/OpenGaussComQueryExecutor.java
index 265b178c779..1dfba228734 100644
--- 
a/proxy/frontend/dialect/opengauss/src/main/java/org/apache/shardingsphere/proxy/frontend/opengauss/command/query/simple/OpenGaussComQueryExecutor.java
+++ 
b/proxy/frontend/dialect/opengauss/src/main/java/org/apache/shardingsphere/proxy/frontend/opengauss/command/query/simple/OpenGaussComQueryExecutor.java
@@ -21,6 +21,7 @@ import lombok.Getter;
 import 
org.apache.shardingsphere.database.connector.core.metadata.database.enums.QuoteCharacter;
 import org.apache.shardingsphere.database.connector.core.type.DatabaseType;
 import org.apache.shardingsphere.database.protocol.packet.DatabasePacket;
+import 
org.apache.shardingsphere.database.protocol.postgresql.constant.PostgreSQLValueFormat;
 import 
org.apache.shardingsphere.database.protocol.postgresql.packet.PostgreSQLPacket;
 import 
org.apache.shardingsphere.database.protocol.postgresql.packet.command.query.PostgreSQLColumnDescription;
 import 
org.apache.shardingsphere.database.protocol.postgresql.packet.command.query.PostgreSQLDataRowPacket;
@@ -33,6 +34,7 @@ import 
org.apache.shardingsphere.infra.spi.type.typed.TypedSPILoader;
 import org.apache.shardingsphere.proxy.backend.handler.ProxyBackendHandler;
 import 
org.apache.shardingsphere.proxy.backend.handler.ProxyBackendHandlerFactory;
 import org.apache.shardingsphere.proxy.backend.handler.ProxySQLComQueryParser;
+import 
org.apache.shardingsphere.proxy.backend.postgresql.response.header.query.PostgreSQLQueryHeaderBuilder;
 import org.apache.shardingsphere.proxy.backend.response.header.ResponseHeader;
 import 
org.apache.shardingsphere.proxy.backend.response.header.query.QueryHeader;
 import 
org.apache.shardingsphere.proxy.backend.response.header.query.QueryResponseHeader;
@@ -93,7 +95,11 @@ public final class OpenGaussComQueryExecutor implements 
QueryCommandExecutor {
         Collection<PostgreSQLColumnDescription> result = new LinkedList<>();
         int columnIndex = 0;
         for (QueryHeader each : queryResponseHeader.getQueryHeaders()) {
-            result.add(new PostgreSQLColumnDescription(each.getColumnLabel(), 
++columnIndex, each.getColumnType(), each.getColumnLength(), 
each.getColumnTypeName()));
+            int currentColumnIndex = ++columnIndex;
+            Integer typeOID = (Integer) 
each.getProtocolAttributes().get(PostgreSQLQueryHeaderBuilder.TYPE_OID);
+            result.add(null == typeOID
+                    ? new PostgreSQLColumnDescription(each.getColumnLabel(), 
currentColumnIndex, each.getColumnType(), each.getColumnLength(), 
each.getColumnTypeName())
+                    : new PostgreSQLColumnDescription(each.getColumnLabel(), 
currentColumnIndex, typeOID, each.getColumnLength(), 
PostgreSQLValueFormat.TEXT.getCode()));
         }
         return result;
     }
diff --git 
a/proxy/frontend/dialect/opengauss/src/test/java/org/apache/shardingsphere/proxy/frontend/opengauss/command/query/simple/OpenGaussComQueryExecutorTest.java
 
b/proxy/frontend/dialect/opengauss/src/test/java/org/apache/shardingsphere/proxy/frontend/opengauss/command/query/simple/OpenGaussComQueryExecutorTest.java
index 9b6abf2a31f..0c174539236 100644
--- 
a/proxy/frontend/dialect/opengauss/src/test/java/org/apache/shardingsphere/proxy/frontend/opengauss/command/query/simple/OpenGaussComQueryExecutorTest.java
+++ 
b/proxy/frontend/dialect/opengauss/src/test/java/org/apache/shardingsphere/proxy/frontend/opengauss/command/query/simple/OpenGaussComQueryExecutorTest.java
@@ -30,6 +30,7 @@ import 
org.apache.shardingsphere.infra.spi.type.typed.TypedSPILoader;
 import org.apache.shardingsphere.proxy.backend.handler.ProxyBackendHandler;
 import 
org.apache.shardingsphere.proxy.backend.handler.ProxyBackendHandlerFactory;
 import org.apache.shardingsphere.proxy.backend.handler.ProxySQLComQueryParser;
+import 
org.apache.shardingsphere.proxy.backend.postgresql.response.header.query.PostgreSQLQueryHeaderBuilder;
 import org.apache.shardingsphere.proxy.backend.response.data.QueryResponseRow;
 import 
org.apache.shardingsphere.proxy.backend.response.header.query.QueryHeader;
 import 
org.apache.shardingsphere.proxy.backend.response.header.query.QueryResponseHeader;
@@ -55,9 +56,9 @@ import org.mockito.Mock;
 import org.mockito.internal.configuration.plugins.Plugins;
 
 import java.sql.SQLException;
+import java.sql.Types;
 import java.util.Arrays;
 import java.util.Collection;
-import java.util.Collections;
 import java.util.LinkedList;
 import java.util.List;
 
@@ -102,8 +103,10 @@ class OpenGaussComQueryExecutorTest {
     @Test
     void assertExecuteQueryReturnsRowDescription() throws SQLException, 
ReflectiveOperationException {
         QueryHeader queryHeader = new QueryHeader("schema", "table", "label", 
"column", 1, "type", 2, 3, true, true, true, true);
+        QueryHeader compositeQueryHeader = new QueryHeader("schema", "table", 
"composite_label", "composite_column", Types.STRUCT, "record_type", 4, 5, true, 
true, true, true);
+        
compositeQueryHeader.getProtocolAttributes().put(PostgreSQLQueryHeaderBuilder.TYPE_OID,
 2249);
         QueryResponseHeader queryResponseHeader = 
mock(QueryResponseHeader.class);
-        
when(queryResponseHeader.getQueryHeaders()).thenReturn(Collections.singletonList(queryHeader));
+        
when(queryResponseHeader.getQueryHeaders()).thenReturn(Arrays.asList(queryHeader,
 compositeQueryHeader));
         when(proxyBackendHandler.execute()).thenReturn(queryResponseHeader);
         Collection<DatabasePacket> actualPackets = queryExecutor.execute();
         List<DatabasePacket> actualPacketList = new 
LinkedList<>(actualPackets);
@@ -112,9 +115,14 @@ class OpenGaussComQueryExecutorTest {
         assertThat(queryExecutor.getResponseType(), is(ResponseType.QUERY));
         Collection<?> columnDescriptions = (Collection<?>) 
Plugins.getMemberAccessor()
                 
.get(PostgreSQLRowDescriptionPacket.class.getDeclaredField("columnDescriptions"),
 actualPacket);
-        PostgreSQLColumnDescription actualColumn = 
(PostgreSQLColumnDescription) columnDescriptions.iterator().next();
+        List<?> actualColumns = new LinkedList<>(columnDescriptions);
+        PostgreSQLColumnDescription actualColumn = 
(PostgreSQLColumnDescription) actualColumns.get(0);
         assertThat(actualColumn.getColumnName(), is("label"));
         assertThat(actualColumn.getColumnIndex(), is(1));
+        PostgreSQLColumnDescription actualCompositeColumn = 
(PostgreSQLColumnDescription) actualColumns.get(1);
+        assertThat(actualCompositeColumn.getColumnName(), 
is("composite_label"));
+        assertThat(actualCompositeColumn.getColumnIndex(), is(2));
+        assertThat(actualCompositeColumn.getTypeOID(), is(2249));
     }
     
     @Test
diff --git 
a/proxy/frontend/dialect/postgresql/src/main/java/org/apache/shardingsphere/proxy/frontend/postgresql/command/PostgreSQLCommandExecutorFactory.java
 
b/proxy/frontend/dialect/postgresql/src/main/java/org/apache/shardingsphere/proxy/frontend/postgresql/command/PostgreSQLCommandExecutorFactory.java
index b0ba38f3da2..5130921704d 100644
--- 
a/proxy/frontend/dialect/postgresql/src/main/java/org/apache/shardingsphere/proxy/frontend/postgresql/command/PostgreSQLCommandExecutorFactory.java
+++ 
b/proxy/frontend/dialect/postgresql/src/main/java/org/apache/shardingsphere/proxy/frontend/postgresql/command/PostgreSQLCommandExecutorFactory.java
@@ -30,6 +30,8 @@ import 
org.apache.shardingsphere.database.protocol.postgresql.packet.command.que
 import 
org.apache.shardingsphere.database.protocol.postgresql.packet.command.query.extended.execute.PostgreSQLComExecutePacket;
 import 
org.apache.shardingsphere.database.protocol.postgresql.packet.command.query.extended.parse.PostgreSQLComParsePacket;
 import 
org.apache.shardingsphere.database.protocol.postgresql.packet.command.query.simple.PostgreSQLComQueryPacket;
+import 
org.apache.shardingsphere.database.protocol.postgresql.type.ColumnTypeOIDResolver;
+import 
org.apache.shardingsphere.database.protocol.postgresql.type.PostgreSQLColumnTypeOIDResolver;
 import org.apache.shardingsphere.proxy.backend.session.ConnectionSession;
 import 
org.apache.shardingsphere.proxy.frontend.command.executor.CommandExecutor;
 import 
org.apache.shardingsphere.proxy.frontend.postgresql.command.generic.PostgreSQLComTerminationExecutor;
@@ -56,6 +58,8 @@ import java.util.List;
 @Slf4j
 public final class PostgreSQLCommandExecutorFactory {
     
+    private static final ColumnTypeOIDResolver COLUMN_TYPE_OID_RESOLVER = new 
PostgreSQLColumnTypeOIDResolver();
+    
     /**
      * Create new instance of command executor.
      *
@@ -115,7 +119,7 @@ public final class PostgreSQLCommandExecutorFactory {
             case BIND_COMMAND:
                 return new PostgreSQLComBindExecutor(portalContext, 
(PostgreSQLComBindPacket) commandPacket, connectionSession);
             case DESCRIBE_COMMAND:
-                return new PostgreSQLComDescribeExecutor(portalContext, 
(PostgreSQLComDescribePacket) commandPacket, connectionSession);
+                return new PostgreSQLComDescribeExecutor(portalContext, 
(PostgreSQLComDescribePacket) commandPacket, connectionSession, 
COLUMN_TYPE_OID_RESOLVER);
             case EXECUTE_COMMAND:
                 return new PostgreSQLComExecuteExecutor(portalContext, 
(PostgreSQLComExecutePacket) commandPacket);
             case SYNC_COMMAND:
diff --git 
a/proxy/frontend/dialect/postgresql/src/main/java/org/apache/shardingsphere/proxy/frontend/postgresql/command/query/extended/describe/PostgreSQLComDescribeExecutor.java
 
b/proxy/frontend/dialect/postgresql/src/main/java/org/apache/shardingsphere/proxy/frontend/postgresql/command/query/extended/describe/PostgreSQLComDescribeExecutor.java
index 411fc417070..20d0275d901 100644
--- 
a/proxy/frontend/dialect/postgresql/src/main/java/org/apache/shardingsphere/proxy/frontend/postgresql/command/query/extended/describe/PostgreSQLComDescribeExecutor.java
+++ 
b/proxy/frontend/dialect/postgresql/src/main/java/org/apache/shardingsphere/proxy/frontend/postgresql/command/query/extended/describe/PostgreSQLComDescribeExecutor.java
@@ -25,9 +25,10 @@ import 
org.apache.shardingsphere.database.protocol.postgresql.constant.PostgreSQ
 import 
org.apache.shardingsphere.database.protocol.postgresql.packet.command.query.PostgreSQLColumnDescription;
 import 
org.apache.shardingsphere.database.protocol.postgresql.packet.command.query.PostgreSQLNoDataPacket;
 import 
org.apache.shardingsphere.database.protocol.postgresql.packet.command.query.PostgreSQLRowDescriptionPacket;
-import 
org.apache.shardingsphere.database.protocol.postgresql.type.PostgreSQLColumnTypeOIDLoader;
 import 
org.apache.shardingsphere.database.protocol.postgresql.packet.command.query.extended.PostgreSQLBinaryColumnType;
 import 
org.apache.shardingsphere.database.protocol.postgresql.packet.command.query.extended.describe.PostgreSQLComDescribePacket;
+import 
org.apache.shardingsphere.database.protocol.postgresql.type.ColumnTypeOIDLoader;
+import 
org.apache.shardingsphere.database.protocol.postgresql.type.ColumnTypeOIDResolver;
 import org.apache.shardingsphere.infra.exception.ShardingSpherePreconditions;
 import 
org.apache.shardingsphere.infra.exception.generic.UnsupportedSQLOperationException;
 import 
org.apache.shardingsphere.infra.metadata.database.ShardingSphereDatabase;
@@ -81,6 +82,8 @@ public final class PostgreSQLComDescribeExecutor implements 
CommandExecutor {
     
     private final ConnectionSession connectionSession;
     
+    private final ColumnTypeOIDResolver columnTypeOIDResolver;
+    
     @Override
     public Collection<DatabasePacket> execute() throws SQLException {
         switch (packet.getType()) {
@@ -233,7 +236,7 @@ public final class PostgreSQLComDescribeExecutor implements 
CommandExecutor {
             ResultSetMetaData metaData = actualPreparedStatement.getMetaData();
             return null == metaData || expectedColumnCount != 
metaData.getColumnCount()
                     ? Collections.emptyMap()
-                    : 
PostgreSQLColumnTypeOIDLoader.load(actualPreparedStatement.getConnection(), 
metaData);
+                    : 
ColumnTypeOIDLoader.load(actualPreparedStatement.getConnection(), metaData, 
columnTypeOIDResolver);
         }
     }
     
@@ -253,7 +256,7 @@ public final class PostgreSQLComDescribeExecutor implements 
CommandExecutor {
             
logicPreparedStatement.setRowDescription(PostgreSQLNoDataPacket.getInstance());
             return;
         }
-        Map<Integer, Integer> columnTypeOIDs = 
PostgreSQLColumnTypeOIDLoader.load(actualPreparedStatement.getConnection(), 
resultSetMetaData);
+        Map<Integer, Integer> columnTypeOIDs = 
ColumnTypeOIDLoader.load(actualPreparedStatement.getConnection(), 
resultSetMetaData, columnTypeOIDResolver);
         List<PostgreSQLColumnDescription> columnDescriptions = new 
ArrayList<>(resultSetMetaData.getColumnCount());
         for (int columnIndex = 1; columnIndex <= 
resultSetMetaData.getColumnCount(); columnIndex++) {
             String columnName = resultSetMetaData.getColumnName(columnIndex);
diff --git 
a/proxy/frontend/dialect/postgresql/src/test/java/org/apache/shardingsphere/proxy/frontend/postgresql/command/query/extended/describe/PostgreSQLComDescribeExecutorTest.java
 
b/proxy/frontend/dialect/postgresql/src/test/java/org/apache/shardingsphere/proxy/frontend/postgresql/command/query/extended/describe/PostgreSQLComDescribeExecutorTest.java
index e08465f1b09..a50d984cc22 100644
--- 
a/proxy/frontend/dialect/postgresql/src/test/java/org/apache/shardingsphere/proxy/frontend/postgresql/command/query/extended/describe/PostgreSQLComDescribeExecutorTest.java
+++ 
b/proxy/frontend/dialect/postgresql/src/test/java/org/apache/shardingsphere/proxy/frontend/postgresql/command/query/extended/describe/PostgreSQLComDescribeExecutorTest.java
@@ -29,7 +29,8 @@ import 
org.apache.shardingsphere.database.protocol.postgresql.packet.command.que
 import 
org.apache.shardingsphere.database.protocol.postgresql.packet.command.query.extended.PostgreSQLBinaryColumnType;
 import 
org.apache.shardingsphere.database.protocol.postgresql.packet.command.query.extended.describe.PostgreSQLComDescribePacket;
 import 
org.apache.shardingsphere.database.protocol.postgresql.payload.PostgreSQLPacketPayload;
-import 
org.apache.shardingsphere.database.protocol.postgresql.type.PostgreSQLColumnTypeOIDLoader;
+import 
org.apache.shardingsphere.database.protocol.postgresql.type.ColumnTypeOIDLoader;
+import 
org.apache.shardingsphere.database.protocol.postgresql.type.ColumnTypeOIDResolver;
 import 
org.apache.shardingsphere.infra.binder.context.statement.SQLStatementContext;
 import 
org.apache.shardingsphere.infra.binder.context.statement.type.dml.InsertStatementContext;
 import 
org.apache.shardingsphere.infra.binder.context.statement.type.dml.SelectStatementContext;
@@ -110,7 +111,7 @@ import static org.mockito.Mockito.verify;
 import static org.mockito.Mockito.when;
 
 @ExtendWith(AutoMockExtension.class)
-@StaticMockSettings({ProxyContext.class, PostgreSQLColumnTypeOIDLoader.class})
+@StaticMockSettings({ProxyContext.class, ColumnTypeOIDLoader.class})
 @MockitoSettings(strictness = Strictness.LENIENT)
 class PostgreSQLComDescribeExecutorTest {
     
@@ -131,6 +132,9 @@ class PostgreSQLComDescribeExecutorTest {
     @Mock
     private ConnectionSession connectionSession;
     
+    @Mock
+    private ColumnTypeOIDResolver columnTypeOIDResolver;
+    
     private Map<Integer, Integer> columnTypeOIDs;
     
     @InjectMocks
@@ -140,7 +144,7 @@ class PostgreSQLComDescribeExecutorTest {
     void setUp() throws SQLException {
         when(connectionSession.getProtocolType()).thenReturn(DATABASE_TYPE);
         columnTypeOIDs = Collections.emptyMap();
-        when(PostgreSQLColumnTypeOIDLoader.load(any(Connection.class), 
any(ResultSetMetaData.class))).thenAnswer(ignored -> columnTypeOIDs);
+        when(ColumnTypeOIDLoader.load(any(Connection.class), 
any(ResultSetMetaData.class), 
any(ColumnTypeOIDResolver.class))).thenAnswer(ignored -> columnTypeOIDs);
     }
     
     @Test
@@ -724,7 +728,7 @@ class PostgreSQLComDescribeExecutorTest {
     
     @Test
     void assertDescribeUnknownType() {
-        assertThrows(UnsupportedSQLOperationException.class, () -> new 
PostgreSQLComDescribeExecutor(portalContext, packet, 
connectionSession).execute());
+        assertThrows(UnsupportedSQLOperationException.class, () -> new 
PostgreSQLComDescribeExecutor(portalContext, packet, connectionSession, 
columnTypeOIDResolver).execute());
     }
     
     private static Stream<Arguments> provideInsertMetaDataCases() {

Reply via email to