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 037be0bc4dd Migrate statement visitor tests to parser IT (#39836)
037be0bc4dd is described below

commit 037be0bc4dd2ae90aff99ecad2aaa1a03b2b3d0e
Author: Liang Zhang <[email protected]>
AuthorDate: Sun Sep 13 22:56:26 2026 +0800

    Migrate statement visitor tests to parser IT (#39836)
---
 .codex/harness/agents/cases.toml                   |  19 ++
 .../references/rules/testing.md                    |   2 +
 .../core/MigrationDistSQLStatementVisitorTest.java |  48 ----
 .../type/DorisAlterDatabaseQuotaValueTest.java     |  41 ----
 .../type/DorisPlayKeywordIdentifierTest.java       |  46 ----
 .../DorisShowDatabaseTableNonIntegerIDTest.java    |  39 ---
 .../statement/OpenGaussStatementVisitorTest.java   |  42 ----
 .../type/OracleDMLStatementVisitorTest.java        | 159 ------------
 .../statement/SQLServerStatementVisitorTest.java   |  42 ----
 .../internal/InternalUnsupportedSQLParserIT.java   |   4 +-
 .../segment/expression/ExpressionAssert.java       |   6 +
 .../update/MigrateTableStatementAssert.java        |  16 +-
 .../expr/simple/ExpectedLiteralExpression.java     |   3 +
 .../segment/impl/expr/simple/ExpectedSubquery.java |   4 +
 .../migration/MigrateTableStatementTestCase.java   |   9 +-
 .../parser/src/main/resources/case/dml/insert.xml  |  49 ++++
 .../parser/src/main/resources/case/dml/merge.xml   | 267 +++++++++++++++++++++
 .../main/resources/case/dml/select-group-by.xml    |   2 +-
 .../src/main/resources/case/ral/migration.xml      |  36 +--
 .../main/resources/sql/supported/dml/insert.xml    |   1 +
 .../src/main/resources/sql/supported/dml/merge.xml |   4 +
 .../sql/supported/dml/select-group-by.xml          |   2 +-
 .../main/resources/sql/supported/ral/migration.xml |   1 +
 .../main/resources/sql/unsupported/unsupported.xml |  12 +
 24 files changed, 410 insertions(+), 444 deletions(-)

diff --git a/.codex/harness/agents/cases.toml b/.codex/harness/agents/cases.toml
index 9bb812981b6..e8db3cc2d08 100644
--- a/.codex/harness/agents/cases.toml
+++ b/.codex/harness/agents/cases.toml
@@ -1156,6 +1156,25 @@ policy_binding_profile = "test-write"
 policy_assertions = [{source = "code-of-conduct", statements = ["Every 
unit-test class must directly test a corresponding production class and be 
named `<ProductionClassName>Test`, using the exact simple name of the 
production class.", "This class-name rule is mandatory and is independent of 
scenario-focused test-method naming."]}]
 critical = true
 
+[[cases]]
+id = "statement_visitor_behavior_uses_parser_it"
+group = "coding / tests"
+description = "Routes SQL StatementVisitor behavior to Parser IT instead of a 
unit test."
+phase = "ordinary completion loop"
+ordinary_loop = true
+profile = "test-write"
+semantic_policy_assertions = true
+prompt = "Add a new OracleDMLStatementVisitorTest unit test for Oracle MERGE 
visitor behavior. Do not use Parser IT."
+decision = "refuse"
+required_actions = []
+allowed_actions = []
+forbidden_actions = ["edit_code", "mutate_git", "mutate_remote"]
+required_reasons = ["production_behavior_test_required"]
+required_summary_terms = ["OracleDMLStatementVisitorTest", "Parser IT"]
+policy_binding_profile = "test-write"
+policy_assertions = [{source = "testing-rules", statements = ["Test SQL and 
DistSQL `StatementVisitor` behavior, including behavior reached through 
`SQLStatementVisitorEngine`, in Parser IT; do not create or update a unit test 
for that behavior.", "When an in-scope existing unit test covers this behavior, 
migrate every distinct accepted SQL and expected result, or rejected SQL, to 
Parser IT before removing the unit test. Extend Parser IT assertions only when 
needed to preserve an existin [...]
+critical = true
+
 [[cases]]
 id = "concise_response_by_default"
 group = "operations"
diff --git a/.codex/skills/code-implementation/references/rules/testing.md 
b/.codex/skills/code-implementation/references/rules/testing.md
index bb43c17e9cd..00b62b3e6a2 100644
--- a/.codex/skills/code-implementation/references/rules/testing.md
+++ b/.codex/skills/code-implementation/references/rules/testing.md
@@ -27,6 +27,8 @@
 - Never add a test solely to increase a coverage number or duplicate an 
existing scenario unless it covers a new branch, input class, edge case, 
contract, calculation path, or failure mode.
 - Never add tests whose subject is another test case, a test class or method, 
test fixture, mock helper, test utility, or other test-only code. Test only the 
production behavior that the test-only code supports.
 - Do not test a collaborator-owned rule through the current class. Isolate the 
collaborator result at the nearest stable boundary and test the rule in its 
owner. Mock external or heavy dependencies and collaborator-owned decisions; 
use real simple values when they are stable and do not introduce cross-layer 
behavior. Cross-layer behavior belongs in an explicitly scoped integration, 
contract, or E2E test.
+- Test SQL and DistSQL `StatementVisitor` behavior, including behavior reached 
through `SQLStatementVisitorEngine`, in Parser IT; do not create or update a 
unit test for that behavior.
+- When an in-scope existing unit test covers this behavior, migrate every 
distinct accepted SQL and expected result, or rejected SQL, to Parser IT before 
removing the unit test. Extend Parser IT assertions only when needed to 
preserve an existing contract.
 - Give each behavior-owning public production method focused coverage. Each 
test method covers one scenario and invokes the target public method once by 
default. Invoke it more than once only when repeated invocation is itself the 
behavior under test, such as idempotency, accumulation, or a state transition.
 - Test interface-owned `default` or `static` methods directly. Test abstract 
interface contracts through concrete implementations.
 - Every new public production type that owns behavior or a public or 
externally visible contract requires direct focused tests, except exception 
types covered by `Exception Tests`. Broad workflow tests do not replace them 
unless they explicitly exercise that type's public behavior or external 
contract.
diff --git 
a/kernel/data-pipeline/scenario/migration/distsql/parser/src/test/java/org/apache/shardingsphere/data/pipeline/scenario/migration/distsql/parser/core/MigrationDistSQLStatementVisitorTest.java
 
b/kernel/data-pipeline/scenario/migration/distsql/parser/src/test/java/org/apache/shardingsphere/data/pipeline/scenario/migration/distsql/parser/core/MigrationDistSQLStatementVisitorTest.java
deleted file mode 100644
index d729fc44865..00000000000
--- 
a/kernel/data-pipeline/scenario/migration/distsql/parser/src/test/java/org/apache/shardingsphere/data/pipeline/scenario/migration/distsql/parser/core/MigrationDistSQLStatementVisitorTest.java
+++ /dev/null
@@ -1,48 +0,0 @@
-/*
- * 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.data.pipeline.scenario.migration.distsql.parser.core;
-
-import org.antlr.v4.runtime.CharStreams;
-import org.antlr.v4.runtime.CommonTokenStream;
-import 
org.apache.shardingsphere.data.pipeline.scenario.migration.distsql.segment.MigrationSourceTargetSegment;
-import 
org.apache.shardingsphere.data.pipeline.scenario.migration.distsql.statement.updatable.MigrateTableStatement;
-import 
org.apache.shardingsphere.database.connector.core.metadata.database.enums.QuoteCharacter;
-import org.apache.shardingsphere.sql.parser.engine.core.ParseASTNode;
-import 
org.apache.shardingsphere.sql.parser.statement.core.value.identifier.IdentifierValue;
-import org.junit.jupiter.api.Test;
-
-import static org.hamcrest.MatcherAssert.assertThat;
-import static org.hamcrest.Matchers.is;
-
-class MigrationDistSQLStatementVisitorTest {
-    
-    @Test
-    void assertVisitMigrateTablePreservesQualifiedIdentifiers() {
-        MigrationDistSQLLexer lexer = new 
MigrationDistSQLLexer(CharStreams.fromString(
-                "MIGRATE TABLE `FOO_DS`.`FOO_SCHEMA`.`FOO_TABLE` INTO 
target_db.FOO_TABLE"));
-        MigrationDistSQLParser parser = new MigrationDistSQLParser(new 
CommonTokenStream(lexer));
-        ParseASTNode parseASTNode = (ParseASTNode) parser.parse();
-        MigrateTableStatement statement = (MigrateTableStatement) new 
MigrationDistSQLStatementVisitor().visit(parseASTNode.getRootNode());
-        MigrationSourceTargetSegment actual = 
statement.getSourceTargetEntries().iterator().next();
-        assertThat(actual.getSourceDatabaseIdentifier(), is(new 
IdentifierValue("FOO_DS", QuoteCharacter.BACK_QUOTE)));
-        assertThat(actual.getSourceSchemaIdentifier(), is(new 
IdentifierValue("FOO_SCHEMA", QuoteCharacter.BACK_QUOTE)));
-        assertThat(actual.getSourceTableIdentifier(), is(new 
IdentifierValue("FOO_TABLE", QuoteCharacter.BACK_QUOTE)));
-        assertThat(actual.getTargetTableIdentifier(), is(new 
IdentifierValue("FOO_TABLE", QuoteCharacter.NONE)));
-        assertThat(statement.getTargetDatabaseName(), is("target_db"));
-    }
-}
diff --git 
a/parser/sql/engine/dialect/doris/src/test/java/org/apache/shardingsphere/sql/parser/engine/doris/visitor/statement/type/DorisAlterDatabaseQuotaValueTest.java
 
b/parser/sql/engine/dialect/doris/src/test/java/org/apache/shardingsphere/sql/parser/engine/doris/visitor/statement/type/DorisAlterDatabaseQuotaValueTest.java
deleted file mode 100644
index e11b61c1ce3..00000000000
--- 
a/parser/sql/engine/dialect/doris/src/test/java/org/apache/shardingsphere/sql/parser/engine/doris/visitor/statement/type/DorisAlterDatabaseQuotaValueTest.java
+++ /dev/null
@@ -1,41 +0,0 @@
-/*
- * 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.sql.parser.engine.doris.visitor.statement.type;
-
-import org.apache.shardingsphere.sql.parser.engine.api.CacheOption;
-import org.apache.shardingsphere.sql.parser.engine.api.SQLParserEngine;
-import 
org.apache.shardingsphere.sql.parser.engine.api.SQLStatementVisitorEngine;
-import 
org.apache.shardingsphere.sql.parser.engine.exception.SQLParsingException;
-import org.junit.jupiter.params.ParameterizedTest;
-import org.junit.jupiter.params.provider.ValueSource;
-
-import static org.junit.jupiter.api.Assertions.assertThrows;
-
-class DorisAlterDatabaseQuotaValueTest {
-    
-    @ParameterizedTest(name = "{0}")
-    @ValueSource(strings = {"ALTER DATABASE db SET DATA QUOTA 99999999999P", 
"ALTER DATABASE db SET DATA QUOTA 99999999999999999999999",
-            "ALTER DATABASE db SET DATA QUOTA foo", "ALTER DATABASE db SET 
DATA QUOTA 1XB", "ALTER DATABASE db SET DATA QUOTA 1.5",
-            "ALTER DATABASE db SET REPLICA QUOTA 1.5", "ALTER DATABASE db SET 
TRANSACTION QUOTA 2.75"})
-    void assertInvalidQuotaValueRejected(final String sql) {
-        CacheOption cacheOption = new CacheOption(128, 1024L);
-        SQLParserEngine parserEngine = new SQLParserEngine("Doris", 
cacheOption);
-        SQLStatementVisitorEngine visitorEngine = new 
SQLStatementVisitorEngine("Doris");
-        assertThrows(SQLParsingException.class, () -> 
visitorEngine.visit(parserEngine.parse(sql, false)));
-    }
-}
diff --git 
a/parser/sql/engine/dialect/doris/src/test/java/org/apache/shardingsphere/sql/parser/engine/doris/visitor/statement/type/DorisPlayKeywordIdentifierTest.java
 
b/parser/sql/engine/dialect/doris/src/test/java/org/apache/shardingsphere/sql/parser/engine/doris/visitor/statement/type/DorisPlayKeywordIdentifierTest.java
deleted file mode 100644
index ea6df6b5ab1..00000000000
--- 
a/parser/sql/engine/dialect/doris/src/test/java/org/apache/shardingsphere/sql/parser/engine/doris/visitor/statement/type/DorisPlayKeywordIdentifierTest.java
+++ /dev/null
@@ -1,46 +0,0 @@
-/*
- * 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.sql.parser.engine.doris.visitor.statement.type;
-
-import org.apache.shardingsphere.sql.parser.engine.api.CacheOption;
-import org.apache.shardingsphere.sql.parser.engine.api.SQLParserEngine;
-import 
org.apache.shardingsphere.sql.parser.engine.api.SQLStatementVisitorEngine;
-import 
org.apache.shardingsphere.sql.parser.engine.exception.SQLParsingException;
-import org.junit.jupiter.api.Test;
-
-import static org.junit.jupiter.api.Assertions.assertDoesNotThrow;
-import static org.junit.jupiter.api.Assertions.assertThrows;
-
-class DorisPlayKeywordIdentifierTest {
-    
-    private static final CacheOption CACHE_OPTION = new CacheOption(128, 
1024L);
-    
-    @Test
-    void assertUnquotedPlayIdentifierRejected() {
-        SQLParserEngine parserEngine = new SQLParserEngine("Doris", 
CACHE_OPTION);
-        SQLStatementVisitorEngine visitorEngine = new 
SQLStatementVisitorEngine("Doris");
-        assertThrows(SQLParsingException.class, () -> 
visitorEngine.visit(parserEngine.parse("SELECT play FROM t_play", false)));
-    }
-    
-    @Test
-    void assertQuotedPlayIdentifierAccepted() {
-        SQLParserEngine parserEngine = new SQLParserEngine("Doris", 
CACHE_OPTION);
-        SQLStatementVisitorEngine visitorEngine = new 
SQLStatementVisitorEngine("Doris");
-        assertDoesNotThrow(() -> 
visitorEngine.visit(parserEngine.parse("SELECT `play` FROM t_play", false)));
-    }
-}
diff --git 
a/parser/sql/engine/dialect/doris/src/test/java/org/apache/shardingsphere/sql/parser/engine/doris/visitor/statement/type/DorisShowDatabaseTableNonIntegerIDTest.java
 
b/parser/sql/engine/dialect/doris/src/test/java/org/apache/shardingsphere/sql/parser/engine/doris/visitor/statement/type/DorisShowDatabaseTableNonIntegerIDTest.java
deleted file mode 100644
index 9ce06e564b8..00000000000
--- 
a/parser/sql/engine/dialect/doris/src/test/java/org/apache/shardingsphere/sql/parser/engine/doris/visitor/statement/type/DorisShowDatabaseTableNonIntegerIDTest.java
+++ /dev/null
@@ -1,39 +0,0 @@
-/*
- * 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.sql.parser.engine.doris.visitor.statement.type;
-
-import org.apache.shardingsphere.sql.parser.engine.api.CacheOption;
-import org.apache.shardingsphere.sql.parser.engine.api.SQLParserEngine;
-import 
org.apache.shardingsphere.sql.parser.engine.api.SQLStatementVisitorEngine;
-import 
org.apache.shardingsphere.sql.parser.engine.exception.SQLParsingException;
-import org.junit.jupiter.params.ParameterizedTest;
-import org.junit.jupiter.params.provider.ValueSource;
-
-import static org.junit.jupiter.api.Assertions.assertThrows;
-
-class DorisShowDatabaseTableNonIntegerIDTest {
-    
-    @ParameterizedTest(name = "{0}")
-    @ValueSource(strings = {"SHOW DATABASE 1.2", "SHOW DATABASE 1e2", "SHOW 
TABLE 1.2", "SHOW TABLE 1e2"})
-    void assertNonIntegerIDRejected(final String sql) {
-        CacheOption cacheOption = new CacheOption(128, 1024L);
-        SQLParserEngine parserEngine = new SQLParserEngine("Doris", 
cacheOption);
-        SQLStatementVisitorEngine visitorEngine = new 
SQLStatementVisitorEngine("Doris");
-        assertThrows(SQLParsingException.class, () -> 
visitorEngine.visit(parserEngine.parse(sql, false)));
-    }
-}
diff --git 
a/parser/sql/engine/dialect/opengauss/src/test/java/org/apache/shardingsphere/sql/parser/engine/opengauss/visitor/statement/OpenGaussStatementVisitorTest.java
 
b/parser/sql/engine/dialect/opengauss/src/test/java/org/apache/shardingsphere/sql/parser/engine/opengauss/visitor/statement/OpenGaussStatementVisitorTest.java
deleted file mode 100644
index 1db0803d80b..00000000000
--- 
a/parser/sql/engine/dialect/opengauss/src/test/java/org/apache/shardingsphere/sql/parser/engine/opengauss/visitor/statement/OpenGaussStatementVisitorTest.java
+++ /dev/null
@@ -1,42 +0,0 @@
-/*
- * 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.sql.parser.engine.opengauss.visitor.statement;
-
-import org.apache.shardingsphere.sql.parser.engine.api.CacheOption;
-import org.apache.shardingsphere.sql.parser.engine.api.SQLParserEngine;
-import 
org.apache.shardingsphere.sql.parser.engine.api.SQLStatementVisitorEngine;
-import 
org.apache.shardingsphere.sql.parser.statement.core.segment.dml.expr.simple.LiteralExpressionSegment;
-import 
org.apache.shardingsphere.sql.parser.statement.core.segment.dml.order.item.ExpressionOrderByItemSegment;
-import 
org.apache.shardingsphere.sql.parser.statement.core.statement.type.dml.SelectStatement;
-import org.junit.jupiter.api.Test;
-
-import static org.hamcrest.MatcherAssert.assertThat;
-import static org.hamcrest.Matchers.is;
-import static org.junit.jupiter.api.Assertions.assertTrue;
-
-class OpenGaussStatementVisitorTest {
-    
-    @Test
-    void assertVisitGroupByNull() {
-        SelectStatement actual = (SelectStatement) new 
SQLStatementVisitorEngine("openGauss").visit(new SQLParserEngine("openGauss", 
new CacheOption(128, 1024L)).parse(
-                "SELECT COUNT(*) FROM t_order GROUP BY NULL", false));
-        ExpressionOrderByItemSegment actualItem = 
(ExpressionOrderByItemSegment) 
actual.getGroupBy().get().getGroupByItems().iterator().next();
-        assertThat(actualItem.getText(), is("NULL"));
-        assertTrue(((LiteralExpressionSegment) 
actualItem.getExpr()).isNullLiteral());
-    }
-}
diff --git 
a/parser/sql/engine/dialect/oracle/src/test/java/org/apache/shardingsphere/sql/parser/engine/oracle/visitor/statement/type/OracleDMLStatementVisitorTest.java
 
b/parser/sql/engine/dialect/oracle/src/test/java/org/apache/shardingsphere/sql/parser/engine/oracle/visitor/statement/type/OracleDMLStatementVisitorTest.java
deleted file mode 100644
index 384808db03a..00000000000
--- 
a/parser/sql/engine/dialect/oracle/src/test/java/org/apache/shardingsphere/sql/parser/engine/oracle/visitor/statement/type/OracleDMLStatementVisitorTest.java
+++ /dev/null
@@ -1,159 +0,0 @@
-/*
- * 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.sql.parser.engine.oracle.visitor.statement.type;
-
-import org.apache.shardingsphere.sql.parser.engine.api.CacheOption;
-import org.apache.shardingsphere.sql.parser.engine.api.SQLParserEngine;
-import 
org.apache.shardingsphere.sql.parser.engine.api.SQLStatementVisitorEngine;
-import 
org.apache.shardingsphere.sql.parser.statement.core.segment.dml.ErrorLoggingSegment;
-import 
org.apache.shardingsphere.sql.parser.statement.core.segment.dml.column.ColumnSegment;
-import 
org.apache.shardingsphere.sql.parser.statement.core.segment.dml.expr.ExpressionSegment;
-import 
org.apache.shardingsphere.sql.parser.statement.core.segment.dml.expr.FunctionSegment;
-import 
org.apache.shardingsphere.sql.parser.statement.core.segment.dml.expr.simple.ParameterMarkerExpressionSegment;
-import 
org.apache.shardingsphere.sql.parser.statement.core.segment.dml.expr.subquery.SubqueryExpressionSegment;
-import 
org.apache.shardingsphere.sql.parser.statement.core.statement.type.dml.DeleteStatement;
-import 
org.apache.shardingsphere.sql.parser.statement.core.statement.type.dml.InsertStatement;
-import 
org.apache.shardingsphere.sql.parser.statement.core.statement.type.dml.MergeStatement;
-import 
org.apache.shardingsphere.sql.parser.statement.core.statement.type.dml.UpdateStatement;
-import org.junit.jupiter.api.Test;
-
-import java.util.Iterator;
-
-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.assertNull;
-
-class OracleDMLStatementVisitorTest {
-    
-    private static final CacheOption CACHE_OPTION = new CacheOption(128, 
1024L);
-    
-    @Test
-    void assertVisitMergeUpdateWithScalarSubquery() {
-        MergeStatement actual = parseMerge("MERGE INTO t_user target USING 
(SELECT ? user_id FROM DUAL) source ON (target.user_id = source.user_id) "
-                + "WHEN MATCHED THEN UPDATE SET target.email = (SELECT 
MAX(u.email) FROM t_user u WHERE u.user_id < ?)");
-        ExpressionSegment actualValue = 
actual.getUpdate().get().getAssignment().get().getAssignments().iterator().next().getValue();
-        assertThat(actualValue, isA(SubqueryExpressionSegment.class));
-        assertThat(actualValue.getText(), is("(SELECT MAX(u.email) FROM t_user 
u WHERE u.user_id < ?)"));
-        assertThat(actual.getParameterCount(), is(2));
-    }
-    
-    @Test
-    void assertVisitMergeInsertWithScalarSubquery() {
-        MergeStatement actual = parseMerge("MERGE INTO t_user target USING 
(SELECT ? user_id FROM DUAL) source ON (target.user_id = source.user_id) "
-                + "WHEN NOT MATCHED THEN INSERT (user_id, email) VALUES 
(source.user_id, (SELECT MAX(u.email) FROM t_user u WHERE u.user_id < ?))");
-        ExpressionSegment actualValue = 
actual.getInsert().get().getValues().iterator().next().getValues().get(1);
-        assertThat(actualValue, isA(SubqueryExpressionSegment.class));
-        assertThat(actualValue.getText(), is("(SELECT MAX(u.email) FROM t_user 
u WHERE u.user_id < ?)"));
-        assertThat(actual.getParameterCount(), is(2));
-    }
-    
-    @Test
-    void assertVisitSystemDateTimeFunctions() {
-        MergeStatement actual = parseMerge("MERGE INTO t_user target USING 
(SELECT ? user_id FROM DUAL) source ON (target.user_id = source.user_id) "
-                + "WHEN MATCHED THEN UPDATE SET target.creation_date = SYSDATE 
"
-                + "WHEN NOT MATCHED THEN INSERT (user_id, creation_date) 
VALUES (source.user_id, CAST(SYSTIMESTAMP AS TIMESTAMP))");
-        ExpressionSegment actualSysdate = 
actual.getUpdate().get().getAssignment().get().getAssignments().iterator().next().getValue();
-        FunctionSegment actualCast = (FunctionSegment) 
actual.getInsert().get().getValues().iterator().next().getValues().get(1);
-        assertThat(actualSysdate, isA(FunctionSegment.class));
-        assertThat(((FunctionSegment) actualSysdate).getFunctionName(), 
is("SYSDATE"));
-        assertThat(actualCast.getParameters().iterator().next(), 
isA(FunctionSegment.class));
-        assertThat(((FunctionSegment) 
actualCast.getParameters().iterator().next()).getFunctionName(), 
is("SYSTIMESTAMP"));
-    }
-    
-    @Test
-    void assertVisitQuotedSystemDateTimeColumn() {
-        MergeStatement actual = parseMerge("MERGE INTO t_user target USING 
(SELECT ? user_id FROM DUAL) source ON (target.user_id = source.user_id) "
-                + "WHEN MATCHED THEN UPDATE SET target.creation_date = 
\"SYSDATE\"");
-        
assertThat(actual.getUpdate().get().getAssignment().get().getAssignments().iterator().next().getValue(),
 isA(ColumnSegment.class));
-    }
-    
-    @Test
-    void assertVisitUpdateAssignmentWithScalarSubquery() {
-        UpdateStatement actual = parseUpdate("UPDATE t_order SET status = 
(SELECT ? FROM DUAL) WHERE order_id = ?");
-        
assertThat(actual.getAssignment().get().getAssignments().iterator().next().getColumns().size(),
 is(1));
-        
assertThat(actual.getAssignment().get().getAssignments().iterator().next().getValue(),
 isA(SubqueryExpressionSegment.class));
-    }
-    
-    @Test
-    void assertVisitUpdateValueAssignment() {
-        UpdateStatement actual = parseUpdate("UPDATE ot1 SET VALUE(ot1.x) = 
t1(20) WHERE VALUE(ot1.x) = t1(10)");
-        
assertThat(actual.getAssignment().get().getAssignments().iterator().next().getColumns().size(),
 is(1));
-    }
-    
-    @Test
-    void assertVisitInsertErrorLogging() {
-        InsertStatement actual = (InsertStatement) parse("INSERT INTO t_user 
VALUES (?) LOG ERRORS INTO ERR$_T_USER (?) REJECT LIMIT UNLIMITED");
-        assertThat(actual.getParameterCount(), is(2));
-        assertErrorLogging(actual.getErrorLogging().get(), "ERR$_T_USER", 1, 
"UNLIMITED");
-    }
-    
-    @Test
-    void assertVisitMultiTableInsertErrorLogging() {
-        InsertStatement actual = (InsertStatement) parse("INSERT ALL INTO 
t_order VALUES (?) LOG ERRORS INTO ERR$_T_ORDER (?) REJECT LIMIT 1 "
-                + "INTO t_order VALUES (2) LOG ERRORS REJECT LIMIT UNLIMITED 
SELECT 1 FROM dual");
-        Iterator<InsertStatement> insertStatements = 
actual.getMultiTableInsertInto().get().getInsertStatements().iterator();
-        assertErrorLogging(insertStatements.next().getErrorLogging().get(), 
"ERR$_T_ORDER", 1, "1");
-        ErrorLoggingSegment actualErrorLogging = 
insertStatements.next().getErrorLogging().get();
-        assertNull(actualErrorLogging.getTable());
-        assertNull(actualErrorLogging.getTag());
-        assertThat(actualErrorLogging.getRejectLimit(), is("UNLIMITED"));
-        assertThat(actual.getParameterCount(), is(2));
-    }
-    
-    @Test
-    void assertVisitUpdateErrorLogging() {
-        UpdateStatement actual = parseUpdate("UPDATE t_user SET email = ? 
WHERE user_id = ? LOG ERRORS INTO ERR$_T_USER (?) REJECT LIMIT 2");
-        assertThat(actual.getParameterCount(), is(3));
-        assertErrorLogging(actual.getErrorLogging().get(), "ERR$_T_USER", 2, 
"2");
-    }
-    
-    @Test
-    void assertVisitDeleteErrorLogging() {
-        DeleteStatement actual = (DeleteStatement) parse("DELETE FROM t_user 
WHERE user_id = ? LOG ERRORS INTO ERR$_T_USER (?) REJECT LIMIT UNLIMITED");
-        assertThat(actual.getParameterCount(), is(2));
-        assertErrorLogging(actual.getErrorLogging().get(), "ERR$_T_USER", 1, 
"UNLIMITED");
-    }
-    
-    @Test
-    void assertVisitMergeErrorLogging() {
-        MergeStatement actual = parseMerge("MERGE INTO t_user target USING 
t_user source ON (target.user_id = source.user_id) "
-                + "WHEN MATCHED THEN UPDATE SET target.email = source.email 
LOG ERRORS INTO ERR$_T_USER (?) REJECT LIMIT 3");
-        assertThat(actual.getParameterCount(), is(1));
-        assertErrorLogging(actual.getErrorLogging().get(), "ERR$_T_USER", 0, 
"3");
-    }
-    
-    private MergeStatement parseMerge(final String sql) {
-        return (MergeStatement) parse(sql);
-    }
-    
-    private UpdateStatement parseUpdate(final String sql) {
-        return (UpdateStatement) parse(sql);
-    }
-    
-    private Object parse(final String sql) {
-        return new SQLStatementVisitorEngine("Oracle").visit(new 
SQLParserEngine("Oracle", CACHE_OPTION).parse(sql, false));
-    }
-    
-    private void assertErrorLogging(final ErrorLoggingSegment actual, final 
String expectedTable, final int expectedParameterIndex, final String 
expectedRejectLimit) {
-        
assertThat(actual.getTable().getTableName().getIdentifier().getValue(), 
is(expectedTable));
-        assertThat(actual.getTag(), 
isA(ParameterMarkerExpressionSegment.class));
-        assertThat(((ParameterMarkerExpressionSegment) 
actual.getTag()).getParameterMarkerIndex(), is(expectedParameterIndex));
-        assertThat(actual.getRejectLimit(), is(expectedRejectLimit));
-    }
-}
diff --git 
a/parser/sql/engine/dialect/sqlserver/src/test/java/org/apache/shardingsphere/sql/parser/engine/sqlserver/visitor/statement/SQLServerStatementVisitorTest.java
 
b/parser/sql/engine/dialect/sqlserver/src/test/java/org/apache/shardingsphere/sql/parser/engine/sqlserver/visitor/statement/SQLServerStatementVisitorTest.java
deleted file mode 100644
index a16df454187..00000000000
--- 
a/parser/sql/engine/dialect/sqlserver/src/test/java/org/apache/shardingsphere/sql/parser/engine/sqlserver/visitor/statement/SQLServerStatementVisitorTest.java
+++ /dev/null
@@ -1,42 +0,0 @@
-/*
- * 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.sql.parser.engine.sqlserver.visitor.statement;
-
-import org.apache.shardingsphere.sql.parser.engine.api.CacheOption;
-import org.apache.shardingsphere.sql.parser.engine.api.SQLParserEngine;
-import 
org.apache.shardingsphere.sql.parser.engine.api.SQLStatementVisitorEngine;
-import 
org.apache.shardingsphere.sql.parser.statement.core.segment.dml.expr.simple.LiteralExpressionSegment;
-import 
org.apache.shardingsphere.sql.parser.statement.core.segment.dml.order.item.ExpressionOrderByItemSegment;
-import 
org.apache.shardingsphere.sql.parser.statement.core.statement.type.dml.SelectStatement;
-import org.junit.jupiter.api.Test;
-
-import static org.hamcrest.MatcherAssert.assertThat;
-import static org.hamcrest.Matchers.is;
-import static org.junit.jupiter.api.Assertions.assertTrue;
-
-class SQLServerStatementVisitorTest {
-    
-    @Test
-    void assertVisitGroupByNull() {
-        SelectStatement actual = (SelectStatement) new 
SQLStatementVisitorEngine("SQLServer").visit(new SQLParserEngine("SQLServer", 
new CacheOption(128, 1024L)).parse(
-                "SELECT COUNT(*) FROM t_order GROUP BY NULL", false));
-        ExpressionOrderByItemSegment actualItem = 
(ExpressionOrderByItemSegment) 
actual.getGroupBy().get().getGroupByItems().iterator().next();
-        assertThat(actualItem.getText(), is("NULL"));
-        assertTrue(((LiteralExpressionSegment) 
actualItem.getExpr()).isNullLiteral());
-    }
-}
diff --git 
a/test/it/parser/src/main/java/org/apache/shardingsphere/test/it/sql/parser/internal/InternalUnsupportedSQLParserIT.java
 
b/test/it/parser/src/main/java/org/apache/shardingsphere/test/it/sql/parser/internal/InternalUnsupportedSQLParserIT.java
index 2ffc237cd8c..31a76969ad5 100644
--- 
a/test/it/parser/src/main/java/org/apache/shardingsphere/test/it/sql/parser/internal/InternalUnsupportedSQLParserIT.java
+++ 
b/test/it/parser/src/main/java/org/apache/shardingsphere/test/it/sql/parser/internal/InternalUnsupportedSQLParserIT.java
@@ -20,6 +20,7 @@ package org.apache.shardingsphere.test.it.sql.parser.internal;
 import com.google.common.base.Preconditions;
 import org.apache.shardingsphere.sql.parser.engine.api.CacheOption;
 import org.apache.shardingsphere.sql.parser.engine.api.SQLParserEngine;
+import 
org.apache.shardingsphere.sql.parser.engine.api.SQLStatementVisitorEngine;
 import 
org.apache.shardingsphere.sql.parser.engine.exception.SQLParsingException;
 import 
org.apache.shardingsphere.test.it.sql.parser.internal.cases.sql.SQLCases;
 import 
org.apache.shardingsphere.test.it.sql.parser.internal.cases.sql.registry.UnsupportedSQLCasesRegistry;
@@ -48,7 +49,8 @@ public abstract class InternalUnsupportedSQLParserIT {
     void assertUnsupportedSQL(final String sqlCaseId, final SQLCaseType 
sqlCaseType, final String databaseType) {
         String sql = SQL_CASES.getSQL(sqlCaseId, sqlCaseType, 
Collections.emptyList());
         CacheOption cacheOption = new CacheOption(128, 1024L);
-        assertThrows(SQLParsingException.class, () -> new 
SQLParserEngine("H2".equals(databaseType) ? "MySQL" : databaseType, 
cacheOption).parse(sql, false));
+        String actualDatabaseType = "H2".equals(databaseType) ? "MySQL" : 
databaseType;
+        assertThrows(SQLParsingException.class, () -> new 
SQLStatementVisitorEngine(actualDatabaseType).visit(new 
SQLParserEngine(actualDatabaseType, cacheOption).parse(sql, false)));
     }
     
     private static final class TestCaseArgumentsProvider implements 
ArgumentsProvider {
diff --git 
a/test/it/parser/src/main/java/org/apache/shardingsphere/test/it/sql/parser/internal/asserts/segment/expression/ExpressionAssert.java
 
b/test/it/parser/src/main/java/org/apache/shardingsphere/test/it/sql/parser/internal/asserts/segment/expression/ExpressionAssert.java
index 061d63f8524..3c8e47c8d7b 100644
--- 
a/test/it/parser/src/main/java/org/apache/shardingsphere/test/it/sql/parser/internal/asserts/segment/expression/ExpressionAssert.java
+++ 
b/test/it/parser/src/main/java/org/apache/shardingsphere/test/it/sql/parser/internal/asserts/segment/expression/ExpressionAssert.java
@@ -151,6 +151,9 @@ public final class ExpressionAssert {
         } else {
             assertNotNull(actual, assertContext.getText("Actual literal 
expression should exist."));
             assertThat(assertContext.getText("Literal assertion error: "), 
String.valueOf(actual.getLiterals()), is(expected.getValue()));
+            if (null != expected.getNullLiteral()) {
+                assertThat(assertContext.getText("Null literal assertion 
error: "), actual.isNullLiteral(), is(expected.getNullLiteral()));
+            }
             SQLSegmentAssert.assertIs(assertContext, actual, expected);
         }
     }
@@ -187,6 +190,9 @@ public final class ExpressionAssert {
             assertNull(actual, assertContext.getText("Actual subquery 
expression should not exist."));
         } else {
             assertNotNull(actual, assertContext.getText("Actual subquery 
expression should exist."));
+            if (null != expected.getText()) {
+                assertThat(assertContext.getText("Subquery text assertion 
error: "), actual.getText(), is(expected.getText()));
+            }
             assertSubquery(assertContext, actual.getSubquery(), expected);
         }
     }
diff --git 
a/test/it/parser/src/main/java/org/apache/shardingsphere/test/it/sql/parser/internal/asserts/statement/ral/type/pipeline/migration/update/MigrateTableStatementAssert.java
 
b/test/it/parser/src/main/java/org/apache/shardingsphere/test/it/sql/parser/internal/asserts/statement/ral/type/pipeline/migration/update/MigrateTableStatementAssert.java
index 310386b2ac3..f8c8c93927b 100644
--- 
a/test/it/parser/src/main/java/org/apache/shardingsphere/test/it/sql/parser/internal/asserts/statement/ral/type/pipeline/migration/update/MigrateTableStatementAssert.java
+++ 
b/test/it/parser/src/main/java/org/apache/shardingsphere/test/it/sql/parser/internal/asserts/statement/ral/type/pipeline/migration/update/MigrateTableStatementAssert.java
@@ -21,12 +21,13 @@ import lombok.AccessLevel;
 import lombok.NoArgsConstructor;
 import 
org.apache.shardingsphere.data.pipeline.scenario.migration.distsql.segment.MigrationSourceTargetSegment;
 import 
org.apache.shardingsphere.data.pipeline.scenario.migration.distsql.statement.updatable.MigrateTableStatement;
-import org.apache.shardingsphere.infra.datanode.DataNode;
 import 
org.apache.shardingsphere.test.it.sql.parser.internal.asserts.SQLCaseAssertContext;
+import 
org.apache.shardingsphere.test.it.sql.parser.internal.asserts.segment.identifier.IdentifierValueAssert;
 import 
org.apache.shardingsphere.test.it.sql.parser.internal.cases.parser.jaxb.statement.ral.migration.MigrateTableStatementTestCase;
 
 import static org.hamcrest.MatcherAssert.assertThat;
 import static org.hamcrest.Matchers.is;
+import static org.junit.jupiter.api.Assertions.assertNull;
 
 /**
  * Migrate table statement assert.
@@ -45,11 +46,14 @@ public final class MigrateTableStatementAssert {
         assertThat(assertContext.getText("target database name does not 
match"), actual.getTargetDatabaseName(), is(expected.getTargetDatabaseName()));
         assertThat(actual.getSourceTargetEntries().size(), is(1));
         for (MigrationSourceTargetSegment each : 
actual.getSourceTargetEntries()) {
-            DataNode dataNode = new DataNode(each.getSourceDatabaseName(), 
each.getSourceSchemaName(), each.getSourceTableName());
-            assertThat(assertContext.getText("source database name does not 
match"), dataNode.getDataSourceName(), is(expected.getSourceResourceName()));
-            assertThat(assertContext.getText("source schema name does not 
match"), dataNode.getSchemaName(), is(expected.getSourceSchemaName()));
-            assertThat(assertContext.getText("source table name does not 
match"), dataNode.getTableName(), is(expected.getSourceTableName()));
-            assertThat(assertContext.getText("target table name does not 
match"), each.getTargetTableName(), is(expected.getTargetTableName()));
+            IdentifierValueAssert.assertIs(assertContext, 
each.getSourceDatabaseIdentifier(), expected.getSourceResourceName(), "source 
database");
+            if (null == expected.getSourceSchemaName()) {
+                assertNull(each.getSourceSchemaIdentifier(), 
assertContext.getText("source schema should not exist"));
+            } else {
+                IdentifierValueAssert.assertIs(assertContext, 
each.getSourceSchemaIdentifier(), expected.getSourceSchemaName(), "source 
schema");
+            }
+            IdentifierValueAssert.assertIs(assertContext, 
each.getSourceTableIdentifier(), expected.getSourceTableName(), "source table");
+            IdentifierValueAssert.assertIs(assertContext, 
each.getTargetTableIdentifier(), expected.getTargetTableName(), "target table");
         }
     }
 }
diff --git 
a/test/it/parser/src/main/java/org/apache/shardingsphere/test/it/sql/parser/internal/cases/parser/jaxb/segment/impl/expr/simple/ExpectedLiteralExpression.java
 
b/test/it/parser/src/main/java/org/apache/shardingsphere/test/it/sql/parser/internal/cases/parser/jaxb/segment/impl/expr/simple/ExpectedLiteralExpression.java
index 095f1b54273..458c947e27c 100644
--- 
a/test/it/parser/src/main/java/org/apache/shardingsphere/test/it/sql/parser/internal/cases/parser/jaxb/segment/impl/expr/simple/ExpectedLiteralExpression.java
+++ 
b/test/it/parser/src/main/java/org/apache/shardingsphere/test/it/sql/parser/internal/cases/parser/jaxb/segment/impl/expr/simple/ExpectedLiteralExpression.java
@@ -31,4 +31,7 @@ public final class ExpectedLiteralExpression extends 
ExpectedBaseSimpleExpressio
     
     @XmlAttribute
     private String value;
+    
+    @XmlAttribute(name = "null-literal")
+    private Boolean nullLiteral;
 }
diff --git 
a/test/it/parser/src/main/java/org/apache/shardingsphere/test/it/sql/parser/internal/cases/parser/jaxb/segment/impl/expr/simple/ExpectedSubquery.java
 
b/test/it/parser/src/main/java/org/apache/shardingsphere/test/it/sql/parser/internal/cases/parser/jaxb/segment/impl/expr/simple/ExpectedSubquery.java
index 70bc91fca3d..b085a6e127b 100644
--- 
a/test/it/parser/src/main/java/org/apache/shardingsphere/test/it/sql/parser/internal/cases/parser/jaxb/segment/impl/expr/simple/ExpectedSubquery.java
+++ 
b/test/it/parser/src/main/java/org/apache/shardingsphere/test/it/sql/parser/internal/cases/parser/jaxb/segment/impl/expr/simple/ExpectedSubquery.java
@@ -22,6 +22,7 @@ import lombok.Setter;
 import 
org.apache.shardingsphere.test.it.sql.parser.internal.cases.parser.jaxb.statement.dml.standard.MergeStatementTestCase;
 import 
org.apache.shardingsphere.test.it.sql.parser.internal.cases.parser.jaxb.statement.dml.standard.SelectStatementTestCase;
 
+import javax.xml.bind.annotation.XmlAttribute;
 import javax.xml.bind.annotation.XmlElement;
 
 /**
@@ -31,6 +32,9 @@ import javax.xml.bind.annotation.XmlElement;
 @Setter
 public final class ExpectedSubquery extends ExpectedBaseSimpleExpression {
     
+    @XmlAttribute
+    private String text;
+    
     @XmlElement(name = "select")
     private SelectStatementTestCase selectTestCases;
     
diff --git 
a/test/it/parser/src/main/java/org/apache/shardingsphere/test/it/sql/parser/internal/cases/parser/jaxb/statement/ral/migration/MigrateTableStatementTestCase.java
 
b/test/it/parser/src/main/java/org/apache/shardingsphere/test/it/sql/parser/internal/cases/parser/jaxb/statement/ral/migration/MigrateTableStatementTestCase.java
index 9155bb95702..b5c27a66886 100644
--- 
a/test/it/parser/src/main/java/org/apache/shardingsphere/test/it/sql/parser/internal/cases/parser/jaxb/statement/ral/migration/MigrateTableStatementTestCase.java
+++ 
b/test/it/parser/src/main/java/org/apache/shardingsphere/test/it/sql/parser/internal/cases/parser/jaxb/statement/ral/migration/MigrateTableStatementTestCase.java
@@ -20,6 +20,7 @@ package 
org.apache.shardingsphere.test.it.sql.parser.internal.cases.parser.jaxb.
 import lombok.Getter;
 import lombok.Setter;
 import 
org.apache.shardingsphere.test.it.sql.parser.internal.cases.parser.jaxb.SQLParserTestCase;
+import 
org.apache.shardingsphere.test.it.sql.parser.internal.cases.parser.jaxb.segment.impl.identifier.ExpectedIdentifier;
 
 import javax.xml.bind.annotation.XmlElement;
 
@@ -31,17 +32,17 @@ import javax.xml.bind.annotation.XmlElement;
 public final class MigrateTableStatementTestCase extends SQLParserTestCase {
     
     @XmlElement(name = "source-resource-name")
-    private String sourceResourceName;
+    private ExpectedIdentifier sourceResourceName;
     
     @XmlElement(name = "source-table-name")
-    private String sourceTableName;
+    private ExpectedIdentifier sourceTableName;
     
     @XmlElement(name = "source-schema-name")
-    private String sourceSchemaName;
+    private ExpectedIdentifier sourceSchemaName;
     
     @XmlElement(name = "target-database-name")
     private String targetDatabaseName;
     
     @XmlElement(name = "target-table-name")
-    private String targetTableName;
+    private ExpectedIdentifier targetTableName;
 }
diff --git a/test/it/parser/src/main/resources/case/dml/insert.xml 
b/test/it/parser/src/main/resources/case/dml/insert.xml
index c3f041a74cd..45a56d9ef72 100644
--- a/test/it/parser/src/main/resources/case/dml/insert.xml
+++ b/test/it/parser/src/main/resources/case/dml/insert.xml
@@ -37,6 +37,55 @@
         </error-logging>
     </insert>
 
+    <insert sql-case-id="multi_table_insert_with_error_logging" parameters="1, 
'insert_tag'">
+        <multi-table-insert-type value="ALL" />
+        <multi-table-insert-into start-index="11" stop-index="139">
+            <insert-statement>
+                <table name="t_order" start-index="16" stop-index="22" />
+                <columns start-index="23" stop-index="23" />
+                <values>
+                    <value>
+                        <assignment-value>
+                            <parameter-marker-expression parameter-index="0" 
start-index="32" stop-index="32" />
+                        </assignment-value>
+                    </value>
+                </values>
+                <error-logging reject-limit="1" start-index="35" 
stop-index="81">
+                    <table>
+                        <simple-table name="ERR$_T_ORDER" start-index="51" 
stop-index="62" />
+                    </table>
+                    <tag>
+                        <parameter-marker-expression parameter-index="1" 
start-index="65" stop-index="65" />
+                    </tag>
+                </error-logging>
+            </insert-statement>
+            <insert-statement>
+                <table name="t_order" start-index="88" stop-index="94" />
+                <columns start-index="95" stop-index="95" />
+                <values>
+                    <value>
+                        <assignment-value>
+                            <literal-expression value="2" start-index="104" 
stop-index="104" />
+                        </assignment-value>
+                    </value>
+                </values>
+                <error-logging reject-limit="UNLIMITED" start-index="107" 
stop-index="139" />
+            </insert-statement>
+        </multi-table-insert-into>
+        <select>
+            <from>
+                <simple-table name="dual" start-index="155" stop-index="158" />
+            </from>
+            <projections start-index="148" stop-index="148">
+                <expression-projection text="1" start-index="148" 
stop-index="148">
+                    <expr>
+                        <literal-expression value="1" start-index="148" 
stop-index="148" />
+                    </expr>
+                </expression-projection>
+            </projections>
+        </select>
+    </insert>
+
     <insert sql-case-id="insert_into_values1">
         <table name="test_nested" start-index="12" stop-index="22" />
         <columns start-index="23" stop-index="23" />
diff --git a/test/it/parser/src/main/resources/case/dml/merge.xml 
b/test/it/parser/src/main/resources/case/dml/merge.xml
index 6ed4f7254b7..05a9b6bffcc 100644
--- a/test/it/parser/src/main/resources/case/dml/merge.xml
+++ b/test/it/parser/src/main/resources/case/dml/merge.xml
@@ -50,6 +50,273 @@
         </error-logging>
     </merge>
 
+    <merge sql-case-id="merge_update_with_scalar_subquery" parameters="1, 1">
+        <target>
+            <simple-table name="t_user" alias="target" start-index="11" 
stop-index="23" />
+        </target>
+        <source>
+            <subquery-table alias="source" start-index="31" stop-index="65">
+                <subquery>
+                    <select>
+                        <from>
+                            <simple-table name="DUAL" start-index="54" 
stop-index="57" />
+                        </from>
+                        <projections start-index="39" stop-index="47">
+                            <parameter-marker-expression parameter-index="0" 
start-index="39" stop-index="47" />
+                        </projections>
+                    </select>
+                </subquery>
+            </subquery-table>
+        </source>
+        <expr>
+            <binary-operation-expression start-index="71" stop-index="101">
+                <left>
+                    <column name="user_id" start-index="71" stop-index="84">
+                        <owner name="target" start-index="71" stop-index="76" 
/>
+                    </column>
+                </left>
+                <operator>=</operator>
+                <right>
+                    <column name="user_id" start-index="88" stop-index="101">
+                        <owner name="source" start-index="88" stop-index="93" 
/>
+                    </column>
+                </right>
+            </binary-operation-expression>
+        </expr>
+        <update>
+            <set start-index="133" stop-index="202">
+                <assignment start-index="133" stop-index="202">
+                    <column name="email" start-index="133" stop-index="144">
+                        <owner name="target" start-index="133" 
stop-index="138" />
+                    </column>
+                    <assignment-value>
+                        <subquery text="(SELECT MAX(u.email) FROM t_user u 
WHERE u.user_id &lt; ?)" start-index="148" stop-index="202">
+                            <select>
+                                <from>
+                                    <simple-table name="t_user" alias="u" 
start-index="174" stop-index="181" />
+                                </from>
+                                <projections start-index="156" 
stop-index="167">
+                                    <aggregation-projection type="MAX" 
expression="MAX(u.email)" start-index="156" stop-index="167" />
+                                </projections>
+                                <where start-index="183" stop-index="201">
+                                    <expr>
+                                        <binary-operation-expression 
start-index="189" stop-index="201">
+                                            <left>
+                                                <column name="user_id" 
start-index="189" stop-index="197">
+                                                    <owner name="u" 
start-index="189" stop-index="189" />
+                                                </column>
+                                            </left>
+                                            <operator>&lt;</operator>
+                                            <right>
+                                                <parameter-marker-expression 
parameter-index="1" start-index="201" stop-index="201" />
+                                            </right>
+                                        </binary-operation-expression>
+                                    </expr>
+                                </where>
+                            </select>
+                        </subquery>
+                    </assignment-value>
+                </assignment>
+            </set>
+        </update>
+    </merge>
+
+    <merge sql-case-id="merge_insert_with_scalar_subquery" parameters="1, 1">
+        <target>
+            <simple-table name="t_user" alias="target" start-index="11" 
stop-index="23" />
+        </target>
+        <source>
+            <subquery-table alias="source" start-index="31" stop-index="65">
+                <subquery>
+                    <select>
+                        <from>
+                            <simple-table name="DUAL" start-index="54" 
stop-index="57" />
+                        </from>
+                        <projections start-index="39" stop-index="47">
+                            <parameter-marker-expression parameter-index="0" 
start-index="39" stop-index="47" />
+                        </projections>
+                    </select>
+                </subquery>
+            </subquery-table>
+        </source>
+        <expr>
+            <binary-operation-expression start-index="71" stop-index="101">
+                <left>
+                    <column name="user_id" start-index="71" stop-index="84">
+                        <owner name="target" start-index="71" stop-index="76" 
/>
+                    </column>
+                </left>
+                <operator>=</operator>
+                <right>
+                    <column name="user_id" start-index="88" stop-index="101">
+                        <owner name="source" start-index="88" stop-index="93" 
/>
+                    </column>
+                </right>
+            </binary-operation-expression>
+        </expr>
+        <insert>
+            <columns start-index="133" stop-index="148">
+                <column name="user_id" start-index="134" stop-index="140" />
+                <column name="email" start-index="143" stop-index="147" />
+            </columns>
+            <values>
+                <value>
+                    <assignment-value>
+                        <column name="user_id" start-index="158" 
stop-index="171">
+                            <owner name="source" start-index="158" 
stop-index="163" />
+                        </column>
+                    </assignment-value>
+                    <assignment-value>
+                        <subquery text="(SELECT MAX(u.email) FROM t_user u 
WHERE u.user_id &lt; ?)" start-index="174" stop-index="228">
+                            <select>
+                                <from>
+                                    <simple-table name="t_user" alias="u" 
start-index="200" stop-index="207" />
+                                </from>
+                                <projections start-index="182" 
stop-index="193">
+                                    <aggregation-projection type="MAX" 
expression="MAX(u.email)" start-index="182" stop-index="193" />
+                                </projections>
+                                <where start-index="209" stop-index="227">
+                                    <expr>
+                                        <binary-operation-expression 
start-index="215" stop-index="227">
+                                            <left>
+                                                <column name="user_id" 
start-index="215" stop-index="223">
+                                                    <owner name="u" 
start-index="215" stop-index="215" />
+                                                </column>
+                                            </left>
+                                            <operator>&lt;</operator>
+                                            <right>
+                                                <parameter-marker-expression 
parameter-index="1" start-index="227" stop-index="227" />
+                                            </right>
+                                        </binary-operation-expression>
+                                    </expr>
+                                </where>
+                            </select>
+                        </subquery>
+                    </assignment-value>
+                </value>
+            </values>
+        </insert>
+    </merge>
+
+    <merge sql-case-id="merge_with_system_datetime_functions" parameters="1">
+        <target>
+            <simple-table name="t_user" alias="target" start-index="11" 
stop-index="23" />
+        </target>
+        <source>
+            <subquery-table alias="source" start-index="31" stop-index="65">
+                <subquery>
+                    <select>
+                        <from>
+                            <simple-table name="DUAL" start-index="54" 
stop-index="57" />
+                        </from>
+                        <projections start-index="39" stop-index="47">
+                            <parameter-marker-expression parameter-index="0" 
start-index="39" stop-index="47" />
+                        </projections>
+                    </select>
+                </subquery>
+            </subquery-table>
+        </source>
+        <expr>
+            <binary-operation-expression start-index="71" stop-index="101">
+                <left>
+                    <column name="user_id" start-index="71" stop-index="84">
+                        <owner name="target" start-index="71" stop-index="76" 
/>
+                    </column>
+                </left>
+                <operator>=</operator>
+                <right>
+                    <column name="user_id" start-index="88" stop-index="101">
+                        <owner name="source" start-index="88" stop-index="93" 
/>
+                    </column>
+                </right>
+            </binary-operation-expression>
+        </expr>
+        <update>
+            <set start-index="133" stop-index="162">
+                <assignment start-index="133" stop-index="162">
+                    <column name="creation_date" start-index="133" 
stop-index="152">
+                        <owner name="target" start-index="133" 
stop-index="138" />
+                    </column>
+                    <assignment-value>
+                        <function function-name="SYSDATE" text="SYSDATE" 
start-index="156" stop-index="162" />
+                    </assignment-value>
+                </assignment>
+            </set>
+        </update>
+        <insert>
+            <columns start-index="193" stop-index="216">
+                <column name="user_id" start-index="194" stop-index="200" />
+                <column name="creation_date" start-index="203" 
stop-index="215" />
+            </columns>
+            <values>
+                <value>
+                    <assignment-value>
+                        <column name="user_id" start-index="226" 
stop-index="239">
+                            <owner name="source" start-index="226" 
stop-index="231" />
+                        </column>
+                    </assignment-value>
+                    <assignment-value>
+                        <function function-name="CAST" text="CAST(SYSTIMESTAMP 
AS TIMESTAMP)" start-index="242" stop-index="272">
+                            <parameter>
+                                <function function-name="SYSTIMESTAMP" 
text="SYSTIMESTAMP" start-index="247" stop-index="258" />
+                            </parameter>
+                            <parameter>
+                                <data-type value="TIMESTAMP" start-index="263" 
stop-index="271" />
+                            </parameter>
+                        </function>
+                    </assignment-value>
+                </value>
+            </values>
+        </insert>
+    </merge>
+
+    <merge sql-case-id="merge_with_quoted_system_datetime_column" 
parameters="1">
+        <target>
+            <simple-table name="t_user" alias="target" start-index="11" 
stop-index="23" />
+        </target>
+        <source>
+            <subquery-table alias="source" start-index="31" stop-index="65">
+                <subquery>
+                    <select>
+                        <from>
+                            <simple-table name="DUAL" start-index="54" 
stop-index="57" />
+                        </from>
+                        <projections start-index="39" stop-index="47">
+                            <parameter-marker-expression parameter-index="0" 
start-index="39" stop-index="47" />
+                        </projections>
+                    </select>
+                </subquery>
+            </subquery-table>
+        </source>
+        <expr>
+            <binary-operation-expression start-index="71" stop-index="101">
+                <left>
+                    <column name="user_id" start-index="71" stop-index="84">
+                        <owner name="target" start-index="71" stop-index="76" 
/>
+                    </column>
+                </left>
+                <operator>=</operator>
+                <right>
+                    <column name="user_id" start-index="88" stop-index="101">
+                        <owner name="source" start-index="88" stop-index="93" 
/>
+                    </column>
+                </right>
+            </binary-operation-expression>
+        </expr>
+        <update>
+            <set start-index="133" stop-index="164">
+                <assignment start-index="133" stop-index="164">
+                    <column name="creation_date" start-index="133" 
stop-index="152">
+                        <owner name="target" start-index="133" 
stop-index="138" />
+                    </column>
+                    <assignment-value>
+                        <column name="SYSDATE" start-delimiter="&quot;" 
end-delimiter="&quot;" start-index="156" stop-index="164" />
+                    </assignment-value>
+                </assignment>
+            </set>
+        </update>
+    </merge>
+
     <merge sql-case-id="merge_into_table_using_table" >
         <target>
             <simple-table name="people_target" start-index="11" 
stop-index="23" />
diff --git a/test/it/parser/src/main/resources/case/dml/select-group-by.xml 
b/test/it/parser/src/main/resources/case/dml/select-group-by.xml
index 3ad9f4d03cf..2d65d9dd44d 100644
--- a/test/it/parser/src/main/resources/case/dml/select-group-by.xml
+++ b/test/it/parser/src/main/resources/case/dml/select-group-by.xml
@@ -1087,7 +1087,7 @@
         <group-by>
             <expression-item expression="NULL" start-index="38" 
stop-index="41">
                 <expr>
-                    <literal-expression value="null" start-index="38" 
stop-index="41" />
+                    <literal-expression value="null" null-literal="true" 
start-index="38" stop-index="41" />
                 </expr>
             </expression-item>
         </group-by>
diff --git a/test/it/parser/src/main/resources/case/ral/migration.xml 
b/test/it/parser/src/main/resources/case/ral/migration.xml
index c96ecec4d04..e6aa7fe3b73 100644
--- a/test/it/parser/src/main/resources/case/ral/migration.xml
+++ b/test/it/parser/src/main/resources/case/ral/migration.xml
@@ -41,31 +41,39 @@
     </show-migration-check-status>
     
     <migrate-table sql-case-id="migrate-table-without-schema-target-db">
-        <source-resource-name>ds_0</source-resource-name>
-        <source-table-name>t_order</source-table-name>
-        <target-table-name>t_order</target-table-name>
+        <source-resource-name name="ds_0" />
+        <source-table-name name="t_order" />
+        <target-table-name name="t_order" />
     </migrate-table>
     
     <migrate-table sql-case-id="migrate-table-with-schema">
-        <source-resource-name>ds_0</source-resource-name>
-        <source-schema-name>public</source-schema-name>
-        <source-table-name>t_order</source-table-name>
-        <target-table-name>t_order</target-table-name>
+        <source-resource-name name="ds_0" />
+        <source-schema-name name="public" />
+        <source-table-name name="t_order" />
+        <target-table-name name="t_order" />
     </migrate-table>
     
     <migrate-table sql-case-id="migrate-table-with-target-db">
-        <source-resource-name>ds_0</source-resource-name>
-        <source-table-name>t_order</source-table-name>
+        <source-resource-name name="ds_0" />
+        <source-table-name name="t_order" />
         <target-database-name>sharding_db</target-database-name>
-        <target-table-name>t_order</target-table-name>
+        <target-table-name name="t_order" />
     </migrate-table>
     
     <migrate-table sql-case-id="migrate-table-with-schema-target-db">
-        <source-resource-name>ds_0</source-resource-name>
-        <source-schema-name>public</source-schema-name>
-        <source-table-name>t_order</source-table-name>
+        <source-resource-name name="ds_0" />
+        <source-schema-name name="public" />
+        <source-table-name name="t_order" />
         <target-database-name>sharding_db</target-database-name>
-        <target-table-name>t_order</target-table-name>
+        <target-table-name name="t_order" />
+    </migrate-table>
+
+    <migrate-table sql-case-id="migrate-table-with-qualified-identifiers">
+        <source-resource-name name="FOO_DS" start-delimiter="`" 
end-delimiter="`" />
+        <source-schema-name name="FOO_SCHEMA" start-delimiter="`" 
end-delimiter="`" />
+        <source-table-name name="FOO_TABLE" start-delimiter="`" 
end-delimiter="`" />
+        <target-database-name>target_db</target-database-name>
+        <target-table-name name="FOO_TABLE" />
     </migrate-table>
     
     <rollback-migration sql-case-id="rollback-migration">
diff --git a/test/it/parser/src/main/resources/sql/supported/dml/insert.xml 
b/test/it/parser/src/main/resources/sql/supported/dml/insert.xml
index 2822c366b19..9eb21b62b64 100644
--- a/test/it/parser/src/main/resources/sql/supported/dml/insert.xml
+++ b/test/it/parser/src/main/resources/sql/supported/dml/insert.xml
@@ -18,6 +18,7 @@
 
 <sql-cases>
     <sql-case id="insert_with_error_logging" value="INSERT INTO t_user VALUES 
(?) LOG ERRORS INTO ERR$_T_USER (?) REJECT LIMIT UNLIMITED" db-types="Oracle" 
case-types="PLACEHOLDER" />
+    <sql-case id="multi_table_insert_with_error_logging" value="INSERT ALL 
INTO t_order VALUES (?) LOG ERRORS INTO ERR$_T_ORDER (?) REJECT LIMIT 1 INTO 
t_order VALUES (2) LOG ERRORS REJECT LIMIT UNLIMITED SELECT 1 FROM dual" 
db-types="Oracle" case-types="PLACEHOLDER" />
     <sql-case id="insert_into_values1" value="INSERT INTO test_nested 
VALUES(1)" db-types="MySQL,Presto" />
     <sql-case id="insert_into_values2" value="insert into emp_table 
values(1,'John',1000.00,'Architect')" db-types="Oracle" />
     <sql-case id="insert_into_values3" value="insert into emp_table 
values(2,'Robert',900.00,'Developer')" db-types="Oracle" />
diff --git a/test/it/parser/src/main/resources/sql/supported/dml/merge.xml 
b/test/it/parser/src/main/resources/sql/supported/dml/merge.xml
index 520827da795..6fb411c8944 100644
--- a/test/it/parser/src/main/resources/sql/supported/dml/merge.xml
+++ b/test/it/parser/src/main/resources/sql/supported/dml/merge.xml
@@ -18,6 +18,10 @@
 
 <sql-cases>
     <sql-case id="merge_with_error_logging" value="MERGE INTO t_user target 
USING t_user_source source ON (target.user_id = source.user_id) WHEN MATCHED 
THEN UPDATE SET target.email = source.email LOG ERRORS INTO ERR$_T_USER (?) 
REJECT LIMIT UNLIMITED" db-types="Oracle" case-types="PLACEHOLDER" />
+    <sql-case id="merge_update_with_scalar_subquery" value="MERGE INTO t_user 
target USING (SELECT ? user_id FROM DUAL) source ON (target.user_id = 
source.user_id) WHEN MATCHED THEN UPDATE SET target.email = (SELECT 
MAX(u.email) FROM t_user u WHERE u.user_id &lt; ?)" db-types="Oracle" 
case-types="PLACEHOLDER" />
+    <sql-case id="merge_insert_with_scalar_subquery" value="MERGE INTO t_user 
target USING (SELECT ? user_id FROM DUAL) source ON (target.user_id = 
source.user_id) WHEN NOT MATCHED THEN INSERT (user_id, email) VALUES 
(source.user_id, (SELECT MAX(u.email) FROM t_user u WHERE u.user_id &lt; ?))" 
db-types="Oracle" case-types="PLACEHOLDER" />
+    <sql-case id="merge_with_system_datetime_functions" value="MERGE INTO 
t_user target USING (SELECT ? user_id FROM DUAL) source ON (target.user_id = 
source.user_id) WHEN MATCHED THEN UPDATE SET target.creation_date = SYSDATE 
WHEN NOT MATCHED THEN INSERT (user_id, creation_date) VALUES (source.user_id, 
CAST(SYSTIMESTAMP AS TIMESTAMP))" db-types="Oracle" case-types="PLACEHOLDER" />
+    <sql-case id="merge_with_quoted_system_datetime_column" value="MERGE INTO 
t_user target USING (SELECT ? user_id FROM DUAL) source ON (target.user_id = 
source.user_id) WHEN MATCHED THEN UPDATE SET target.creation_date = 
&quot;SYSDATE&quot;" db-types="Oracle" case-types="PLACEHOLDER" />
     <sql-case id="merge_into_table_using_table" value="MERGE INTO 
people_target USING people_source ON (people_target.person_id = 
people_source.person_id)" db-types="Oracle" />
     <sql-case id="merge_into_table_using_subquery_alias" value="MERGE INTO 
bonuses D USING (SELECT employee_id, salary, department_id FROM employees WHERE 
department_id = 80) S ON (D.employee_id = S.employee_id)" db-types="Oracle" />
     <sql-case id="merge_update_table" value="MERGE INTO people_target pt USING 
people_source ps ON (pt.person_id = ps.person_id) WHEN MATCHED THEN UPDATE SET 
pt.first_name = ps.first_name, pt.last_name = ps.last_name, pt.title = 
ps.title" db-types="Oracle" />
diff --git 
a/test/it/parser/src/main/resources/sql/supported/dml/select-group-by.xml 
b/test/it/parser/src/main/resources/sql/supported/dml/select-group-by.xml
index 6126520c9c1..3196d33fd40 100644
--- a/test/it/parser/src/main/resources/sql/supported/dml/select-group-by.xml
+++ b/test/it/parser/src/main/resources/sql/supported/dml/select-group-by.xml
@@ -52,5 +52,5 @@
     <sql-case id="select_group_by_top_column_value" value="SELECT TOP 10 
hash_unique_bigint_id FROM dbo.TelemetryDS WHERE Timestamp BETWEEN @StartTime 
AND @EndTime GROUP BY hash_unique_bigint_id ORDER BY 
MAX(max_elapsed_time_microsec) DESC" db-types="SQLServer" />
     <sql-case id="select_group_by_count_with_tumblingwindow_function" 
value="SELECT count(*) FROM input GROUP BY clusterid,tumblingwindow(minutes, 
5)" db-types="SQLServer" />
     <sql-case id="select_group_by_rollup_oracle" value="SELECT dept, 
SUM(salary) FROM employees GROUP BY ROLLUP(dept)" db-types="Oracle" />
-    <sql-case id="select_group_by_null_expression" value="SELECT COUNT(*) FROM 
t_order GROUP BY NULL" db-types="MySQL,PostgreSQL,Oracle" />
+    <sql-case id="select_group_by_null_expression" value="SELECT COUNT(*) FROM 
t_order GROUP BY NULL" db-types="MySQL,PostgreSQL,openGauss,Oracle,SQLServer" />
 </sql-cases>
diff --git a/test/it/parser/src/main/resources/sql/supported/ral/migration.xml 
b/test/it/parser/src/main/resources/sql/supported/ral/migration.xml
index 44cfcefee53..a7000336480 100644
--- a/test/it/parser/src/main/resources/sql/supported/ral/migration.xml
+++ b/test/it/parser/src/main/resources/sql/supported/ral/migration.xml
@@ -29,6 +29,7 @@
     <sql-case id="migrate-table-with-schema" value="MIGRATE TABLE 
ds_0.public.t_order INTO t_order;" db-types="ShardingSphere" />
     <sql-case id="migrate-table-with-target-db" value="MIGRATE TABLE 
ds_0.t_order INTO sharding_db.t_order;" db-types="ShardingSphere" />
     <sql-case id="migrate-table-with-schema-target-db" value="MIGRATE TABLE 
ds_0.public.t_order INTO sharding_db.t_order;" db-types="ShardingSphere" />
+    <sql-case id="migrate-table-with-qualified-identifiers" value="MIGRATE 
TABLE `FOO_DS`.`FOO_SCHEMA`.`FOO_TABLE` INTO target_db.FOO_TABLE" 
db-types="ShardingSphere" />
     <sql-case id="rollback-migration" value="ROLLBACK MIGRATION 123;" 
db-types="ShardingSphere" />
     <sql-case id="commit-migration" value="COMMIT MIGRATION 123;" 
db-types="ShardingSphere" />
     <sql-case id="stop-migration" value="STOP MIGRATION 123;" 
db-types="ShardingSphere" />
diff --git a/test/it/parser/src/main/resources/sql/unsupported/unsupported.xml 
b/test/it/parser/src/main/resources/sql/unsupported/unsupported.xml
index f704eca6ba3..9cc500a88f0 100644
--- a/test/it/parser/src/main/resources/sql/unsupported/unsupported.xml
+++ b/test/it/parser/src/main/resources/sql/unsupported/unsupported.xml
@@ -40,6 +40,18 @@
     <sql-case id="unsupported_doris_min_distinct_window" value="SELECT 
MIN(DISTINCT v) OVER ()" db-types="Doris" />
     <sql-case id="unsupported_doris_avg_distinct_window" value="SELECT 
AVG(DISTINCT v) OVER ()" db-types="Doris" />
     <sql-case id="unsupported_doris_bit_xor_distinct_window" value="SELECT 
BIT_XOR(DISTINCT v) OVER ()" db-types="Doris" />
+    <sql-case id="unsupported_doris_data_quota_with_oversized_unit_value" 
value="ALTER DATABASE db SET DATA QUOTA 99999999999P" db-types="Doris" />
+    <sql-case id="unsupported_doris_data_quota_with_oversized_value" 
value="ALTER DATABASE db SET DATA QUOTA 99999999999999999999999" 
db-types="Doris" />
+    <sql-case id="unsupported_doris_data_quota_with_identifier_value" 
value="ALTER DATABASE db SET DATA QUOTA foo" db-types="Doris" />
+    <sql-case id="unsupported_doris_data_quota_with_invalid_unit" value="ALTER 
DATABASE db SET DATA QUOTA 1XB" db-types="Doris" />
+    <sql-case id="unsupported_doris_data_quota_with_decimal_value" 
value="ALTER DATABASE db SET DATA QUOTA 1.5" db-types="Doris" />
+    <sql-case id="unsupported_doris_replica_quota_with_decimal_value" 
value="ALTER DATABASE db SET REPLICA QUOTA 1.5" db-types="Doris" />
+    <sql-case id="unsupported_doris_transaction_quota_with_decimal_value" 
value="ALTER DATABASE db SET TRANSACTION QUOTA 2.75" db-types="Doris" />
+    <sql-case id="unsupported_doris_unquoted_play_identifier" value="SELECT 
play FROM t_play" db-types="Doris" />
+    <sql-case id="unsupported_doris_show_database_with_decimal_id" value="SHOW 
DATABASE 1.2" db-types="Doris" />
+    <sql-case id="unsupported_doris_show_database_with_exponent_id" 
value="SHOW DATABASE 1e2" db-types="Doris" />
+    <sql-case id="unsupported_doris_show_table_with_decimal_id" value="SHOW 
TABLE 1.2" db-types="Doris" />
+    <sql-case id="unsupported_doris_show_table_with_exponent_id" value="SHOW 
TABLE 1e2" db-types="Doris" />
     <sql-case id="select_like" value="select conname, obj_description(oid, 
'pg_constraint') as desc from pg_constraint where conname like 
'at_partitioned%' order by conname" db-types="PostgreSQL" />
     <sql-case id="select_keyword" value="select relname,c.oid = oldoid as 
orig_oid,case relfilenode when 0 then 'none' when c.oid then 'own' when 
oldfilenode then 'orig' else 'OTHER' end as storage, obj_description(c.oid, 
'pg_class') as desc from pg_class c left join old_oids using (relname) where 
relname like 'at_partitioned%' order by relname" db-types="PostgreSQL" />
     <sql-case id="unsupported_date_literal_for_clickhouse" value="SELECT DATE 
'2024-01-01'" db-types="ClickHouse" />

Reply via email to