未验证 提交 02b8b170 编写于 作者: J Juan Pan(Trista) 提交者: GitHub

Add exceptions for unsupported SQL, incomplete rules and other exceptions (#7054)

* Add exception for unsupported SQL, incomplete rules and other exceptions.

* check style
上级 398213ec
...@@ -46,6 +46,8 @@ public enum MySQLServerErrorCode implements SQLErrorCode { ...@@ -46,6 +46,8 @@ public enum MySQLServerErrorCode implements SQLErrorCode {
ER_TABLE_EXISTS_ERROR(1050, "42S01", "Table '%s' already exists"), ER_TABLE_EXISTS_ERROR(1050, "42S01", "Table '%s' already exists"),
ER_NOT_SUPPORTED_YET(1235, "42000", "This version of ShardingProxy doesn't yet support this SQL. '%s'"),
ER_ERROR_ON_MODIFYING_GTID_EXECUTED_TABLE(3176, "HY000", ER_ERROR_ON_MODIFYING_GTID_EXECUTED_TABLE(3176, "HY000",
"Please do not modify the %s table with an XA transaction. This is an internal system table used to store GTIDs for committed transactions. " "Please do not modify the %s table with an XA transaction. This is an internal system table used to store GTIDs for committed transactions. "
+ "Although modifying it can lead to an inconsistent GTID state, if neccessary you can modify it with a non-XA transaction."); + "Although modifying it can lead to an inconsistent GTID state, if neccessary you can modify it with a non-XA transaction.");
......
...@@ -19,6 +19,7 @@ package org.apache.shardingsphere.proxy.backend.communication.jdbc; ...@@ -19,6 +19,7 @@ package org.apache.shardingsphere.proxy.backend.communication.jdbc;
import lombok.RequiredArgsConstructor; import lombok.RequiredArgsConstructor;
import org.apache.shardingsphere.infra.callback.orchestration.MetaDataCallback; import org.apache.shardingsphere.infra.callback.orchestration.MetaDataCallback;
import org.apache.shardingsphere.infra.config.exception.ShardingSphereConfigurationException;
import org.apache.shardingsphere.infra.config.properties.ConfigurationPropertyKey; import org.apache.shardingsphere.infra.config.properties.ConfigurationPropertyKey;
import org.apache.shardingsphere.infra.executor.sql.QueryResult; import org.apache.shardingsphere.infra.executor.sql.QueryResult;
import org.apache.shardingsphere.infra.executor.sql.context.ExecutionContext; import org.apache.shardingsphere.infra.executor.sql.context.ExecutionContext;
...@@ -88,7 +89,8 @@ public final class JDBCDatabaseCommunicationEngine implements DatabaseCommunicat ...@@ -88,7 +89,8 @@ public final class JDBCDatabaseCommunicationEngine implements DatabaseCommunicat
SQLLogger.logSQL(sql, ProxySchemaContexts.getInstance().getSchemaContexts().getProps().<Boolean>getValue(ConfigurationPropertyKey.SQL_SIMPLE), executionContext); SQLLogger.logSQL(sql, ProxySchemaContexts.getInstance().getSchemaContexts().getProps().<Boolean>getValue(ConfigurationPropertyKey.SQL_SIMPLE), executionContext);
} }
return execute(executionContext); return execute(executionContext);
} catch (final TableExistsException | SQLException ex) { } catch (final TableExistsException | ShardingSphereConfigurationException | SQLException ex) {
// TODO Particular handling needed for `createTable` without shardingRule and dataNode.
return new ErrorResponse(ex); return new ErrorResponse(ex);
} }
} }
......
...@@ -22,6 +22,7 @@ import lombok.NoArgsConstructor; ...@@ -22,6 +22,7 @@ import lombok.NoArgsConstructor;
import org.apache.shardingsphere.db.protocol.error.CommonErrorCode; import org.apache.shardingsphere.db.protocol.error.CommonErrorCode;
import org.apache.shardingsphere.db.protocol.mysql.constant.MySQLServerErrorCode; import org.apache.shardingsphere.db.protocol.mysql.constant.MySQLServerErrorCode;
import org.apache.shardingsphere.db.protocol.mysql.packet.generic.MySQLErrPacket; import org.apache.shardingsphere.db.protocol.mysql.packet.generic.MySQLErrPacket;
import org.apache.shardingsphere.infra.config.exception.ShardingSphereConfigurationException;
import org.apache.shardingsphere.proxy.backend.exception.DBCreateExistsException; import org.apache.shardingsphere.proxy.backend.exception.DBCreateExistsException;
import org.apache.shardingsphere.proxy.backend.exception.NoDatabaseSelectedException; import org.apache.shardingsphere.proxy.backend.exception.NoDatabaseSelectedException;
import org.apache.shardingsphere.proxy.backend.exception.TableModifyInTransactionException; import org.apache.shardingsphere.proxy.backend.exception.TableModifyInTransactionException;
...@@ -29,6 +30,7 @@ import org.apache.shardingsphere.proxy.backend.exception.UnknownDatabaseExceptio ...@@ -29,6 +30,7 @@ import org.apache.shardingsphere.proxy.backend.exception.UnknownDatabaseExceptio
import org.apache.shardingsphere.proxy.backend.text.sctl.ShardingCTLErrorCode; import org.apache.shardingsphere.proxy.backend.text.sctl.ShardingCTLErrorCode;
import org.apache.shardingsphere.proxy.backend.text.sctl.exception.ShardingCTLException; import org.apache.shardingsphere.proxy.backend.text.sctl.exception.ShardingCTLException;
import org.apache.shardingsphere.sharding.route.engine.exception.TableExistsException; import org.apache.shardingsphere.sharding.route.engine.exception.TableExistsException;
import org.apache.shardingsphere.sql.parser.exception.SQLParsingException;
import java.sql.SQLException; import java.sql.SQLException;
...@@ -70,6 +72,9 @@ public final class MySQLErrPacketFactory { ...@@ -70,6 +72,9 @@ public final class MySQLErrPacketFactory {
if (cause instanceof TableExistsException) { if (cause instanceof TableExistsException) {
return new MySQLErrPacket(sequenceId, MySQLServerErrorCode.ER_TABLE_EXISTS_ERROR, ((TableExistsException) cause).getTableName()); return new MySQLErrPacket(sequenceId, MySQLServerErrorCode.ER_TABLE_EXISTS_ERROR, ((TableExistsException) cause).getTableName());
} }
if (cause instanceof ShardingSphereConfigurationException || cause instanceof SQLParsingException) {
return new MySQLErrPacket(sequenceId, MySQLServerErrorCode.ER_NOT_SUPPORTED_YET, cause.getMessage());
}
return new MySQLErrPacket(sequenceId, CommonErrorCode.UNKNOWN_EXCEPTION, cause.getMessage()); return new MySQLErrPacket(sequenceId, CommonErrorCode.UNKNOWN_EXCEPTION, cause.getMessage());
} }
} }
...@@ -80,7 +80,7 @@ public final class MySQLComStmtExecuteExecutor implements QueryCommandExecutor { ...@@ -80,7 +80,7 @@ public final class MySQLComStmtExecuteExecutor implements QueryCommandExecutor {
if (ProxySchemaContexts.getInstance().getSchemaContexts().isCircuitBreak()) { if (ProxySchemaContexts.getInstance().getSchemaContexts().isCircuitBreak()) {
return Collections.singletonList(new MySQLErrPacket(1, CommonErrorCode.CIRCUIT_BREAK_MODE)); return Collections.singletonList(new MySQLErrPacket(1, CommonErrorCode.CIRCUIT_BREAK_MODE));
} }
BackendResponse backendResponse = databaseCommunicationEngine.execute(); BackendResponse backendResponse = getBackendResponse();
if (backendResponse instanceof QueryResponse) { if (backendResponse instanceof QueryResponse) {
isQueryResponse = true; isQueryResponse = true;
return createQueryPacket((QueryResponse) backendResponse); return createQueryPacket((QueryResponse) backendResponse);
...@@ -93,6 +93,18 @@ public final class MySQLComStmtExecuteExecutor implements QueryCommandExecutor { ...@@ -93,6 +93,18 @@ public final class MySQLComStmtExecuteExecutor implements QueryCommandExecutor {
return Collections.singletonList(createErrorPacket(((ErrorResponse) backendResponse).getCause())); return Collections.singletonList(createErrorPacket(((ErrorResponse) backendResponse).getCause()));
} }
private BackendResponse getBackendResponse() {
BackendResponse result;
try {
result = databaseCommunicationEngine.execute();
// CHECKSTYLE:OFF
} catch (final Exception ex) {
// CHECKSTYLE:OFF
result = new ErrorResponse(ex);
}
return result;
}
private Collection<DatabasePacket<?>> createQueryPacket(final QueryResponse backendResponse) { private Collection<DatabasePacket<?>> createQueryPacket(final QueryResponse backendResponse) {
Collection<DatabasePacket<?>> result = new LinkedList<>(); Collection<DatabasePacket<?>> result = new LinkedList<>();
List<QueryHeader> queryHeader = backendResponse.getQueryHeaders(); List<QueryHeader> queryHeader = backendResponse.getQueryHeaders();
......
...@@ -76,7 +76,7 @@ public final class MySQLComQueryPacketExecutor implements QueryCommandExecutor { ...@@ -76,7 +76,7 @@ public final class MySQLComQueryPacketExecutor implements QueryCommandExecutor {
if (ProxySchemaContexts.getInstance().getSchemaContexts().isCircuitBreak()) { if (ProxySchemaContexts.getInstance().getSchemaContexts().isCircuitBreak()) {
return Collections.singletonList(new MySQLErrPacket(1, CommonErrorCode.CIRCUIT_BREAK_MODE)); return Collections.singletonList(new MySQLErrPacket(1, CommonErrorCode.CIRCUIT_BREAK_MODE));
} }
BackendResponse backendResponse = textProtocolBackendHandler.execute(); BackendResponse backendResponse = getBackendResponse();
if (backendResponse instanceof QueryResponse) { if (backendResponse instanceof QueryResponse) {
isQueryResponse = true; isQueryResponse = true;
return createQueryPackets((QueryResponse) backendResponse); return createQueryPackets((QueryResponse) backendResponse);
...@@ -89,6 +89,18 @@ public final class MySQLComQueryPacketExecutor implements QueryCommandExecutor { ...@@ -89,6 +89,18 @@ public final class MySQLComQueryPacketExecutor implements QueryCommandExecutor {
return Collections.singletonList(createErrorPacket(((ErrorResponse) backendResponse).getCause())); return Collections.singletonList(createErrorPacket(((ErrorResponse) backendResponse).getCause()));
} }
private BackendResponse getBackendResponse() {
BackendResponse result;
try {
result = textProtocolBackendHandler.execute();
// CHECKSTYLE:OFF
} catch (final Exception ex) {
// CHECKSTYLE:OFF
result = new ErrorResponse(ex);
}
return result;
}
private Collection<DatabasePacket<?>> createQueryPackets(final QueryResponse backendResponse) { private Collection<DatabasePacket<?>> createQueryPackets(final QueryResponse backendResponse) {
Collection<DatabasePacket<?>> result = new LinkedList<>(); Collection<DatabasePacket<?>> result = new LinkedList<>();
List<QueryHeader> queryHeader = backendResponse.getQueryHeaders(); List<QueryHeader> queryHeader = backendResponse.getQueryHeaders();
......
...@@ -94,7 +94,7 @@ public final class PostgreSQLComBindExecutor implements QueryCommandExecutor { ...@@ -94,7 +94,7 @@ public final class PostgreSQLComBindExecutor implements QueryCommandExecutor {
if (null == databaseCommunicationEngine) { if (null == databaseCommunicationEngine) {
return result; return result;
} }
BackendResponse backendResponse = databaseCommunicationEngine.execute(); BackendResponse backendResponse = getBackendResponse();
if (backendResponse instanceof QueryResponse) { if (backendResponse instanceof QueryResponse) {
createQueryPacket((QueryResponse) backendResponse).ifPresent(result::add); createQueryPacket((QueryResponse) backendResponse).ifPresent(result::add);
} }
...@@ -109,6 +109,18 @@ public final class PostgreSQLComBindExecutor implements QueryCommandExecutor { ...@@ -109,6 +109,18 @@ public final class PostgreSQLComBindExecutor implements QueryCommandExecutor {
return result; return result;
} }
private BackendResponse getBackendResponse() {
BackendResponse result;
try {
result = databaseCommunicationEngine.execute();
// CHECKSTYLE:OFF
} catch (final Exception ex) {
// CHECKSTYLE:OFF
result = new ErrorResponse(ex);
}
return result;
}
private Optional<PostgreSQLRowDescriptionPacket> createQueryPacket(final QueryResponse queryResponse) { private Optional<PostgreSQLRowDescriptionPacket> createQueryPacket(final QueryResponse queryResponse) {
List<PostgreSQLColumnDescription> columnDescriptions = getPostgreSQLColumnDescriptions(queryResponse); List<PostgreSQLColumnDescription> columnDescriptions = getPostgreSQLColumnDescriptions(queryResponse);
isQueryResponse = !columnDescriptions.isEmpty(); isQueryResponse = !columnDescriptions.isEmpty();
......
...@@ -73,7 +73,7 @@ public final class PostgreSQLComQueryExecutor implements QueryCommandExecutor { ...@@ -73,7 +73,7 @@ public final class PostgreSQLComQueryExecutor implements QueryCommandExecutor {
if (ProxySchemaContexts.getInstance().getSchemaContexts().isCircuitBreak()) { if (ProxySchemaContexts.getInstance().getSchemaContexts().isCircuitBreak()) {
return Collections.singletonList(new PostgreSQLErrorResponsePacket()); return Collections.singletonList(new PostgreSQLErrorResponsePacket());
} }
BackendResponse backendResponse = textProtocolBackendHandler.execute(); BackendResponse backendResponse = getBackendResponse();
if (backendResponse instanceof QueryResponse) { if (backendResponse instanceof QueryResponse) {
Optional<PostgreSQLRowDescriptionPacket> result = createQueryPacket((QueryResponse) backendResponse); Optional<PostgreSQLRowDescriptionPacket> result = createQueryPacket((QueryResponse) backendResponse);
return result.<List<DatabasePacket<?>>>map(Collections::singletonList).orElseGet(Collections::emptyList); return result.<List<DatabasePacket<?>>>map(Collections::singletonList).orElseGet(Collections::emptyList);
...@@ -86,6 +86,18 @@ public final class PostgreSQLComQueryExecutor implements QueryCommandExecutor { ...@@ -86,6 +86,18 @@ public final class PostgreSQLComQueryExecutor implements QueryCommandExecutor {
return Collections.singletonList(createErrorPacket((ErrorResponse) backendResponse)); return Collections.singletonList(createErrorPacket((ErrorResponse) backendResponse));
} }
private BackendResponse getBackendResponse() {
BackendResponse result;
try {
result = textProtocolBackendHandler.execute();
// CHECKSTYLE:OFF
} catch (final Exception ex) {
// CHECKSTYLE:OFF
result = new ErrorResponse(ex);
}
return result;
}
private Optional<PostgreSQLRowDescriptionPacket> createQueryPacket(final QueryResponse queryResponse) { private Optional<PostgreSQLRowDescriptionPacket> createQueryPacket(final QueryResponse queryResponse) {
List<PostgreSQLColumnDescription> columnDescriptions = getPostgreSQLColumnDescriptions(queryResponse); List<PostgreSQLColumnDescription> columnDescriptions = getPostgreSQLColumnDescriptions(queryResponse);
isQueryResponse = !columnDescriptions.isEmpty(); isQueryResponse = !columnDescriptions.isEmpty();
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册