This is an automated email from the ASF dual-hosted git repository. zhangliang 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 302e0c7e2f9 Add DialectDatabaseMetaData.isSupportDDLInXATransaction() and isSupportMetaDataRefreshInTransaction() (#35105) 302e0c7e2f9 is described below commit 302e0c7e2f95620bef14f6752a35d2aa3a50f3e8 Author: Liang Zhang <zhangli...@apache.org> AuthorDate: Sat Mar 29 15:51:28 2025 +0800 Add DialectDatabaseMetaData.isSupportDDLInXATransaction() and isSupportMetaDataRefreshInTransaction() (#35105) * Add DialectDatabaseMetaData.isSupportDDLInXATransaction() and isSupportMetaDataRefreshInTransaction() * Add DialectDatabaseMetaData.isSupportDDLInXATransaction() and isSupportMetaDataRefreshInTransaction() * Add DialectDatabaseMetaData.isSupportDDLInXATransaction() and isSupportMetaDataRefreshInTransaction() * Add DialectDatabaseMetaData.isSupportDDLInXATransaction() and isSupportMetaDataRefreshInTransaction() --- .../metadata/database/DialectDatabaseMetaData.java | 14 ++++++-- .../database/OpenGaussDatabaseMetaData.java | 7 +++- .../database/PostgreSQLDatabaseMetaData.java | 7 +++- .../proxy/backend/connector/ProxySQLExecutor.java | 42 +++++++++++----------- 4 files changed, 44 insertions(+), 26 deletions(-) diff --git a/infra/database/core/src/main/java/org/apache/shardingsphere/infra/database/core/metadata/database/DialectDatabaseMetaData.java b/infra/database/core/src/main/java/org/apache/shardingsphere/infra/database/core/metadata/database/DialectDatabaseMetaData.java index 78b94a29031..00a2f9fa792 100644 --- a/infra/database/core/src/main/java/org/apache/shardingsphere/infra/database/core/metadata/database/DialectDatabaseMetaData.java +++ b/infra/database/core/src/main/java/org/apache/shardingsphere/infra/database/core/metadata/database/DialectDatabaseMetaData.java @@ -149,11 +149,21 @@ public interface DialectDatabaseMetaData extends DatabaseTypedSPI { } /** - * Whether support DDL in transaction. + * Whether support DDL in XA transaction. * * @return support or not */ - default boolean isSupportDDLInTransaction() { + default boolean isSupportDDLInXATransaction() { + return false; + } + + /** + * Whether support meta data refresh in transaction. + * + * @return support or not + */ + // TODO Investgate the reason of some databases cannot support meta data refreshed in transaction. The method should be removed finally after metadata refresh supported for all database. + default boolean isSupportMetaDataRefreshInTransaction() { return true; } } diff --git a/infra/database/type/opengauss/src/main/java/org/apache/shardingsphere/infra/database/opengauss/metadata/database/OpenGaussDatabaseMetaData.java b/infra/database/type/opengauss/src/main/java/org/apache/shardingsphere/infra/database/opengauss/metadata/database/OpenGaussDatabaseMetaData.java index b22b3448578..5062aa15965 100644 --- a/infra/database/type/opengauss/src/main/java/org/apache/shardingsphere/infra/database/opengauss/metadata/database/OpenGaussDatabaseMetaData.java +++ b/infra/database/type/opengauss/src/main/java/org/apache/shardingsphere/infra/database/opengauss/metadata/database/OpenGaussDatabaseMetaData.java @@ -99,7 +99,12 @@ public final class OpenGaussDatabaseMetaData implements DialectDatabaseMetaData } @Override - public boolean isSupportDDLInTransaction() { + public boolean isSupportDDLInXATransaction() { + return true; + } + + @Override + public boolean isSupportMetaDataRefreshInTransaction() { return false; } diff --git a/infra/database/type/postgresql/src/main/java/org/apache/shardingsphere/infra/database/postgresql/metadata/database/PostgreSQLDatabaseMetaData.java b/infra/database/type/postgresql/src/main/java/org/apache/shardingsphere/infra/database/postgresql/metadata/database/PostgreSQLDatabaseMetaData.java index 002bd2b8bea..f49552d7768 100644 --- a/infra/database/type/postgresql/src/main/java/org/apache/shardingsphere/infra/database/postgresql/metadata/database/PostgreSQLDatabaseMetaData.java +++ b/infra/database/type/postgresql/src/main/java/org/apache/shardingsphere/infra/database/postgresql/metadata/database/PostgreSQLDatabaseMetaData.java @@ -91,7 +91,12 @@ public final class PostgreSQLDatabaseMetaData implements DialectDatabaseMetaData } @Override - public boolean isSupportDDLInTransaction() { + public boolean isSupportDDLInXATransaction() { + return true; + } + + @Override + public boolean isSupportMetaDataRefreshInTransaction() { return false; } diff --git a/proxy/backend/core/src/main/java/org/apache/shardingsphere/proxy/backend/connector/ProxySQLExecutor.java b/proxy/backend/core/src/main/java/org/apache/shardingsphere/proxy/backend/connector/ProxySQLExecutor.java index 0b66fbcb808..393c23e1958 100644 --- a/proxy/backend/core/src/main/java/org/apache/shardingsphere/proxy/backend/connector/ProxySQLExecutor.java +++ b/proxy/backend/core/src/main/java/org/apache/shardingsphere/proxy/backend/connector/ProxySQLExecutor.java @@ -129,47 +129,45 @@ public final class ProxySQLExecutor { * @param executionContext execution context */ public void checkExecutePrerequisites(final ExecutionContext executionContext) { - ShardingSpherePreconditions.checkState(isValidExecutePrerequisites(executionContext), () -> new TableModifyInTransactionException(getTableName(executionContext))); + ShardingSpherePreconditions.checkState( + isValidExecutePrerequisites(executionContext.getSqlStatementContext().getSqlStatement()), () -> new TableModifyInTransactionException(getTableName(executionContext))); } - private boolean isValidExecutePrerequisites(final ExecutionContext executionContext) { - SQLStatement sqlStatement = executionContext.getSqlStatementContext().getSqlStatement(); - boolean isSupportDDLInTransaction = DatabaseTypedSPILoader.getService(DialectDatabaseMetaData.class, sqlStatement.getDatabaseType()).isSupportDDLInTransaction(); - if (isExecuteDDLInXATransaction(sqlStatement, isSupportDDLInTransaction)) { - return false; + private boolean isValidExecutePrerequisites(final SQLStatement sqlStatement) { + return !(sqlStatement instanceof DDLStatement) || isSupportDDLInTransaction((DDLStatement) sqlStatement); + } + + private boolean isSupportDDLInTransaction(final DDLStatement sqlStatement) { + DialectDatabaseMetaData dialectDatabaseMetaData = DatabaseTypedSPILoader.getService(DialectDatabaseMetaData.class, sqlStatement.getDatabaseType()); + boolean isDDLWithoutMetaDataChanged = isDDLWithoutMetaDataChanged(sqlStatement); + if (isInXATransaction()) { + return dialectDatabaseMetaData.isSupportDDLInXATransaction() && (isDDLWithoutMetaDataChanged || dialectDatabaseMetaData.isSupportMetaDataRefreshInTransaction()); } - if (isExecuteDDLInLocalTransaction(sqlStatement)) { - // TODO implement DDL statement commit/rollback in PostgreSQL/openGauss transaction - return isSupportedSQLStatement(sqlStatement) || isSupportDDLInTransaction; + if (isInLocalTransaction()) { + return dialectDatabaseMetaData.isSupportMetaDataRefreshInTransaction() || isDDLWithoutMetaDataChanged; } return true; } - private boolean isExecuteDDLInXATransaction(final SQLStatement sqlStatement, final boolean isSupportDDLInTransaction) { + private boolean isInXATransaction() { TransactionType transactionType = TransactionUtils.getTransactionType(databaseConnectionManager.getConnectionSession().getConnectionContext().getTransactionContext()); TransactionStatus transactionStatus = databaseConnectionManager.getConnectionSession().getTransactionStatus(); - return TransactionType.XA == transactionType && transactionStatus.isInTransaction() && isUnsupportedDDLStatement(sqlStatement, isSupportDDLInTransaction); + return TransactionType.XA == transactionType && transactionStatus.isInTransaction(); } - private boolean isExecuteDDLInLocalTransaction(final SQLStatement sqlStatement) { - return sqlStatement instanceof DDLStatement && databaseConnectionManager.getConnectionSession().getTransactionStatus().isInTransaction(); + private boolean isInLocalTransaction() { + return databaseConnectionManager.getConnectionSession().getTransactionStatus().isInTransaction(); } - private boolean isSupportedSQLStatement(final SQLStatement sqlStatement) { + // TODO should be removed after metadata refresh supported for all database. + private boolean isDDLWithoutMetaDataChanged(final DDLStatement sqlStatement) { return isCursorStatement(sqlStatement) || sqlStatement instanceof TruncateStatement; } - private boolean isCursorStatement(final SQLStatement sqlStatement) { + private boolean isCursorStatement(final DDLStatement sqlStatement) { return sqlStatement instanceof OpenGaussCursorStatement || sqlStatement instanceof CloseStatement || sqlStatement instanceof MoveStatement || sqlStatement instanceof FetchStatement; } - private boolean isUnsupportedDDLStatement(final SQLStatement sqlStatement, final boolean isSupportDDLInTransaction) { - if (!isSupportDDLInTransaction && isSupportedSQLStatement(sqlStatement)) { - return false; - } - return sqlStatement instanceof DDLStatement; - } - private String getTableName(final ExecutionContext executionContext) { return executionContext.getSqlStatementContext() instanceof TableAvailable && !((TableAvailable) executionContext.getSqlStatementContext()).getTablesContext().getSimpleTables().isEmpty() ? ((TableAvailable) executionContext.getSqlStatementContext()).getTablesContext().getSimpleTables().iterator().next().getTableName().getIdentifier().getValue()