You are viewing a plain text version of this content. The canonical link for it is here.
Posted to notifications@shardingsphere.apache.org by su...@apache.org on 2022/12/29 10:56:20 UTC

[shardingsphere] branch master updated: Fix NPE when describing PostgreSQL composite type (#23165)

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

sunnianjun 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 a190fd5e3cc Fix NPE when describing PostgreSQL composite type (#23165)
a190fd5e3cc is described below

commit a190fd5e3cc352545fbc7f0ec84015627b0ec132
Author: 吴伟杰 <wu...@apache.org>
AuthorDate: Thu Dec 29 18:56:13 2022 +0800

    Fix NPE when describing PostgreSQL composite type (#23165)
    
    * Fix NPE when describing PostgreSQL composite type
    
    * Test cover composite type with alias
---
 .../command/query/extended/PostgreSQLColumnType.java     |  2 ++
 .../extended/describe/PostgreSQLComDescribeExecutor.java | 11 ++++++++---
 .../describe/PostgreSQLComDescribeExecutorTest.java      | 16 +++++++++++++---
 3 files changed, 23 insertions(+), 6 deletions(-)

diff --git a/db-protocol/postgresql/src/main/java/org/apache/shardingsphere/db/protocol/postgresql/packet/command/query/extended/PostgreSQLColumnType.java b/db-protocol/postgresql/src/main/java/org/apache/shardingsphere/db/protocol/postgresql/packet/command/query/extended/PostgreSQLColumnType.java
index 58bf870b57a..1787782a575 100644
--- a/db-protocol/postgresql/src/main/java/org/apache/shardingsphere/db/protocol/postgresql/packet/command/query/extended/PostgreSQLColumnType.java
+++ b/db-protocol/postgresql/src/main/java/org/apache/shardingsphere/db/protocol/postgresql/packet/command/query/extended/PostgreSQLColumnType.java
@@ -176,6 +176,8 @@ public enum PostgreSQLColumnType implements BinaryColumnType {
         JDBC_TYPE_AND_COLUMN_TYPE_MAP.put(Types.OTHER, POSTGRESQL_TYPE_JSON);
         JDBC_TYPE_AND_COLUMN_TYPE_MAP.put(Types.SQLXML, POSTGRESQL_TYPE_XML);
         JDBC_TYPE_AND_COLUMN_TYPE_MAP.put(Types.BOOLEAN, POSTGRESQL_TYPE_BOOL);
+        // TODO Temporary solution for https://github.com/apache/shardingsphere/issues/22522
+        JDBC_TYPE_AND_COLUMN_TYPE_MAP.put(Types.STRUCT, POSTGRESQL_TYPE_VARCHAR);
     }
     
     /**
diff --git a/proxy/frontend/postgresql/src/main/java/org/apache/shardingsphere/proxy/frontend/postgresql/command/query/extended/describe/PostgreSQLComDescribeExecutor.java b/proxy/frontend/postgresql/src/main/java/org/apache/shardingsphere/proxy/frontend/postgresql/command/query/extended/describe/PostgreSQLComDescribeExecutor.java
index dfcc56abc82..d1a6681a47d 100644
--- a/proxy/frontend/postgresql/src/main/java/org/apache/shardingsphere/proxy/frontend/postgresql/command/query/extended/describe/PostgreSQLComDescribeExecutor.java
+++ b/proxy/frontend/postgresql/src/main/java/org/apache/shardingsphere/proxy/frontend/postgresql/command/query/extended/describe/PostgreSQLComDescribeExecutor.java
@@ -196,9 +196,10 @@ public final class PostgreSQLComDescribeExecutor implements CommandExecutor {
                         .forEach(result::add);
             }
             if (each instanceof ColumnProjectionSegment) {
-                String columnName = ((ColumnProjectionSegment) each).getColumn().getIdentifier().getValue();
-                ShardingSphereColumn column = columnsOfTable.getOrDefault(columnName, caseInsensitiveColumnsOfTable.get(columnName));
-                String alias = ((ColumnProjectionSegment) each).getAlias().orElseGet(column::getName);
+                ColumnProjectionSegment segment = (ColumnProjectionSegment) each;
+                String columnName = segment.getColumn().getIdentifier().getValue();
+                ShardingSphereColumn column = columnsOfTable.getOrDefault(columnName, caseInsensitiveColumnsOfTable.getOrDefault(columnName, generateDefaultColumn(segment)));
+                String alias = segment.getAlias().orElseGet(column::getName);
                 result.add(new PostgreSQLColumnDescription(alias, 0, column.getDataType(), estimateColumnLength(column.getDataType()), ""));
             }
             if (each instanceof ExpressionProjectionSegment) {
@@ -208,6 +209,10 @@ public final class PostgreSQLComDescribeExecutor implements CommandExecutor {
         return new PostgreSQLRowDescriptionPacket(result);
     }
     
+    private ShardingSphereColumn generateDefaultColumn(final ColumnProjectionSegment segment) {
+        return new ShardingSphereColumn(segment.getColumn().getIdentifier().getValue(), Types.VARCHAR, false, false, false, true, false);
+    }
+    
     private PostgreSQLColumnDescription convertExpressionToDescription(final ExpressionProjectionSegment expressionProjectionSegment) {
         ExpressionSegment expressionSegment = expressionProjectionSegment.getExpr();
         String columnName = expressionProjectionSegment.getAlias().orElse(ANONYMOUS_COLUMN_NAME);
diff --git a/proxy/frontend/postgresql/src/test/java/org/apache/shardingsphere/proxy/frontend/postgresql/command/query/extended/describe/PostgreSQLComDescribeExecutorTest.java b/proxy/frontend/postgresql/src/test/java/org/apache/shardingsphere/proxy/frontend/postgresql/command/query/extended/describe/PostgreSQLComDescribeExecutorTest.java
index 51e23f5aead..34f17449482 100644
--- a/proxy/frontend/postgresql/src/test/java/org/apache/shardingsphere/proxy/frontend/postgresql/command/query/extended/describe/PostgreSQLComDescribeExecutorTest.java
+++ b/proxy/frontend/postgresql/src/test/java/org/apache/shardingsphere/proxy/frontend/postgresql/command/query/extended/describe/PostgreSQLComDescribeExecutorTest.java
@@ -255,7 +255,7 @@ public final class PostgreSQLComDescribeExecutorTest extends ProxyContextRestore
         final String statementId = "S_2";
         when(packet.getName()).thenReturn(statementId);
         String sql = "insert into t_order (k, c, pad) values (?, ?, ?) "
-                + "returning id, id alias_id, 'anonymous', 'OK' literal_string, 1 literal_int, 4294967296 literal_bigint, 1.1 literal_numeric, t_order.*";
+                + "returning id, id alias_id, 'anonymous', 'OK' literal_string, 1 literal_int, 4294967296 literal_bigint, 1.1 literal_numeric, t_order.*, t_order, t_order alias_t_order";
         SQLStatement sqlStatement = SQL_PARSER_ENGINE.parse(sql, false);
         List<PostgreSQLColumnType> parameterTypes = new ArrayList<>(sqlStatement.getParameterCount());
         for (int i = 0; i < sqlStatement.getParameterCount(); i++) {
@@ -275,8 +275,12 @@ public final class PostgreSQLComDescribeExecutorTest extends ProxyContextRestore
         verify(mockPayload, times(2)).writeInt4(18);
         DatabasePacket<?> actualRowDescriptionPacket = actualPacketsIterator.next();
         assertThat(actualRowDescriptionPacket, is(instanceOf(PostgreSQLRowDescriptionPacket.class)));
-        List<PostgreSQLColumnDescription> actualColumnDescriptions = new ArrayList<>(getColumnDescriptionsFromPacket((PostgreSQLRowDescriptionPacket) actualRowDescriptionPacket));
-        assertThat(actualColumnDescriptions.size(), is(11));
+        assertRowDescriptions((PostgreSQLRowDescriptionPacket) actualRowDescriptionPacket);
+    }
+    
+    private void assertRowDescriptions(final PostgreSQLRowDescriptionPacket actualRowDescriptionPacket) {
+        List<PostgreSQLColumnDescription> actualColumnDescriptions = new ArrayList<>(getColumnDescriptionsFromPacket(actualRowDescriptionPacket));
+        assertThat(actualColumnDescriptions.size(), is(13));
         assertThat(actualColumnDescriptions.get(0).getColumnName(), is("id"));
         assertThat(actualColumnDescriptions.get(0).getTypeOID(), is(PostgreSQLColumnType.POSTGRESQL_TYPE_INT4.getValue()));
         assertThat(actualColumnDescriptions.get(0).getColumnLength(), is(4));
@@ -310,6 +314,12 @@ public final class PostgreSQLComDescribeExecutorTest extends ProxyContextRestore
         assertThat(actualColumnDescriptions.get(10).getColumnName(), is("pad"));
         assertThat(actualColumnDescriptions.get(10).getTypeOID(), is(PostgreSQLColumnType.POSTGRESQL_TYPE_CHAR.getValue()));
         assertThat(actualColumnDescriptions.get(10).getColumnLength(), is(-1));
+        assertThat(actualColumnDescriptions.get(11).getColumnName(), is("t_order"));
+        assertThat(actualColumnDescriptions.get(11).getTypeOID(), is(PostgreSQLColumnType.POSTGRESQL_TYPE_VARCHAR.getValue()));
+        assertThat(actualColumnDescriptions.get(11).getColumnLength(), is(-1));
+        assertThat(actualColumnDescriptions.get(12).getColumnName(), is("alias_t_order"));
+        assertThat(actualColumnDescriptions.get(12).getTypeOID(), is(PostgreSQLColumnType.POSTGRESQL_TYPE_VARCHAR.getValue()));
+        assertThat(actualColumnDescriptions.get(12).getColumnLength(), is(-1));
     }
     
     @SuppressWarnings("unchecked")