You are viewing a plain text version of this content. The canonical link for it is here.
Posted to notifications@shardingsphere.apache.org by me...@apache.org on 2022/09/07 16:03:32 UTC

[shardingsphere] branch master updated: Add ColumnNotFoundException (#20864)

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

menghaoran 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 4d008b4d760 Add ColumnNotFoundException (#20864)
4d008b4d760 is described below

commit 4d008b4d760206a8f5612c2b7a20e711552095cb
Author: Liang Zhang <zh...@apache.org>
AuthorDate: Thu Sep 8 00:03:24 2022 +0800

    Add ColumnNotFoundException (#20864)
---
 .../metadata/ColumnNotFoundException.java          | 36 ++++++++++++++++++++++
 .../mapper/PostgreSQLDialectExceptionMapper.java   |  5 +++
 .../postgresql/vendor/PostgreSQLVendorError.java   |  2 +-
 .../handler/transaction/TransactionXAHandler.java  |  4 +--
 .../fixture/CallTimeRecordDataSource.java          |  2 +-
 .../describe/PostgreSQLComDescribeExecutor.java    | 13 +++-----
 .../PostgreSQLComDescribeExecutorTest.java         | 15 +++------
 7 files changed, 54 insertions(+), 23 deletions(-)

diff --git a/shardingsphere-dialect-exception/shardingsphere-postgresql-dialect-exception/src/main/java/org/apache/shardingsphere/dialect/postgresql/exception/metadata/ColumnNotFoundException.java b/shardingsphere-dialect-exception/shardingsphere-postgresql-dialect-exception/src/main/java/org/apache/shardingsphere/dialect/postgresql/exception/metadata/ColumnNotFoundException.java
new file mode 100644
index 00000000000..bfe13e798d3
--- /dev/null
+++ b/shardingsphere-dialect-exception/shardingsphere-postgresql-dialect-exception/src/main/java/org/apache/shardingsphere/dialect/postgresql/exception/metadata/ColumnNotFoundException.java
@@ -0,0 +1,36 @@
+/*
+ * 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.dialect.postgresql.exception.metadata;
+
+import lombok.Getter;
+import lombok.RequiredArgsConstructor;
+import org.apache.shardingsphere.dialect.exception.SQLDialectException;
+
+/**
+ * Column not found exception.
+ */
+@RequiredArgsConstructor
+@Getter
+public final class ColumnNotFoundException extends SQLDialectException {
+    
+    private static final long serialVersionUID = 1634603729199573437L;
+    
+    private final String tableName;
+    
+    private final String columnName;
+}
diff --git a/shardingsphere-dialect-exception/shardingsphere-postgresql-dialect-exception/src/main/java/org/apache/shardingsphere/dialect/postgresql/mapper/PostgreSQLDialectExceptionMapper.java b/shardingsphere-dialect-exception/shardingsphere-postgresql-dialect-exception/src/main/java/org/apache/shardingsphere/dialect/postgresql/mapper/PostgreSQLDialectExceptionMapper.java
index 407c3e130d1..a2ca4f392c4 100644
--- a/shardingsphere-dialect-exception/shardingsphere-postgresql-dialect-exception/src/main/java/org/apache/shardingsphere/dialect/postgresql/mapper/PostgreSQLDialectExceptionMapper.java
+++ b/shardingsphere-dialect-exception/shardingsphere-postgresql-dialect-exception/src/main/java/org/apache/shardingsphere/dialect/postgresql/mapper/PostgreSQLDialectExceptionMapper.java
@@ -29,6 +29,7 @@ import org.apache.shardingsphere.dialect.postgresql.exception.authority.EmptyUse
 import org.apache.shardingsphere.dialect.postgresql.exception.authority.InvalidPasswordException;
 import org.apache.shardingsphere.dialect.postgresql.exception.authority.PrivilegeNotGrantedException;
 import org.apache.shardingsphere.dialect.postgresql.exception.authority.UnknownUsernameException;
+import org.apache.shardingsphere.dialect.postgresql.exception.metadata.ColumnNotFoundException;
 import org.apache.shardingsphere.dialect.postgresql.exception.protocol.ProtocolViolationException;
 import org.apache.shardingsphere.dialect.postgresql.message.ServerErrorMessageBuilder;
 import org.apache.shardingsphere.dialect.postgresql.vendor.PostgreSQLVendorError;
@@ -82,6 +83,10 @@ public final class PostgreSQLDialectExceptionMapper implements SQLDialectExcepti
             ProtocolViolationException cause = (ProtocolViolationException) sqlDialectException;
             return new PSQLException(ServerErrorMessageBuilder.build("FATAL", PostgreSQLVendorError.PROTOCOL_VIOLATION, cause.getExpectedMessageType(), cause.getActualMessageType()));
         }
+        if (sqlDialectException instanceof ColumnNotFoundException) {
+            ColumnNotFoundException cause = (ColumnNotFoundException) sqlDialectException;
+            return new PSQLException(ServerErrorMessageBuilder.build("FATAL", PostgreSQLVendorError.UNDEFINED_COLUMN, cause.getTableName(), cause.getColumnName()));
+        }
         return new PSQLException(sqlDialectException.getMessage(), PSQLState.UNEXPECTED_ERROR);
     }
     
diff --git a/shardingsphere-dialect-exception/shardingsphere-postgresql-dialect-exception/src/main/java/org/apache/shardingsphere/dialect/postgresql/vendor/PostgreSQLVendorError.java b/shardingsphere-dialect-exception/shardingsphere-postgresql-dialect-exception/src/main/java/org/apache/shardingsphere/dialect/postgresql/vendor/PostgreSQLVendorError.java
index 078838d23e6..c2f1f3332ac 100644
--- a/shardingsphere-dialect-exception/shardingsphere-postgresql-dialect-exception/src/main/java/org/apache/shardingsphere/dialect/postgresql/vendor/PostgreSQLVendorError.java
+++ b/shardingsphere-dialect-exception/shardingsphere-postgresql-dialect-exception/src/main/java/org/apache/shardingsphere/dialect/postgresql/vendor/PostgreSQLVendorError.java
@@ -51,7 +51,7 @@ public enum PostgreSQLVendorError implements VendorError {
     
     INVALID_CATALOG_NAME(XOpenSQLState.INVALID_CATALOG_NAME, "database \"%s\" does not exist"),
     
-    UNDEFINED_COLUMN(PostgreSQLState.UNDEFINED_COLUMN, "undefined_column"),
+    UNDEFINED_COLUMN(PostgreSQLState.UNDEFINED_COLUMN, "Column \"%s\" of table \"%s\" does not exist"),
     
     DATA_SOURCE_REJECTED_CONNECTION_ATTEMPT(XOpenSQLState.DATA_SOURCE_REJECTED_CONNECTION_ATTEMPT, "server rejected establishment of sql connection"),
     
diff --git a/shardingsphere-proxy/shardingsphere-proxy-backend/src/main/java/org/apache/shardingsphere/proxy/backend/handler/transaction/TransactionXAHandler.java b/shardingsphere-proxy/shardingsphere-proxy-backend/src/main/java/org/apache/shardingsphere/proxy/backend/handler/transaction/TransactionXAHandler.java
index 97e12472264..d584f1256b9 100644
--- a/shardingsphere-proxy/shardingsphere-proxy-backend/src/main/java/org/apache/shardingsphere/proxy/backend/handler/transaction/TransactionXAHandler.java
+++ b/shardingsphere-proxy/shardingsphere-proxy-backend/src/main/java/org/apache/shardingsphere/proxy/backend/handler/transaction/TransactionXAHandler.java
@@ -71,8 +71,8 @@ public final class TransactionXAHandler implements ProxyBackendHandler {
             case "START":
             case "BEGIN":
                 /*
-                 * we have to let session occupy the thread when doing xa transaction.
-                 * according to https://dev.mysql.com/doc/refman/5.7/en/xa-states.html XA and local transactions are mutually exclusive
+                 * we have to let session occupy the thread when doing xa transaction. according to https://dev.mysql.com/doc/refman/5.7/en/xa-states.html XA and local transactions are mutually
+                 * exclusive
                  */
                 ShardingSpherePreconditions.checkState(!connectionSession.getTransactionStatus().isInTransaction(), new StartNestedXATransactionException());
                 ResponseHeader header = backendHandler.execute();
diff --git a/shardingsphere-proxy/shardingsphere-proxy-backend/src/test/java/org/apache/shardingsphere/proxy/backend/communication/jdbc/datasource/fixture/CallTimeRecordDataSource.java b/shardingsphere-proxy/shardingsphere-proxy-backend/src/test/java/org/apache/shardingsphere/proxy/backend/communication/jdbc/datasource/fixture/CallTimeRecordDataSource.java
index 32485101be3..be28af3c029 100644
--- a/shardingsphere-proxy/shardingsphere-proxy-backend/src/test/java/org/apache/shardingsphere/proxy/backend/communication/jdbc/datasource/fixture/CallTimeRecordDataSource.java
+++ b/shardingsphere-proxy/shardingsphere-proxy-backend/src/test/java/org/apache/shardingsphere/proxy/backend/communication/jdbc/datasource/fixture/CallTimeRecordDataSource.java
@@ -49,7 +49,7 @@ public final class CallTimeRecordDataSource implements DataSource, AutoCloseable
     @Override
     public Connection getConnection() throws SQLException {
         if (5 <= count.get()) {
-            throw new SQLException("data source is not enough");
+            throw new SQLException("Data source is not enough");
         }
         count.getAndIncrement();
         return new CallTimeRecordConnection();
diff --git a/shardingsphere-proxy/shardingsphere-proxy-frontend/shardingsphere-proxy-frontend-postgresql/src/main/java/org/apache/shardingsphere/proxy/frontend/postgresql/command/query/extended/describe/PostgreSQLComDescribeExecutor.java b/shardingsphere-proxy/shardingsphere-proxy-frontend/shardingsphere-proxy-frontend-postgresql/src/main/java/org/apache/shardingsphere/proxy/frontend/postgresql/command/query/extended/describe/PostgreSQLComDescribeExecutor.java
index 0ae26fb4549..a41ad946574 100644
--- a/shardingsphere-proxy/shardingsphere-proxy-frontend/shardingsphere-proxy-frontend-postgresql/src/main/java/org/apache/shardingsphere/proxy/frontend/postgresql/command/query/extended/describe/PostgreSQLComDescribeExecutor.java
+++ b/shardingsphere-proxy/shardingsphere-proxy-frontend/shardingsphere-proxy-frontend-postgresql/src/main/java/org/apache/shardingsphere/proxy/frontend/postgresql/command/query/extended/describe/PostgreSQLComDescribeExecutor.java
@@ -19,13 +19,13 @@ package org.apache.shardingsphere.proxy.frontend.postgresql.command.query.extend
 
 import lombok.RequiredArgsConstructor;
 import org.apache.shardingsphere.db.protocol.packet.DatabasePacket;
-import org.apache.shardingsphere.dialect.postgresql.vendor.PostgreSQLVendorError;
 import org.apache.shardingsphere.db.protocol.postgresql.packet.PostgreSQLPacket;
 import org.apache.shardingsphere.db.protocol.postgresql.packet.command.query.PostgreSQLColumnDescription;
 import org.apache.shardingsphere.db.protocol.postgresql.packet.command.query.PostgreSQLNoDataPacket;
 import org.apache.shardingsphere.db.protocol.postgresql.packet.command.query.PostgreSQLRowDescriptionPacket;
 import org.apache.shardingsphere.db.protocol.postgresql.packet.command.query.extended.PostgreSQLColumnType;
 import org.apache.shardingsphere.db.protocol.postgresql.packet.command.query.extended.describe.PostgreSQLComDescribePacket;
+import org.apache.shardingsphere.dialect.postgresql.exception.metadata.ColumnNotFoundException;
 import org.apache.shardingsphere.infra.binder.QueryContext;
 import org.apache.shardingsphere.infra.binder.SQLStatementContextFactory;
 import org.apache.shardingsphere.infra.binder.statement.SQLStatementContext;
@@ -37,6 +37,7 @@ import org.apache.shardingsphere.infra.executor.sql.execute.engine.ConnectionMod
 import org.apache.shardingsphere.infra.metadata.database.ShardingSphereDatabase;
 import org.apache.shardingsphere.infra.metadata.database.schema.decorator.model.ShardingSphereColumn;
 import org.apache.shardingsphere.infra.metadata.database.schema.decorator.model.ShardingSphereTable;
+import org.apache.shardingsphere.infra.util.exception.ShardingSpherePreconditions;
 import org.apache.shardingsphere.mode.metadata.MetaDataContexts;
 import org.apache.shardingsphere.proxy.backend.communication.jdbc.connection.JDBCBackendConnection;
 import org.apache.shardingsphere.proxy.backend.context.ProxyContext;
@@ -113,7 +114,7 @@ public final class PostgreSQLComDescribeExecutor implements CommandExecutor {
         tryDescribePreparedStatementByJDBC(preparedStatement);
     }
     
-    private void describeInsertStatementByDatabaseMetaData(final PostgreSQLPreparedStatement preparedStatement) throws SQLException {
+    private void describeInsertStatementByDatabaseMetaData(final PostgreSQLPreparedStatement preparedStatement) {
         if (!preparedStatement.describeRows().isPresent()) {
             // TODO Consider the SQL `insert into table (col) values ($1) returning id`
             preparedStatement.setRowDescription(PostgreSQLNoDataPacket.getInstance());
@@ -162,12 +163,8 @@ public final class PostgreSQLComDescribeExecutor implements CommandExecutor {
                     }
                     column = caseInsensitiveColumns.get(columnName);
                 }
-                if (null == column) {
-                    String reason = String.format("Column \"%s\" of relation \"%s\" does not exist. Please check the SQL or execute REFRESH TABLE METADATA.", columnName, logicTableName);
-                    throw new SQLException(reason, PostgreSQLVendorError.UNDEFINED_COLUMN.getSqlState().getValue());
-                }
-                PostgreSQLColumnType parameterType = PostgreSQLColumnType.valueOfJDBCType(column.getDataType());
-                preparedStatement.getParameterTypes().set(parameterMarkerIndex++, parameterType);
+                ShardingSpherePreconditions.checkState(null != column, new ColumnNotFoundException(logicTableName, columnName));
+                preparedStatement.getParameterTypes().set(parameterMarkerIndex++, PostgreSQLColumnType.valueOfJDBCType(column.getDataType()));
             }
         }
     }
diff --git a/shardingsphere-proxy/shardingsphere-proxy-frontend/shardingsphere-proxy-frontend-postgresql/src/test/java/org/apache/shardingsphere/proxy/frontend/postgresql/command/query/extended/describe/PostgreSQLComDescribeExecutorTest.java b/shardingsphere-proxy/shardingsphere-proxy-frontend/shardingsphere-proxy-frontend-postgresql/src/test/java/org/apache/shardingsphere/proxy/frontend/postgresql/command/query/extended/describe/PostgreSQLComDescribeExecutorTest.java
index 7049efa79ec..567df89a639 100644
--- a/shardingsphere-proxy/shardingsphere-proxy-frontend/shardingsphere-proxy-frontend-postgresql/src/test/java/org/apache/shardingsphere/proxy/frontend/postgresql/command/query/extended/describe/PostgreSQLComDescribeExecutorTest.java
+++ b/shardingsphere-proxy/shardingsphere-proxy-frontend/shardingsphere-proxy-frontend-postgresql/src/test/java/org/apache/shardingsphere/proxy/frontend/postgresql/command/query/extended/describe/PostgreSQLComDescribeExecutorTest.java
@@ -19,7 +19,6 @@ package org.apache.shardingsphere.proxy.frontend.postgresql.command.query.extend
 
 import lombok.SneakyThrows;
 import org.apache.shardingsphere.db.protocol.packet.DatabasePacket;
-import org.apache.shardingsphere.dialect.postgresql.vendor.PostgreSQLVendorError;
 import org.apache.shardingsphere.db.protocol.postgresql.packet.command.query.PostgreSQLColumnDescription;
 import org.apache.shardingsphere.db.protocol.postgresql.packet.command.query.PostgreSQLNoDataPacket;
 import org.apache.shardingsphere.db.protocol.postgresql.packet.command.query.PostgreSQLParameterDescriptionPacket;
@@ -27,6 +26,7 @@ import org.apache.shardingsphere.db.protocol.postgresql.packet.command.query.Pos
 import org.apache.shardingsphere.db.protocol.postgresql.packet.command.query.extended.PostgreSQLColumnType;
 import org.apache.shardingsphere.db.protocol.postgresql.packet.command.query.extended.describe.PostgreSQLComDescribePacket;
 import org.apache.shardingsphere.db.protocol.postgresql.payload.PostgreSQLPacketPayload;
+import org.apache.shardingsphere.dialect.postgresql.exception.metadata.ColumnNotFoundException;
 import org.apache.shardingsphere.infra.config.props.ConfigurationPropertyKey;
 import org.apache.shardingsphere.infra.database.type.dialect.PostgreSQLDatabaseType;
 import org.apache.shardingsphere.infra.executor.sql.execute.engine.ConnectionMode;
@@ -215,8 +215,8 @@ public final class PostgreSQLComDescribeExecutorTest extends ProxyContextRestore
         assertThat(actualPacketsIterator.next(), is(PostgreSQLNoDataPacket.getInstance()));
     }
     
-    @Test
-    public void assertDescribePreparedStatementInsertWithUndefinedColumns() {
+    @Test(expected = ColumnNotFoundException.class)
+    public void assertDescribePreparedStatementInsertWithUndefinedColumns() throws SQLException {
         when(packet.getType()).thenReturn('S');
         final String statementId = "S_2";
         when(packet.getName()).thenReturn(statementId);
@@ -227,14 +227,7 @@ public final class PostgreSQLComDescribeExecutorTest extends ProxyContextRestore
             parameterTypes.add(PostgreSQLColumnType.POSTGRESQL_TYPE_UNSPECIFIED);
         }
         connectionSession.getPreparedStatementRegistry().addPreparedStatement(statementId, new PostgreSQLPreparedStatement(sql, sqlStatement, null, parameterTypes));
-        SQLException actual = null;
-        try {
-            executor.execute();
-        } catch (final SQLException ex) {
-            actual = ex;
-        }
-        assertThat(actual.getSQLState(), is(PostgreSQLVendorError.UNDEFINED_COLUMN.getSqlState().getValue()));
-        assertThat(actual.getMessage(), is("Column \"undefined_column\" of relation \"t_order\" does not exist. Please check the SQL or execute REFRESH TABLE METADATA."));
+        executor.execute();
     }
     
     @Test