You are viewing a plain text version of this content. The canonical link for it is here.
Posted to notifications@shardingsphere.apache.org by zh...@apache.org on 2020/06/19 15:01:06 UTC
[shardingsphere] branch master updated: #4632,
add parser test case & fix replace statement (#6136)
This is an automated email from the ASF dual-hosted git repository.
zhangliang pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/shardingsphere.git
The following commit(s) were added to refs/heads/master by this push:
new 177bddd #4632, add parser test case & fix replace statement (#6136)
177bddd is described below
commit 177bdddd2d65a33341f33b70c01692242848414d
Author: Zhang Yonglun <zh...@apache.org>
AuthorDate: Fri Jun 19 23:00:57 2020 +0800
#4632, add parser test case & fix replace statement (#6136)
---
.../src/main/antlr4/imports/mysql/DMLStatement.g4 | 10 +-
.../parser/mysql/visitor/impl/MySQLDMLVisitor.java | 56 +-
.../segment/dml/column/ReplaceColumnsSegment.java | 38 +
.../parser/sql/statement/dml/ReplaceStatement.java | 2 +-
.../asserts/statement/dml/DMLStatementAssert.java | 5 +
.../statement/dml/impl/ReplaceStatementAssert.java | 83 ++
.../jaxb/cases/domain/SQLParserTestCases.java | 7 +-
.../statement/dml/ReplaceStatementTestCase.java | 48 ++
.../src/test/resources/case/dml/replace.xml | 835 +++++++++++++++++++++
.../test/resources/sql/supported/dml/replace.xml | 49 ++
10 files changed, 1114 insertions(+), 19 deletions(-)
diff --git a/shardingsphere-sql-parser/shardingsphere-sql-parser-dialect/shardingsphere-sql-parser-mysql/src/main/antlr4/imports/mysql/DMLStatement.g4 b/shardingsphere-sql-parser/shardingsphere-sql-parser-dialect/shardingsphere-sql-parser-mysql/src/main/antlr4/imports/mysql/DMLStatement.g4
index 366ad9c..de9960b 100644
--- a/shardingsphere-sql-parser/shardingsphere-sql-parser-dialect/shardingsphere-sql-parser-mysql/src/main/antlr4/imports/mysql/DMLStatement.g4
+++ b/shardingsphere-sql-parser/shardingsphere-sql-parser-dialect/shardingsphere-sql-parser-mysql/src/main/antlr4/imports/mysql/DMLStatement.g4
@@ -48,13 +48,21 @@ derivedColumns_
;
replace
- : REPLACE replaceSpecification_? INTO? tableName partitionNames_? (insertValuesClause | setAssignmentsClause | insertSelectClause)
+ : REPLACE replaceSpecification_? INTO? tableName partitionNames_? (replaceValuesClause | setAssignmentsClause | replaceSelectClause)
;
replaceSpecification_
: LOW_PRIORITY | DELAYED
;
+replaceValuesClause
+ : columnNames? (VALUES | VALUE) (assignmentValues (COMMA_ assignmentValues)* | rowConstructorList) valueReference_?
+ ;
+
+replaceSelectClause
+ : valueReference_? columnNames? select
+ ;
+
update
: withClause_? UPDATE updateSpecification_ tableReferences setAssignmentsClause whereClause? orderByClause? limitClause?
;
diff --git a/shardingsphere-sql-parser/shardingsphere-sql-parser-dialect/shardingsphere-sql-parser-mysql/src/main/java/org/apache/shardingsphere/sql/parser/mysql/visitor/impl/MySQLDMLVisitor.java b/shardingsphere-sql-parser/shardingsphere-sql-parser-dialect/shardingsphere-sql-parser-mysql/src/main/java/org/apache/shardingsphere/sql/parser/mysql/visitor/impl/MySQLDMLVisitor.java
index 4653b53..fef53c7 100644
--- a/shardingsphere-sql-parser/shardingsphere-sql-parser-dialect/shardingsphere-sql-parser-mysql/src/main/java/org/apache/shardingsphere/sql/parser/mysql/visitor/impl/MySQLDMLVisitor.java
+++ b/shardingsphere-sql-parser/shardingsphere-sql-parser-dialect/shardingsphere-sql-parser-mysql/src/main/java/org/apache/shardingsphere/sql/parser/mysql/visitor/impl/MySQLDMLVisitor.java
@@ -36,6 +36,7 @@ import org.apache.shardingsphere.sql.parser.autogen.MySQLStatementParser.FromCla
import org.apache.shardingsphere.sql.parser.autogen.MySQLStatementParser.GroupByClauseContext;
import org.apache.shardingsphere.sql.parser.autogen.MySQLStatementParser.InsertContext;
import org.apache.shardingsphere.sql.parser.autogen.MySQLStatementParser.InsertValuesClauseContext;
+import org.apache.shardingsphere.sql.parser.autogen.MySQLStatementParser.ReplaceValuesClauseContext;
import org.apache.shardingsphere.sql.parser.autogen.MySQLStatementParser.JoinSpecificationContext;
import org.apache.shardingsphere.sql.parser.autogen.MySQLStatementParser.JoinedTableContext;
import org.apache.shardingsphere.sql.parser.autogen.MySQLStatementParser.LimitClauseContext;
@@ -156,22 +157,6 @@ public final class MySQLDMLVisitor extends MySQLVisitor implements DMLVisitor {
@SuppressWarnings("unchecked")
@Override
- public ASTNode visitReplace(final ReplaceContext ctx) {
- // TODO :FIXME, since there is no segment for insertValuesClause, InsertStatement is created by sub rule.
- ReplaceStatement result;
- if (null != ctx.insertValuesClause()) {
- result = (ReplaceStatement) visit(ctx.insertValuesClause());
- } else {
- result = new ReplaceStatement();
- result.setSetAssignment((SetAssignmentSegment) visit(ctx.setAssignmentsClause()));
- }
- result.setTable((SimpleTableSegment) visit(ctx.tableName()));
- result.setParameterCount(getCurrentParameterIndex());
- return result;
- }
-
- @SuppressWarnings("unchecked")
- @Override
public ASTNode visitInsertValuesClause(final InsertValuesClauseContext ctx) {
InsertStatement result = new InsertStatement();
if (null != ctx.columnNames()) {
@@ -205,6 +190,45 @@ public final class MySQLDMLVisitor extends MySQLVisitor implements DMLVisitor {
@SuppressWarnings("unchecked")
@Override
+ public ASTNode visitReplace(final ReplaceContext ctx) {
+ // TODO :FIXME, since there is no segment for replaceValuesClause, ReplaceStatement is created by sub rule.
+ ReplaceStatement result;
+ if (null != ctx.replaceValuesClause()) {
+ result = (ReplaceStatement) visit(ctx.replaceValuesClause());
+ } else {
+ result = new ReplaceStatement();
+ result.setSetAssignment((SetAssignmentSegment) visit(ctx.setAssignmentsClause()));
+ }
+ result.setTable((SimpleTableSegment) visit(ctx.tableName()));
+ result.setParameterCount(getCurrentParameterIndex());
+ return result;
+ }
+
+ @SuppressWarnings("unchecked")
+ @Override
+ public ASTNode visitReplaceValuesClause(final ReplaceValuesClauseContext ctx) {
+ ReplaceStatement result = new ReplaceStatement();
+ if (null != ctx.columnNames()) {
+ ColumnNamesContext columnNames = ctx.columnNames();
+ CollectionValue<ColumnSegment> columnSegments = (CollectionValue<ColumnSegment>) visit(columnNames);
+ result.setReplaceColumns(new InsertColumnsSegment(columnNames.start.getStartIndex(), columnNames.stop.getStopIndex(), columnSegments.getValue()));
+ } else {
+ result.setReplaceColumns(new InsertColumnsSegment(ctx.start.getStartIndex() - 1, ctx.start.getStartIndex() - 1, Collections.emptyList()));
+ }
+ result.getValues().addAll(createReplaceValuesSegments(ctx.assignmentValues()));
+ return result;
+ }
+
+ private Collection<InsertValuesSegment> createReplaceValuesSegments(final Collection<AssignmentValuesContext> assignmentValuesContexts) {
+ Collection<InsertValuesSegment> result = new LinkedList<>();
+ for (AssignmentValuesContext each : assignmentValuesContexts) {
+ result.add((InsertValuesSegment) visit(each));
+ }
+ return result;
+ }
+
+ @SuppressWarnings("unchecked")
+ @Override
public ASTNode visitUpdate(final UpdateContext ctx) {
UpdateStatement result = new UpdateStatement();
CollectionValue<TableReferenceSegment> tableReferences = (CollectionValue<TableReferenceSegment>) visit(ctx.tableReferences());
diff --git a/shardingsphere-sql-parser/shardingsphere-sql-parser-statement/src/main/java/org/apache/shardingsphere/sql/parser/sql/segment/dml/column/ReplaceColumnsSegment.java b/shardingsphere-sql-parser/shardingsphere-sql-parser-statement/src/main/java/org/apache/shardingsphere/sql/parser/sql/segment/dml/column/ReplaceColumnsSegment.java
new file mode 100644
index 0000000..9385bfd
--- /dev/null
+++ b/shardingsphere-sql-parser/shardingsphere-sql-parser-statement/src/main/java/org/apache/shardingsphere/sql/parser/sql/segment/dml/column/ReplaceColumnsSegment.java
@@ -0,0 +1,38 @@
+/*
+ * 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.sql.segment.dml.column;
+
+import lombok.Getter;
+import lombok.RequiredArgsConstructor;
+import org.apache.shardingsphere.sql.parser.sql.segment.SQLSegment;
+
+import java.util.Collection;
+
+/**
+ * Replace columns segment.
+ */
+@RequiredArgsConstructor
+@Getter
+public final class ReplaceColumnsSegment implements SQLSegment {
+
+ private final int startIndex;
+
+ private final int stopIndex;
+
+ private final Collection<ColumnSegment> columns;
+}
diff --git a/shardingsphere-sql-parser/shardingsphere-sql-parser-statement/src/main/java/org/apache/shardingsphere/sql/parser/sql/statement/dml/ReplaceStatement.java b/shardingsphere-sql-parser/shardingsphere-sql-parser-statement/src/main/java/org/apache/shardingsphere/sql/parser/sql/statement/dml/ReplaceStatement.java
index 087de1a..477fb63 100644
--- a/shardingsphere-sql-parser/shardingsphere-sql-parser-statement/src/main/java/org/apache/shardingsphere/sql/parser/sql/statement/dml/ReplaceStatement.java
+++ b/shardingsphere-sql-parser/shardingsphere-sql-parser-statement/src/main/java/org/apache/shardingsphere/sql/parser/sql/statement/dml/ReplaceStatement.java
@@ -54,7 +54,7 @@ public final class ReplaceStatement extends DMLStatement {
*
* @return replace columns segment
*/
- public Optional<InsertColumnsSegment> getInsertColumns() {
+ public Optional<InsertColumnsSegment> getReplaceColumns() {
return Optional.ofNullable(replaceColumns);
}
diff --git a/shardingsphere-sql-parser/shardingsphere-sql-parser-test/src/test/java/org/apache/shardingsphere/sql/parser/integrate/asserts/statement/dml/DMLStatementAssert.java b/shardingsphere-sql-parser/shardingsphere-sql-parser-test/src/test/java/org/apache/shardingsphere/sql/parser/integrate/asserts/statement/dml/DMLStatementAssert.java
index 0d30d01..71dbbdf 100644
--- a/shardingsphere-sql-parser/shardingsphere-sql-parser-test/src/test/java/org/apache/shardingsphere/sql/parser/integrate/asserts/statement/dml/DMLStatementAssert.java
+++ b/shardingsphere-sql-parser/shardingsphere-sql-parser-test/src/test/java/org/apache/shardingsphere/sql/parser/integrate/asserts/statement/dml/DMLStatementAssert.java
@@ -22,16 +22,19 @@ import lombok.NoArgsConstructor;
import org.apache.shardingsphere.sql.parser.integrate.asserts.SQLCaseAssertContext;
import org.apache.shardingsphere.sql.parser.integrate.asserts.statement.dml.impl.DeleteStatementAssert;
import org.apache.shardingsphere.sql.parser.integrate.asserts.statement.dml.impl.InsertStatementAssert;
+import org.apache.shardingsphere.sql.parser.integrate.asserts.statement.dml.impl.ReplaceStatementAssert;
import org.apache.shardingsphere.sql.parser.integrate.asserts.statement.dml.impl.SelectStatementAssert;
import org.apache.shardingsphere.sql.parser.integrate.asserts.statement.dml.impl.UpdateStatementAssert;
import org.apache.shardingsphere.sql.parser.integrate.jaxb.cases.domain.statement.SQLParserTestCase;
import org.apache.shardingsphere.sql.parser.integrate.jaxb.cases.domain.statement.dml.DeleteStatementTestCase;
import org.apache.shardingsphere.sql.parser.integrate.jaxb.cases.domain.statement.dml.InsertStatementTestCase;
+import org.apache.shardingsphere.sql.parser.integrate.jaxb.cases.domain.statement.dml.ReplaceStatementTestCase;
import org.apache.shardingsphere.sql.parser.integrate.jaxb.cases.domain.statement.dml.SelectStatementTestCase;
import org.apache.shardingsphere.sql.parser.integrate.jaxb.cases.domain.statement.dml.UpdateStatementTestCase;
import org.apache.shardingsphere.sql.parser.sql.statement.dml.DMLStatement;
import org.apache.shardingsphere.sql.parser.sql.statement.dml.DeleteStatement;
import org.apache.shardingsphere.sql.parser.sql.statement.dml.InsertStatement;
+import org.apache.shardingsphere.sql.parser.sql.statement.dml.ReplaceStatement;
import org.apache.shardingsphere.sql.parser.sql.statement.dml.SelectStatement;
import org.apache.shardingsphere.sql.parser.sql.statement.dml.UpdateStatement;
@@ -57,6 +60,8 @@ public final class DMLStatementAssert {
DeleteStatementAssert.assertIs(assertContext, (DeleteStatement) actual, (DeleteStatementTestCase) expected);
} else if (actual instanceof InsertStatement) {
InsertStatementAssert.assertIs(assertContext, (InsertStatement) actual, (InsertStatementTestCase) expected);
+ } else if (actual instanceof ReplaceStatement) {
+ ReplaceStatementAssert.assertIs(assertContext, (ReplaceStatement) actual, (ReplaceStatementTestCase) expected);
}
}
}
diff --git a/shardingsphere-sql-parser/shardingsphere-sql-parser-test/src/test/java/org/apache/shardingsphere/sql/parser/integrate/asserts/statement/dml/impl/ReplaceStatementAssert.java b/shardingsphere-sql-parser/shardingsphere-sql-parser-test/src/test/java/org/apache/shardingsphere/sql/parser/integrate/asserts/statement/dml/impl/ReplaceStatementAssert.java
new file mode 100644
index 0000000..1f68e2c
--- /dev/null
+++ b/shardingsphere-sql-parser/shardingsphere-sql-parser-test/src/test/java/org/apache/shardingsphere/sql/parser/integrate/asserts/statement/dml/impl/ReplaceStatementAssert.java
@@ -0,0 +1,83 @@
+/*
+ * 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.integrate.asserts.statement.dml.impl;
+
+import lombok.AccessLevel;
+import lombok.NoArgsConstructor;
+import org.apache.shardingsphere.sql.parser.integrate.asserts.SQLCaseAssertContext;
+import org.apache.shardingsphere.sql.parser.integrate.asserts.segment.insert.InsertColumnsClauseAssert;
+import org.apache.shardingsphere.sql.parser.integrate.asserts.segment.insert.InsertValuesClauseAssert;
+import org.apache.shardingsphere.sql.parser.integrate.asserts.segment.set.SetClauseAssert;
+import org.apache.shardingsphere.sql.parser.integrate.asserts.segment.table.TableAssert;
+import org.apache.shardingsphere.sql.parser.integrate.jaxb.cases.domain.statement.dml.ReplaceStatementTestCase;
+import org.apache.shardingsphere.sql.parser.sql.statement.dml.ReplaceStatement;
+
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
+
+/**
+ * Replace statement assert.
+ */
+@NoArgsConstructor(access = AccessLevel.PRIVATE)
+public final class ReplaceStatementAssert {
+
+ /**
+ * Assert insert statement is correct with expected parser result.
+ *
+ * @param assertContext assert context
+ * @param actual actual insert statement
+ * @param expected expected insert statement test case
+ */
+ public static void assertIs(final SQLCaseAssertContext assertContext, final ReplaceStatement actual, final ReplaceStatementTestCase expected) {
+ assertTable(assertContext, actual, expected);
+ assertReplaceColumnsClause(assertContext, actual, expected);
+ assertReplaceValuesClause(assertContext, actual, expected);
+ assertSetClause(assertContext, actual, expected);
+ }
+
+ private static void assertTable(final SQLCaseAssertContext assertContext, final ReplaceStatement actual, final ReplaceStatementTestCase expected) {
+ TableAssert.assertIs(assertContext, actual.getTable(), expected.getTable());
+ }
+
+ private static void assertReplaceColumnsClause(final SQLCaseAssertContext assertContext, final ReplaceStatement actual, final ReplaceStatementTestCase expected) {
+ if (null != expected.getReplaceColumnsClause()) {
+ assertTrue(assertContext.getText("Actual insert columns segment should exist."), actual.getReplaceColumns().isPresent());
+ InsertColumnsClauseAssert.assertIs(assertContext, actual.getReplaceColumns().get(), expected.getReplaceColumnsClause());
+ } else {
+ assertFalse(assertContext.getText("Actual insert columns segment should not exist."), actual.getReplaceColumns().isPresent());
+ }
+ }
+
+ private static void assertReplaceValuesClause(final SQLCaseAssertContext assertContext, final ReplaceStatement actual, final ReplaceStatementTestCase expected) {
+ if (null != expected.getReplaceValuesClause()) {
+ assertFalse(assertContext.getText("Actual insert values segment should exist."), actual.getValues().isEmpty());
+ InsertValuesClauseAssert.assertIs(assertContext, actual.getValues(), expected.getReplaceValuesClause());
+ } else {
+ assertTrue(assertContext.getText("Actual insert values segment should not exist."), actual.getValues().isEmpty());
+ }
+ }
+
+ private static void assertSetClause(final SQLCaseAssertContext assertContext, final ReplaceStatement actual, final ReplaceStatementTestCase expected) {
+ if (null != expected.getSetClause()) {
+ assertTrue(assertContext.getText("Actual set assignment segment should exist."), actual.getSetAssignment().isPresent());
+ SetClauseAssert.assertIs(assertContext, actual.getSetAssignment().get(), expected.getSetClause());
+ } else {
+ assertFalse(assertContext.getText("Actual set assignment segment should not exist."), actual.getSetAssignment().isPresent());
+ }
+ }
+}
diff --git a/shardingsphere-sql-parser/shardingsphere-sql-parser-test/src/test/java/org/apache/shardingsphere/sql/parser/integrate/jaxb/cases/domain/SQLParserTestCases.java b/shardingsphere-sql-parser/shardingsphere-sql-parser-test/src/test/java/org/apache/shardingsphere/sql/parser/integrate/jaxb/cases/domain/SQLParserTestCases.java
index b8bb94b..d795159 100644
--- a/shardingsphere-sql-parser/shardingsphere-sql-parser-test/src/test/java/org/apache/shardingsphere/sql/parser/integrate/jaxb/cases/domain/SQLParserTestCases.java
+++ b/shardingsphere-sql-parser/shardingsphere-sql-parser-test/src/test/java/org/apache/shardingsphere/sql/parser/integrate/jaxb/cases/domain/SQLParserTestCases.java
@@ -56,6 +56,7 @@ import org.apache.shardingsphere.sql.parser.integrate.jaxb.cases.domain.statemen
import org.apache.shardingsphere.sql.parser.integrate.jaxb.cases.domain.statement.ddl.TruncateStatementTestCase;
import org.apache.shardingsphere.sql.parser.integrate.jaxb.cases.domain.statement.dml.DeleteStatementTestCase;
import org.apache.shardingsphere.sql.parser.integrate.jaxb.cases.domain.statement.dml.InsertStatementTestCase;
+import org.apache.shardingsphere.sql.parser.integrate.jaxb.cases.domain.statement.dml.ReplaceStatementTestCase;
import org.apache.shardingsphere.sql.parser.integrate.jaxb.cases.domain.statement.dml.SelectStatementTestCase;
import org.apache.shardingsphere.sql.parser.integrate.jaxb.cases.domain.statement.dml.UpdateStatementTestCase;
import org.apache.shardingsphere.sql.parser.integrate.jaxb.cases.domain.statement.tcl.BeginTransactionStatementTestCase;
@@ -92,7 +93,10 @@ public final class SQLParserTestCases {
@XmlElement(name = "insert")
private final List<InsertStatementTestCase> insertTestCases = new LinkedList<>();
-
+
+ @XmlElement(name = "replace")
+ private final List<ReplaceStatementTestCase> replaceTestCases = new LinkedList<>();
+
@XmlElement(name = "create-table")
private final List<CreateTableStatementTestCase> createTableTestCases = new LinkedList<>();
@@ -224,6 +228,7 @@ public final class SQLParserTestCases {
putAll(updateTestCases, result);
putAll(deleteTestCases, result);
putAll(insertTestCases, result);
+ putAll(replaceTestCases, result);
putAll(createTableTestCases, result);
putAll(alterTableTestCases, result);
putAll(dropTableTestCases, result);
diff --git a/shardingsphere-sql-parser/shardingsphere-sql-parser-test/src/test/java/org/apache/shardingsphere/sql/parser/integrate/jaxb/cases/domain/statement/dml/ReplaceStatementTestCase.java b/shardingsphere-sql-parser/shardingsphere-sql-parser-test/src/test/java/org/apache/shardingsphere/sql/parser/integrate/jaxb/cases/domain/statement/dml/ReplaceStatementTestCase.java
new file mode 100644
index 0000000..e37839e
--- /dev/null
+++ b/shardingsphere-sql-parser/shardingsphere-sql-parser-test/src/test/java/org/apache/shardingsphere/sql/parser/integrate/jaxb/cases/domain/statement/dml/ReplaceStatementTestCase.java
@@ -0,0 +1,48 @@
+/*
+ * 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.integrate.jaxb.cases.domain.statement.dml;
+
+import lombok.Getter;
+import lombok.Setter;
+import org.apache.shardingsphere.sql.parser.integrate.jaxb.cases.domain.segment.impl.insert.ExpectedInsertColumnsClause;
+import org.apache.shardingsphere.sql.parser.integrate.jaxb.cases.domain.segment.impl.insert.ExpectedInsertValuesClause;
+import org.apache.shardingsphere.sql.parser.integrate.jaxb.cases.domain.segment.impl.set.ExpectedSetClause;
+import org.apache.shardingsphere.sql.parser.integrate.jaxb.cases.domain.segment.impl.table.ExpectedSimpleTable;
+import org.apache.shardingsphere.sql.parser.integrate.jaxb.cases.domain.statement.SQLParserTestCase;
+
+import javax.xml.bind.annotation.XmlElement;
+
+/**
+ * Replace statement test case.
+ */
+@Getter
+@Setter
+public final class ReplaceStatementTestCase extends SQLParserTestCase {
+
+ @XmlElement
+ private ExpectedSimpleTable table;
+
+ @XmlElement(name = "columns")
+ private ExpectedInsertColumnsClause replaceColumnsClause;
+
+ @XmlElement(name = "values")
+ private ExpectedInsertValuesClause replaceValuesClause;
+
+ @XmlElement(name = "set")
+ private ExpectedSetClause setClause;
+}
diff --git a/shardingsphere-sql-parser/shardingsphere-sql-parser-test/src/test/resources/case/dml/replace.xml b/shardingsphere-sql-parser/shardingsphere-sql-parser-test/src/test/resources/case/dml/replace.xml
new file mode 100644
index 0000000..0f497c7
--- /dev/null
+++ b/shardingsphere-sql-parser/shardingsphere-sql-parser-test/src/test/resources/case/dml/replace.xml
@@ -0,0 +1,835 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ ~ 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.
+ -->
+
+<sql-parser-test-cases>
+ <replace sql-case-id="replace_with_all_placeholders" parameters="1, 1, 'init'">
+ <table name="t_order" start-index="13" stop-index="19" />
+ <columns start-index="21" stop-index="47">
+ <column name="order_id" start-index="22" stop-index="29" />
+ <column name="user_id" start-index="32" stop-index="38" />
+ <column name="status" start-index="41" stop-index="46" />
+ </columns>
+ <values>
+ <value>
+ <assignment-value>
+ <parameter-marker-expression value="0" start-index="57" stop-index="57" />
+ <literal-expression value="1" start-index="57" stop-index="57" />
+ </assignment-value>
+ <assignment-value>
+ <parameter-marker-expression value="1" start-index="60" stop-index="60" />
+ <literal-expression value="1" start-index="60" stop-index="60" />
+ </assignment-value>
+ <assignment-value>
+ <parameter-marker-expression value="2" start-index="63" stop-index="63" />
+ <literal-expression value="init" start-index="63" stop-index="68" />
+ </assignment-value>
+ </value>
+ </values>
+ </replace>
+
+ <replace sql-case-id="replace_with_now_function" parameters="1, 1, 'init'">
+ <table name="t_order_item" start-index="13" stop-index="24" />
+ <columns start-index="26" stop-index="76">
+ <column name="item_id" start-index="27" stop-index="33" />
+ <column name="order_id" start-index="36" stop-index="43" />
+ <column name="user_id" start-index="46" stop-index="52" />
+ <column name="status" start-index="55" stop-index="60" />
+ <column name="creation_date" start-index="63" stop-index="75" />
+ </columns>
+ <values>
+ <value>
+ <assignment-value>
+ <parameter-marker-expression value="0" start-index="86" stop-index="86" />
+ <literal-expression value="1" start-index="86" stop-index="86" />
+ </assignment-value>
+ <assignment-value>
+ <parameter-marker-expression value="1" start-index="89" stop-index="89" />
+ <literal-expression value="1" start-index="89" stop-index="89" />
+ </assignment-value>
+ <assignment-value>
+ <parameter-marker-expression value="2" start-index="92" stop-index="92" />
+ <literal-expression value="init" start-index="92" stop-index="97" />
+ </assignment-value>
+ <assignment-value>
+ <literal-expression value="replace" start-index="95" stop-index="103" literal-start-index="100" literal-stop-index="108" />
+ </assignment-value>
+ <assignment-value>
+ <common-expression text="now()" start-index="106" stop-index="110" literal-start-index="111" literal-stop-index="115" />
+ </assignment-value>
+ </value>
+ </values>
+ </replace>
+
+ <replace sql-case-id="replace_without_parameters">
+ <table name="t_order" start-index="13" stop-index="19" />
+ <columns start-index="21" stop-index="47">
+ <column name="order_id" start-index="22" stop-index="29" />
+ <column name="user_id" start-index="32" stop-index="38" />
+ <column name="status" start-index="41" stop-index="46" />
+ </columns>
+ <values>
+ <value>
+ <assignment-value>
+ <parameter-marker-expression value="0" />
+ <literal-expression value="1" start-index="57" stop-index="57" />
+ </assignment-value>
+ <assignment-value>
+ <parameter-marker-expression value="1" />
+ <literal-expression value="1" start-index="60" stop-index="60" />
+ </assignment-value>
+ <assignment-value>
+ <parameter-marker-expression value="2" />
+ <literal-expression value="replace" start-index="63" stop-index="71" />
+ </assignment-value>
+ </value>
+ </values>
+ </replace>
+
+ <replace sql-case-id="replace_with_multiple_values">
+ <table name="t_order" start-index="13" stop-index="19" />
+ <columns start-index="21" stop-index="47">
+ <column name="order_id" start-index="22" stop-index="29" />
+ <column name="user_id" start-index="32" stop-index="38" />
+ <column name="status" start-index="41" stop-index="46" />
+ </columns>
+ <values>
+ <value>
+ <assignment-value>
+ <literal-expression value="1" start-index="57" stop-index="57" />
+ </assignment-value>
+ <assignment-value>
+ <literal-expression value="1" start-index="60" stop-index="60" />
+ </assignment-value>
+ <assignment-value>
+ <literal-expression value="replace" start-index="63" stop-index="71" />
+ </assignment-value>
+ </value>
+ <value>
+ <assignment-value>
+ <literal-expression value="2" start-index="76" stop-index="76" />
+ </assignment-value>
+ <assignment-value>
+ <literal-expression value="2" start-index="79" stop-index="79" />
+ </assignment-value>
+ <assignment-value>
+ <literal-expression value="replace2" start-index="82" stop-index="91" />
+ </assignment-value>
+ </value>
+ </values>
+ </replace>
+
+ <replace sql-case-id="replace_with_special_characters">
+ <table name="t_order" start-delimiter="`" end-delimiter="`" start-index="13" stop-index="21" />
+ <columns start-index="23" stop-index="55">
+ <column name="order_id" start-delimiter="`" end-delimiter="`" start-index="24" stop-index="33" />
+ <column name="user_id" start-delimiter="`" end-delimiter="`" start-index="36" stop-index="44" />
+ <column name="status" start-delimiter="`" end-delimiter="`" start-index="47" stop-index="54" />
+ </columns>
+ <values>
+ <value>
+ <assignment-value>
+ <literal-expression value="1" start-index="65" stop-index="65" />
+ </assignment-value>
+ <assignment-value>
+ <literal-expression value="1" start-index="68" stop-index="68" />
+ </assignment-value>
+ <assignment-value>
+ <literal-expression value="replace" start-index="71" stop-index="79" />
+ </assignment-value>
+ </value>
+ </values>
+ </replace>
+
+ <replace sql-case-id="replace_with_all_placeholders_for_table_identifier" parameters="1, 1, 'init'">
+ <table name="t_order" start-index="13" stop-index="19" />
+ <columns start-index="21" stop-index="71">
+ <column name="order_id" start-index="22" stop-index="37">
+ <owner name="t_order" start-index="22" stop-index="28" />
+ </column>
+ <column name="user_id" start-index="40" stop-index="54">
+ <owner name="t_order" start-index="40" stop-index="46" />
+ </column>
+ <column name="status" start-index="57" stop-index="70">
+ <owner name="t_order" start-index="57" stop-index="63" />
+ </column>
+ </columns>
+ <values>
+ <value>
+ <assignment-value>
+ <parameter-marker-expression value="0" start-index="81" stop-index="81" />
+ <literal-expression value="1" start-index="81" stop-index="81" />
+ </assignment-value>
+ <assignment-value>
+ <parameter-marker-expression value="1" start-index="84" stop-index="84" />
+ <literal-expression value="1" start-index="84" stop-index="84" />
+ </assignment-value>
+ <assignment-value>
+ <parameter-marker-expression value="2" start-index="87" stop-index="87" />
+ <literal-expression value="init" start-index="87" stop-index="92" />
+ </assignment-value>
+ </value>
+ </values>
+ </replace>
+
+ <replace sql-case-id="replace_without_columns_with_all_placeholders" parameters="1, 1, 'init'">
+ <table name="t_order" start-index="13" stop-index="19" />
+ <columns start-index="20" stop-index="20" />
+ <values>
+ <value>
+ <assignment-value>
+ <parameter-marker-expression value="0" start-index="29" stop-index="29" />
+ <literal-expression value="1" start-index="29" stop-index="29" />
+ </assignment-value>
+ <assignment-value>
+ <parameter-marker-expression value="1" start-index="32" stop-index="32" />
+ <literal-expression value="1" start-index="32" stop-index="32" />
+ </assignment-value>
+ <assignment-value>
+ <parameter-marker-expression value="2" start-index="35" stop-index="35" />
+ <literal-expression value="init" start-index="35" stop-index="40" />
+ </assignment-value>
+ </value>
+ </values>
+ </replace>
+
+ <replace sql-case-id="replace_set_with_all_placeholders" parameters="1, 1, 'init'">
+ <table name="t_order" start-index="13" stop-index="19" />
+ <set start-index="21" stop-index="61" literal-stop-index="66">
+ <assignment>
+ <column name="order_id" start-index="25" stop-index="32" />
+ <assignment-value>
+ <parameter-marker-expression value="0" start-index="36" stop-index="36" />
+ <literal-expression value="1" literal-start-index="36" literal-stop-index="36"/>
+ </assignment-value>
+ </assignment>
+ <assignment>
+ <column name="user_id" start-index="39" stop-index="45" />
+ <assignment-value>
+ <parameter-marker-expression value="1" start-index="49" stop-index="49" />
+ <literal-expression value="1" literal-start-index="49" literal-stop-index="49" />
+ </assignment-value>
+ </assignment>
+ <assignment>
+ <column name="status" start-index="52" stop-index="57" />
+ <assignment-value>
+ <parameter-marker-expression value="2" start-index="61" stop-index="61" />
+ <literal-expression value="init" literal-start-index="61" literal-stop-index="66" />
+ </assignment-value>
+ </assignment>
+ </set>
+ </replace>
+
+ <replace sql-case-id="replace_with_partial_placeholders" parameters="1, 1">
+ <table name="t_order" start-index="13" stop-index="19" />
+ <columns start-index="21" stop-index="47">
+ <column name="order_id" start-index="22" stop-index="29" />
+ <column name="user_id" start-index="32" stop-index="38" />
+ <column name="status" start-index="41" stop-index="46" />
+ </columns>
+ <values>
+ <value>
+ <assignment-value>
+ <parameter-marker-expression value="0" start-index="57" stop-index="57" />
+ <literal-expression value="1" start-index="57" stop-index="57" />
+ </assignment-value>
+ <assignment-value>
+ <parameter-marker-expression value="1" start-index="60" stop-index="60" />
+ <literal-expression value="1" start-index="60" stop-index="60" />
+ </assignment-value>
+ <assignment-value>
+ <literal-expression value="replace" start-index="63" stop-index="71" />
+ </assignment-value>
+ </value>
+ </values>
+ </replace>
+
+ <replace sql-case-id="replace_set_with_partial_placeholders" parameters="1, 1">
+ <table name="t_order" start-index="13" stop-index="19" />
+ <set start-index="21" stop-index="69">
+ <assignment>
+ <column name="order_id" start-index="25" stop-index="32" />
+ <assignment-value>
+ <parameter-marker-expression value="0" start-index="36" stop-index="36" />
+ <literal-expression value="1" start-index="36" stop-index="36" />
+ </assignment-value>
+ </assignment>
+ <assignment>
+ <column name="user_id" start-index="39" stop-index="45" />
+ <assignment-value>
+ <parameter-marker-expression value="1" start-index="49" stop-index="49" />
+ <literal-expression value="1" start-index="49" stop-index="49" />
+ </assignment-value>
+ </assignment>
+ <assignment>
+ <column name="status" start-index="52" stop-index="57" />
+ <assignment-value>
+ <literal-expression value="replace" start-index="61" stop-index="69" />
+ </assignment-value>
+ </assignment>
+ </set>
+ </replace>
+
+ <replace sql-case-id="replace_with_generate_key_column" parameters="10000, 1000, 10">
+ <table name="t_order_item" start-index="13" stop-index="24" />
+ <columns start-index="25" stop-index="75">
+ <column name="item_id" start-index="26" stop-index="32" />
+ <column name="order_id" start-index="35" stop-index="42" />
+ <column name="user_id" start-index="45" stop-index="51" />
+ <column name="status" start-index="54" stop-index="59" />
+ <column name="creation_date" start-index="62" stop-index="74" />
+ </columns>
+ <values>
+ <value>
+ <assignment-value>
+ <parameter-marker-expression value="0" start-index="85" stop-index="85" />
+ <literal-expression value="10000" start-index="85" stop-index="89" />
+ </assignment-value>
+ <assignment-value>
+ <parameter-marker-expression value="1" start-index="88" stop-index="88" />
+ <literal-expression value="1000" start-index="92" stop-index="95" />
+ </assignment-value>
+ <assignment-value>
+ <parameter-marker-expression value="2" start-index="91" stop-index="91" />
+ <literal-expression value="10" start-index="98" stop-index="99" />
+ </assignment-value>
+ <assignment-value>
+ <literal-expression value="replace" start-index="94" stop-index="102" literal-start-index="102" literal-stop-index="110" />
+ </assignment-value>
+ <assignment-value>
+ <literal-expression value="2017-08-08" start-index="105" stop-index="116" literal-start-index="113" literal-stop-index="124"/>
+ </assignment-value>
+ </value>
+ </values>
+ </replace>
+
+ <replace sql-case-id="replace_without_generate_key_column" parameters="1000, 10">
+ <table name="t_order_item" start-index="13" stop-index="24" />
+ <columns start-index="25" stop-index="66">
+ <column name="order_id" start-index="26" stop-index="33" />
+ <column name="user_id" start-index="36" stop-index="42" />
+ <column name="status" start-index="45" stop-index="50" />
+ <column name="creation_date" start-index="53" stop-index="65" />
+ </columns>
+ <values>
+ <value>
+ <assignment-value>
+ <parameter-marker-expression value="0" start-index="76" stop-index="76" />
+ <literal-expression value="1000" start-index="76" stop-index="79" />
+ </assignment-value>
+ <assignment-value>
+ <parameter-marker-expression value="1" start-index="79" stop-index="79" />
+ <literal-expression value="10" start-index="82" stop-index="83" />
+ </assignment-value>
+ <assignment-value>
+ <literal-expression value="replace" start-index="82" stop-index="90" literal-start-index="86" literal-stop-index="94" />
+ </assignment-value>
+ <assignment-value>
+ <literal-expression value="2017-08-08" start-index="93" stop-index="104" literal-start-index="97" literal-stop-index="108" />
+ </assignment-value>
+ </value>
+ </values>
+ </replace>
+
+ <replace sql-case-id="replace_set_with_generate_key_column" parameters="10000, 1000, 10">
+ <table name="t_order_item" start-index="13" stop-index="24" />
+ <set start-index="26" stop-index="115" literal-stop-index="123">
+ <assignment>
+ <column name="item_id" start-index="30" stop-index="36" />
+ <assignment-value>
+ <parameter-marker-expression value="0" start-index="40" stop-index="40" />
+ <literal-expression value="10000" start-index="40" stop-index="44" />
+ </assignment-value>
+ </assignment>
+ <assignment>
+ <column name="order_id" start-index="43" stop-index="50" literal-start-index="47" literal-stop-index="54" />
+ <assignment-value>
+ <parameter-marker-expression value="1" start-index="54" stop-index="54" />
+ <literal-expression value="1000" start-index="58" stop-index="61" />
+ </assignment-value>
+ </assignment>
+ <assignment>
+ <column name="user_id" start-index="57" stop-index="63" literal-start-index="64" literal-stop-index="70" />
+ <assignment-value>
+ <parameter-marker-expression value="2" start-index="67" stop-index="67" />
+ <literal-expression value="10" start-index="74" stop-index="75" />
+ </assignment-value>
+ </assignment>
+ <assignment>
+ <column name="status" start-index="70" stop-index="75" literal-start-index="78" literal-stop-index="83" />
+ <assignment-value>
+ <literal-expression value="replace" start-index="79" stop-index="87" literal-start-index="87" literal-stop-index="95" />
+ </assignment-value>
+ </assignment>
+ <assignment>
+ <column name="creation_date" start-index="90" stop-index="102" literal-start-index="98" literal-stop-index="110" />
+ <assignment-value>
+ <literal-expression value="2017-08-08" start-index="104" stop-index="115" literal-start-index="112" literal-stop-index="123" />
+ </assignment-value>
+ </assignment>
+ </set>
+ </replace>
+
+ <replace sql-case-id="replace_set_without_generate_key_column" parameters="1000, 10">
+ <table name="t_order_item" start-index="13" stop-index="24" />
+ <set start-index="26" stop-index="102" literal-stop-index="106">
+ <assignment>
+ <column name="order_id" start-index="30" stop-index="37" />
+ <assignment-value>
+ <parameter-marker-expression value="0" start-index="41" stop-index="41" />
+ <literal-expression value="1000" start-index="41" stop-index="44" />
+ </assignment-value>
+ </assignment>
+ <assignment>
+ <column name="user_id" start-index="44" stop-index="50" literal-start-index="47" literal-stop-index="53" />
+ <assignment-value>
+ <parameter-marker-expression value="1" start-index="54" stop-index="54" />
+ <literal-expression value="10" start-index="57" stop-index="58" />
+ </assignment-value>
+ </assignment>
+ <assignment>
+ <column name="status" start-index="57" stop-index="62" literal-start-index="61" literal-stop-index="66" />
+ <assignment-value>
+ <literal-expression value="replace" start-index="66" stop-index="74" literal-start-index="70" literal-stop-index="78" />
+ </assignment-value>
+ </assignment>
+ <assignment>
+ <column name="creation_date" start-index="77" stop-index="89" literal-start-index="81" literal-stop-index="93" />
+ <assignment-value>
+ <literal-expression value="2017-08-08" start-index="91" stop-index="102" literal-start-index="95" literal-stop-index="106"/>
+ </assignment-value>
+ </assignment>
+ </set>
+ </replace>
+
+ <replace sql-case-id="replace_set_with_all_placeholders_for_table_identifier" parameters="1, 1, 'init'">
+ <table name="t_order" start-index="13" stop-index="19" />
+ <set start-index="21" stop-index="85" literal-stop-index="90">
+ <assignment>
+ <column name="order_id" start-index="25" stop-index="40">
+ <owner name="t_order" start-index="25" stop-index="31" />
+ </column>
+ <assignment-value>
+ <parameter-marker-expression value="0" start-index="44" stop-index="44" />
+ <literal-expression value="1" start-index="44" stop-index="44" />
+ </assignment-value>
+ </assignment>
+ <assignment>
+ <column name="user_id" start-index="47" stop-index="61">
+ <owner name="t_order" start-index="47" stop-index="53" />
+ </column>
+ <assignment-value>
+ <parameter-marker-expression value="1" start-index="65" stop-index="65" />
+ <literal-expression value="1" start-index="65" stop-index="65" />
+ </assignment-value>
+ </assignment>
+ <assignment>
+ <column name="status" start-index="68" stop-index="81">
+ <owner name="t_order" start-index="68" stop-index="74" />
+ </column>
+ <assignment-value>
+ <parameter-marker-expression value="2" start-index="85" stop-index="85" />
+ <literal-expression value="init" start-index="85" stop-index="90" />
+ </assignment-value>
+ </assignment>
+ </set>
+ </replace>
+
+ <replace sql-case-id="replace_with_batch" parameters="1000, 10, 'init', 1100, 11, 'init'">
+ <table name="t_order" start-index="13" stop-index="19" />
+ <columns start-index="21" stop-index="47">
+ <column name="order_id" start-index="22" stop-index="29" />
+ <column name="user_id" start-index="32" stop-index="38" />
+ <column name="status" start-index="41" stop-index="46" />
+ </columns>
+ <values>
+ <value>
+ <assignment-value>
+ <parameter-marker-expression value="0" start-index="57" stop-index="57" />
+ <literal-expression value="1000" start-index="57" stop-index="60" />
+ </assignment-value>
+ <assignment-value>
+ <parameter-marker-expression value="1" start-index="60" stop-index="60" />
+ <literal-expression value="10" start-index="63" stop-index="64" />
+ </assignment-value>
+ <assignment-value>
+ <parameter-marker-expression value="2" start-index="63" stop-index="63" />
+ <literal-expression value="init" start-index="67" stop-index="72" />
+ </assignment-value>
+ </value>
+ <value>
+ <assignment-value>
+ <parameter-marker-expression value="3" start-index="68" stop-index="68" />
+ <literal-expression value="1100" start-index="77" stop-index="80" />
+ </assignment-value>
+ <assignment-value>
+ <parameter-marker-expression value="4" start-index="71" stop-index="71" />
+ <literal-expression value="11" start-index="83" stop-index="84" />
+ </assignment-value>
+ <assignment-value>
+ <parameter-marker-expression value="5" start-index="74" stop-index="74" />
+ <literal-expression value="init" start-index="87" stop-index="92" />
+ </assignment-value>
+ </value>
+ </values>
+ </replace>
+
+ <replace sql-case-id="replace_with_batch_and_irregular_parameters" parameters="1, 2, 2, 'init'">
+ <table name="t_order" start-index="13" stop-index="19" />
+ <columns start-index="21" stop-index="47">
+ <column name="order_id" start-index="22" stop-index="29" />
+ <column name="user_id" start-index="32" stop-index="38" />
+ <column name="status" start-index="41" stop-index="46" />
+ </columns>
+ <values>
+ <value>
+ <assignment-value>
+ <parameter-marker-expression value="0" start-index="57" stop-index="57" />
+ <literal-expression value="1" start-index="57" stop-index="57" />
+ </assignment-value>
+ <assignment-value>
+ <literal-expression value="1" start-index="60" stop-index="60" />
+ </assignment-value>
+ <assignment-value>
+ <literal-expression value="replace" start-index="63" stop-index="71" />
+ </assignment-value>
+ </value>
+ <value>
+ <assignment-value>
+ <parameter-marker-expression value="1" start-index="76" stop-index="76" />
+ <literal-expression value="2" start-index="76" stop-index="76" />
+ </assignment-value>
+ <assignment-value>
+ <parameter-marker-expression value="2" start-index="79" stop-index="79" />
+ <literal-expression value="2" start-index="79" stop-index="79" />
+ </assignment-value>
+ <assignment-value>
+ <parameter-marker-expression value="3" start-index="82" stop-index="82" />
+ <literal-expression value="init" start-index="82" stop-index="87" />
+ </assignment-value>
+ </value>
+ </values>
+ </replace>
+
+ <!--<replace sql-case-id="replace_with_batch_and_composite_expression" parameters="1, 1, 'init', 2, 2, 'init'">-->
+ <!--<table name="t_order" start-index="13" stop-index="19" />-->
+ <!--</replace>-->
+
+ <replace sql-case-id="replace_with_batch_and_with_generate_key_column" parameters="10000, 1000, 10, 10010, 1001, 10">
+ <table name="t_order_item" start-index="13" stop-index="24" />
+ <columns start-index="25" stop-index="75">
+ <column name="item_id" start-index="26" stop-index="32" />
+ <column name="order_id" start-index="35" stop-index="42" />
+ <column name="user_id" start-index="45" stop-index="51" />
+ <column name="status" start-index="54" stop-index="59" />
+ <column name="creation_date" start-index="62" stop-index="74" />
+ </columns>
+ <values>
+ <value>
+ <assignment-value>
+ <parameter-marker-expression value="0" start-index="85" stop-index="85" />
+ <literal-expression value="10000" start-index="85" stop-index="89" />
+ </assignment-value>
+ <assignment-value>
+ <parameter-marker-expression value="1" start-index="88" stop-index="88" />
+ <literal-expression value="1000" start-index="92" stop-index="95" />
+ </assignment-value>
+ <assignment-value>
+ <parameter-marker-expression value="2" start-index="91" stop-index="91" />
+ <literal-expression value="10" start-index="98" stop-index="99" />
+ </assignment-value>
+ <assignment-value>
+ <literal-expression value="replace" start-index="94" stop-index="102" literal-start-index="102" literal-stop-index="110" />
+ </assignment-value>
+ <assignment-value>
+ <literal-expression value="2017-08-08" start-index="105" stop-index="116" literal-start-index="113" literal-stop-index="124" />
+ </assignment-value>
+ </value>
+ <value>
+ <assignment-value>
+ <parameter-marker-expression value="3" start-index="121" stop-index="121" />
+ <literal-expression value="10010" start-index="129" stop-index="133" />
+ </assignment-value>
+ <assignment-value>
+ <parameter-marker-expression value="4" start-index="124" stop-index="124" />
+ <literal-expression value="1001" start-index="136" stop-index="139" />
+ </assignment-value>
+ <assignment-value>
+ <parameter-marker-expression value="5" start-index="127" stop-index="127" />
+ <literal-expression value="10" start-index="142" stop-index="143" />
+ </assignment-value>
+ <assignment-value>
+ <literal-expression value="replace" start-index="130" stop-index="138" literal-start-index="146" literal-stop-index="154"/>
+ </assignment-value>
+ <assignment-value>
+ <literal-expression value="2017-08-08" start-index="141" stop-index="152" literal-start-index="157" literal-stop-index="168" />
+ </assignment-value>
+ </value>
+ </values>
+ </replace>
+
+ <replace sql-case-id="replace_with_batch_and_without_generate_key_column" parameters="1000, 10, 1001, 10">
+ <table name="t_order_item" start-index="13" stop-index="24" />
+ <columns start-index="25" stop-index="66">
+ <column name="order_id" start-index="26" stop-index="33" />
+ <column name="user_id" start-index="36" stop-index="42" />
+ <column name="status" start-index="45" stop-index="50" />
+ <column name="creation_date" start-index="53" stop-index="65" />
+ </columns>
+ <values>
+ <value>
+ <assignment-value>
+ <parameter-marker-expression value="0" start-index="76" stop-index="76" />
+ <literal-expression value="1000" start-index="76" stop-index="79" />
+ </assignment-value>
+ <assignment-value>
+ <parameter-marker-expression value="1" start-index="79" stop-index="79" />
+ <literal-expression value="10" start-index="82" stop-index="83" />
+ </assignment-value>
+ <assignment-value>
+ <literal-expression value="replace" start-index="82" stop-index="90" literal-start-index="86" literal-stop-index="94" />
+ </assignment-value>
+ <assignment-value>
+ <literal-expression value="2017-08-08" start-index="93" stop-index="104" literal-start-index="97" literal-stop-index="108" />
+ </assignment-value>
+ </value>
+ <value>
+ <assignment-value>
+ <parameter-marker-expression value="2" start-index="109" stop-index="109" />
+ <literal-expression value="1001" start-index="113" stop-index="116" />
+ </assignment-value>
+ <assignment-value>
+ <parameter-marker-expression value="3" start-index="112" stop-index="112" />
+ <literal-expression value="10" start-index="119" stop-index="120" />
+ </assignment-value>
+ <assignment-value>
+ <literal-expression value="replace" start-index="115" stop-index="123" literal-start-index="123" literal-stop-index="131" />
+ </assignment-value>
+ <assignment-value>
+ <literal-expression value="2017-08-08" start-index="126" stop-index="137" literal-start-index="134" literal-stop-index="145" />
+ </assignment-value>
+ </value>
+ </values>
+ </replace>
+
+ <replace sql-case-id="replace_without_columns_and_with_generate_key_column" parameters="10000, 1000, 10">
+ <table name="t_order_item" start-index="13" stop-index="24" />
+ <columns start-index="25" stop-index="25" />
+ <values>
+ <value>
+ <assignment-value>
+ <parameter-marker-expression value="0" start-index="33" stop-index="33" />
+ <literal-expression value="10000" literal-start-index="33" literal-stop-index="37"/>
+ </assignment-value>
+ <assignment-value>
+ <parameter-marker-expression value="1" start-index="36" stop-index="36" />
+ <literal-expression value="1000" start-index="36" stop-index="41" literal-start-index="40" literal-stop-index="43" />
+ </assignment-value>
+ <assignment-value>
+ <parameter-marker-expression value="2" start-index="39" stop-index="39" />
+ <literal-expression value="10" start-index="39" stop-index="42" literal-start-index="46" literal-stop-index="47" />
+ </assignment-value>
+ <assignment-value>
+ <literal-expression value="replace" start-index="42" stop-index="50" literal-start-index="50" literal-stop-index="58" />
+ </assignment-value>
+ <assignment-value>
+ <literal-expression value="2017-08-08" start-index="53" stop-index="64" literal-start-index="61" literal-stop-index="72" />
+ </assignment-value>
+ </value>
+ </values>
+ </replace>
+
+ <replace sql-case-id="replace_without_columns_and_without_generate_key_column" parameters="1000, 10">
+ <table name="t_order_item" start-index="13" stop-index="24" />
+ <columns start-index="25" stop-index="25" />
+ <values>
+ <value>
+ <assignment-value>
+ <parameter-marker-expression value="0" start-index="33" stop-index="33" />
+ <literal-expression value="1000" start-index="33" stop-index="36" />
+ </assignment-value>
+ <assignment-value>
+ <parameter-marker-expression value="1" start-index="36" stop-index="36" />
+ <literal-expression value="10" start-index="39" stop-index="40" />
+ </assignment-value>
+ <assignment-value>
+ <literal-expression value="replace" start-index="39" stop-index="47" literal-start-index="43" literal-stop-index="51" />
+ </assignment-value>
+ <assignment-value>
+ <literal-expression value="2017-08-08" start-index="50" stop-index="61" literal-start-index="54" literal-stop-index="65" />
+ </assignment-value>
+ </value>
+ </values>
+ </replace>
+
+ <!-- // TODO
+ <replace sql-case-id="assertInsertSelect" sql="REPLACE INTO `order` ('order_id', 'state') (SELECT 1, 'RUNNING' FROM dual UNION ALL SELECT 2, 'RUNNING' FROM dual )"">
+ <table name="order" />
+ <condition-contexts>
+ <condition-context/>
+ </condition-contexts>
+ </replace>
+ -->
+
+ <replace sql-case-id="replace_with_one_auto_increment_column">
+ <table name="t_auto_increment_table" start-index="13" stop-index="34" />
+ <columns start-index="35" stop-index="35" />
+ <values>
+ <value />
+ </values>
+ </replace>
+
+ <replace sql-case-id="replace_with_double_value">
+ <table name="t_double_test" start-index="13" stop-index="25" />
+ <columns start-index="26" stop-index="31">
+ <column name="col1" start-index="27" stop-index="30" />
+ </columns>
+ <values>
+ <value>
+ <assignment-value>
+ <literal-expression value="1.22" start-index="40" stop-index="43" />
+ </assignment-value>
+ </value>
+ </values>
+ </replace>
+
+ <replace sql-case-id="replace_with_null_value">
+ <table name="t_null_value_test" start-index="13" stop-index="29" />
+ <columns start-index="30" stop-index="35">
+ <column name="col1" start-index="31" stop-index="34" />
+ </columns>
+ <values>
+ <value>
+ <assignment-value>
+ <common-expression text="null" />
+ </assignment-value>
+ </value>
+ </values>
+ </replace>
+
+ <replace sql-case-id="replace_with_blob_value">
+ <table name="t_blob_value_test" start-index="13" stop-index="29" />
+ <columns start-index="30" stop-index="35">
+ <column name="col1" start-index="31" stop-index="34" />
+ </columns>
+ <values>
+ <value>
+ <assignment-value>
+ <literal-expression value="_BINARY'This is a binary value.'" />
+ </assignment-value>
+ </value>
+ </values>
+ </replace>
+
+ <replace sql-case-id="replace_with_function" parameters="1000, 10">
+ <table name="t_order" start-index="13" stop-index="19" />
+ <columns start-index="20" stop-index="52">
+ <column name="present_date" start-index="21" stop-index="32" />
+ <column name="order_id" start-index="35" stop-index="42" />
+ <column name="user_id" start-index="45" stop-index="51" />
+ </columns>
+ <values>
+ <value>
+ <assignment-value>
+ <common-expression text="curdate()" start-index="62" stop-index="70" literal-start-index="62" literal-stop-index="70" />
+ </assignment-value>
+ <assignment-value>
+ <parameter-marker-expression value="0" start-index="73" stop-index="73" />
+ <literal-expression value="1000" start-index="73" stop-index="76" />
+ </assignment-value>
+ <assignment-value>
+ <parameter-marker-expression value="1" start-index="76" stop-index="76" />
+ <literal-expression value="10" start-index="79" stop-index="80" />
+ </assignment-value>
+ </value>
+ </values>
+ </replace>
+
+ <replace sql-case-id="replace_with_unix_timestamp_function" parameters="2019-10-19, 1000, 10">
+ <table name="t_order" start-index="13" stop-index="19" />
+ <columns start-index="20" stop-index="46">
+ <column name="status" start-index="21" stop-index="26" />
+ <column name="order_id" start-index="29" stop-index="36" />
+ <column name="user_id" start-index="39" stop-index="45" />
+ </columns>
+ <values>
+ <value>
+ <assignment-value>
+ <common-expression text="unix_timestamp(?)" literal-text="unix_timestamp(2019-10-19)" start-index="56" stop-index="72" literal-start-index="56" literal-stop-index="81" />
+ </assignment-value>
+ <assignment-value>
+ <parameter-marker-expression value="1" start-index="75" stop-index="75" />
+ <literal-expression value="1000" start-index="84" stop-index="87" />
+ </assignment-value>
+ <assignment-value>
+ <parameter-marker-expression value="2" start-index="78" stop-index="78" />
+ <literal-expression value="10" start-index="90" stop-index="91" />
+ </assignment-value>
+ </value>
+ </values>
+ </replace>
+
+ <replace sql-case-id="replace_with_str_to_date" parameters="2019-12-10, 1, 1">
+ <table name="t_order" start-index="13" stop-index="19" />
+ <columns start-index="20" stop-index="52">
+ <column name="present_date" start-index="21" stop-index="32" />
+ <column name="order_id" start-index="35" stop-index="42" />
+ <column name="user_id" start-index="45" stop-index="51" />
+ </columns>
+ <values>
+ <value>
+ <assignment-value>
+ <parameter-marker-expression value="0" start-index="90" stop-index="90" />
+ <common-expression text="str_to_date(?,'%Y-%m-%d')" literal-text="str_to_date(2019-12-10,'%Y-%m-%d')" start-index="62" stop-index="87" literal-start-index="62" literal-stop-index="96" />
+ </assignment-value>
+ <assignment-value>
+ <parameter-marker-expression value="1" start-index="90" stop-index="90" />
+ <literal-expression value="1" start-index="99" stop-index="99" />
+ </assignment-value>
+ <assignment-value>
+ <parameter-marker-expression value="2" start-index="93" stop-index="93" />
+ <literal-expression value="1" start-index="102" stop-index="102" />
+ </assignment-value>
+ </value>
+ </values>
+ </replace>
+
+ <replace sql-case-id="replace_with_str_date_add" parameters="1, 1, 1">
+ <table name="t_order" start-index="13" stop-index="19" />
+ <columns start-index="20" stop-index="52">
+ <column name="present_date" start-index="21" stop-index="32" />
+ <column name="order_id" start-index="35" stop-index="42" />
+ <column name="user_id" start-index="45" stop-index="51" />
+ </columns>
+ <values>
+ <value>
+ <assignment-value>
+ <parameter-marker-expression value="0" start-index="97" stop-index="97" />
+ <common-expression text="date_add(now(),interval?second)" literal-text="date_add(now(),interval1second)" start-index="62" stop-index="94" literal-start-index="62" literal-stop-index="94" />
+ </assignment-value>
+ <assignment-value>
+ <parameter-marker-expression value="1" start-index="97" stop-index="97" />
+ <literal-expression value="1" start-index="97" stop-index="97" />
+ </assignment-value>
+ <assignment-value>
+ <parameter-marker-expression value="2" start-index="100" stop-index="100" />
+ <literal-expression value="1" start-index="100" stop-index="100" />
+ </assignment-value>
+ </value>
+ </values>
+ </replace>
+</sql-parser-test-cases>
diff --git a/shardingsphere-sql-parser/shardingsphere-sql-parser-test/src/test/resources/sql/supported/dml/replace.xml b/shardingsphere-sql-parser/shardingsphere-sql-parser-test/src/test/resources/sql/supported/dml/replace.xml
new file mode 100644
index 0000000..898c0d9
--- /dev/null
+++ b/shardingsphere-sql-parser/shardingsphere-sql-parser-test/src/test/resources/sql/supported/dml/replace.xml
@@ -0,0 +1,49 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ ~ 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.
+ -->
+
+<sql-cases>
+ <sql-case id="replace_with_all_placeholders" value="REPLACE INTO t_order (order_id, user_id, status) VALUES (?, ?, ?)" db-types="MySQL" />
+ <sql-case id="replace_with_now_function" value="REPLACE INTO t_order_item (item_id, order_id, user_id, status, creation_date) VALUES (?, ?, ?, 'replace', now())" db-types="MySQL" />
+ <sql-case id="replace_without_parameters" value="REPLACE INTO t_order (order_id, user_id, status) VALUES (1, 1, 'replace')" db-types="MySQL" />
+ <sql-case id="replace_with_special_characters" value="REPLACE INTO `t_order` (`order_id`, `user_id`, `status`) VALUES (1, 1, 'replace')" db-types="MySQL" />
+ <sql-case id="replace_with_all_placeholders_for_table_identifier" value="REPLACE INTO t_order (t_order.order_id, t_order.user_id, t_order.status) VALUES (?, ?, ?)" db-types="MySQL" />
+ <sql-case id="replace_without_columns_with_all_placeholders" value="REPLACE INTO t_order VALUES (?, ?, ?)" db-types="MySQL" />
+ <sql-case id="replace_set_with_all_placeholders" value="REPLACE INTO t_order SET order_id = ?, user_id = ?, status = ?" db-types="MySQL" />
+ <sql-case id="replace_set_with_all_placeholders_for_table_identifier" value="REPLACE INTO t_order SET t_order.order_id = ?, t_order.user_id = ?, t_order.status = ?" db-types="MySQL" />
+ <sql-case id="replace_with_partial_placeholders" value="REPLACE INTO t_order (order_id, user_id, status) VALUES (?, ?, 'replace')" db-types="MySQL" />
+ <sql-case id="replace_set_with_partial_placeholders" value="REPLACE INTO t_order SET order_id = ?, user_id = ?, status = 'replace'" db-types="MySQL" />
+ <sql-case id="replace_with_generate_key_column" value="REPLACE INTO t_order_item(item_id, order_id, user_id, status, creation_date) values (?, ?, ?, 'replace', '2017-08-08')" db-types="MySQL" />
+ <sql-case id="replace_set_with_generate_key_column" value="REPLACE INTO t_order_item SET item_id = ?, order_id = ?, user_id = ?, status = 'replace', creation_date='2017-08-08'" db-types="MySQL" />
+ <sql-case id="replace_without_generate_key_column" value="REPLACE INTO t_order_item(order_id, user_id, status, creation_date) values (?, ?, 'replace', '2017-08-08')" db-types="MySQL" />
+ <sql-case id="replace_without_columns_and_with_generate_key_column" value="REPLACE INTO t_order_item values(?, ?, ?, 'replace', '2017-08-08')" db-types="MySQL" />
+ <sql-case id="replace_without_columns_and_without_generate_key_column" value="REPLACE INTO t_order_item values(?, ?, 'replace', '2017-08-08')" db-types="MySQL" />
+ <sql-case id="replace_set_without_generate_key_column" value="REPLACE INTO t_order_item SET order_id = ?, user_id = ?, status = 'replace', creation_date='2017-08-08'" db-types="MySQL" />
+ <sql-case id="replace_with_batch" value="REPLACE INTO t_order (order_id, user_id, status) VALUES (?, ?, ?), (?, ?, ?)" db-types="MySQL" />
+ <sql-case id="replace_with_batch_and_irregular_parameters" value="REPLACE INTO t_order (order_id, user_id, status) VALUES (?, 1, 'replace'), (?, ?, ?)" db-types="MySQL" />
+ <sql-case id="replace_with_batch_and_with_generate_key_column" value="REPLACE INTO t_order_item(item_id, order_id, user_id, status, creation_date) values (?, ?, ?, 'replace', '2017-08-08'), (?, ?, ?, 'replace', '2017-08-08')" db-types="MySQL" />
+ <sql-case id="replace_with_batch_and_without_generate_key_column" value="REPLACE INTO t_order_item(order_id, user_id, status, creation_date) values (?, ?, 'replace', '2017-08-08'), (?, ?, 'replace', '2017-08-08')" db-types="MySQL" />
+ <sql-case id="replace_with_multiple_values" value="REPLACE INTO t_order (order_id, user_id, status) VALUES (1, 1, 'replace'), (2, 2, 'replace2')" db-types="MySQL" />
+ <sql-case id="replace_with_one_auto_increment_column" value="REPLACE INTO t_auto_increment_table VALUES()" db-types="MySQL" />
+ <sql-case id="replace_with_double_value" value="REPLACE INTO t_double_test(col1) VALUES(1.22)" db-types="MySQL" />
+ <sql-case id="replace_with_null_value" value="REPLACE INTO t_null_value_test(col1) VALUES(null)" db-types="MySQL" />
+ <sql-case id="replace_with_blob_value" value="REPLACE INTO t_blob_value_test(col1) VALUES(_BINARY'This is a binary value.')" db-types="MySQL" />
+ <sql-case id="replace_with_function" value="REPLACE INTO t_order(present_date, order_id, user_id) VALUES (curdate(), ?, ?)" db-types="MySQL" />
+ <sql-case id="replace_with_unix_timestamp_function" value="REPLACE INTO t_order(status, order_id, user_id) VALUES (unix_timestamp(?), ?, ?)" db-types="MySQL" />
+ <sql-case id="replace_with_str_to_date" value="REPLACE INTO t_order(present_date, order_id, user_id) VALUES (str_to_date(?, '%Y-%m-%d'), ?, ?)" db-types="MySQL" />
+ <sql-case id="replace_with_str_date_add" value="REPLACE INTO t_order(present_date, order_id, user_id) VALUES (date_add(now(),interval ? second), ?, ?)" db-types="MySQL" />
+</sql-cases>