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

terrymanu 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 731888e29c5 Refactor local code paths and reuse compiled patterns 
(#40348)
731888e29c5 is described below

commit 731888e29c562c66305652e300bb45b971c3fd4c
Author: Liang Zhang <[email protected]>
AuthorDate: Thu Oct 22 23:22:17 2026 +0800

    Refactor local code paths and reuse compiled patterns (#40348)
    
    * Run initial blind PR reviews in parallel
    
    * Refactor local code paths and reuse compiled patterns
---
 .../batch/FirebirdBatchMessageCommandPacket.java   |  2 +-
 .../FirebirdBatchMessageCommandPacketTest.java     | 19 +++++++
 .../FirebirdExecuteStatementPacketTest.java        |  1 +
 .../value/time/MySQLDateBinlogProtocolValue.java   |  6 +--
 .../EncryptProjectionTokenGenerator.java           | 27 ++++------
 .../EncryptProjectionTokenGeneratorTest.java       | 18 +++++++
 ...plittingDataSourceRuleConfigurationChecker.java |  3 --
 .../util/ShardingValueTypeConvertUtils.java        | 22 +++-----
 .../util/ShardingValueTypeConvertUtilsTest.java    | 11 ++++
 .../infra/props/TypedPropertyValue.java            | 26 +++-------
 .../infra/props/TypedPropertyValueTest.java        |  3 +-
 .../expr/groovy/GroovyInlineExpressionParser.java  |  9 +++-
 .../DriverExecuteBatchExecutor.java                | 16 ++----
 .../resultset/MySQLResultSetValueConverter.java    |  2 +-
 .../core/statement/DistSQLStatementExecutor.java   |  2 +-
 .../SingleMutableDataNodeRuleAttribute.java        | 52 ++++++++++---------
 .../SingleMutableDataNodeRuleAttributeTest.java    | 16 ++++++
 .../impl/LiteralExpressionConverter.java           | 15 ++++--
 .../impl/LiteralExpressionConverterTest.java       | 27 ++++++++--
 .../calcite/CalciteSQLFederationExecutor.java      |  5 +-
 .../changed/RuleItemChangedNodePathBuilder.java    |  4 ++
 .../index/DropIndexPushDownMetaDataRefresher.java  |  5 +-
 .../CreateTablePushDownMetaDataRefresher.java      |  5 +-
 .../executor/MySQLSetVariableAdminExecutor.java    | 16 +++---
 ...MySQLSelectWithoutFromAdminExecutorFactory.java |  5 +-
 ...LSelectWithoutFromAdminExecutorFactoryTest.java | 59 +++++++---------------
 .../batch/FirebirdBatchCreateCommandExecutor.java  |  2 +-
 .../FirebirdBatchCreateCommandExecutorTest.java    |  1 -
 ...irebirdPrepareStatementCommandExecutorTest.java | 28 ++++++++++
 .../PostgreSQLAuthenticationEngine.java            |  3 +-
 .../describe/PostgreSQLComDescribeExecutor.java    |  9 +++-
 31 files changed, 251 insertions(+), 168 deletions(-)

diff --git 
a/database/protocol/dialect/firebird/src/main/java/org/apache/shardingsphere/database/protocol/firebird/packet/command/query/batch/FirebirdBatchMessageCommandPacket.java
 
b/database/protocol/dialect/firebird/src/main/java/org/apache/shardingsphere/database/protocol/firebird/packet/command/query/batch/FirebirdBatchMessageCommandPacket.java
index 20c2e48f935..0ba6db82c7c 100644
--- 
a/database/protocol/dialect/firebird/src/main/java/org/apache/shardingsphere/database/protocol/firebird/packet/command/query/batch/FirebirdBatchMessageCommandPacket.java
+++ 
b/database/protocol/dialect/firebird/src/main/java/org/apache/shardingsphere/database/protocol/firebird/packet/command/query/batch/FirebirdBatchMessageCommandPacket.java
@@ -84,10 +84,10 @@ public final class FirebirdBatchMessageCommandPacket 
extends FirebirdCommandPack
      * @return length of packet, or {@code -1} when the packet is incomplete
      */
     public static int getLength(final FirebirdPacketPayload payload, final 
List<FirebirdBatchColumnDescriptor> columnDescriptors) {
-        int startReaderIndex = payload.getByteBuf().readerIndex();
         if (payload.getByteBuf().readableBytes() < 
FIXED_BATCH_MSG_HEADER_LENGTH) {
             return -1;
         }
+        int startReaderIndex = payload.getByteBuf().readerIndex();
         payload.skipReserved(8);
         return parseBatchMessages(payload, startReaderIndex, 
payload.readInt4Unsigned(), columnDescriptors);
     }
diff --git 
a/database/protocol/dialect/firebird/src/test/java/org/apache/shardingsphere/database/protocol/firebird/packet/command/query/batch/FirebirdBatchMessageCommandPacketTest.java
 
b/database/protocol/dialect/firebird/src/test/java/org/apache/shardingsphere/database/protocol/firebird/packet/command/query/batch/FirebirdBatchMessageCommandPacketTest.java
index 261f0a50551..07239508a96 100644
--- 
a/database/protocol/dialect/firebird/src/test/java/org/apache/shardingsphere/database/protocol/firebird/packet/command/query/batch/FirebirdBatchMessageCommandPacketTest.java
+++ 
b/database/protocol/dialect/firebird/src/test/java/org/apache/shardingsphere/database/protocol/firebird/packet/command/query/batch/FirebirdBatchMessageCommandPacketTest.java
@@ -38,4 +38,23 @@ class FirebirdBatchMessageCommandPacketTest {
                 Collections.singletonList(new 
FirebirdBatchColumnDescriptor(FirebirdBinaryColumnType.LONG, Integer.BYTES, 0, 
0)));
         assertThat(actual, is(20));
     }
+    
+    @Test
+    void assertGetLengthWithIncompleteHeader() {
+        ByteBuf packet = Unpooled.buffer().writeZero(11);
+        packet.readerIndex(2);
+        int actual = FirebirdBatchMessageCommandPacket.getLength(new 
FirebirdPacketPayload(packet, StandardCharsets.UTF_8), Collections.emptyList());
+        assertThat(actual, is(-1));
+        assertThat(packet.readerIndex(), is(2));
+    }
+    
+    @Test
+    void assertGetLengthWithNonzeroReaderIndex() {
+        ByteBuf packet = 
Unpooled.buffer().writeZero(3).writeInt(0).writeInt(42).writeInt(1).writeByte(0).writeZero(3).writeInt(100);
+        packet.readerIndex(3);
+        int actual = FirebirdBatchMessageCommandPacket.getLength(new 
FirebirdPacketPayload(packet, StandardCharsets.UTF_8),
+                Collections.singletonList(new 
FirebirdBatchColumnDescriptor(FirebirdBinaryColumnType.LONG, Integer.BYTES, 0, 
0)));
+        assertThat(actual, is(20));
+        assertThat(packet.readerIndex(), is(23));
+    }
 }
diff --git 
a/database/protocol/dialect/firebird/src/test/java/org/apache/shardingsphere/database/protocol/firebird/packet/command/query/statement/execute/FirebirdExecuteStatementPacketTest.java
 
b/database/protocol/dialect/firebird/src/test/java/org/apache/shardingsphere/database/protocol/firebird/packet/command/query/statement/execute/FirebirdExecuteStatementPacketTest.java
index 247dae55549..2eabae0233f 100644
--- 
a/database/protocol/dialect/firebird/src/test/java/org/apache/shardingsphere/database/protocol/firebird/packet/command/query/statement/execute/FirebirdExecuteStatementPacketTest.java
+++ 
b/database/protocol/dialect/firebird/src/test/java/org/apache/shardingsphere/database/protocol/firebird/packet/command/query/statement/execute/FirebirdExecuteStatementPacketTest.java
@@ -39,6 +39,7 @@ import java.util.stream.Stream;
 
 import static org.hamcrest.MatcherAssert.assertThat;
 import static org.hamcrest.Matchers.is;
+import static org.mockito.ArgumentMatchers.anyInt;
 import static org.mockito.Mockito.lenient;
 import static org.mockito.Mockito.mock;
 import static org.mockito.Mockito.verify;
diff --git 
a/database/protocol/dialect/mysql/src/main/java/org/apache/shardingsphere/database/protocol/mysql/packet/binlog/row/column/value/time/MySQLDateBinlogProtocolValue.java
 
b/database/protocol/dialect/mysql/src/main/java/org/apache/shardingsphere/database/protocol/mysql/packet/binlog/row/column/value/time/MySQLDateBinlogProtocolValue.java
index 3ce663f4f1e..b6eb571d63e 100644
--- 
a/database/protocol/dialect/mysql/src/main/java/org/apache/shardingsphere/database/protocol/mysql/packet/binlog/row/column/value/time/MySQLDateBinlogProtocolValue.java
+++ 
b/database/protocol/dialect/mysql/src/main/java/org/apache/shardingsphere/database/protocol/mysql/packet/binlog/row/column/value/time/MySQLDateBinlogProtocolValue.java
@@ -36,12 +36,12 @@ public final class MySQLDateBinlogProtocolValue implements 
MySQLBinlogProtocolVa
     @Override
     public Serializable read(final MySQLBinlogColumnDef columnDef, final 
MySQLPacketPayload payload) {
         int date = payload.getByteBuf().readUnsignedMediumLE();
-        int year = date / 16 / 32;
-        int month = date / 32 % 16;
-        int day = date % 32;
         if (0 == date) {
             return MySQLTimeValueUtils.ZERO_OF_DATE;
         }
+        int year = date / 16 / 32;
+        int month = date / 32 % 16;
+        int day = date % 32;
         return MySQLTimeValueUtils.isCompleteDate(month, day) ? 
Date.valueOf(LocalDate.of(year, month, day)) : 
MySQLTimeValueUtils.formatIncompleteDate(year, month, day);
     }
 }
diff --git 
a/features/encrypt/core/src/main/java/org/apache/shardingsphere/encrypt/rewrite/token/generator/projection/EncryptProjectionTokenGenerator.java
 
b/features/encrypt/core/src/main/java/org/apache/shardingsphere/encrypt/rewrite/token/generator/projection/EncryptProjectionTokenGenerator.java
index eebe6a084db..c84b4426891 100644
--- 
a/features/encrypt/core/src/main/java/org/apache/shardingsphere/encrypt/rewrite/token/generator/projection/EncryptProjectionTokenGenerator.java
+++ 
b/features/encrypt/core/src/main/java/org/apache/shardingsphere/encrypt/rewrite/token/generator/projection/EncryptProjectionTokenGenerator.java
@@ -100,10 +100,6 @@ public final class EncryptProjectionTokenGenerator {
      * @return generated SQL tokens
      */
     public Collection<SQLToken> generateSQLTokens(final SQLStatementContext 
sqlStatementContext) {
-        return generateSQLTokens(sqlStatementContext, "");
-    }
-    
-    private Collection<SQLToken> generateSQLTokens(final SQLStatementContext 
sqlStatementContext, final String operator) {
         Collection<SQLToken> sqlTokens = sqlStatementContext instanceof 
SelectStatementContext
                 ? generateSelectSQLTokens((SelectStatementContext) 
sqlStatementContext)
                 : Collections.emptyList();
@@ -114,25 +110,23 @@ public final class EncryptProjectionTokenGenerator {
             if (each instanceof BinaryOperationExpression) {
                 BinaryOperationExpression binaryExpression = 
(BinaryOperationExpression) each;
                 checkBinaryOperationEncryptor(binaryExpression);
-                String expressionOperator = binaryExpression.getOperator();
-                generateExpressionSQLTokens(binaryExpression.getLeft(), 
subqueryContexts, processedSubqueryIndexes, result, expressionOperator);
-                generateExpressionSQLTokens(binaryExpression.getRight(), 
subqueryContexts, processedSubqueryIndexes, result, expressionOperator);
+                generateExpressionSQLTokens(binaryExpression.getLeft(), 
subqueryContexts, processedSubqueryIndexes, result);
+                generateExpressionSQLTokens(binaryExpression.getRight(), 
subqueryContexts, processedSubqueryIndexes, result);
             } else if (each instanceof InExpression) {
                 InExpression inExpression = (InExpression) each;
                 checkInExpressionEncryptor(inExpression);
-                generateExpressionSQLTokens(inExpression.getLeft(), 
subqueryContexts, processedSubqueryIndexes, result, "IN");
-                generateExpressionSQLTokens(inExpression.getRight(), 
subqueryContexts, processedSubqueryIndexes, result, "IN");
+                generateExpressionSQLTokens(inExpression.getLeft(), 
subqueryContexts, processedSubqueryIndexes, result);
+                generateExpressionSQLTokens(inExpression.getRight(), 
subqueryContexts, processedSubqueryIndexes, result);
             } else if (each instanceof BetweenExpression) {
                 BetweenExpression betweenExpression = (BetweenExpression) each;
-                generateExpressionSQLTokens(betweenExpression.getLeft(), 
subqueryContexts, processedSubqueryIndexes, result, "BETWEEN");
-                
generateExpressionSQLTokens(betweenExpression.getBetweenExpr(), 
subqueryContexts, processedSubqueryIndexes, result, "BETWEEN");
-                generateExpressionSQLTokens(betweenExpression.getAndExpr(), 
subqueryContexts, processedSubqueryIndexes, result, "BETWEEN");
+                generateExpressionSQLTokens(betweenExpression.getLeft(), 
subqueryContexts, processedSubqueryIndexes, result);
+                
generateExpressionSQLTokens(betweenExpression.getBetweenExpr(), 
subqueryContexts, processedSubqueryIndexes, result);
+                generateExpressionSQLTokens(betweenExpression.getAndExpr(), 
subqueryContexts, processedSubqueryIndexes, result);
             }
         }
-        String subqueryOperator = sqlStatementContext instanceof 
SelectStatementContext && ((SelectStatementContext) 
sqlStatementContext).isContainsCombine() ? "COMBINE" : "";
         for (Entry<Integer, SelectStatementContext> entry : 
subqueryContexts.entrySet()) {
             if (!processedSubqueryIndexes.contains(entry.getKey())) {
-                result.addAll(generateSQLTokens(entry.getValue(), 
subqueryOperator));
+                result.addAll(generateSQLTokens(entry.getValue()));
             }
         }
         return result;
@@ -154,13 +148,12 @@ public final class EncryptProjectionTokenGenerator {
     }
     
     private void generateExpressionSQLTokens(final ExpressionSegment 
expressionSegment, final Map<Integer, SelectStatementContext> subqueryContexts,
-                                             final Collection<Integer> 
processedSubqueryIndexes,
-                                             final Collection<SQLToken> 
result, final String operator) {
+                                             final Collection<Integer> 
processedSubqueryIndexes, final Collection<SQLToken> sqlTokens) {
         Integer subqueryStartIndex = getSubqueryStartIndex(expressionSegment);
         if (null != subqueryStartIndex && 
processedSubqueryIndexes.add(subqueryStartIndex)) {
             SelectStatementContext subqueryContext = 
subqueryContexts.get(subqueryStartIndex);
             if (null != subqueryContext) {
-                result.addAll(generateSQLTokens(subqueryContext, operator));
+                sqlTokens.addAll(generateSQLTokens(subqueryContext));
             }
         }
     }
diff --git 
a/features/encrypt/core/src/test/java/org/apache/shardingsphere/encrypt/rewrite/token/generator/projection/EncryptProjectionTokenGeneratorTest.java
 
b/features/encrypt/core/src/test/java/org/apache/shardingsphere/encrypt/rewrite/token/generator/projection/EncryptProjectionTokenGeneratorTest.java
index 70f4dbb75ea..bb0b3115b7e 100644
--- 
a/features/encrypt/core/src/test/java/org/apache/shardingsphere/encrypt/rewrite/token/generator/projection/EncryptProjectionTokenGeneratorTest.java
+++ 
b/features/encrypt/core/src/test/java/org/apache/shardingsphere/encrypt/rewrite/token/generator/projection/EncryptProjectionTokenGeneratorTest.java
@@ -250,4 +250,22 @@ class EncryptProjectionTokenGeneratorTest {
         }
         return result;
     }
+    
+    @Test
+    void assertGenerateSQLTokensWithDerivedSubqueryProjections() {
+        EncryptProjectionTokenGenerator actualGenerator = new 
EncryptProjectionTokenGenerator(Collections.emptyList(), databaseType, 
mockEncryptRule(createEncryptColumnWithDerivedColumns()),
+                identifierContext);
+        SelectStatementContext subqueryContext = 
mockInsertSelectStatementContext(TableSourceType.PHYSICAL_TABLE, 
QuoteCharacter.QUOTE);
+        when(subqueryContext.getSubqueryType()).thenReturn(SubqueryType.TABLE);
+        SelectStatementContext sqlStatementContext = 
mock(SelectStatementContext.class, RETURNS_DEEP_STUBS);
+        
when(sqlStatementContext.getSubqueryContexts()).thenReturn(Collections.singletonMap(0,
 subqueryContext));
+        Collection<SQLToken> actual = 
actualGenerator.generateSQLTokens(sqlStatementContext);
+        assertThat(actual.size(), is(1));
+        SubstitutableColumnNameToken actualToken = 
(SubstitutableColumnNameToken) actual.iterator().next();
+        List<ColumnProjection> actualProjections = 
getColumnProjections(actualToken.getProjections());
+        assertThat(getProjectionNames(actualProjections), 
is(Arrays.asList("cipher_mobile", "assisted_mobile", "like_mobile")));
+        assertThat(actualProjections.get(0).getAlias().get().getValue(), 
is(EncryptDerivedColumnSuffix.CIPHER.getDerivedColumnName("mobile", 
identifierContext)));
+        assertThat(actualProjections.get(1).getAlias().get().getValue(), 
is(EncryptDerivedColumnSuffix.ASSISTED_QUERY.getDerivedColumnName("mobile", 
identifierContext)));
+        assertThat(actualProjections.get(2).getAlias().get().getValue(), 
is(EncryptDerivedColumnSuffix.LIKE_QUERY.getDerivedColumnName("mobile", 
identifierContext)));
+    }
 }
diff --git 
a/features/readwrite-splitting/core/src/main/java/org/apache/shardingsphere/readwritesplitting/checker/ReadwriteSplittingDataSourceRuleConfigurationChecker.java
 
b/features/readwrite-splitting/core/src/main/java/org/apache/shardingsphere/readwritesplitting/checker/ReadwriteSplittingDataSourceRuleConfigurationChecker.java
index bbe997145a4..6691f88bf1c 100644
--- 
a/features/readwrite-splitting/core/src/main/java/org/apache/shardingsphere/readwritesplitting/checker/ReadwriteSplittingDataSourceRuleConfigurationChecker.java
+++ 
b/features/readwrite-splitting/core/src/main/java/org/apache/shardingsphere/readwritesplitting/checker/ReadwriteSplittingDataSourceRuleConfigurationChecker.java
@@ -36,8 +36,6 @@ import java.util.Map;
  */
 public final class ReadwriteSplittingDataSourceRuleConfigurationChecker {
     
-    private final String databaseName;
-    
     private final ReadwriteSplittingDataSourceGroupRuleConfiguration config;
     
     private final Map<String, DataSource> dataSourceMap;
@@ -46,7 +44,6 @@ public final class 
ReadwriteSplittingDataSourceRuleConfigurationChecker {
     
     public ReadwriteSplittingDataSourceRuleConfigurationChecker(final String 
databaseName,
                                                                 final 
ReadwriteSplittingDataSourceGroupRuleConfiguration config, final Map<String, 
DataSource> dataSourceMap) {
-        this.databaseName = databaseName;
         this.config = config;
         this.dataSourceMap = dataSourceMap;
         exceptionIdentifier = new 
ReadwriteSplittingRuleExceptionIdentifier(databaseName, config.getName());
diff --git 
a/features/sharding/core/src/main/java/org/apache/shardingsphere/sharding/util/ShardingValueTypeConvertUtils.java
 
b/features/sharding/core/src/main/java/org/apache/shardingsphere/sharding/util/ShardingValueTypeConvertUtils.java
index 7347a0a30c4..e70096f4a04 100644
--- 
a/features/sharding/core/src/main/java/org/apache/shardingsphere/sharding/util/ShardingValueTypeConvertUtils.java
+++ 
b/features/sharding/core/src/main/java/org/apache/shardingsphere/sharding/util/ShardingValueTypeConvertUtils.java
@@ -24,6 +24,7 @@ import java.math.BigDecimal;
 import java.math.BigInteger;
 import java.sql.Time;
 import java.sql.Timestamp;
+import java.time.DateTimeException;
 import java.time.Duration;
 import java.time.Instant;
 import java.time.LocalDate;
@@ -33,6 +34,7 @@ import java.time.MonthDay;
 import java.time.Year;
 import java.time.YearMonth;
 import java.time.ZoneId;
+import java.time.format.DateTimeParseException;
 import java.util.Collection;
 import java.util.Date;
 import java.util.LinkedList;
@@ -424,9 +426,7 @@ public final class ShardingValueTypeConvertUtils {
     private static Instant parseInstant(final String value) {
         try {
             return Instant.parse(value);
-            // CHECKSTYLE:OFF
-        } catch (final Exception ignored) {
-            // CHECKSTYLE:ON
+        } catch (final DateTimeParseException ignored) {
             return parseInstantByLocalDateTime(value);
         }
     }
@@ -434,9 +434,7 @@ public final class ShardingValueTypeConvertUtils {
     private static Instant parseInstantByLocalDateTime(final String value) {
         try {
             return 
LocalDateTime.parse(value).atZone(ZoneId.systemDefault()).toInstant();
-            // CHECKSTYLE:OFF
-        } catch (final Exception ignored) {
-            // CHECKSTYLE:ON
+        } catch (final DateTimeException ignored) {
             return 
LocalDate.parse(value).atStartOfDay(ZoneId.systemDefault()).toInstant();
         }
     }
@@ -444,9 +442,7 @@ public final class ShardingValueTypeConvertUtils {
     private static LocalDate parseLocalDate(final String value) {
         try {
             return LocalDate.parse(value);
-            // CHECKSTYLE:OFF
-        } catch (final Exception ignored) {
-            // CHECKSTYLE:ON
+        } catch (final DateTimeParseException ignored) {
             return LocalDateTime.parse(value).toLocalDate();
         }
     }
@@ -454,9 +450,7 @@ public final class ShardingValueTypeConvertUtils {
     private static LocalDateTime parseLocalDateTime(final String value) {
         try {
             return LocalDateTime.parse(value);
-            // CHECKSTYLE:OFF
-        } catch (final Exception ignored) {
-            // CHECKSTYLE:ON
+        } catch (final DateTimeParseException ignored) {
             return 
Instant.parse(value).atZone(ZoneId.systemDefault()).toLocalDateTime();
         }
     }
@@ -464,9 +458,7 @@ public final class ShardingValueTypeConvertUtils {
     private static LocalTime parseLocalTime(final String value) {
         try {
             return LocalTime.parse(value);
-            // CHECKSTYLE:OFF
-        } catch (final Exception ignored) {
-            // CHECKSTYLE:ON
+        } catch (final DateTimeParseException ignored) {
             return LocalDateTime.parse(value).toLocalTime();
         }
     }
diff --git 
a/features/sharding/core/src/test/java/org/apache/shardingsphere/sharding/util/ShardingValueTypeConvertUtilsTest.java
 
b/features/sharding/core/src/test/java/org/apache/shardingsphere/sharding/util/ShardingValueTypeConvertUtilsTest.java
index a20d2e3c350..d26244edcfa 100644
--- 
a/features/sharding/core/src/test/java/org/apache/shardingsphere/sharding/util/ShardingValueTypeConvertUtilsTest.java
+++ 
b/features/sharding/core/src/test/java/org/apache/shardingsphere/sharding/util/ShardingValueTypeConvertUtilsTest.java
@@ -20,6 +20,7 @@ package org.apache.shardingsphere.sharding.util;
 import org.junit.jupiter.params.ParameterizedTest;
 import org.junit.jupiter.params.provider.Arguments;
 import org.junit.jupiter.params.provider.MethodSource;
+import org.junit.jupiter.params.provider.ValueSource;
 
 import java.math.BigDecimal;
 import java.math.BigInteger;
@@ -34,6 +35,7 @@ import java.time.MonthDay;
 import java.time.Year;
 import java.time.YearMonth;
 import java.time.ZoneId;
+import java.time.format.DateTimeParseException;
 import java.util.Arrays;
 import java.util.Collection;
 import java.util.Date;
@@ -42,6 +44,7 @@ import java.util.stream.Stream;
 import static org.hamcrest.MatcherAssert.assertThat;
 import static org.hamcrest.Matchers.is;
 import static org.hamcrest.Matchers.isA;
+import static org.junit.jupiter.api.Assertions.assertThrows;
 
 class ShardingValueTypeConvertUtilsTest {
     
@@ -51,6 +54,12 @@ class ShardingValueTypeConvertUtilsTest {
         assertThat(ShardingValueTypeConvertUtils.convertToTargetType(value, 
targetType), is(expected));
     }
     
+    @ParameterizedTest(name = "{0}")
+    @ValueSource(classes = {Instant.class, LocalDate.class, 
LocalDateTime.class, Time.class})
+    void assertConvertToTargetTypeWithInvalidTemporalValue(final Class<?> 
targetType) {
+        assertThrows(DateTimeParseException.class, () -> 
ShardingValueTypeConvertUtils.convertToTargetType("2024-08-05T25:30:45", 
targetType));
+    }
+    
     @ParameterizedTest(name = "{0}")
     @MethodSource("convertCollectionTypeArguments")
     void assertConvertCollectionType(final String name, final 
Collection<Comparable<?>> source, final Class<?> targetType, final int 
expectedSize, final Class<?> expectedElementType) {
@@ -128,6 +137,7 @@ class ShardingValueTypeConvertUtilsTest {
                 Arguments.of("SqlDate <- String(LocalDate)", "2024-08-05", 
java.sql.Date.class, java.sql.Date.valueOf(LocalDate.of(2024, 8, 5))),
                 Arguments.of("SqlTime <- LocalTime", LocalTime.of(12, 30, 45), 
Time.class, Time.valueOf(LocalTime.of(12, 30, 45))),
                 Arguments.of("SqlTime <- String", "12:30:45", Time.class, 
Time.valueOf(LocalTime.of(12, 30, 45))),
+                Arguments.of("SqlTime <- String(LocalDateTime)", 
"2024-08-05T12:30:45", Time.class, Time.valueOf(LocalTime.of(12, 30, 45))),
                 Arguments.of("Timestamp <- LocalDateTime", 
LocalDateTime.of(2024, 1, 1, 12, 30, 45), Timestamp.class, 
Timestamp.valueOf(LocalDateTime.of(2024, 1, 1, 12, 30, 45))),
                 Arguments.of("Timestamp <- Instant", 
Instant.parse("2024-01-01T12:30:45Z"), Timestamp.class, 
Timestamp.from(Instant.parse("2024-01-01T12:30:45Z"))),
                 Arguments.of("Timestamp <- String", "2024-08-05T12:30:45", 
Timestamp.class, Timestamp.from(LocalDateTime.of(2024, 8, 5, 12, 30, 
45).atZone(ZoneId.systemDefault()).toInstant())),
@@ -144,6 +154,7 @@ class ShardingValueTypeConvertUtilsTest {
                 Arguments.of("LocalDateTime <- LocalDate", LocalDate.of(2024, 
1, 1), LocalDateTime.class, LocalDateTime.of(2024, 1, 1, 0, 0)),
                 Arguments.of("LocalDateTime <- Timestamp", 
Timestamp.valueOf("2024-01-01 12:30:45"), LocalDateTime.class, 
LocalDateTime.of(2024, 1, 1, 12, 30, 45)),
                 Arguments.of("LocalDateTime <- String", "2024-08-05T12:30:45", 
LocalDateTime.class, LocalDateTime.of(2024, 8, 5, 12, 30, 45)),
+                Arguments.of("LocalDateTime <- String(Instant)", 
"2024-08-05T12:30:45Z", LocalDateTime.class, 
Instant.parse("2024-08-05T12:30:45Z").atZone(ZoneId.systemDefault()).toLocalDateTime()),
                 Arguments.of("Instant <- Long", 1704067200000L, Instant.class, 
Instant.ofEpochMilli(1704067200000L)),
                 Arguments.of("Instant <- String", "2024-08-05T12:30:45Z", 
Instant.class, Instant.parse("2024-08-05T12:30:45Z")),
                 Arguments.of("Instant <- String(LocalDate)", "2024-08-05", 
Instant.class, LocalDate.of(2024, 8, 
5).atStartOfDay(ZoneId.systemDefault()).toInstant()),
diff --git 
a/infra/common/src/main/java/org/apache/shardingsphere/infra/props/TypedPropertyValue.java
 
b/infra/common/src/main/java/org/apache/shardingsphere/infra/props/TypedPropertyValue.java
index 95b400bf4e4..c81bdacfb44 100644
--- 
a/infra/common/src/main/java/org/apache/shardingsphere/infra/props/TypedPropertyValue.java
+++ 
b/infra/common/src/main/java/org/apache/shardingsphere/infra/props/TypedPropertyValue.java
@@ -39,33 +39,21 @@ public final class TypedPropertyValue {
         if (boolean.class == key.getType() || Boolean.class == key.getType()) {
             return Boolean.valueOf(value);
         }
-        if (int.class == key.getType() || Integer.class == key.getType()) {
-            try {
+        try {
+            if (int.class == key.getType() || Integer.class == key.getType()) {
                 return Integer.valueOf(value);
-            } catch (final NumberFormatException ignored) {
-                throw new TypedPropertyValueException(key, value);
             }
-        }
-        if (long.class == key.getType() || Long.class == key.getType()) {
-            try {
+            if (long.class == key.getType() || Long.class == key.getType()) {
                 return Long.valueOf(value);
-            } catch (final NumberFormatException ignored) {
-                throw new TypedPropertyValueException(key, value);
             }
-        }
-        if (float.class == key.getType() || Float.class == key.getType()) {
-            try {
+            if (float.class == key.getType() || Float.class == key.getType()) {
                 return Float.valueOf(value);
-            } catch (final NumberFormatException ignored) {
-                throw new TypedPropertyValueException(key, value);
             }
-        }
-        if (double.class == key.getType() || Double.class == key.getType()) {
-            try {
+            if (double.class == key.getType() || Double.class == 
key.getType()) {
                 return Double.valueOf(value);
-            } catch (final NumberFormatException ignored) {
-                throw new TypedPropertyValueException(key, value);
             }
+        } catch (final NumberFormatException ignored) {
+            throw new TypedPropertyValueException(key, value);
         }
         if (Enum.class.isAssignableFrom(key.getType())) {
             return getEnumValue(key, value);
diff --git 
a/infra/common/src/test/java/org/apache/shardingsphere/infra/props/TypedPropertyValueTest.java
 
b/infra/common/src/test/java/org/apache/shardingsphere/infra/props/TypedPropertyValueTest.java
index f00555cfe68..7450d1800f2 100644
--- 
a/infra/common/src/test/java/org/apache/shardingsphere/infra/props/TypedPropertyValueTest.java
+++ 
b/infra/common/src/test/java/org/apache/shardingsphere/infra/props/TypedPropertyValueTest.java
@@ -53,7 +53,8 @@ class TypedPropertyValueTest {
     @ParameterizedTest(name = "{0}")
     @MethodSource("getInvalidNumberValueArguments")
     void assertGetInvalidNumberValue(final String name, final TypedPropertyKey 
key) {
-        assertThrows(TypedPropertyValueException.class, () -> new 
TypedPropertyValue(key, "test"));
+        TypedPropertyValueException actual = 
assertThrows(TypedPropertyValueException.class, () -> new 
TypedPropertyValue(key, "test"));
+        assertThat(actual.getMessage(), is(String.format("Value `test` of `%s` 
cannot convert to type `%s`", key.getKey(), key.getType().getName())));
     }
     
     @Test
diff --git 
a/infra/expr/type/groovy/src/main/java/org/apache/shardingsphere/infra/expr/groovy/GroovyInlineExpressionParser.java
 
b/infra/expr/type/groovy/src/main/java/org/apache/shardingsphere/infra/expr/groovy/GroovyInlineExpressionParser.java
index 27e895f17dc..8a5d9eb13c9 100644
--- 
a/infra/expr/type/groovy/src/main/java/org/apache/shardingsphere/infra/expr/groovy/GroovyInlineExpressionParser.java
+++ 
b/infra/expr/type/groovy/src/main/java/org/apache/shardingsphere/infra/expr/groovy/GroovyInlineExpressionParser.java
@@ -43,6 +43,7 @@ import java.util.List;
 import java.util.Map;
 import java.util.Properties;
 import java.util.Set;
+import java.util.regex.Pattern;
 import java.util.stream.Collectors;
 
 /**
@@ -52,6 +53,10 @@ public final class GroovyInlineExpressionParser implements 
InlineExpressionParse
     
     private static final String INLINE_EXPRESSION_KEY = "inlineExpression";
     
+    private static final Pattern INLINE_EXPRESSION_SPLIT_PATTERN = 
Pattern.compile("\\s*,\\s*");
+    
+    private static final Pattern CONSTANT_EXPRESSION_QUOTES_PATTERN = 
Pattern.compile("(^\")|(\"$)");
+    
     private static final GroovyShell SHELL = new GroovyShell();
     
     private static volatile long currentCacheSize = 
Long.parseLong(ConfigurationPropertyKey.GROOVY_INLINE_EXPRESSION_PARSING_CACHE_MAX_SIZE.getDefaultValue());
@@ -94,7 +99,7 @@ public final class GroovyInlineExpressionParser implements 
InlineExpressionParse
             return Collections.emptyList();
         }
         if (isConstantExpression(inlineExpression)) {
-            return 
Arrays.stream(inlineExpression.split("\\s*,\\s*")).map(String::trim).filter(each
 -> !each.isEmpty()).collect(Collectors.toList());
+            return 
Arrays.stream(INLINE_EXPRESSION_SPLIT_PATTERN.split(inlineExpression)).map(String::trim).filter(each
 -> !each.isEmpty()).collect(Collectors.toList());
         }
         return 
flatten(evaluate(GroovyUtils.split(handlePlaceHolder(inlineExpression))));
     }
@@ -135,7 +140,7 @@ public final class GroovyInlineExpressionParser implements 
InlineExpressionParse
     
     private Object evaluate(final String expression) {
         if (isConstantExpression(expression)) {
-            return expression.replaceAll("(^\")|(\"$)", "");
+            return 
CONSTANT_EXPRESSION_QUOTES_PATTERN.matcher(expression).replaceAll("");
         }
         Script script = scriptCache.get(expression, SHELL::parse);
         return null == script ? expression : script.run();
diff --git 
a/jdbc/src/main/java/org/apache/shardingsphere/driver/executor/engine/batch/preparedstatement/DriverExecuteBatchExecutor.java
 
b/jdbc/src/main/java/org/apache/shardingsphere/driver/executor/engine/batch/preparedstatement/DriverExecuteBatchExecutor.java
index 23c0f7f4fe1..c6970621a87 100644
--- 
a/jdbc/src/main/java/org/apache/shardingsphere/driver/executor/engine/batch/preparedstatement/DriverExecuteBatchExecutor.java
+++ 
b/jdbc/src/main/java/org/apache/shardingsphere/driver/executor/engine/batch/preparedstatement/DriverExecuteBatchExecutor.java
@@ -107,7 +107,7 @@ public final class DriverExecuteBatchExecutor {
      * @return generated keys
      * @throws SQLException SQL exception
      */
-    @SuppressWarnings("rawtypes")
+    @SuppressWarnings({"rawtypes", "unchecked"})
     public int[] executeBatch(final ShardingSphereDatabase database, final 
SQLStatementContext sqlStatementContext, final Collection<Comparable<?>> 
generatedValues,
                               final StatementOption statementOption, final 
StatementAddCallback addCallback, final 
PreparedStatementParametersReplayCallback replayCallback,
                               final GeneratedKeyCallback generatedKeyCallback) 
throws SQLException {
@@ -115,18 +115,10 @@ public final class DriverExecuteBatchExecutor {
             return new int[0];
         }
         // TODO add raw SQL executor
-        return doExecuteBatch(database, batchPreparedStatementExecutor, 
sqlStatementContext, generatedValues, statementOption, executionContext, 
addCallback, replayCallback, generatedKeyCallback);
-    }
-    
-    @SuppressWarnings({"rawtypes", "unchecked"})
-    private int[] doExecuteBatch(final ShardingSphereDatabase database, final 
BatchPreparedStatementExecutor batchExecutor,
-                                 final SQLStatementContext 
sqlStatementContext, final Collection<Comparable<?>> generatedValues, final 
StatementOption statementOption,
-                                 final ExecutionContext executionContext, 
final StatementAddCallback addCallback, final 
PreparedStatementParametersReplayCallback replayCallback,
-                                 final GeneratedKeyCallback 
generatedKeyCallback) throws SQLException {
-        initBatchPreparedStatementExecutor(database, batchExecutor, 
executionContext, replayCallback);
-        int[] result = batchExecutor.executeBatch(sqlStatementContext);
+        initBatchPreparedStatementExecutor(database, 
batchPreparedStatementExecutor, executionContext, replayCallback);
+        int[] result = 
batchPreparedStatementExecutor.executeBatch(sqlStatementContext);
         if (statementOption.isReturnGeneratedKeys() && 
generatedValues.isEmpty()) {
-            addCallback.add(batchExecutor.getStatements(), 
Collections.emptyList());
+            addCallback.add(batchPreparedStatementExecutor.getStatements(), 
Collections.emptyList());
             generatedKeyCallback.generateKeys();
         }
         return result;
diff --git 
a/jdbc/src/main/java/org/apache/shardingsphere/driver/jdbc/core/resultset/MySQLResultSetValueConverter.java
 
b/jdbc/src/main/java/org/apache/shardingsphere/driver/jdbc/core/resultset/MySQLResultSetValueConverter.java
index 2308ff7f0b2..12721b70d05 100644
--- 
a/jdbc/src/main/java/org/apache/shardingsphere/driver/jdbc/core/resultset/MySQLResultSetValueConverter.java
+++ 
b/jdbc/src/main/java/org/apache/shardingsphere/driver/jdbc/core/resultset/MySQLResultSetValueConverter.java
@@ -46,7 +46,7 @@ public final class MySQLResultSetValueConverter implements 
DialectResultSetValue
             switch (convertType.getName()) {
                 case "boolean":
                 case "java.lang.Boolean":
-                    return stringValue.isEmpty() ? false : 
convertBooleanValue(stringValue, convertType);
+                    return !stringValue.isEmpty() && 
convertBooleanValue(stringValue, convertType);
                 case "byte":
                 case "java.lang.Byte":
                     return stringValue.isEmpty() ? (byte) 0 : 
convertByteValue(stringValue, convertType);
diff --git 
a/jdbc/src/main/java/org/apache/shardingsphere/driver/jdbc/core/statement/DistSQLStatementExecutor.java
 
b/jdbc/src/main/java/org/apache/shardingsphere/driver/jdbc/core/statement/DistSQLStatementExecutor.java
index 29fb349f970..3ea330e060d 100644
--- 
a/jdbc/src/main/java/org/apache/shardingsphere/driver/jdbc/core/statement/DistSQLStatementExecutor.java
+++ 
b/jdbc/src/main/java/org/apache/shardingsphere/driver/jdbc/core/statement/DistSQLStatementExecutor.java
@@ -65,7 +65,7 @@ final class DistSQLStatementExecutor {
         new DistSQLUpdateExecuteEngine(sqlStatement, 
connection.getCurrentDatabaseName(), connection.getContextManager(), 
createConnectionContext(queryContext)).executeUpdate();
     }
     
-    boolean isQuery(final QueryContext queryContext) throws SQLException {
+    boolean isQuery(final QueryContext queryContext) {
         DistSQLStatement sqlStatement = (DistSQLStatement) 
queryContext.getSqlStatementContext().getSqlStatement();
         checkTransaction(sqlStatement);
         ShardingSpherePreconditions.checkState(isQuery(sqlStatement) || 
isUpdate(sqlStatement), () -> new 
UnsupportedSQLOperationException(sqlStatement.getClass().getName()));
diff --git 
a/kernel/single/core/src/main/java/org/apache/shardingsphere/single/rule/attribute/SingleMutableDataNodeRuleAttribute.java
 
b/kernel/single/core/src/main/java/org/apache/shardingsphere/single/rule/attribute/SingleMutableDataNodeRuleAttribute.java
index 1dfef5371e1..9306fd1ff2b 100644
--- 
a/kernel/single/core/src/main/java/org/apache/shardingsphere/single/rule/attribute/SingleMutableDataNodeRuleAttribute.java
+++ 
b/kernel/single/core/src/main/java/org/apache/shardingsphere/single/rule/attribute/SingleMutableDataNodeRuleAttribute.java
@@ -96,34 +96,38 @@ public final class SingleMutableDataNodeRuleAttribute 
implements MutableDataNode
     @Override
     public void remove(final Collection<String> schemaNames, final String 
tableName) {
         for (String each : findMatchedTableKeys(tableName)) {
-            Collection<DataNode> dataNodes = singleTableDataNodes.get(each);
-            if (null == dataNodes) {
-                continue;
-            }
-            Collection<String> removedDataNodeStrings = new LinkedList<>();
-            Iterator<DataNode> iterator = dataNodes.iterator();
-            while (iterator.hasNext()) {
-                DataNode dataNode = iterator.next();
-                if (schemaNames.contains(dataNode.getSchemaName())) {
-                    iterator.remove();
-                    removedDataNodeStrings.add(getDataNodeString(dataNode, 
each));
-                }
+            removeTableDataNodes(schemaNames, each);
+        }
+    }
+    
+    private void removeTableDataNodes(final Collection<String> schemaNames, 
final String tableName) {
+        Collection<DataNode> dataNodes = singleTableDataNodes.get(tableName);
+        if (null == dataNodes) {
+            return;
+        }
+        Collection<String> removedDataNodeStrings = new LinkedList<>();
+        Iterator<DataNode> iterator = dataNodes.iterator();
+        while (iterator.hasNext()) {
+            DataNode dataNode = iterator.next();
+            if (schemaNames.contains(dataNode.getSchemaName())) {
+                iterator.remove();
+                removedDataNodeStrings.add(getDataNodeString(dataNode, 
tableName));
             }
-            if (!removedDataNodeStrings.isEmpty()) {
-                Collection<String> retainedDataNodeStrings = new 
LinkedHashSet<>(dataNodes.size(), 1F);
-                for (DataNode dataNode : dataNodes) {
-                    retainedDataNodeStrings.add(getDataNodeString(dataNode, 
each));
-                }
-                removedDataNodeStrings.removeAll(retainedDataNodeStrings);
-                for (String removedDataNodeString : removedDataNodeStrings) {
-                    configuration.getTables().remove(removedDataNodeString);
-                }
+        }
+        if (!removedDataNodeStrings.isEmpty()) {
+            Collection<String> retainedDataNodeStrings = new 
LinkedHashSet<>(dataNodes.size(), 1F);
+            for (DataNode each : dataNodes) {
+                retainedDataNodeStrings.add(getDataNodeString(each, 
tableName));
             }
-            if (dataNodes.isEmpty()) {
-                singleTableDataNodes.remove(each);
-                tableMapperRuleAttribute.getLogicTableNames().remove(each);
+            removedDataNodeStrings.removeAll(retainedDataNodeStrings);
+            for (String each : removedDataNodeStrings) {
+                configuration.getTables().remove(each);
             }
         }
+        if (dataNodes.isEmpty()) {
+            singleTableDataNodes.remove(tableName);
+            tableMapperRuleAttribute.getLogicTableNames().remove(tableName);
+        }
     }
     
     private String getDataNodeString(final DataNode dataNode, final String 
tableName) {
diff --git 
a/kernel/single/core/src/test/java/org/apache/shardingsphere/single/rule/attribute/SingleMutableDataNodeRuleAttributeTest.java
 
b/kernel/single/core/src/test/java/org/apache/shardingsphere/single/rule/attribute/SingleMutableDataNodeRuleAttributeTest.java
index 27128f3ab46..fbca0e9d411 100644
--- 
a/kernel/single/core/src/test/java/org/apache/shardingsphere/single/rule/attribute/SingleMutableDataNodeRuleAttributeTest.java
+++ 
b/kernel/single/core/src/test/java/org/apache/shardingsphere/single/rule/attribute/SingleMutableDataNodeRuleAttributeTest.java
@@ -132,6 +132,22 @@ class SingleMutableDataNodeRuleAttributeTest {
         assertTrue(tableMapperRuleAttribute.getLogicTableNames().isEmpty());
     }
     
+    @Test
+    void assertRemoveWithCaseInsensitiveTableNames() {
+        Collection<DataNode> initialDataNodes = Arrays.asList(new 
DataNode("foo_ds", "foo_schema", "Foo_Tbl"), new DataNode("foo_ds", 
"foo_schema", "FOO_TBL"));
+        SingleRuleConfiguration ruleConfig = new SingleRuleConfiguration(new 
LinkedList<>(createDataNodeStrings(initialDataNodes)), null);
+        Map<String, Collection<DataNode>> singleTableDataNodes = new 
LinkedHashMap<>(2, 1F);
+        for (DataNode each : initialDataNodes) {
+            singleTableDataNodes.put(each.getTableName(), new 
LinkedHashSet<>(Collections.singleton(each)));
+        }
+        SingleTableMapperRuleAttribute tableMapperRuleAttribute = new 
SingleTableMapperRuleAttribute(singleTableDataNodes.values());
+        SingleMutableDataNodeRuleAttribute ruleAttribute = 
createRuleAttribute(ruleConfig, Collections.singleton("foo_ds"), 
singleTableDataNodes, tableMapperRuleAttribute);
+        ruleAttribute.remove(Collections.singleton("foo_schema"), "foo_tbl");
+        assertTrue(singleTableDataNodes.isEmpty());
+        assertTrue(ruleConfig.getTables().isEmpty());
+        assertTrue(tableMapperRuleAttribute.getLogicTableNames().isEmpty());
+    }
+    
     @ParameterizedTest(name = "{0}")
     @MethodSource("findTableDataNodeArguments")
     void assertFindTableDataNode(final String name, final Collection<DataNode> 
initialDataNodes, final String schemaName, final String tableName,
diff --git 
a/kernel/sql-federation/compiler/src/main/java/org/apache/shardingsphere/sqlfederation/compiler/sql/ast/converter/segment/expression/impl/LiteralExpressionConverter.java
 
b/kernel/sql-federation/compiler/src/main/java/org/apache/shardingsphere/sqlfederation/compiler/sql/ast/converter/segment/expression/impl/LiteralExpressionConverter.java
index 5b4272952ab..83058a9de29 100644
--- 
a/kernel/sql-federation/compiler/src/main/java/org/apache/shardingsphere/sqlfederation/compiler/sql/ast/converter/segment/expression/impl/LiteralExpressionConverter.java
+++ 
b/kernel/sql-federation/compiler/src/main/java/org/apache/shardingsphere/sqlfederation/compiler/sql/ast/converter/segment/expression/impl/LiteralExpressionConverter.java
@@ -31,6 +31,7 @@ import org.apache.calcite.util.TimestampString;
 import org.apache.calcite.util.TimestampWithTimeZoneString;
 import org.apache.shardingsphere.infra.util.datetime.DateTimeFormatterFactory;
 import 
org.apache.shardingsphere.sql.parser.statement.core.segment.dml.expr.simple.LiteralExpressionSegment;
+import org.checkerframework.checker.nullness.qual.Nullable;
 
 import java.sql.Time;
 import java.sql.Timestamp;
@@ -89,11 +90,7 @@ public final class LiteralExpressionConverter {
             return Optional.of(convertLocalTime(segment, literalValue, 
dataType));
         }
         if (segment.getLiterals() instanceof LocalDateTime) {
-            LocalDateTime dateTime = (LocalDateTime) segment.getLiterals();
-            String fraction = literalValue.contains(".") ? 
literalValue.substring(literalValue.lastIndexOf('.') + 1) : "";
-            TimestampString timestampString = 
TimestampString.fromCalendarFields(toCalendar(dateTime.getYear(), 
dateTime.getMonthValue(),
-                    dateTime.getDayOfMonth(), dateTime.getHour(), 
dateTime.getMinute(), dateTime.getSecond())).withFraction(fraction);
-            return 
Optional.of(SqlLiteral.createTimestamp(SqlTypeName.TIMESTAMP, timestampString, 
getTimeScale(literalValue, dataType), SqlParserPos.ZERO));
+            return Optional.of(convertLocalDateTime(segment, literalValue, 
dataType));
         }
         if (segment.getLiterals() instanceof ZonedDateTime) {
             return Optional.of(SqlLiteral.createTimestamp(new 
TimestampWithTimeZoneString(literalValue), getTimeScale(literalValue, 
dataType), SqlParserPos.ZERO));
@@ -148,6 +145,14 @@ public final class LiteralExpressionConverter {
         return SqlLiteral.createTime(new TimeString(formattedValue), 
getTimeScale(literalValue, dataType), SqlParserPos.ZERO);
     }
     
+    private static SqlNode convertLocalDateTime(final LiteralExpressionSegment 
segment, final String literalValue, @Nullable final RelDataType dataType) {
+        LocalDateTime dateTime = (LocalDateTime) segment.getLiterals();
+        String fraction = literalValue.contains(".") ? 
literalValue.substring(literalValue.lastIndexOf('.') + 1) : "";
+        TimestampString timestampString = 
TimestampString.fromCalendarFields(toCalendar(dateTime.getYear(), 
dateTime.getMonthValue(), dateTime.getDayOfMonth(), dateTime.getHour(),
+                dateTime.getMinute(), 
dateTime.getSecond())).withFraction(fraction);
+        return SqlLiteral.createTimestamp(SqlTypeName.TIMESTAMP, 
timestampString, getTimeScale(literalValue, dataType), SqlParserPos.ZERO);
+    }
+    
     private static int getTimeScale(final String literalValue, final 
RelDataType dataType) {
         if (null != dataType && dataType.getScale() > 0) {
             return dataType.getScale();
diff --git 
a/kernel/sql-federation/compiler/src/test/java/org/apache/shardingsphere/sqlfederation/compiler/sql/ast/converter/segment/expression/impl/LiteralExpressionConverterTest.java
 
b/kernel/sql-federation/compiler/src/test/java/org/apache/shardingsphere/sqlfederation/compiler/sql/ast/converter/segment/expression/impl/LiteralExpressionConverterTest.java
index 7d43d8c701c..26b9818672b 100644
--- 
a/kernel/sql-federation/compiler/src/test/java/org/apache/shardingsphere/sqlfederation/compiler/sql/ast/converter/segment/expression/impl/LiteralExpressionConverterTest.java
+++ 
b/kernel/sql-federation/compiler/src/test/java/org/apache/shardingsphere/sqlfederation/compiler/sql/ast/converter/segment/expression/impl/LiteralExpressionConverterTest.java
@@ -17,13 +17,19 @@
 
 package 
org.apache.shardingsphere.sqlfederation.compiler.sql.ast.converter.segment.expression.impl;
 
+import org.apache.calcite.rel.type.RelDataType;
 import org.apache.calcite.runtime.CalciteException;
 import org.apache.calcite.sql.SqlLiteral;
 import org.apache.calcite.sql.SqlNumericLiteral;
+import org.apache.calcite.sql.SqlTimestampLiteral;
 import org.apache.calcite.sql.type.SqlTypeName;
 import org.apache.calcite.util.TimeString;
 import 
org.apache.shardingsphere.sql.parser.statement.core.segment.dml.expr.simple.LiteralExpressionSegment;
+import org.checkerframework.checker.nullness.qual.Nullable;
 import org.junit.jupiter.api.Test;
+import org.junit.jupiter.params.ParameterizedTest;
+import org.junit.jupiter.params.provider.Arguments;
+import org.junit.jupiter.params.provider.MethodSource;
 
 import java.sql.Date;
 import java.sql.Time;
@@ -35,6 +41,7 @@ import java.time.ZoneId;
 import java.time.ZonedDateTime;
 import java.util.Calendar;
 import java.util.Optional;
+import java.util.stream.Stream;
 
 import static org.hamcrest.MatcherAssert.assertThat;
 import static org.hamcrest.Matchers.is;
@@ -42,6 +49,8 @@ import static org.junit.jupiter.api.Assertions.assertFalse;
 import static org.junit.jupiter.api.Assertions.assertNotNull;
 import static org.junit.jupiter.api.Assertions.assertThrows;
 import static org.junit.jupiter.api.Assertions.assertTrue;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.when;
 
 class LiteralExpressionConverterTest {
     
@@ -162,11 +171,23 @@ class LiteralExpressionConverterTest {
         assertThat(actual.getTypeName(), is(SqlTypeName.TIME));
     }
     
-    @Test
-    void assertConvertLocalDateTime() {
-        SqlLiteral actual = (SqlLiteral) 
LiteralExpressionConverter.convert(new LiteralExpressionSegment(0, 0, 
LocalDateTime.of(2020, 1, 1, 1, 1, 1)), null).orElse(null);
+    @ParameterizedTest(name = "{0}")
+    @MethodSource("getLocalDateTimeArguments")
+    void assertConvertLocalDateTime(final String name, final LocalDateTime 
dateTime, @Nullable final RelDataType dataType, final String expectedTimestamp, 
final int expectedPrecision) {
+        SqlTimestampLiteral actual = (SqlTimestampLiteral) 
LiteralExpressionConverter.convert(new LiteralExpressionSegment(0, 0, 
dateTime), dataType).orElse(null);
         assertNotNull(actual);
         assertThat(actual.getTypeName(), is(SqlTypeName.TIMESTAMP));
+        assertThat(actual.getTimestamp().toString(), is(expectedTimestamp));
+        assertThat(actual.getPrec(), is(expectedPrecision));
+    }
+    
+    private static Stream<Arguments> getLocalDateTimeArguments() {
+        RelDataType dataType = mock(RelDataType.class);
+        when(dataType.getScale()).thenReturn(6);
+        return Stream.of(
+                Arguments.of("without fraction", LocalDateTime.of(2020, 1, 1, 
1, 1, 1), null, "2020-01-01 01:01:01", 0),
+                Arguments.of("inferred fractional precision", 
LocalDateTime.of(2020, 1, 1, 1, 1, 1, 123000000), null, "2020-01-01 
01:01:01.123", 4),
+                Arguments.of("data type precision", LocalDateTime.of(2020, 1, 
1, 1, 1, 1, 123000000), dataType, "2020-01-01 01:01:01.123", 6));
     }
     
     @Test
diff --git 
a/kernel/sql-federation/provider/calcite/src/main/java/org/apache/shardingsphere/sqlfederation/provider/calcite/CalciteSQLFederationExecutor.java
 
b/kernel/sql-federation/provider/calcite/src/main/java/org/apache/shardingsphere/sqlfederation/provider/calcite/CalciteSQLFederationExecutor.java
index c1208d56243..95bfc192e40 100644
--- 
a/kernel/sql-federation/provider/calcite/src/main/java/org/apache/shardingsphere/sqlfederation/provider/calcite/CalciteSQLFederationExecutor.java
+++ 
b/kernel/sql-federation/provider/calcite/src/main/java/org/apache/shardingsphere/sqlfederation/provider/calcite/CalciteSQLFederationExecutor.java
@@ -70,6 +70,7 @@ import java.util.Collections;
 import java.util.LinkedList;
 import java.util.List;
 import java.util.Optional;
+import java.util.regex.Pattern;
 
 /**
  * Calcite SQL federation executor.
@@ -83,6 +84,8 @@ public final class CalciteSQLFederationExecutor implements 
SQLFederationExecutor
     
     private static final int MAX_ERROR_MESSAGE_LENGTH = 5000;
     
+    private static final Pattern EXECUTION_PLAN_ID_PATTERN = 
Pattern.compile(", id = \\d+");
+    
     private final String currentDatabaseName;
     
     private final String currentSchemaName;
@@ -183,7 +186,7 @@ public final class CalciteSQLFederationExecutor implements 
SQLFederationExecutor
     
     private void logExecutionPlan(final SQLFederationExecutionPlan 
executionPlan, final ConfigurationProperties props) {
         if (props.<Boolean>getValue(ConfigurationPropertyKey.SQL_SHOW)) {
-            log.info("SQL Federation Execution Plan: {}", 
RelOptUtil.toString(executionPlan.getPhysicalPlan(), 
SqlExplainLevel.ALL_ATTRIBUTES).replaceAll(", id = \\d+", ""));
+            log.info("SQL Federation Execution Plan: {}", 
EXECUTION_PLAN_ID_PATTERN.matcher(RelOptUtil.toString(executionPlan.getPhysicalPlan(),
 SqlExplainLevel.ALL_ATTRIBUTES)).replaceAll(""));
         }
     }
     
diff --git 
a/mode/core/src/main/java/org/apache/shardingsphere/mode/metadata/changed/RuleItemChangedNodePathBuilder.java
 
b/mode/core/src/main/java/org/apache/shardingsphere/mode/metadata/changed/RuleItemChangedNodePathBuilder.java
index 74ad7b384fd..c37c0c85a0d 100644
--- 
a/mode/core/src/main/java/org/apache/shardingsphere/mode/metadata/changed/RuleItemChangedNodePathBuilder.java
+++ 
b/mode/core/src/main/java/org/apache/shardingsphere/mode/metadata/changed/RuleItemChangedNodePathBuilder.java
@@ -62,6 +62,10 @@ public final class RuleItemChangedNodePathBuilder {
                 return Optional.of(databaseRuleNodePath);
             }
         }
+        return buildUniqueItem(databaseName, path, eventType, 
databaseRuleNode);
+    }
+    
+    private Optional<DatabaseRuleNodePath> buildUniqueItem(final String 
databaseName, final String path, final Type eventType, final DatabaseRuleNode 
databaseRuleNode) {
         for (String each : databaseRuleNode.getUniqueItems()) {
             DatabaseRuleNodePath databaseRuleNodePath = new 
DatabaseRuleNodePath(databaseName, databaseRuleNode.getRuleType(), new 
DatabaseRuleItem(each));
             if (Type.DELETED == eventType) {
diff --git 
a/mode/core/src/main/java/org/apache/shardingsphere/mode/metadata/refresher/pushdown/type/index/DropIndexPushDownMetaDataRefresher.java
 
b/mode/core/src/main/java/org/apache/shardingsphere/mode/metadata/refresher/pushdown/type/index/DropIndexPushDownMetaDataRefresher.java
index 96ee98473e8..be296bc96d5 100644
--- 
a/mode/core/src/main/java/org/apache/shardingsphere/mode/metadata/refresher/pushdown/type/index/DropIndexPushDownMetaDataRefresher.java
+++ 
b/mode/core/src/main/java/org/apache/shardingsphere/mode/metadata/refresher/pushdown/type/index/DropIndexPushDownMetaDataRefresher.java
@@ -49,7 +49,7 @@ public final class DropIndexPushDownMetaDataRefresher 
implements PushDownMetaDat
         for (IndexSegment each : sqlStatement.getIndexes()) {
             String actualSchemaName = 
SchemaRefreshUtils.getActualSchemaName(database,
                     
each.getOwner().map(OwnerSegment::getIdentifier).orElse(new 
IdentifierValue(schemaName)));
-            Optional<String> logicTableName = findActualTableName(database, 
actualSchemaName, sqlStatement, each, props);
+            Optional<String> logicTableName = findActualTableName(database, 
actualSchemaName, sqlStatement, each);
             if (!logicTableName.isPresent()) {
                 continue;
             }
@@ -63,8 +63,7 @@ public final class DropIndexPushDownMetaDataRefresher 
implements PushDownMetaDat
         }
     }
     
-    private Optional<String> findActualTableName(final ShardingSphereDatabase 
database, final String schemaName,
-                                                 final DropIndexStatement 
sqlStatement, final IndexSegment indexSegment, final ConfigurationProperties 
props) {
+    private Optional<String> findActualTableName(final ShardingSphereDatabase 
database, final String schemaName, final DropIndexStatement sqlStatement, final 
IndexSegment indexSegment) {
         Optional<SimpleTableSegment> simpleTableSegment = 
sqlStatement.getSimpleTable();
         if (simpleTableSegment.isPresent()) {
             return Optional.of(TableRefreshUtils.getActualTableName(database, 
schemaName, simpleTableSegment.get().getTableName().getIdentifier()));
diff --git 
a/mode/core/src/main/java/org/apache/shardingsphere/mode/metadata/refresher/pushdown/type/table/CreateTablePushDownMetaDataRefresher.java
 
b/mode/core/src/main/java/org/apache/shardingsphere/mode/metadata/refresher/pushdown/type/table/CreateTablePushDownMetaDataRefresher.java
index ba75eb563b8..0b7f35b104a 100644
--- 
a/mode/core/src/main/java/org/apache/shardingsphere/mode/metadata/refresher/pushdown/type/table/CreateTablePushDownMetaDataRefresher.java
+++ 
b/mode/core/src/main/java/org/apache/shardingsphere/mode/metadata/refresher/pushdown/type/table/CreateTablePushDownMetaDataRefresher.java
@@ -49,12 +49,11 @@ public final class CreateTablePushDownMetaDataRefresher 
implements PushDownMetaD
     public void refresh(final MetaDataManagerPersistService 
metaDataManagerPersistService, final ShardingSphereDatabase database, final 
String logicDataSourceName,
                         final String schemaName, final DatabaseType 
databaseType, final CreateTableStatement sqlStatement, final 
ConfigurationProperties props) throws SQLException {
         ShardingSphereTable loadedTable = 
metaDataLoader.loadCreatedTable(database, logicDataSourceName, schemaName, 
sqlStatement.getTable().getTableName().getIdentifier(), props,
-                createRevisionCandidateSchemas(database, schemaName, 
sqlStatement, props));
+                createRevisionCandidateSchemas(database, schemaName, 
sqlStatement));
         metaDataManagerPersistService.createTable(database, schemaName, 
loadedTable);
     }
     
-    private Collection<ShardingSphereSchema> 
createRevisionCandidateSchemas(final ShardingSphereDatabase database, final 
String schemaName,
-                                                                            
final CreateTableStatement sqlStatement, final ConfigurationProperties props) {
+    private Collection<ShardingSphereSchema> 
createRevisionCandidateSchemas(final ShardingSphereDatabase database, final 
String schemaName, final CreateTableStatement sqlStatement) {
         Collection<ShardingSphereIndex> indexes = 
createRevisionCandidateIndexes(sqlStatement);
         if (indexes.isEmpty()) {
             return database.getAllSchemas();
diff --git 
a/proxy/backend/dialect/mysql/src/main/java/org/apache/shardingsphere/proxy/backend/mysql/handler/admin/executor/MySQLSetVariableAdminExecutor.java
 
b/proxy/backend/dialect/mysql/src/main/java/org/apache/shardingsphere/proxy/backend/mysql/handler/admin/executor/MySQLSetVariableAdminExecutor.java
index 3ef23dec45d..5fd6b45bb39 100644
--- 
a/proxy/backend/dialect/mysql/src/main/java/org/apache/shardingsphere/proxy/backend/mysql/handler/admin/executor/MySQLSetVariableAdminExecutor.java
+++ 
b/proxy/backend/dialect/mysql/src/main/java/org/apache/shardingsphere/proxy/backend/mysql/handler/admin/executor/MySQLSetVariableAdminExecutor.java
@@ -125,11 +125,13 @@ public final class MySQLSetVariableAdminExecutor 
implements DatabaseAdminUpdateE
             return false;
         }
         VariableAssignSegment first = variableAssigns.get(0);
-        return 
CHARACTER_SET_CLIENT.equalsIgnoreCase(first.getVariable().getVariable())
-                && 
CHARACTER_SET_RESULTS.equalsIgnoreCase(variableAssigns.get(1).getVariable().getVariable())
-                && 
CHARACTER_SET_CONNECTION.equalsIgnoreCase(variableAssigns.get(2).getVariable().getVariable())
-                && 
COLLATION_CONNECTION.equalsIgnoreCase(variableAssigns.get(3).getVariable().getVariable())
-                && variableAssigns.subList(1, 4).stream().allMatch(each -> 
first.getStartIndex() == each.getStartIndex() && first.getStopIndex() == 
each.getStopIndex());
+        if 
(!CHARACTER_SET_CLIENT.equalsIgnoreCase(first.getVariable().getVariable())
+                || 
!CHARACTER_SET_RESULTS.equalsIgnoreCase(variableAssigns.get(1).getVariable().getVariable())
+                || 
!CHARACTER_SET_CONNECTION.equalsIgnoreCase(variableAssigns.get(2).getVariable().getVariable())
+                || 
!COLLATION_CONNECTION.equalsIgnoreCase(variableAssigns.get(3).getVariable().getVariable()))
 {
+            return false;
+        }
+        return variableAssigns.subList(1, 4).stream().allMatch(each -> 
first.getStartIndex() == each.getStartIndex() && first.getStopIndex() == 
each.getStopIndex());
     }
     
     private MySQLSessionCharsetContext updateCharsetContext(final 
MySQLSessionCharsetContext context, final VariableAssignSegment variableAssign,
@@ -171,10 +173,10 @@ public final class MySQLSetVariableAdminExecutor 
implements DatabaseAdminUpdateE
     }
     
     private MySQLSessionCharsetContext updateResultCharacterSet(final 
MySQLSessionCharsetContext context, final String value) {
-        String normalizedValue = 
formatVariableValue(value).toLowerCase(Locale.ROOT);
         if (isKeyword(value, "null")) {
             return context.withoutResultConversion();
         }
+        String normalizedValue = 
formatVariableValue(value).toLowerCase(Locale.ROOT);
         return "binary".equals(normalizedValue) ? context.withBinaryResult() : 
context.withResultCharacterSet(parseCharacterSet(value));
     }
     
@@ -194,10 +196,10 @@ public final class MySQLSetVariableAdminExecutor 
implements DatabaseAdminUpdateE
     }
     
     private MySQLCharacterSets parseCollation(final String value) {
-        String normalizedValue = formatVariableValue(value);
         if (isKeyword(value, "@@collation_database")) {
             return 
MySQLCharacterSets.findByCollationName(MySQLSystemVariable.COLLATION_DATABASE.getDefaultValue());
         }
+        String normalizedValue = formatVariableValue(value);
         return isKeyword(value, "default")
                 ? 
MySQLCharacterSets.findByCollationName(MySQLSystemVariable.COLLATION_CONNECTION.getDefaultValue())
                 : MySQLCharacterSets.findByCollationName(normalizedValue);
diff --git 
a/proxy/backend/dialect/mysql/src/main/java/org/apache/shardingsphere/proxy/backend/mysql/handler/admin/factory/withoutfrom/MySQLSelectWithoutFromAdminExecutorFactory.java
 
b/proxy/backend/dialect/mysql/src/main/java/org/apache/shardingsphere/proxy/backend/mysql/handler/admin/factory/withoutfrom/MySQLSelectWithoutFromAdminExecutorFactory.java
index c544e89bee7..0e405c9a734 100644
--- 
a/proxy/backend/dialect/mysql/src/main/java/org/apache/shardingsphere/proxy/backend/mysql/handler/admin/factory/withoutfrom/MySQLSelectWithoutFromAdminExecutorFactory.java
+++ 
b/proxy/backend/dialect/mysql/src/main/java/org/apache/shardingsphere/proxy/backend/mysql/handler/admin/factory/withoutfrom/MySQLSelectWithoutFromAdminExecutorFactory.java
@@ -37,6 +37,7 @@ import 
org.apache.shardingsphere.sql.parser.statement.core.statement.type.dml.Se
 import java.util.Collection;
 import java.util.Iterator;
 import java.util.Optional;
+import java.util.regex.Pattern;
 
 /**
  * Select without from admin executor factory for MySQL.
@@ -44,6 +45,8 @@ import java.util.Optional;
 @NoArgsConstructor(access = AccessLevel.PRIVATE)
 public final class MySQLSelectWithoutFromAdminExecutorFactory {
     
+    private static final Pattern FUNCTION_PARENTHESES_WHITESPACE_PATTERN = 
Pattern.compile("\\s+\\(");
+    
     /**
      * New instance of select without from admin executor factory for MySQL.
      *
@@ -84,7 +87,7 @@ public final class MySQLSelectWithoutFromAdminExecutorFactory 
{
             return false;
         }
         String projectionText = ((ExpressionProjectionSegment) 
firstProjection).getText();
-        String trimmedText = projectionText.replaceAll("\\s+\\(", "(");
+        String trimmedText = 
FUNCTION_PARENTHESES_WHITESPACE_PATTERN.matcher(projectionText).replaceAll("(");
         return functionName.equalsIgnoreCase(trimmedText);
     }
     
diff --git 
a/proxy/backend/dialect/mysql/src/test/java/org/apache/shardingsphere/proxy/backend/mysql/handler/admin/factory/withoutfrom/MySQLSelectWithoutFromAdminExecutorFactoryTest.java
 
b/proxy/backend/dialect/mysql/src/test/java/org/apache/shardingsphere/proxy/backend/mysql/handler/admin/factory/withoutfrom/MySQLSelectWithoutFromAdminExecutorFactoryTest.java
index 232ab0bb988..22500eba484 100644
--- 
a/proxy/backend/dialect/mysql/src/test/java/org/apache/shardingsphere/proxy/backend/mysql/handler/admin/factory/withoutfrom/MySQLSelectWithoutFromAdminExecutorFactoryTest.java
+++ 
b/proxy/backend/dialect/mysql/src/test/java/org/apache/shardingsphere/proxy/backend/mysql/handler/admin/factory/withoutfrom/MySQLSelectWithoutFromAdminExecutorFactoryTest.java
@@ -36,6 +36,8 @@ import 
org.apache.shardingsphere.sql.parser.statement.core.segment.dml.item.Proj
 import 
org.apache.shardingsphere.sql.parser.statement.core.statement.type.dml.SelectStatement;
 import org.junit.jupiter.api.Test;
 import org.junit.jupiter.params.ParameterizedTest;
+import org.junit.jupiter.params.provider.Arguments;
+import org.junit.jupiter.params.provider.MethodSource;
 import org.junit.jupiter.params.provider.ValueSource;
 
 import java.util.Arrays;
@@ -43,6 +45,7 @@ import java.util.Collection;
 import java.util.Collections;
 import java.util.LinkedList;
 import java.util.Optional;
+import java.util.stream.Stream;
 
 import static org.hamcrest.MatcherAssert.assertThat;
 import static org.hamcrest.Matchers.isA;
@@ -64,40 +67,24 @@ class MySQLSelectWithoutFromAdminExecutorFactoryTest {
         assertThat(actual.get(), isA(MySQLSystemVariableQueryExecutor.class));
     }
     
-    @Test
-    void assertCreateShowConnectionIdExecutor() {
-        SelectStatement selectStatement = 
createSelectStatement(Collections.singletonList(new 
ExpressionProjectionSegment(0, 0, "connection_id()")));
-        Optional<DatabaseAdminExecutor> actual = 
MySQLSelectWithoutFromAdminExecutorFactory.newInstance(
-                mockSelectStatementContext(selectStatement), "", null, 
mock(ShardingSphereMetaData.class));
-        assertTrue(actual.isPresent());
-        assertThat(actual.get(), isA(ShowConnectionIdExecutor.class));
-    }
-    
-    @Test
-    void assertCreateShowVersionExecutor() {
-        SelectStatement selectStatement = 
createSelectStatement(Collections.singletonList(new 
ExpressionProjectionSegment(0, 0, "version()")));
-        Optional<DatabaseAdminExecutor> actual = 
MySQLSelectWithoutFromAdminExecutorFactory.newInstance(
-                mockSelectStatementContext(selectStatement), "", null, 
mock(ShardingSphereMetaData.class));
-        assertTrue(actual.isPresent());
-        assertThat(actual.get(), isA(ShowVersionExecutor.class));
-    }
-    
-    @Test
-    void assertCreateShowCurrentUserExecutor() {
-        SelectStatement selectStatement = 
createSelectStatement(Collections.singletonList(new 
ExpressionProjectionSegment(0, 0, 
ShowCurrentUserExecutor.FUNCTION_NAME_ALIAS)));
-        Optional<DatabaseAdminExecutor> actual = 
MySQLSelectWithoutFromAdminExecutorFactory.newInstance(
-                mockSelectStatementContext(selectStatement), "", null, 
mock(ShardingSphereMetaData.class));
+    @ParameterizedTest(name = "{0}")
+    @MethodSource("specialFunctionArguments")
+    void assertCreateSpecialFunctionExecutor(final String name, final String 
projectionText, final Class<? extends DatabaseAdminExecutor> expectedType) {
+        SelectStatement selectStatement = 
createSelectStatement(Collections.singletonList(new 
ExpressionProjectionSegment(0, 0, projectionText)));
+        Optional<DatabaseAdminExecutor> actual = 
MySQLSelectWithoutFromAdminExecutorFactory.newInstance(mockSelectStatementContext(selectStatement),
 "", null, mock(ShardingSphereMetaData.class));
         assertTrue(actual.isPresent());
-        assertThat(actual.get(), isA(ShowCurrentUserExecutor.class));
+        assertThat(actual.get(), isA(expectedType));
     }
     
-    @Test
-    void assertCreateShowCurrentDatabaseExecutor() {
-        SelectStatement selectStatement = 
createSelectStatement(Collections.singletonList(new 
ExpressionProjectionSegment(0, 0, "database()")));
-        Optional<DatabaseAdminExecutor> actual = 
MySQLSelectWithoutFromAdminExecutorFactory.newInstance(
-                mockSelectStatementContext(selectStatement), "", null, 
mock(ShardingSphereMetaData.class));
-        assertTrue(actual.isPresent());
-        assertThat(actual.get(), isA(ShowCurrentDatabaseExecutor.class));
+    private static Stream<Arguments> specialFunctionArguments() {
+        return Stream.of(
+                Arguments.of("Connection id", "connection_id()", 
ShowConnectionIdExecutor.class),
+                Arguments.of("Version", "version()", 
ShowVersionExecutor.class),
+                Arguments.of("Current user function", "current_user()", 
ShowCurrentUserExecutor.class),
+                Arguments.of("Current user alias", 
ShowCurrentUserExecutor.FUNCTION_NAME_ALIAS, ShowCurrentUserExecutor.class),
+                Arguments.of("Current database", "database()", 
ShowCurrentDatabaseExecutor.class),
+                Arguments.of("Space before parentheses", "connection_id ()", 
ShowConnectionIdExecutor.class),
+                Arguments.of("Tab before parentheses", "version\t()", 
ShowVersionExecutor.class));
     }
     
     @ParameterizedTest(name = "{0}")
@@ -164,16 +151,6 @@ class MySQLSelectWithoutFromAdminExecutorFactoryTest {
         assertThat(actual.get(), isA(UnicastResourceShowExecutor.class));
     }
     
-    @Test
-    void assertCreateShowCurrentUserExecutorWithAliasName() {
-        ExpressionProjectionSegment projection = new 
ExpressionProjectionSegment(0, 0, "current_user");
-        SelectStatement selectStatement = 
createSelectStatement(Collections.singletonList(projection));
-        Optional<DatabaseAdminExecutor> actual = 
MySQLSelectWithoutFromAdminExecutorFactory.newInstance(
-                mockSelectStatementContext(selectStatement), "", null, 
mock(ShardingSphereMetaData.class));
-        assertTrue(actual.isPresent());
-        assertThat(actual.get(), isA(ShowCurrentUserExecutor.class));
-    }
-    
     private SelectStatement createSelectStatement(final 
Iterable<ProjectionSegment> projections) {
         ProjectionsSegment projectionsSegment = new ProjectionsSegment(0, 0);
         projections.forEach(projectionsSegment.getProjections()::add);
diff --git 
a/proxy/frontend/dialect/firebird/src/main/java/org/apache/shardingsphere/proxy/frontend/firebird/command/query/batch/FirebirdBatchCreateCommandExecutor.java
 
b/proxy/frontend/dialect/firebird/src/main/java/org/apache/shardingsphere/proxy/frontend/firebird/command/query/batch/FirebirdBatchCreateCommandExecutor.java
index e1c52636c6b..0ecca0ed835 100644
--- 
a/proxy/frontend/dialect/firebird/src/main/java/org/apache/shardingsphere/proxy/frontend/firebird/command/query/batch/FirebirdBatchCreateCommandExecutor.java
+++ 
b/proxy/frontend/dialect/firebird/src/main/java/org/apache/shardingsphere/proxy/frontend/firebird/command/query/batch/FirebirdBatchCreateCommandExecutor.java
@@ -67,9 +67,9 @@ public final class FirebirdBatchCreateCommandExecutor 
implements CommandExecutor
     
     @Override
     public Collection<DatabasePacket> execute() {
-        int connectionId = connectionSession.getConnectionId();
         int statementId = packet.getStatementHandle();
         
ShardingSpherePreconditions.checkNotNull(connectionSession.getServerPreparedStatementRegistry().getPreparedStatement(statementId),
 () -> new InvalidStatementHandleException(statementId));
+        int connectionId = connectionSession.getConnectionId();
         ShardingSpherePreconditions.checkState(null == 
FirebirdBatchStatementManager.getInstance().getBatchStatement(connectionId, 
statementId), () -> new BatchAlreadyOpenedException(statementId));
         ByteBuf batchBlr = packet.getBatchBlr();
         FirebirdParseBatchBlr messageFormat = 
FirebirdParseBatchBlr.parse(batchBlr, batchBlr.readableBytes());
diff --git 
a/proxy/frontend/dialect/firebird/src/test/java/org/apache/shardingsphere/proxy/frontend/firebird/command/query/batch/FirebirdBatchCreateCommandExecutorTest.java
 
b/proxy/frontend/dialect/firebird/src/test/java/org/apache/shardingsphere/proxy/frontend/firebird/command/query/batch/FirebirdBatchCreateCommandExecutorTest.java
index 635ac98e529..a76f005e26a 100644
--- 
a/proxy/frontend/dialect/firebird/src/test/java/org/apache/shardingsphere/proxy/frontend/firebird/command/query/batch/FirebirdBatchCreateCommandExecutorTest.java
+++ 
b/proxy/frontend/dialect/firebird/src/test/java/org/apache/shardingsphere/proxy/frontend/firebird/command/query/batch/FirebirdBatchCreateCommandExecutorTest.java
@@ -160,7 +160,6 @@ class FirebirdBatchCreateCommandExecutorTest {
     @Test
     void assertExecuteWhenStatementDoesNotExist() {
         FirebirdBatchRegistry.getInstance().registerConnection(CONNECTION_ID);
-        when(connectionSession.getConnectionId()).thenReturn(CONNECTION_ID);
         when(packet.getStatementHandle()).thenReturn(STATEMENT_ID);
         
when(connectionSession.getServerPreparedStatementRegistry().getPreparedStatement(STATEMENT_ID)).thenReturn(null);
         assertThrows(InvalidStatementHandleException.class, () -> new 
FirebirdBatchCreateCommandExecutor(packet, connectionSession).execute());
diff --git 
a/proxy/frontend/dialect/firebird/src/test/java/org/apache/shardingsphere/proxy/frontend/firebird/command/query/statement/prepare/FirebirdPrepareStatementCommandExecutorTest.java
 
b/proxy/frontend/dialect/firebird/src/test/java/org/apache/shardingsphere/proxy/frontend/firebird/command/query/statement/prepare/FirebirdPrepareStatementCommandExecutorTest.java
index 3a8bbaa6a87..6c957ad7a5b 100644
--- 
a/proxy/frontend/dialect/firebird/src/test/java/org/apache/shardingsphere/proxy/frontend/firebird/command/query/statement/prepare/FirebirdPrepareStatementCommandExecutorTest.java
+++ 
b/proxy/frontend/dialect/firebird/src/test/java/org/apache/shardingsphere/proxy/frontend/firebird/command/query/statement/prepare/FirebirdPrepareStatementCommandExecutorTest.java
@@ -300,6 +300,34 @@ class FirebirdPrepareStatementCommandExecutorTest {
         return actualReturnPacket.getDescribeSelect().get(0);
     }
     
+    @Test
+    void assertDescribeBinaryExpressions() throws Exception {
+        when(packet.getSQL()).thenReturn("SELECT 'foo' || 'bar', 1 + 2 FROM 
foo_tbl");
+        when(packet.nextItem()).thenReturn(true, true, true, true, true, true, 
false);
+        when(packet.getCurrentItem()).thenReturn(
+                FirebirdSQLInfoPacketType.STMT_TYPE,
+                FirebirdSQLInfoPacketType.SELECT,
+                FirebirdSQLInfoPacketType.FIELD,
+                FirebirdSQLInfoPacketType.FIELD,
+                FirebirdSQLInfoPacketType.TYPE,
+                FirebirdSQLInfoPacketType.TYPE,
+                FirebirdSQLInfoPacketType.DESCRIBE_END,
+                FirebirdSQLInfoPacketType.DESCRIBE_END);
+        FirebirdPrepareStatementCommandExecutor executor = new 
FirebirdPrepareStatementCommandExecutor(packet, connectionSession);
+        FirebirdPrepareStatementReturnPacket actualReturnPacket = 
(FirebirdPrepareStatementReturnPacket) ((FirebirdGenericResponsePacket) 
executor.execute().iterator().next()).getData();
+        assertThat(actualReturnPacket.getDescribeSelect().size(), is(2));
+        FirebirdPacketPayload concatenationPayload = 
mock(FirebirdPacketPayload.class);
+        
when(concatenationPayload.getCharset()).thenReturn(StandardCharsets.UTF_8);
+        
actualReturnPacket.getDescribeSelect().get(0).write(concatenationPayload);
+        
verify(concatenationPayload).writeBytes("CONCATENATION".getBytes(StandardCharsets.UTF_8));
+        
verify(concatenationPayload).writeInt4LE(FirebirdBinaryColumnType.VARYING.getValue()
 + 1);
+        FirebirdPacketPayload arithmeticPayload = 
mock(FirebirdPacketPayload.class);
+        
when(arithmeticPayload.getCharset()).thenReturn(StandardCharsets.UTF_8);
+        actualReturnPacket.getDescribeSelect().get(1).write(arithmeticPayload);
+        
verify(arithmeticPayload).writeBytes("+".getBytes(StandardCharsets.UTF_8));
+        
verify(arithmeticPayload).writeInt4LE(FirebirdBinaryColumnType.LONG.getValue() 
+ 1);
+    }
+    
     @Test
     void assertDescribeLiterals() throws Exception {
         when(packet.getSQL()).thenReturn("SELECT 'it''s', 1 AS one FROM 
foo_tbl");
diff --git 
a/proxy/frontend/dialect/postgresql/src/main/java/org/apache/shardingsphere/proxy/frontend/postgresql/authentication/PostgreSQLAuthenticationEngine.java
 
b/proxy/frontend/dialect/postgresql/src/main/java/org/apache/shardingsphere/proxy/frontend/postgresql/authentication/PostgreSQLAuthenticationEngine.java
index 31634b486a8..1d85b70b5ee 100644
--- 
a/proxy/frontend/dialect/postgresql/src/main/java/org/apache/shardingsphere/proxy/frontend/postgresql/authentication/PostgreSQLAuthenticationEngine.java
+++ 
b/proxy/frontend/dialect/postgresql/src/main/java/org/apache/shardingsphere/proxy/frontend/postgresql/authentication/PostgreSQLAuthenticationEngine.java
@@ -26,6 +26,7 @@ import 
org.apache.shardingsphere.authentication.result.AuthenticationResult;
 import 
org.apache.shardingsphere.authentication.result.AuthenticationResultBuilder;
 import org.apache.shardingsphere.authority.checker.AuthorityChecker;
 import org.apache.shardingsphere.authority.rule.AuthorityRule;
+import 
org.apache.shardingsphere.database.connector.core.metadata.database.enums.QuoteCharacter;
 import org.apache.shardingsphere.database.connector.core.type.DatabaseType;
 import 
org.apache.shardingsphere.database.exception.core.exception.data.InvalidParameterValueException;
 import 
org.apache.shardingsphere.database.exception.core.exception.syntax.database.UnknownDatabaseException;
@@ -159,7 +160,7 @@ public final class PostgreSQLAuthenticationEngine 
implements AuthenticationEngin
     }
     
     private String formatClientEncoding(final String value) {
-        return value.startsWith("'") && value.endsWith("'") || 
value.startsWith("\"") && value.endsWith("\"") ? value.substring(1, 
value.length() - 1).trim() : value.trim();
+        return QuoteCharacter.SINGLE_QUOTE.isWrapped(value) || 
QuoteCharacter.QUOTE.isWrapped(value) ? value.substring(1, value.length() - 
1).trim() : value.trim();
     }
     
     private PostgreSQLIdentifierPacket getIdentifierPacket(final String 
username, final AuthorityRule rule) {
diff --git 
a/proxy/frontend/dialect/postgresql/src/main/java/org/apache/shardingsphere/proxy/frontend/postgresql/command/query/extended/describe/PostgreSQLComDescribeExecutor.java
 
b/proxy/frontend/dialect/postgresql/src/main/java/org/apache/shardingsphere/proxy/frontend/postgresql/command/query/extended/describe/PostgreSQLComDescribeExecutor.java
index 3c60d284168..e32af2b8c35 100644
--- 
a/proxy/frontend/dialect/postgresql/src/main/java/org/apache/shardingsphere/proxy/frontend/postgresql/command/query/extended/describe/PostgreSQLComDescribeExecutor.java
+++ 
b/proxy/frontend/dialect/postgresql/src/main/java/org/apache/shardingsphere/proxy/frontend/postgresql/command/query/extended/describe/PostgreSQLComDescribeExecutor.java
@@ -175,8 +175,7 @@ public final class PostgreSQLComDescribeExecutor implements 
CommandExecutor {
         List<PostgreSQLColumnDescription> result = new ArrayList<>();
         for (ProjectionSegment each : 
returningSegment.getProjections().getProjections()) {
             if (each instanceof ShorthandProjectionSegment) {
-                table.getAllColumns().stream()
-                        .map(column -> new 
PostgreSQLColumnDescription(column.getName(), 0, column.getDataType(), 
estimateColumnLength(column.getDataType()), "")).forEach(result::add);
+                appendShorthandColumns(table, result);
             }
             if (each instanceof ColumnProjectionSegment) {
                 ColumnProjectionSegment segment = (ColumnProjectionSegment) 
each;
@@ -193,6 +192,12 @@ public final class PostgreSQLComDescribeExecutor 
implements CommandExecutor {
         return new PostgreSQLRowDescriptionPacket(result);
     }
     
+    private void appendShorthandColumns(final ShardingSphereTable table, final 
Collection<PostgreSQLColumnDescription> columns) {
+        for (ShardingSphereColumn each : table.getAllColumns()) {
+            columns.add(new PostgreSQLColumnDescription(each.getName(), 0, 
each.getDataType(), estimateColumnLength(each.getDataType()), ""));
+        }
+    }
+    
     private ShardingSphereColumn generateDefaultColumn(final 
ColumnProjectionSegment segment) {
         return new 
ShardingSphereColumn(segment.getColumn().getIdentifier().getValue(), 
Types.VARCHAR, false, false, false, true, false, false);
     }

Reply via email to