You are viewing a plain text version of this content. The canonical link for it is here.
Posted to notifications@shardingsphere.apache.org by du...@apache.org on 2023/06/01 10:36:13 UTC

[shardingsphere] branch master updated: Fix sonar issues on Reduce the number of conditional operators (#25991)

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

duanzhengqiang 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 828419698c1 Fix sonar issues on Reduce the number of conditional operators (#25991)
828419698c1 is described below

commit 828419698c1c38f830663f3411ac8c8305d3e792
Author: Liang Zhang <zh...@apache.org>
AuthorDate: Thu Jun 1 18:36:05 2023 +0800

    Fix sonar issues on Reduce the number of conditional operators (#25991)
    
    * Fix sonar issue on ShowShardingTableRulesUsedAlgorithmExecutor
    
    * Fix sonar issue on DropBroadcastTableRuleStatementUpdater
    
    * Fix sonar issue on DropDefaultStrategyStatementUpdater
    
    * Fix sonar issue on DropShardingTableRuleStatementUpdater
    
    * Fix sonar issue on MemoryMergedResult
    
    * Fix sonar issue on ShardingSpherePreparedStatement
    
    * Fix sonar issue on ShardingSphereStatement
    
    * Fix sonar issue on PostgreSQLColumnPropertiesAppender
    
    * Fix sonar issue on SQLFederationResultSet
    
    * Fix sonar issue on MetaDataChangedWatcher
    
    * Fix sonar issue on JDBCRepositorySQLLoader
    
    * Fix sonar issue on MySQLFormatVisitor
    
    * Fix sonar issue on ReadOnlyProxyState and UnavailableProxyState
    
    * Fix sonar issue on MySQLSetCharsetExecutor
    
    * Fix sonar issue on PostgreSQLCharacterSets
    
    * Fix sonar issue on MySQLComQueryPacketExecutor
    
    * Add SQLLineComment
    
    * Fix code format
    
    * Fix code format
---
 ...howShardingTableRulesUsedAlgorithmExecutor.java | 30 ++++++++++--
 .../DropBroadcastTableRuleStatementUpdater.java    | 11 ++++-
 .../DropDefaultStrategyStatementUpdater.java       | 11 ++++-
 .../DropShardingTableRuleStatementUpdater.java     | 11 ++++-
 .../result/impl/memory/MemoryMergedResult.java     |  8 +++-
 .../jdbc/adapter/AbstractStatementAdapter.java     | 55 +++++++++++++++-------
 .../statement/ShardingSpherePreparedStatement.java | 16 +------
 .../core/statement/ShardingSphereStatement.java    | 16 +------
 .../PostgreSQLColumnPropertiesAppender.java        | 10 ++--
 .../advanced/resultset/SQLFederationResultSet.java |  9 ++--
 .../metadata/watcher/MetaDataChangedWatcher.java   | 12 ++++-
 .../jdbc/sql/JDBCRepositorySQLLoader.java          | 21 ++-------
 .../mysql/visitor/format/MySQLFormatVisitor.java   | 18 +++++--
 .../parser/sql/common/enums/QuoteCharacter.java    | 10 ++++
 .../sql/common/enums/QuoteCharacterTest.java       | 12 +++++
 .../handler/ProxyBackendHandlerFactory.java        |  2 +-
 .../backend/state/{spi => }/ProxyClusterState.java |  2 +-
 .../state/SupportedSQLStatementJudgeEngine.java    | 54 +++++++++++++++++++++
 .../backend/state/impl/ReadOnlyProxyState.java     | 24 ++++++----
 .../backend/state/impl/UnavailableProxyState.java  | 26 ++++++----
 ...ngsphere.proxy.backend.state.ProxyClusterState} |  0
 .../SupportedSQLStatementJudgeEngineTest.java      | 53 +++++++++++++++++++++
 .../admin/executor/MySQLSetCharsetExecutor.java    |  3 +-
 .../handler/admin/PostgreSQLCharacterSets.java     |  4 +-
 .../text/query/MySQLComQueryPacketExecutor.java    | 11 ++++-
 .../loader/DefaultExternalTestParameterLoader.java |  6 +--
 .../loader/ExternalMySQLTestParameterLoader.java   |  6 +--
 .../sql/parser/external/loader/SQLLineComment.java | 26 ++++++----
 28 files changed, 339 insertions(+), 128 deletions(-)

diff --git a/features/sharding/distsql/handler/src/main/java/org/apache/shardingsphere/sharding/distsql/handler/query/ShowShardingTableRulesUsedAlgorithmExecutor.java b/features/sharding/distsql/handler/src/main/java/org/apache/shardingsphere/sharding/distsql/handler/query/ShowShardingTableRulesUsedAlgorithmExecutor.java
index 8b47f2ee42b..67b5d4fbb76 100644
--- a/features/sharding/distsql/handler/src/main/java/org/apache/shardingsphere/sharding/distsql/handler/query/ShowShardingTableRulesUsedAlgorithmExecutor.java
+++ b/features/sharding/distsql/handler/src/main/java/org/apache/shardingsphere/sharding/distsql/handler/query/ShowShardingTableRulesUsedAlgorithmExecutor.java
@@ -21,6 +21,7 @@ import org.apache.shardingsphere.distsql.handler.query.RQLExecutor;
 import org.apache.shardingsphere.infra.merge.result.impl.local.LocalDataQueryResultRow;
 import org.apache.shardingsphere.infra.metadata.database.ShardingSphereDatabase;
 import org.apache.shardingsphere.sharding.api.config.ShardingRuleConfiguration;
+import org.apache.shardingsphere.sharding.api.config.rule.ShardingTableRuleConfiguration;
 import org.apache.shardingsphere.sharding.distsql.parser.statement.ShowShardingTableRulesUsedAlgorithmStatement;
 import org.apache.shardingsphere.sharding.rule.ShardingRule;
 
@@ -53,10 +54,7 @@ public final class ShowShardingTableRulesUsedAlgorithmExecutor implements RQLExe
         boolean matchDefaultTableShardingStrategy = null != config.getDefaultTableShardingStrategy()
                 && algorithmName.equals(config.getDefaultTableShardingStrategy().getShardingAlgorithmName());
         config.getTables().forEach(each -> {
-            if (null == each.getDatabaseShardingStrategy() && matchDefaultDatabaseShardingStrategy
-                    || null != each.getDatabaseShardingStrategy() && algorithmName.equals(each.getDatabaseShardingStrategy().getShardingAlgorithmName())
-                    || null == each.getTableShardingStrategy() && matchDefaultTableShardingStrategy
-                    || null != each.getTableShardingStrategy() && algorithmName.equals(each.getTableShardingStrategy().getShardingAlgorithmName())) {
+            if (isMatchDatabaseShardingStrategy(each, algorithmName, matchDefaultDatabaseShardingStrategy) || isMatchTableShardingStrategy(each, algorithmName, matchDefaultTableShardingStrategy)) {
                 result.add(new LocalDataQueryResultRow("table", each.getLogicTable()));
             }
         });
@@ -67,6 +65,30 @@ public final class ShowShardingTableRulesUsedAlgorithmExecutor implements RQLExe
         });
     }
     
+    private boolean isMatchDatabaseShardingStrategy(final ShardingTableRuleConfiguration tableRuleConfig, final String algorithmName, final boolean matchDefaultDatabaseShardingStrategy) {
+        return isMatchDatabaseShardingStrategy(tableRuleConfig, algorithmName) || isMatchDefaultDatabaseShardingStrategy(tableRuleConfig, matchDefaultDatabaseShardingStrategy);
+    }
+    
+    private boolean isMatchDatabaseShardingStrategy(final ShardingTableRuleConfiguration tableRuleConfig, final String algorithmName) {
+        return null != tableRuleConfig.getDatabaseShardingStrategy() && algorithmName.equals(tableRuleConfig.getDatabaseShardingStrategy().getShardingAlgorithmName());
+    }
+    
+    private boolean isMatchDefaultDatabaseShardingStrategy(final ShardingTableRuleConfiguration tableRuleConfig, final boolean matchDefaultDatabaseShardingStrategy) {
+        return null == tableRuleConfig.getDatabaseShardingStrategy() && matchDefaultDatabaseShardingStrategy;
+    }
+    
+    private boolean isMatchTableShardingStrategy(final ShardingTableRuleConfiguration tableRuleConfig, final String algorithmName, final boolean matchDefaultTableShardingStrategy) {
+        return isMatchTableShardingStrategy(tableRuleConfig, algorithmName) || isMatchDefaultTableShardingStrategy(tableRuleConfig, matchDefaultTableShardingStrategy);
+    }
+    
+    private boolean isMatchTableShardingStrategy(final ShardingTableRuleConfiguration tableRuleConfig, final String algorithmName) {
+        return null != tableRuleConfig.getTableShardingStrategy() && algorithmName.equals(tableRuleConfig.getTableShardingStrategy().getShardingAlgorithmName());
+    }
+    
+    private boolean isMatchDefaultTableShardingStrategy(final ShardingTableRuleConfiguration tableRuleConfig, final boolean matchDefaultTableShardingStrategy) {
+        return null == tableRuleConfig.getTableShardingStrategy() && matchDefaultTableShardingStrategy;
+    }
+    
     @Override
     public Collection<String> getColumnNames() {
         return Arrays.asList("type", "name");
diff --git a/features/sharding/distsql/handler/src/main/java/org/apache/shardingsphere/sharding/distsql/handler/update/DropBroadcastTableRuleStatementUpdater.java b/features/sharding/distsql/handler/src/main/java/org/apache/shardingsphere/sharding/distsql/handler/update/DropBroadcastTableRuleStatementUpdater.java
index 34675e52679..9c23a67c305 100644
--- a/features/sharding/distsql/handler/src/main/java/org/apache/shardingsphere/sharding/distsql/handler/update/DropBroadcastTableRuleStatementUpdater.java
+++ b/features/sharding/distsql/handler/src/main/java/org/apache/shardingsphere/sharding/distsql/handler/update/DropBroadcastTableRuleStatementUpdater.java
@@ -68,8 +68,15 @@ public final class DropBroadcastTableRuleStatementUpdater implements RuleDefinit
     @Override
     public boolean updateCurrentRuleConfiguration(final DropBroadcastTableRuleStatement sqlStatement, final ShardingRuleConfiguration currentRuleConfig) {
         currentRuleConfig.getBroadcastTables().removeIf(each -> containsIgnoreCase(sqlStatement.getTables(), each));
-        return currentRuleConfig.getTables().isEmpty() && currentRuleConfig.getAutoTables().isEmpty() && currentRuleConfig.getBroadcastTables().isEmpty()
-                && null == currentRuleConfig.getDefaultDatabaseShardingStrategy() && null == currentRuleConfig.getDefaultTableShardingStrategy();
+        return isEmptyShardingTables(currentRuleConfig) && currentRuleConfig.getBroadcastTables().isEmpty() && isEmptyShardingStrategy(currentRuleConfig);
+    }
+    
+    private boolean isEmptyShardingTables(final ShardingRuleConfiguration currentRuleConfig) {
+        return currentRuleConfig.getTables().isEmpty() && currentRuleConfig.getAutoTables().isEmpty();
+    }
+    
+    private boolean isEmptyShardingStrategy(final ShardingRuleConfiguration currentRuleConfig) {
+        return null == currentRuleConfig.getDefaultDatabaseShardingStrategy() && null == currentRuleConfig.getDefaultTableShardingStrategy();
     }
     
     @Override
diff --git a/features/sharding/distsql/handler/src/main/java/org/apache/shardingsphere/sharding/distsql/handler/update/DropDefaultStrategyStatementUpdater.java b/features/sharding/distsql/handler/src/main/java/org/apache/shardingsphere/sharding/distsql/handler/update/DropDefaultStrategyStatementUpdater.java
index deae1b60465..7a8b203a17d 100644
--- a/features/sharding/distsql/handler/src/main/java/org/apache/shardingsphere/sharding/distsql/handler/update/DropDefaultStrategyStatementUpdater.java
+++ b/features/sharding/distsql/handler/src/main/java/org/apache/shardingsphere/sharding/distsql/handler/update/DropDefaultStrategyStatementUpdater.java
@@ -80,8 +80,15 @@ public final class DropDefaultStrategyStatementUpdater implements RuleDefinition
             currentRuleConfig.setDefaultDatabaseShardingStrategy(null);
         }
         UnusedAlgorithmFinder.find(currentRuleConfig).forEach(each -> currentRuleConfig.getShardingAlgorithms().remove(each));
-        return currentRuleConfig.getTables().isEmpty() && currentRuleConfig.getAutoTables().isEmpty() && currentRuleConfig.getBroadcastTables().isEmpty()
-                && null == currentRuleConfig.getDefaultDatabaseShardingStrategy() && null == currentRuleConfig.getDefaultTableShardingStrategy();
+        return isEmptyShardingTables(currentRuleConfig) && currentRuleConfig.getBroadcastTables().isEmpty() && isEmptyShardingStrategy(currentRuleConfig);
+    }
+    
+    private boolean isEmptyShardingTables(final ShardingRuleConfiguration currentRuleConfig) {
+        return currentRuleConfig.getTables().isEmpty() && currentRuleConfig.getAutoTables().isEmpty();
+    }
+    
+    private boolean isEmptyShardingStrategy(final ShardingRuleConfiguration currentRuleConfig) {
+        return null == currentRuleConfig.getDefaultDatabaseShardingStrategy() && null == currentRuleConfig.getDefaultTableShardingStrategy();
     }
     
     @Override
diff --git a/features/sharding/distsql/handler/src/main/java/org/apache/shardingsphere/sharding/distsql/handler/update/DropShardingTableRuleStatementUpdater.java b/features/sharding/distsql/handler/src/main/java/org/apache/shardingsphere/sharding/distsql/handler/update/DropShardingTableRuleStatementUpdater.java
index e75d666d357..69c30022cd1 100644
--- a/features/sharding/distsql/handler/src/main/java/org/apache/shardingsphere/sharding/distsql/handler/update/DropShardingTableRuleStatementUpdater.java
+++ b/features/sharding/distsql/handler/src/main/java/org/apache/shardingsphere/sharding/distsql/handler/update/DropShardingTableRuleStatementUpdater.java
@@ -112,8 +112,7 @@ public final class DropShardingTableRuleStatementUpdater implements RuleDefiniti
         UnusedAlgorithmFinder.find(currentRuleConfig).forEach(each -> currentRuleConfig.getShardingAlgorithms().remove(each));
         dropUnusedKeyGenerator(currentRuleConfig);
         dropUnusedAuditor(currentRuleConfig);
-        return currentRuleConfig.getTables().isEmpty() && currentRuleConfig.getAutoTables().isEmpty() && currentRuleConfig.getBroadcastTables().isEmpty()
-                && null == currentRuleConfig.getDefaultDatabaseShardingStrategy() && null == currentRuleConfig.getDefaultTableShardingStrategy();
+        return isEmptyShardingTables(currentRuleConfig) && currentRuleConfig.getBroadcastTables().isEmpty() && isEmptyShardingStrategy(currentRuleConfig);
     }
     
     private void dropShardingTable(final ShardingRuleConfiguration currentRuleConfig, final String tableName) {
@@ -149,6 +148,14 @@ public final class DropShardingTableRuleStatementUpdater implements RuleDefiniti
         unusedAuditors.forEach(each -> currentRuleConfig.getAuditors().remove(each));
     }
     
+    private boolean isEmptyShardingTables(final ShardingRuleConfiguration currentRuleConfig) {
+        return currentRuleConfig.getTables().isEmpty() && currentRuleConfig.getAutoTables().isEmpty();
+    }
+    
+    private boolean isEmptyShardingStrategy(final ShardingRuleConfiguration currentRuleConfig) {
+        return null == currentRuleConfig.getDefaultDatabaseShardingStrategy() && null == currentRuleConfig.getDefaultTableShardingStrategy();
+    }
+    
     @Override
     public Class<ShardingRuleConfiguration> getRuleConfigurationClass() {
         return ShardingRuleConfiguration.class;
diff --git a/infra/merge/src/main/java/org/apache/shardingsphere/infra/merge/result/impl/memory/MemoryMergedResult.java b/infra/merge/src/main/java/org/apache/shardingsphere/infra/merge/result/impl/memory/MemoryMergedResult.java
index d0d874db5a9..ff3b0b06bd3 100644
--- a/infra/merge/src/main/java/org/apache/shardingsphere/infra/merge/result/impl/memory/MemoryMergedResult.java
+++ b/infra/merge/src/main/java/org/apache/shardingsphere/infra/merge/result/impl/memory/MemoryMergedResult.java
@@ -31,7 +31,10 @@ import java.sql.Clob;
 import java.sql.SQLException;
 import java.sql.SQLFeatureNotSupportedException;
 import java.sql.SQLXML;
+import java.util.Arrays;
 import java.util.Calendar;
+import java.util.Collection;
+import java.util.HashSet;
 import java.util.Iterator;
 import java.util.List;
 
@@ -42,6 +45,8 @@ import java.util.List;
  */
 public abstract class MemoryMergedResult<T extends ShardingSphereRule> implements MergedResult {
     
+    private static final Collection<Class<?>> INVALID_MEMORY_TYPES = new HashSet<>(Arrays.asList(Blob.class, Clob.class, Reader.class, InputStream.class, SQLXML.class));
+    
     private final Iterator<MemoryQueryResultRow> memoryResultSetRows;
     
     private MemoryQueryResultRow currentResultSetRow;
@@ -69,8 +74,7 @@ public abstract class MemoryMergedResult<T extends ShardingSphereRule> implement
     
     @Override
     public final Object getValue(final int columnIndex, final Class<?> type) throws SQLException {
-        ShardingSpherePreconditions.checkState(Blob.class != type && Clob.class != type && Reader.class != type && InputStream.class != type && SQLXML.class != type,
-                () -> new SQLFeatureNotSupportedException(String.format("Get value from `%s`", type.getName())));
+        ShardingSpherePreconditions.checkState(!INVALID_MEMORY_TYPES.contains(type), () -> new SQLFeatureNotSupportedException(String.format("Get value from `%s`", type.getName())));
         Object result = currentResultSetRow.getCell(columnIndex);
         wasNull = null == result;
         return result;
diff --git a/jdbc/core/src/main/java/org/apache/shardingsphere/driver/jdbc/adapter/AbstractStatementAdapter.java b/jdbc/core/src/main/java/org/apache/shardingsphere/driver/jdbc/adapter/AbstractStatementAdapter.java
index e4df3748b22..c82c3ea0d40 100644
--- a/jdbc/core/src/main/java/org/apache/shardingsphere/driver/jdbc/adapter/AbstractStatementAdapter.java
+++ b/jdbc/core/src/main/java/org/apache/shardingsphere/driver/jdbc/adapter/AbstractStatementAdapter.java
@@ -26,7 +26,13 @@ import org.apache.shardingsphere.driver.jdbc.core.statement.StatementManager;
 import org.apache.shardingsphere.driver.jdbc.unsupported.AbstractUnsupportedOperationStatement;
 import org.apache.shardingsphere.infra.database.type.DatabaseType;
 import org.apache.shardingsphere.infra.database.type.SchemaSupportedDatabaseType;
+import org.apache.shardingsphere.infra.executor.sql.context.ExecutionContext;
 import org.apache.shardingsphere.mode.metadata.MetaDataContexts;
+import org.apache.shardingsphere.sql.parser.sql.common.statement.SQLStatement;
+import org.apache.shardingsphere.sql.parser.sql.common.statement.dml.DMLStatement;
+import org.apache.shardingsphere.sql.parser.sql.common.statement.dml.SelectStatement;
+import org.apache.shardingsphere.transaction.ConnectionTransaction;
+import org.apache.shardingsphere.transaction.api.TransactionType;
 
 import java.sql.SQLException;
 import java.sql.SQLWarning;
@@ -50,6 +56,38 @@ public abstract class AbstractStatementAdapter extends AbstractUnsupportedOperat
     
     private boolean closed;
     
+    protected final boolean isNeedImplicitCommitTransaction(final ShardingSphereConnection connection, final ExecutionContext executionContext) {
+        return isInDistributedTransaction(connection) && isModifiedSQL(executionContext) && executionContext.getExecutionUnits().size() > 1;
+    }
+    
+    private boolean isInDistributedTransaction(final ShardingSphereConnection connection) {
+        ConnectionTransaction connectionTransaction = connection.getDatabaseConnectionManager().getConnectionTransaction();
+        boolean isInTransaction = connection.getDatabaseConnectionManager().getConnectionContext().getTransactionContext().isInTransaction();
+        return TransactionType.isDistributedTransaction(connectionTransaction.getTransactionType()) && !isInTransaction;
+    }
+    
+    private boolean isModifiedSQL(final ExecutionContext executionContext) {
+        SQLStatement sqlStatement = executionContext.getSqlStatementContext().getSqlStatement();
+        return sqlStatement instanceof DMLStatement && !(sqlStatement instanceof SelectStatement);
+    }
+    
+    protected final void handleExceptionInTransaction(final ShardingSphereConnection connection, final MetaDataContexts metaDataContexts) {
+        if (connection.getDatabaseConnectionManager().getConnectionTransaction().isInTransaction()) {
+            DatabaseType databaseType = metaDataContexts.getMetaData().getDatabase(connection.getDatabaseName()).getProtocolType();
+            if (databaseType instanceof SchemaSupportedDatabaseType) {
+                connection.getDatabaseConnectionManager().getConnectionTransaction().setRollbackOnly(true);
+            }
+        }
+    }
+    
+    protected abstract boolean isAccumulate();
+    
+    protected abstract Collection<? extends Statement> getRoutedStatements();
+    
+    protected abstract DriverExecutor getExecutor();
+    
+    protected abstract StatementManager getStatementManager();
+    
     @SuppressWarnings({"unchecked", "rawtypes"})
     @Override
     public final void setPoolable(final boolean poolable) throws SQLException {
@@ -191,21 +229,4 @@ public abstract class AbstractStatementAdapter extends AbstractUnsupportedOperat
             getRoutedStatements().clear();
         }
     }
-    
-    protected final void handleExceptionInTransaction(final ShardingSphereConnection connection, final MetaDataContexts metaDataContexts) {
-        if (connection.getDatabaseConnectionManager().getConnectionTransaction().isInTransaction()) {
-            DatabaseType databaseType = metaDataContexts.getMetaData().getDatabase(connection.getDatabaseName()).getProtocolType();
-            if (databaseType instanceof SchemaSupportedDatabaseType) {
-                connection.getDatabaseConnectionManager().getConnectionTransaction().setRollbackOnly(true);
-            }
-        }
-    }
-    
-    protected abstract boolean isAccumulate();
-    
-    protected abstract Collection<? extends Statement> getRoutedStatements();
-    
-    protected abstract DriverExecutor getExecutor();
-    
-    protected abstract StatementManager getStatementManager();
 }
diff --git a/jdbc/core/src/main/java/org/apache/shardingsphere/driver/jdbc/core/statement/ShardingSpherePreparedStatement.java b/jdbc/core/src/main/java/org/apache/shardingsphere/driver/jdbc/core/statement/ShardingSpherePreparedStatement.java
index 49e6dbea5f4..596301cd447 100644
--- a/jdbc/core/src/main/java/org/apache/shardingsphere/driver/jdbc/core/statement/ShardingSpherePreparedStatement.java
+++ b/jdbc/core/src/main/java/org/apache/shardingsphere/driver/jdbc/core/statement/ShardingSpherePreparedStatement.java
@@ -88,14 +88,10 @@ import org.apache.shardingsphere.mode.metadata.MetaDataContexts;
 import org.apache.shardingsphere.parser.rule.SQLParserRule;
 import org.apache.shardingsphere.sql.parser.sql.common.statement.SQLStatement;
 import org.apache.shardingsphere.sql.parser.sql.common.statement.dal.DALStatement;
-import org.apache.shardingsphere.sql.parser.sql.common.statement.dml.DMLStatement;
-import org.apache.shardingsphere.sql.parser.sql.common.statement.dml.SelectStatement;
 import org.apache.shardingsphere.sqlfederation.spi.SQLFederationExecutorContext;
 import org.apache.shardingsphere.traffic.engine.TrafficEngine;
 import org.apache.shardingsphere.traffic.exception.metadata.EmptyTrafficExecutionUnitException;
 import org.apache.shardingsphere.traffic.rule.TrafficRule;
-import org.apache.shardingsphere.transaction.ConnectionTransaction;
-import org.apache.shardingsphere.transaction.api.TransactionType;
 
 import java.sql.Connection;
 import java.sql.ParameterMetaData;
@@ -374,7 +370,7 @@ public final class ShardingSpherePreparedStatement extends AbstractPreparedState
                 Collection<ExecuteResult> executeResults = executor.getRawExecutor().execute(createRawExecutionGroupContext(), executionContext.getQueryContext(), new RawSQLExecutorCallback());
                 return accumulate(executeResults);
             }
-            return isNeedImplicitCommitTransaction(executionContext) ? executeUpdateWithImplicitCommitTransaction() : useDriverToExecuteUpdate();
+            return isNeedImplicitCommitTransaction(connection, executionContext) ? executeUpdateWithImplicitCommitTransaction() : useDriverToExecuteUpdate();
             // CHECKSTYLE:OFF
         } catch (final RuntimeException ex) {
             // CHECKSTYLE:ON
@@ -443,7 +439,7 @@ public final class ShardingSpherePreparedStatement extends AbstractPreparedState
                 Collection<ExecuteResult> executeResults = executor.getRawExecutor().execute(createRawExecutionGroupContext(), executionContext.getQueryContext(), new RawSQLExecutorCallback());
                 return executeResults.iterator().next() instanceof QueryResult;
             }
-            return isNeedImplicitCommitTransaction(executionContext) ? executeWithImplicitCommitTransaction() : useDriverToExecute();
+            return isNeedImplicitCommitTransaction(connection, executionContext) ? executeWithImplicitCommitTransaction() : useDriverToExecute();
             // CHECKSTYLE:OFF
         } catch (final RuntimeException ex) {
             // CHECKSTYLE:ON
@@ -469,14 +465,6 @@ public final class ShardingSpherePreparedStatement extends AbstractPreparedState
                 .prepare(executionContext.getRouteContext(), executionContext.getExecutionUnits(), new ExecutionGroupReportContext(connection.getDatabaseName()));
     }
     
-    private boolean isNeedImplicitCommitTransaction(final ExecutionContext executionContext) {
-        ConnectionTransaction connectionTransaction = connection.getDatabaseConnectionManager().getConnectionTransaction();
-        boolean isInTransaction = connection.getDatabaseConnectionManager().getConnectionContext().getTransactionContext().isInTransaction();
-        SQLStatement sqlStatement = executionContext.getSqlStatementContext().getSqlStatement();
-        return TransactionType.isDistributedTransaction(connectionTransaction.getTransactionType()) && !isInTransaction && sqlStatement instanceof DMLStatement
-                && !(sqlStatement instanceof SelectStatement) && executionContext.getExecutionUnits().size() > 1;
-    }
-    
     private boolean executeWithImplicitCommitTransaction() throws SQLException {
         boolean result;
         try {
diff --git a/jdbc/core/src/main/java/org/apache/shardingsphere/driver/jdbc/core/statement/ShardingSphereStatement.java b/jdbc/core/src/main/java/org/apache/shardingsphere/driver/jdbc/core/statement/ShardingSphereStatement.java
index ab0dc1421ef..3b3ff67fda2 100644
--- a/jdbc/core/src/main/java/org/apache/shardingsphere/driver/jdbc/core/statement/ShardingSphereStatement.java
+++ b/jdbc/core/src/main/java/org/apache/shardingsphere/driver/jdbc/core/statement/ShardingSphereStatement.java
@@ -83,15 +83,11 @@ import org.apache.shardingsphere.mode.metadata.MetaDataContexts;
 import org.apache.shardingsphere.parser.rule.SQLParserRule;
 import org.apache.shardingsphere.sql.parser.sql.common.statement.SQLStatement;
 import org.apache.shardingsphere.sql.parser.sql.common.statement.dal.DALStatement;
-import org.apache.shardingsphere.sql.parser.sql.common.statement.dml.DMLStatement;
-import org.apache.shardingsphere.sql.parser.sql.common.statement.dml.SelectStatement;
 import org.apache.shardingsphere.sqlfederation.spi.SQLFederationExecutorContext;
 import org.apache.shardingsphere.traffic.engine.TrafficEngine;
 import org.apache.shardingsphere.traffic.exception.metadata.EmptyTrafficExecutionUnitException;
 import org.apache.shardingsphere.traffic.executor.TrafficExecutorCallback;
 import org.apache.shardingsphere.traffic.rule.TrafficRule;
-import org.apache.shardingsphere.transaction.ConnectionTransaction;
-import org.apache.shardingsphere.transaction.api.TransactionType;
 
 import java.sql.Connection;
 import java.sql.ResultSet;
@@ -340,7 +336,7 @@ public final class ShardingSphereStatement extends AbstractStatementAdapter {
     }
     
     private int executeUpdate(final ExecuteUpdateCallback updateCallback, final SQLStatementContext sqlStatementContext) throws SQLException {
-        return isNeedImplicitCommitTransaction(executionContext) ? executeUpdateWithImplicitCommitTransaction(updateCallback, sqlStatementContext)
+        return isNeedImplicitCommitTransaction(connection, executionContext) ? executeUpdateWithImplicitCommitTransaction(updateCallback, sqlStatementContext)
                 : useDriverToExecuteUpdate(updateCallback, sqlStatementContext);
     }
     
@@ -480,7 +476,7 @@ public final class ShardingSphereStatement extends AbstractStatementAdapter {
                 Collection<ExecuteResult> results = executor.getRawExecutor().execute(createRawExecutionContext(), executionContext.getQueryContext(), new RawSQLExecutorCallback());
                 return results.iterator().next() instanceof QueryResult;
             }
-            return isNeedImplicitCommitTransaction(executionContext) ? executeWithImplicitCommitTransaction(executeCallback) : useDriverToExecute(executeCallback);
+            return isNeedImplicitCommitTransaction(connection, executionContext) ? executeWithImplicitCommitTransaction(executeCallback) : useDriverToExecute(executeCallback);
         } finally {
             currentResultSet = null;
         }
@@ -559,14 +555,6 @@ public final class ShardingSphereStatement extends AbstractStatementAdapter {
                 .prepare(executionContext.getRouteContext(), executionContext.getExecutionUnits(), new ExecutionGroupReportContext(connection.getDatabaseName()));
     }
     
-    private boolean isNeedImplicitCommitTransaction(final ExecutionContext executionContext) {
-        ConnectionTransaction connectionTransaction = connection.getDatabaseConnectionManager().getConnectionTransaction();
-        boolean isInTransaction = connection.getDatabaseConnectionManager().getConnectionContext().getTransactionContext().isInTransaction();
-        SQLStatement sqlStatement = executionContext.getSqlStatementContext().getSqlStatement();
-        return TransactionType.isDistributedTransaction(connectionTransaction.getTransactionType()) && !isInTransaction && sqlStatement instanceof DMLStatement
-                && !(sqlStatement instanceof SelectStatement) && executionContext.getExecutionUnits().size() > 1;
-    }
-    
     private boolean executeWithImplicitCommitTransaction(final ExecuteCallback callback) throws SQLException {
         boolean result;
         try {
diff --git a/kernel/data-pipeline/dialect/postgresql/src/main/java/org/apache/shardingsphere/data/pipeline/postgresql/ddlgenerator/PostgreSQLColumnPropertiesAppender.java b/kernel/data-pipeline/dialect/postgresql/src/main/java/org/apache/shardingsphere/data/pipeline/postgresql/ddlgenerator/PostgreSQLColumnPropertiesAppender.java
index b66f9e8158d..464d2d6bc9c 100644
--- a/kernel/data-pipeline/dialect/postgresql/src/main/java/org/apache/shardingsphere/data/pipeline/postgresql/ddlgenerator/PostgreSQLColumnPropertiesAppender.java
+++ b/kernel/data-pipeline/dialect/postgresql/src/main/java/org/apache/shardingsphere/data/pipeline/postgresql/ddlgenerator/PostgreSQLColumnPropertiesAppender.java
@@ -25,6 +25,7 @@ import java.sql.SQLException;
 import java.util.Arrays;
 import java.util.Collection;
 import java.util.Collections;
+import java.util.HashSet;
 import java.util.LinkedHashMap;
 import java.util.LinkedList;
 import java.util.Map;
@@ -37,6 +38,11 @@ import java.util.stream.Collectors;
  */
 public final class PostgreSQLColumnPropertiesAppender extends AbstractPostgreSQLDDLAdapter {
     
+    private static final Collection<String> TIME_TYPE_NAMES = new HashSet<>(Arrays.asList(
+            "time", "timetz", "time without time zone", "time with time zone", "timestamp", "timestamptz", "timestamp without time zone", "timestamp with time zone"));
+    
+    private static final Collection<String> BIT_TYPE_NAMES = new HashSet<>(Arrays.asList("bit", "bit varying", "varbit"));
+    
     private static final Pattern LENGTH_PRECISION_PATTERN = Pattern.compile("(\\d+),(\\d+)");
     
     private static final Pattern LENGTH_PATTERN = Pattern.compile("(\\d+)");
@@ -262,9 +268,7 @@ public final class PostgreSQLColumnPropertiesAppender extends AbstractPostgreSQL
             int prec = (typmod - 4) & 0xffff;
             result += String.valueOf(len);
             result += "," + prec;
-        } else if ("time".equals(name) || "timetz".equals(name) || "time without time zone".equals(name) || "time with time zone".equals(name)
-                || "timestamp".equals(name) || "timestamptz".equals(name) || "timestamp without time zone".equals(name) || "timestamp with time zone".equals(name)
-                || "bit".equals(name) || "bit varying".equals(name) || "varbit".equals(name)) {
+        } else if (TIME_TYPE_NAMES.contains(name) || BIT_TYPE_NAMES.contains(name)) {
             int len = typmod;
             result += String.valueOf(len);
         } else if ("interval".equals(name)) {
diff --git a/kernel/sql-federation/executor/advanced/src/main/java/org/apache/shardingsphere/sqlfederation/advanced/resultset/SQLFederationResultSet.java b/kernel/sql-federation/executor/advanced/src/main/java/org/apache/shardingsphere/sqlfederation/advanced/resultset/SQLFederationResultSet.java
index 3fa7a90366d..2f8c24e7de6 100644
--- a/kernel/sql-federation/executor/advanced/src/main/java/org/apache/shardingsphere/sqlfederation/advanced/resultset/SQLFederationResultSet.java
+++ b/kernel/sql-federation/executor/advanced/src/main/java/org/apache/shardingsphere/sqlfederation/advanced/resultset/SQLFederationResultSet.java
@@ -46,8 +46,11 @@ import java.sql.SQLXML;
 import java.sql.Statement;
 import java.sql.Time;
 import java.sql.Timestamp;
+import java.util.Arrays;
 import java.util.Calendar;
+import java.util.Collection;
 import java.util.HashMap;
+import java.util.HashSet;
 import java.util.List;
 import java.util.Map;
 
@@ -62,6 +65,8 @@ public final class SQLFederationResultSet extends AbstractUnsupportedOperationRe
     
     private static final String BINARY = "Binary";
     
+    private static final Collection<Class<?>> INVALID_FEDERATION_TYPES = new HashSet<>(Arrays.asList(Blob.class, Clob.class, Reader.class, InputStream.class, SQLXML.class));
+    
     private final Enumerator<Object> enumerator;
     
     private final Map<String, Integer> columnLabelAndIndexes;
@@ -467,9 +472,7 @@ public final class SQLFederationResultSet extends AbstractUnsupportedOperationRe
     }
     
     private Object getValue(final int columnIndex, final Class<?> type) throws SQLException {
-        if (Blob.class == type || Clob.class == type || Reader.class == type || InputStream.class == type || SQLXML.class == type) {
-            throw new SQLFeatureNotSupportedException(String.format("Get value from `%s`", type.getName()));
-        }
+        ShardingSpherePreconditions.checkState(!INVALID_FEDERATION_TYPES.contains(type), () -> new SQLFeatureNotSupportedException(String.format("Get value from `%s`", type.getName())));
         Object result = currentRows[columnIndex - 1];
         wasNull = null == result;
         return result;
diff --git a/mode/type/cluster/core/src/main/java/org/apache/shardingsphere/mode/manager/cluster/coordinator/registry/metadata/watcher/MetaDataChangedWatcher.java b/mode/type/cluster/core/src/main/java/org/apache/shardingsphere/mode/manager/cluster/coordinator/registry/metadata/watcher/MetaDataChangedWatcher.java
index 7399d448716..54fbcc7cf91 100644
--- a/mode/type/cluster/core/src/main/java/org/apache/shardingsphere/mode/manager/cluster/coordinator/registry/metadata/watcher/MetaDataChangedWatcher.java
+++ b/mode/type/cluster/core/src/main/java/org/apache/shardingsphere/mode/manager/cluster/coordinator/registry/metadata/watcher/MetaDataChangedWatcher.java
@@ -95,12 +95,20 @@ public final class MetaDataChangedWatcher implements GovernanceWatcher<Governanc
     }
     
     private boolean schemaMetaDataChanged(final DataChangedEvent event) {
+        if (Strings.isNullOrEmpty(event.getValue())) {
+            return false;
+        }
         Optional<String> databaseName = DatabaseMetaDataNode.getDatabaseNameByDatabasePath(event.getKey());
+        if (!databaseName.isPresent()) {
+            return false;
+        }
         Optional<String> schemaName = DatabaseMetaDataNode.getSchemaNameBySchemaPath(event.getKey());
+        if (!schemaName.isPresent()) {
+            return false;
+        }
         Optional<String> tableName = DatabaseMetaDataNode.getTableName(event.getKey());
         Optional<String> viewName = DatabaseMetaDataNode.getViewName(event.getKey());
-        return databaseName.isPresent() && schemaName.isPresent() && !Strings.isNullOrEmpty(event.getValue())
-                && (tableName.isPresent() && !SystemSchemaBuilderRule.isSystemTable(databaseName.get(), tableName.get()) || viewName.isPresent());
+        return tableName.isPresent() && !SystemSchemaBuilderRule.isSystemTable(databaseName.get(), tableName.get()) || viewName.isPresent();
     }
     
     private Optional<GovernanceEvent> createDatabaseChangedEvent(final DataChangedEvent event) {
diff --git a/mode/type/standalone/repository/provider/jdbc/src/main/java/org/apache/shardingsphere/mode/repository/standalone/jdbc/sql/JDBCRepositorySQLLoader.java b/mode/type/standalone/repository/provider/jdbc/src/main/java/org/apache/shardingsphere/mode/repository/standalone/jdbc/sql/JDBCRepositorySQLLoader.java
index de891dc3af2..6794a0d7ad5 100644
--- a/mode/type/standalone/repository/provider/jdbc/src/main/java/org/apache/shardingsphere/mode/repository/standalone/jdbc/sql/JDBCRepositorySQLLoader.java
+++ b/mode/type/standalone/repository/provider/jdbc/src/main/java/org/apache/shardingsphere/mode/repository/standalone/jdbc/sql/JDBCRepositorySQLLoader.java
@@ -34,7 +34,10 @@ import java.nio.file.Path;
 import java.nio.file.Paths;
 import java.nio.file.SimpleFileVisitor;
 import java.nio.file.attribute.BasicFileAttributes;
+import java.util.Arrays;
+import java.util.Collection;
 import java.util.Enumeration;
+import java.util.HashSet;
 import java.util.Objects;
 import java.util.jar.JarEntry;
 import java.util.jar.JarFile;
@@ -49,15 +52,7 @@ public final class JDBCRepositorySQLLoader {
     
     private static final String FILE_EXTENSION = ".xml";
     
-    private static final String URL_PROTOCOL_JAR = "jar";
-    
-    private static final String URL_PROTOCOL_WAR = "war";
-    
-    private static final String URL_PROTOCOL_ZIP = "zip";
-    
-    private static final String URL_PROTOCOL_WSJAR = "wsjar";
-    
-    private static final String URL_PROTOCOL_VFSZIP = "vfszip";
+    private static final Collection<String> JAR_URL_PROTOCOLS = new HashSet<>(Arrays.asList("jar", "war", "zip", "wsjar", "vfszip"));
     
     /**
      * Load JDBC repository SQL.
@@ -74,7 +69,7 @@ public final class JDBCRepositorySQLLoader {
         JDBCRepositorySQL result = null;
         while (resources.hasMoreElements()) {
             URL resource = resources.nextElement();
-            result = isJarURL(resource) ? loadFromJar(resource, type) : loadFromDirectory(resource, type);
+            result = JAR_URL_PROTOCOLS.contains(resource.getProtocol()) ? loadFromJar(resource, type) : loadFromDirectory(resource, type);
             if (null != result && Objects.equals(result.isDefault(), false)) {
                 break;
             }
@@ -82,12 +77,6 @@ public final class JDBCRepositorySQLLoader {
         return result;
     }
     
-    private static boolean isJarURL(final URL url) {
-        String protocol = url.getProtocol();
-        return URL_PROTOCOL_JAR.equals(protocol) || URL_PROTOCOL_WAR.equals(protocol) || URL_PROTOCOL_ZIP.equals(protocol)
-                || URL_PROTOCOL_VFSZIP.equals(protocol) || URL_PROTOCOL_WSJAR.equals(protocol);
-    }
-    
     private static JDBCRepositorySQL loadFromDirectory(final URL url, final String type) throws URISyntaxException, IOException {
         final JDBCRepositorySQL[] result = new JDBCRepositorySQL[1];
         Files.walkFileTree(Paths.get(url.toURI()), new SimpleFileVisitor<Path>() {
diff --git a/parser/sql/dialect/mysql/src/main/java/org/apache/shardingsphere/sql/parser/mysql/visitor/format/MySQLFormatVisitor.java b/parser/sql/dialect/mysql/src/main/java/org/apache/shardingsphere/sql/parser/mysql/visitor/format/MySQLFormatVisitor.java
index dcae7187ab5..11f318615ce 100644
--- a/parser/sql/dialect/mysql/src/main/java/org/apache/shardingsphere/sql/parser/mysql/visitor/format/MySQLFormatVisitor.java
+++ b/parser/sql/dialect/mysql/src/main/java/org/apache/shardingsphere/sql/parser/mysql/visitor/format/MySQLFormatVisitor.java
@@ -17,6 +17,7 @@
 
 package org.apache.shardingsphere.sql.parser.mysql.visitor.format;
 
+import org.antlr.v4.runtime.ParserRuleContext;
 import org.antlr.v4.runtime.tree.ParseTree;
 import org.antlr.v4.runtime.tree.RuleNode;
 import org.antlr.v4.runtime.tree.TerminalNode;
@@ -70,6 +71,9 @@ import org.apache.shardingsphere.sql.parser.autogen.MySQLStatementParser.UserVar
 import org.apache.shardingsphere.sql.parser.autogen.MySQLStatementParser.WhereClauseContext;
 import org.apache.shardingsphere.sql.parser.autogen.MySQLStatementParser.WithClauseContext;
 
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.HashSet;
 import java.util.Properties;
 
 /**
@@ -77,6 +81,9 @@ import java.util.Properties;
  */
 public final class MySQLFormatVisitor extends MySQLStatementBaseVisitor<String> implements SQLFormatVisitor {
     
+    private static final Collection<Class<? extends ParserRuleContext>> DATA_TYPE_EXTRA_DESCRIPTION_CONTEXT_CLASSES = new HashSet<>(
+            Arrays.asList(FieldLengthContext.class, PrecisionContext.class, StringListContext.class, TypeDatetimePrecisionContext.class));
+    
     private final StringBuilder formattedSQL = new StringBuilder(256);
     
     private boolean upperCase = true;
@@ -642,7 +649,7 @@ public final class MySQLFormatVisitor extends MySQLStatementBaseVisitor<String>
         int childCount = ctx.getChildCount();
         for (int i = 0; i < childCount; i++) {
             ParseTree child = ctx.getChild(i);
-            if (i != 0 && !(child instanceof FieldLengthContext || child instanceof PrecisionContext || child instanceof StringListContext || child instanceof TypeDatetimePrecisionContext)) {
+            if (0 != i && !DATA_TYPE_EXTRA_DESCRIPTION_CONTEXT_CLASSES.contains(child.getClass())) {
                 formatPrint(" ");
             }
             child.accept(this);
@@ -799,9 +806,12 @@ public final class MySQLFormatVisitor extends MySQLStatementBaseVisitor<String>
         String result = defaultResult();
         int childCount = node.getChildCount();
         for (int i = 0; i < childCount; i++) {
-            if (i != 0 && !"(".equals(node.getChild(i - 1).getText()) && !".".equals(node.getChild(i - 1).getText())
-                    && !")".equals(node.getChild(i).getText()) && !"(".equals(node.getChild(i).getText()) && !".".equals(node.getChild(i).getText())) {
-                formatPrint(" ");
+            if (0 != i) {
+                String previousText = node.getChild(i - 1).getText();
+                String text = node.getChild(i).getText();
+                if (!"(".equals(previousText) && !".".equals(previousText) && !")".equals(text) && !"(".equals(text) && !".".equals(text)) {
+                    formatPrint(" ");
+                }
             }
             if (!shouldVisitNextChild(node, result)) {
                 break;
diff --git a/parser/sql/statement/src/main/java/org/apache/shardingsphere/sql/parser/sql/common/enums/QuoteCharacter.java b/parser/sql/statement/src/main/java/org/apache/shardingsphere/sql/parser/sql/common/enums/QuoteCharacter.java
index 4646a7516e1..7ae5b7f8240 100644
--- a/parser/sql/statement/src/main/java/org/apache/shardingsphere/sql/parser/sql/common/enums/QuoteCharacter.java
+++ b/parser/sql/statement/src/main/java/org/apache/shardingsphere/sql/parser/sql/common/enums/QuoteCharacter.java
@@ -68,4 +68,14 @@ public enum QuoteCharacter {
     public String wrap(final String value) {
         return startDelimiter + value + endDelimiter;
     }
+    
+    /**
+     * Is wrapped by quote character.
+     * 
+     * @param value value to be judged
+     * @return is wrapped or not
+     */
+    public boolean isWrapped(final String value) {
+        return value.startsWith(startDelimiter) && value.endsWith(endDelimiter);
+    }
 }
diff --git a/parser/sql/statement/src/test/java/org/apache/shardingsphere/sql/parser/sql/common/enums/QuoteCharacterTest.java b/parser/sql/statement/src/test/java/org/apache/shardingsphere/sql/parser/sql/common/enums/QuoteCharacterTest.java
index c335679f818..7663ac6854f 100644
--- a/parser/sql/statement/src/test/java/org/apache/shardingsphere/sql/parser/sql/common/enums/QuoteCharacterTest.java
+++ b/parser/sql/statement/src/test/java/org/apache/shardingsphere/sql/parser/sql/common/enums/QuoteCharacterTest.java
@@ -21,6 +21,8 @@ import org.junit.jupiter.api.Test;
 
 import static org.hamcrest.CoreMatchers.is;
 import static org.hamcrest.MatcherAssert.assertThat;
+import static org.junit.jupiter.api.Assertions.assertFalse;
+import static org.junit.jupiter.api.Assertions.assertTrue;
 
 class QuoteCharacterTest {
     
@@ -63,4 +65,14 @@ class QuoteCharacterTest {
     void assertWarp() {
         assertThat(QuoteCharacter.BACK_QUOTE.wrap("test"), is("`test`"));
     }
+    
+    @Test
+    void assertIsWrapped() {
+        assertTrue(QuoteCharacter.SINGLE_QUOTE.isWrapped("'test'"));
+    }
+    
+    @Test
+    void assertIsNotWrapped() {
+        assertFalse(QuoteCharacter.SINGLE_QUOTE.isWrapped("'test\""));
+    }
 }
diff --git a/proxy/backend/core/src/main/java/org/apache/shardingsphere/proxy/backend/handler/ProxyBackendHandlerFactory.java b/proxy/backend/core/src/main/java/org/apache/shardingsphere/proxy/backend/handler/ProxyBackendHandlerFactory.java
index 6db0b64d554..ce7847618a3 100644
--- a/proxy/backend/core/src/main/java/org/apache/shardingsphere/proxy/backend/handler/ProxyBackendHandlerFactory.java
+++ b/proxy/backend/core/src/main/java/org/apache/shardingsphere/proxy/backend/handler/ProxyBackendHandlerFactory.java
@@ -49,7 +49,7 @@ import org.apache.shardingsphere.proxy.backend.handler.extra.ExtraProxyBackendHa
 import org.apache.shardingsphere.proxy.backend.handler.skip.SkipBackendHandler;
 import org.apache.shardingsphere.proxy.backend.handler.transaction.TransactionBackendHandlerFactory;
 import org.apache.shardingsphere.proxy.backend.session.ConnectionSession;
-import org.apache.shardingsphere.proxy.backend.state.spi.ProxyClusterState;
+import org.apache.shardingsphere.proxy.backend.state.ProxyClusterState;
 import org.apache.shardingsphere.sql.parser.sql.common.statement.SQLStatement;
 import org.apache.shardingsphere.sql.parser.sql.common.statement.dal.EmptyStatement;
 import org.apache.shardingsphere.sql.parser.sql.common.statement.dal.FlushStatement;
diff --git a/proxy/backend/core/src/main/java/org/apache/shardingsphere/proxy/backend/state/spi/ProxyClusterState.java b/proxy/backend/core/src/main/java/org/apache/shardingsphere/proxy/backend/state/ProxyClusterState.java
similarity index 95%
copy from proxy/backend/core/src/main/java/org/apache/shardingsphere/proxy/backend/state/spi/ProxyClusterState.java
copy to proxy/backend/core/src/main/java/org/apache/shardingsphere/proxy/backend/state/ProxyClusterState.java
index 175c9bb71de..c8c95858011 100644
--- a/proxy/backend/core/src/main/java/org/apache/shardingsphere/proxy/backend/state/spi/ProxyClusterState.java
+++ b/proxy/backend/core/src/main/java/org/apache/shardingsphere/proxy/backend/state/ProxyClusterState.java
@@ -15,7 +15,7 @@
  * limitations under the License.
  */
 
-package org.apache.shardingsphere.proxy.backend.state.spi;
+package org.apache.shardingsphere.proxy.backend.state;
 
 import org.apache.shardingsphere.infra.util.spi.type.typed.TypedSPI;
 import org.apache.shardingsphere.sql.parser.sql.common.statement.SQLStatement;
diff --git a/proxy/backend/core/src/main/java/org/apache/shardingsphere/proxy/backend/state/SupportedSQLStatementJudgeEngine.java b/proxy/backend/core/src/main/java/org/apache/shardingsphere/proxy/backend/state/SupportedSQLStatementJudgeEngine.java
new file mode 100644
index 00000000000..38701c0b806
--- /dev/null
+++ b/proxy/backend/core/src/main/java/org/apache/shardingsphere/proxy/backend/state/SupportedSQLStatementJudgeEngine.java
@@ -0,0 +1,54 @@
+/*
+ * 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.proxy.backend.state;
+
+import lombok.RequiredArgsConstructor;
+import org.apache.shardingsphere.sql.parser.sql.common.statement.SQLStatement;
+
+import java.util.Collection;
+
+/**
+ * Supported SQL statement judge engine.
+ */
+@RequiredArgsConstructor
+public final class SupportedSQLStatementJudgeEngine {
+    
+    private final Collection<Class<? extends SQLStatement>> supportedSQLStatements;
+    
+    private final Collection<Class<? extends SQLStatement>> unsupportedSQLStatements;
+    
+    /**
+     * Judge whether SQL statement is supported.
+     * 
+     * @param sqlStatement SQL statement to be judged
+     * @return supported or not
+     */
+    public boolean isSupported(final SQLStatement sqlStatement) {
+        for (Class<? extends SQLStatement> each : supportedSQLStatements) {
+            if (each.isAssignableFrom(sqlStatement.getClass())) {
+                return true;
+            }
+        }
+        for (Class<? extends SQLStatement> each : unsupportedSQLStatements) {
+            if (each.isAssignableFrom(sqlStatement.getClass())) {
+                return false;
+            }
+        }
+        return true;
+    }
+}
diff --git a/proxy/backend/core/src/main/java/org/apache/shardingsphere/proxy/backend/state/impl/ReadOnlyProxyState.java b/proxy/backend/core/src/main/java/org/apache/shardingsphere/proxy/backend/state/impl/ReadOnlyProxyState.java
index 285e21a4039..5e20fcbdea6 100644
--- a/proxy/backend/core/src/main/java/org/apache/shardingsphere/proxy/backend/state/impl/ReadOnlyProxyState.java
+++ b/proxy/backend/core/src/main/java/org/apache/shardingsphere/proxy/backend/state/impl/ReadOnlyProxyState.java
@@ -20,29 +20,35 @@ package org.apache.shardingsphere.proxy.backend.state.impl;
 import org.apache.shardingsphere.distsql.parser.statement.ral.UpdatableRALStatement;
 import org.apache.shardingsphere.distsql.parser.statement.ral.updatable.UnlockClusterStatement;
 import org.apache.shardingsphere.distsql.parser.statement.rdl.RDLStatement;
+import org.apache.shardingsphere.infra.util.exception.ShardingSpherePreconditions;
 import org.apache.shardingsphere.proxy.backend.exception.ReadOnlyException;
-import org.apache.shardingsphere.proxy.backend.state.spi.ProxyClusterState;
+import org.apache.shardingsphere.proxy.backend.state.ProxyClusterState;
+import org.apache.shardingsphere.proxy.backend.state.SupportedSQLStatementJudgeEngine;
 import org.apache.shardingsphere.sql.parser.sql.common.statement.SQLStatement;
 import org.apache.shardingsphere.sql.parser.sql.common.statement.ddl.DDLStatement;
 import org.apache.shardingsphere.sql.parser.sql.common.statement.dml.DeleteStatement;
 import org.apache.shardingsphere.sql.parser.sql.common.statement.dml.InsertStatement;
 import org.apache.shardingsphere.sql.parser.sql.common.statement.dml.UpdateStatement;
 
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.Collections;
+
 /**
  * ReadOnly proxy state.
  */
 public final class ReadOnlyProxyState implements ProxyClusterState {
     
+    private static final Collection<Class<? extends SQLStatement>> SUPPORTED_SQL_STATEMENTS = Collections.singleton(UnlockClusterStatement.class);
+    
+    private static final Collection<Class<? extends SQLStatement>> UNSUPPORTED_SQL_STATEMENTS = Arrays.asList(
+            InsertStatement.class, UpdateStatement.class, DeleteStatement.class, DDLStatement.class, UpdatableRALStatement.class, RDLStatement.class);
+    
+    private final SupportedSQLStatementJudgeEngine judgeEngine = new SupportedSQLStatementJudgeEngine(SUPPORTED_SQL_STATEMENTS, UNSUPPORTED_SQL_STATEMENTS);
+    
     @Override
     public void check(final SQLStatement sqlStatement) {
-        if (isUnsupportedStatement(sqlStatement)) {
-            throw new ReadOnlyException();
-        }
-    }
-    
-    private boolean isUnsupportedStatement(final SQLStatement sqlStatement) {
-        return sqlStatement instanceof InsertStatement || sqlStatement instanceof UpdateStatement || sqlStatement instanceof DeleteStatement || sqlStatement instanceof DDLStatement
-                || sqlStatement instanceof UpdatableRALStatement && !(sqlStatement instanceof UnlockClusterStatement) || sqlStatement instanceof RDLStatement;
+        ShardingSpherePreconditions.checkState(judgeEngine.isSupported(sqlStatement), ReadOnlyException::new);
     }
     
     @Override
diff --git a/proxy/backend/core/src/main/java/org/apache/shardingsphere/proxy/backend/state/impl/UnavailableProxyState.java b/proxy/backend/core/src/main/java/org/apache/shardingsphere/proxy/backend/state/impl/UnavailableProxyState.java
index fdc55fdbcb6..ee91da17adb 100644
--- a/proxy/backend/core/src/main/java/org/apache/shardingsphere/proxy/backend/state/impl/UnavailableProxyState.java
+++ b/proxy/backend/core/src/main/java/org/apache/shardingsphere/proxy/backend/state/impl/UnavailableProxyState.java
@@ -21,29 +21,35 @@ import org.apache.shardingsphere.distsql.parser.statement.ral.QueryableRALStatem
 import org.apache.shardingsphere.distsql.parser.statement.ral.updatable.ImportMetaDataStatement;
 import org.apache.shardingsphere.distsql.parser.statement.ral.updatable.UnlockClusterStatement;
 import org.apache.shardingsphere.distsql.parser.statement.rql.RQLStatement;
+import org.apache.shardingsphere.infra.util.exception.ShardingSpherePreconditions;
 import org.apache.shardingsphere.proxy.backend.exception.UnavailableException;
-import org.apache.shardingsphere.proxy.backend.state.spi.ProxyClusterState;
+import org.apache.shardingsphere.proxy.backend.state.ProxyClusterState;
+import org.apache.shardingsphere.proxy.backend.state.SupportedSQLStatementJudgeEngine;
 import org.apache.shardingsphere.sql.parser.sql.common.statement.SQLStatement;
 import org.apache.shardingsphere.sql.parser.sql.common.statement.dal.ShowStatement;
 import org.apache.shardingsphere.sql.parser.sql.dialect.statement.mysql.dal.MySQLShowDatabasesStatement;
 import org.apache.shardingsphere.sql.parser.sql.dialect.statement.mysql.dal.MySQLUseStatement;
 
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.Collections;
+
 /**
  * Unavailable proxy state.
  */
 public final class UnavailableProxyState implements ProxyClusterState {
     
+    private static final Collection<Class<? extends SQLStatement>> SUPPORTED_SQL_STATEMENTS = Arrays.asList(
+            ImportMetaDataStatement.class, ShowStatement.class, QueryableRALStatement.class,
+            RQLStatement.class, UnlockClusterStatement.class, MySQLShowDatabasesStatement.class, MySQLUseStatement.class);
+    
+    private static final Collection<Class<? extends SQLStatement>> UNSUPPORTED_SQL_STATEMENTS = Collections.singleton(SQLStatement.class);
+    
+    private final SupportedSQLStatementJudgeEngine judgeEngine = new SupportedSQLStatementJudgeEngine(SUPPORTED_SQL_STATEMENTS, UNSUPPORTED_SQL_STATEMENTS);
+    
     @Override
     public void check(final SQLStatement sqlStatement) {
-        if (isSupportedStatement(sqlStatement)) {
-            return;
-        }
-        throw new UnavailableException();
-    }
-    
-    private boolean isSupportedStatement(final SQLStatement sqlStatement) {
-        return sqlStatement instanceof ImportMetaDataStatement || sqlStatement instanceof ShowStatement || sqlStatement instanceof QueryableRALStatement || sqlStatement instanceof RQLStatement
-                || sqlStatement instanceof UnlockClusterStatement || sqlStatement instanceof MySQLShowDatabasesStatement || sqlStatement instanceof MySQLUseStatement;
+        ShardingSpherePreconditions.checkState(judgeEngine.isSupported(sqlStatement), UnavailableException::new);
     }
     
     @Override
diff --git a/proxy/backend/core/src/main/resources/META-INF/services/org.apache.shardingsphere.proxy.backend.state.spi.ProxyClusterState b/proxy/backend/core/src/main/resources/META-INF/services/org.apache.shardingsphere.proxy.backend.state.ProxyClusterState
similarity index 100%
rename from proxy/backend/core/src/main/resources/META-INF/services/org.apache.shardingsphere.proxy.backend.state.spi.ProxyClusterState
rename to proxy/backend/core/src/main/resources/META-INF/services/org.apache.shardingsphere.proxy.backend.state.ProxyClusterState
diff --git a/proxy/backend/core/src/test/java/org/apache/shardingsphere/proxy/backend/state/SupportedSQLStatementJudgeEngineTest.java b/proxy/backend/core/src/test/java/org/apache/shardingsphere/proxy/backend/state/SupportedSQLStatementJudgeEngineTest.java
new file mode 100644
index 00000000000..c166c2e7341
--- /dev/null
+++ b/proxy/backend/core/src/test/java/org/apache/shardingsphere/proxy/backend/state/SupportedSQLStatementJudgeEngineTest.java
@@ -0,0 +1,53 @@
+/*
+ * 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.proxy.backend.state;
+
+import org.apache.shardingsphere.sql.parser.sql.common.statement.SQLStatement;
+import org.apache.shardingsphere.sql.parser.sql.common.statement.dml.DeleteStatement;
+import org.apache.shardingsphere.sql.parser.sql.common.statement.dml.SelectStatement;
+import org.apache.shardingsphere.sql.parser.sql.common.statement.dml.UpdateStatement;
+import org.junit.jupiter.api.Test;
+
+import java.util.Collections;
+
+import static org.junit.jupiter.api.Assertions.assertFalse;
+import static org.junit.jupiter.api.Assertions.assertTrue;
+import static org.mockito.Mockito.mock;
+
+class SupportedSQLStatementJudgeEngineTest {
+    
+    @Test
+    void assertIsSupportedWithInSupportedList() {
+        assertTrue(new SupportedSQLStatementJudgeEngine(Collections.singleton(SelectStatement.class), Collections.emptyList()).isSupported(mock(SelectStatement.class)));
+    }
+    
+    @Test
+    void assertIsNotSupportedWithInUnsupportedList() {
+        assertFalse(new SupportedSQLStatementJudgeEngine(Collections.emptyList(), Collections.singleton(SelectStatement.class)).isSupported(mock(SelectStatement.class)));
+    }
+    
+    @Test
+    void assertIsSupportedWithOverlappedList() {
+        assertTrue(new SupportedSQLStatementJudgeEngine(Collections.singleton(SelectStatement.class), Collections.singleton(SQLStatement.class)).isSupported(mock(SelectStatement.class)));
+    }
+    
+    @Test
+    void assertIsSupportedWithoutList() {
+        assertTrue(new SupportedSQLStatementJudgeEngine(Collections.singleton(SelectStatement.class), Collections.singleton(UpdateStatement.class)).isSupported(mock(DeleteStatement.class)));
+    }
+}
diff --git a/proxy/backend/type/mysql/src/main/java/org/apache/shardingsphere/proxy/backend/mysql/handler/admin/executor/MySQLSetCharsetExecutor.java b/proxy/backend/type/mysql/src/main/java/org/apache/shardingsphere/proxy/backend/mysql/handler/admin/executor/MySQLSetCharsetExecutor.java
index 996ced9a680..9583ddec930 100644
--- a/proxy/backend/type/mysql/src/main/java/org/apache/shardingsphere/proxy/backend/mysql/handler/admin/executor/MySQLSetCharsetExecutor.java
+++ b/proxy/backend/type/mysql/src/main/java/org/apache/shardingsphere/proxy/backend/mysql/handler/admin/executor/MySQLSetCharsetExecutor.java
@@ -22,6 +22,7 @@ import org.apache.shardingsphere.db.protocol.mysql.constant.MySQLConstants;
 import org.apache.shardingsphere.dialect.mysql.exception.UnknownCharsetException;
 import org.apache.shardingsphere.proxy.backend.mysql.handler.admin.MySQLSessionVariableHandler;
 import org.apache.shardingsphere.proxy.backend.session.ConnectionSession;
+import org.apache.shardingsphere.sql.parser.sql.common.enums.QuoteCharacter;
 
 import java.nio.charset.Charset;
 import java.nio.charset.StandardCharsets;
@@ -48,7 +49,7 @@ public final class MySQLSetCharsetExecutor implements MySQLSessionVariableHandle
     }
     
     private String formatValue(final String value) {
-        return value.startsWith("'") && value.endsWith("'") || value.startsWith("\"") && value.endsWith("\"") ? value.substring(1, value.length() - 1) : value.trim();
+        return QuoteCharacter.SINGLE_QUOTE.isWrapped(value) || QuoteCharacter.QUOTE.isWrapped(value) ? value.substring(1, value.length() - 1) : value.trim();
     }
     
     private Charset parseCharset(final String value) {
diff --git a/proxy/backend/type/postgresql/src/main/java/org/apache/shardingsphere/proxy/backend/postgresql/handler/admin/PostgreSQLCharacterSets.java b/proxy/backend/type/postgresql/src/main/java/org/apache/shardingsphere/proxy/backend/postgresql/handler/admin/PostgreSQLCharacterSets.java
index ba4d756dbac..96b22befc3a 100644
--- a/proxy/backend/type/postgresql/src/main/java/org/apache/shardingsphere/proxy/backend/postgresql/handler/admin/PostgreSQLCharacterSets.java
+++ b/proxy/backend/type/postgresql/src/main/java/org/apache/shardingsphere/proxy/backend/postgresql/handler/admin/PostgreSQLCharacterSets.java
@@ -17,6 +17,8 @@
 
 package org.apache.shardingsphere.proxy.backend.postgresql.handler.admin;
 
+import org.apache.shardingsphere.sql.parser.sql.common.enums.QuoteCharacter;
+
 import java.nio.charset.Charset;
 import java.nio.charset.StandardCharsets;
 import java.nio.charset.UnsupportedCharsetException;
@@ -113,6 +115,6 @@ public enum PostgreSQLCharacterSets {
     }
     
     private static String formatValue(final String value) {
-        return value.startsWith("'") && value.endsWith("'") || value.startsWith("\"") && value.endsWith("\"") ? value.substring(1, value.length() - 1) : value.trim();
+        return QuoteCharacter.SINGLE_QUOTE.isWrapped(value) || QuoteCharacter.QUOTE.isWrapped(value) ? value.substring(1, value.length() - 1) : value.trim();
     }
 }
diff --git a/proxy/frontend/type/mysql/src/main/java/org/apache/shardingsphere/proxy/frontend/mysql/command/query/text/query/MySQLComQueryPacketExecutor.java b/proxy/frontend/type/mysql/src/main/java/org/apache/shardingsphere/proxy/frontend/mysql/command/query/text/query/MySQLComQueryPacketExecutor.java
index a19d5a770ed..293dbc77892 100644
--- a/proxy/frontend/type/mysql/src/main/java/org/apache/shardingsphere/proxy/frontend/mysql/command/query/text/query/MySQLComQueryPacketExecutor.java
+++ b/proxy/frontend/type/mysql/src/main/java/org/apache/shardingsphere/proxy/frontend/mysql/command/query/text/query/MySQLComQueryPacketExecutor.java
@@ -82,9 +82,16 @@ public final class MySQLComQueryPacketExecutor implements QueryCommandExecutor {
     
     private boolean areMultiStatements(final ConnectionSession connectionSession, final SQLStatement sqlStatement, final String sql) {
         // TODO Multi statements should be identified by SQL Parser instead of checking if sql contains ";".
+        return isMultiStatementsEnabled(connectionSession) && isSuitableMultiStatementsSQLStatement(sqlStatement) && sql.contains(";");
+    }
+    
+    private boolean isMultiStatementsEnabled(final ConnectionSession connectionSession) {
         return connectionSession.getAttributeMap().hasAttr(MySQLConstants.MYSQL_OPTION_MULTI_STATEMENTS)
-                && MySQLComSetOptionPacket.MYSQL_OPTION_MULTI_STATEMENTS_ON == connectionSession.getAttributeMap().attr(MySQLConstants.MYSQL_OPTION_MULTI_STATEMENTS).get()
-                && (sqlStatement instanceof UpdateStatement || sqlStatement instanceof DeleteStatement) && sql.contains(";");
+                && MySQLComSetOptionPacket.MYSQL_OPTION_MULTI_STATEMENTS_ON == connectionSession.getAttributeMap().attr(MySQLConstants.MYSQL_OPTION_MULTI_STATEMENTS).get();
+    }
+    
+    private boolean isSuitableMultiStatementsSQLStatement(final SQLStatement sqlStatement) {
+        return sqlStatement instanceof UpdateStatement || sqlStatement instanceof DeleteStatement;
     }
     
     @Override
diff --git a/test/it/parser/src/main/java/org/apache/shardingsphere/test/it/sql/parser/external/loader/DefaultExternalTestParameterLoader.java b/test/it/parser/src/main/java/org/apache/shardingsphere/test/it/sql/parser/external/loader/DefaultExternalTestParameterLoader.java
index 92aba08961f..d3ebcfb53b3 100644
--- a/test/it/parser/src/main/java/org/apache/shardingsphere/test/it/sql/parser/external/loader/DefaultExternalTestParameterLoader.java
+++ b/test/it/parser/src/main/java/org/apache/shardingsphere/test/it/sql/parser/external/loader/DefaultExternalTestParameterLoader.java
@@ -69,11 +69,7 @@ public final class DefaultExternalTestParameterLoader extends AbstractTestParame
     }
     
     private String getStatement(final String completedSQL, final String rawSQLLine, final boolean inProcedure) {
-        return (rawSQLLine.isEmpty() || isComment(rawSQLLine)) && !inProcedure ? "" : completedSQL + rawSQLLine + " ";
-    }
-    
-    private boolean isComment(final String line) {
-        return line.startsWith("#") || line.startsWith("/") || line.startsWith("--") || line.startsWith(":") || line.startsWith("\\");
+        return (rawSQLLine.isEmpty() || SQLLineComment.isComment(rawSQLLine)) && !inProcedure ? "" : completedSQL + rawSQLLine + " ";
     }
     
     private int searchInResultContent(final int resultIndex, final List<String> resultLines, final String completedSQL, final int statementLines) {
diff --git a/test/it/parser/src/main/java/org/apache/shardingsphere/test/it/sql/parser/external/loader/ExternalMySQLTestParameterLoader.java b/test/it/parser/src/main/java/org/apache/shardingsphere/test/it/sql/parser/external/loader/ExternalMySQLTestParameterLoader.java
index afd52d15320..22f46f1a214 100644
--- a/test/it/parser/src/main/java/org/apache/shardingsphere/test/it/sql/parser/external/loader/ExternalMySQLTestParameterLoader.java
+++ b/test/it/parser/src/main/java/org/apache/shardingsphere/test/it/sql/parser/external/loader/ExternalMySQLTestParameterLoader.java
@@ -47,7 +47,7 @@ public final class ExternalMySQLTestParameterLoader extends AbstractTestParamete
         String delimiter = ";";
         for (String each : sqlCaseFileContent) {
             String line = each.trim();
-            if (line.isEmpty() || lines.isEmpty() && isComment(line)) {
+            if (line.isEmpty() || lines.isEmpty() && SQLLineComment.isComment(line)) {
                 continue;
             }
             if (lines.isEmpty() && line.toUpperCase().startsWith("DELIMITER")) {
@@ -68,10 +68,6 @@ public final class ExternalMySQLTestParameterLoader extends AbstractTestParamete
         return result;
     }
     
-    private boolean isComment(final String line) {
-        return line.startsWith("#") || line.startsWith("/") || line.startsWith("--") || line.startsWith(":") || line.startsWith("\\");
-    }
-    
     private String getNewDelimiter(final String sql, final String delimiter) {
         String newDelimiter = sql.substring(DELIMITER_COMMAND_LENGTH, sql.endsWith(delimiter) ? sql.length() - delimiter.length() : sql.length()).trim();
         if (newDelimiter.startsWith("\"") && newDelimiter.endsWith("\"") || newDelimiter.startsWith("'") && newDelimiter.endsWith("'")) {
diff --git a/proxy/backend/core/src/main/java/org/apache/shardingsphere/proxy/backend/state/spi/ProxyClusterState.java b/test/it/parser/src/main/java/org/apache/shardingsphere/test/it/sql/parser/external/loader/SQLLineComment.java
similarity index 56%
rename from proxy/backend/core/src/main/java/org/apache/shardingsphere/proxy/backend/state/spi/ProxyClusterState.java
rename to test/it/parser/src/main/java/org/apache/shardingsphere/test/it/sql/parser/external/loader/SQLLineComment.java
index 175c9bb71de..7c919cd9b4a 100644
--- a/proxy/backend/core/src/main/java/org/apache/shardingsphere/proxy/backend/state/spi/ProxyClusterState.java
+++ b/test/it/parser/src/main/java/org/apache/shardingsphere/test/it/sql/parser/external/loader/SQLLineComment.java
@@ -15,20 +15,30 @@
  * limitations under the License.
  */
 
-package org.apache.shardingsphere.proxy.backend.state.spi;
+package org.apache.shardingsphere.test.it.sql.parser.external.loader;
 
-import org.apache.shardingsphere.infra.util.spi.type.typed.TypedSPI;
-import org.apache.shardingsphere.sql.parser.sql.common.statement.SQLStatement;
+import lombok.AccessLevel;
+import lombok.NoArgsConstructor;
+
+import java.util.Arrays;
+import java.util.Collection;
 
 /**
- * Proxy cluster state.
+ * SQL line comment.
  */
-public interface ProxyClusterState extends TypedSPI {
+@NoArgsConstructor(access = AccessLevel.PRIVATE)
+public final class SQLLineComment {
+    
+    private static final Collection<String> COMMENT_PREFIXES = Arrays.asList("#", "/", "--", ":", "\\");
     
     /**
-     * Check sql statement.
+     * Judge whether SQL line is comment.
      * 
-     * @param sqlStatement sql statement
+     * @param line SQL line
+     * @return SQL line is comment or not
      */
-    void check(SQLStatement sqlStatement);
+    public static boolean isComment(final String line) {
+        return COMMENT_PREFIXES.stream().anyMatch(line::startsWith);
+    }
+    
 }