You are viewing a plain text version of this content. The canonical link for it is here.
Posted to notifications@shardingsphere.apache.org by pa...@apache.org on 2020/07/28 03:17:23 UTC

[shardingsphere] branch master updated: support mysql replace select statement parse route and rewrite (#6456)

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

panjuan 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 950e9ed  support mysql replace select statement parse route and rewrite (#6456)
950e9ed is described below

commit 950e9ed18085450e97c361db68f3f321ea53435c
Author: DuanZhengqiang <st...@gmail.com>
AuthorDate: Mon Jul 27 22:17:10 2020 -0500

    support mysql replace select statement parse route and rewrite (#6456)
---
 .../src/test/resources/sharding/insert.xml         | 152 +++++++++++++++++++++
 .../parser/mysql/visitor/impl/MySQLDMLVisitor.java |  16 +++
 .../src/test/resources/case/dml/replace.xml        | 134 ++++++++++++++++++
 .../test/resources/sql/supported/dml/replace.xml   |   4 +
 4 files changed, 306 insertions(+)

diff --git a/shardingsphere-features/shardingsphere-sharding/shardingsphere-sharding-rewrite/src/test/resources/sharding/insert.xml b/shardingsphere-features/shardingsphere-sharding/shardingsphere-sharding-rewrite/src/test/resources/sharding/insert.xml
index e66a3d4..fd1fdcc 100644
--- a/shardingsphere-features/shardingsphere-sharding/shardingsphere-sharding-rewrite/src/test/resources/sharding/insert.xml
+++ b/shardingsphere-features/shardingsphere-sharding/shardingsphere-sharding-rewrite/src/test/resources/sharding/insert.xml
@@ -392,4 +392,156 @@
         <input sql="REPLACE INTO t_account SET amount = 1000, status = 'OK'" />
         <output sql="REPLACE INTO t_account_1 SET amount = 1000, status = 'OK', account_id = 1" />
     </rewrite-assertion>
+
+    <rewrite-assertion id="replace_select_with_all_columns_with_sharding_column_for_parameters" db-type="MySQL">
+        <input sql="REPLACE INTO t_account (account_id, amount, status) SELECT account_id, amount, status FROM t_account WHERE account_id = ?" parameters="100" />
+        <output sql="REPLACE INTO t_account_0 (account_id, amount, status) SELECT account_id, amount, status FROM t_account_0 WHERE account_id = ?" parameters="100" />
+    </rewrite-assertion>
+
+    <rewrite-assertion id="replace_select_with_all_columns_without_sharding_column_for_parameters" db-type="MySQL">
+        <input sql="REPLACE INTO t_account (account_id, amount, status) SELECT account_id, amount, status FROM t_account WHERE amount = ?" parameters="1000" />
+        <output sql="REPLACE INTO t_account_0 (account_id, amount, status) SELECT account_id, amount, status FROM t_account_0 WHERE amount = ?" parameters="1000" />
+        <output sql="REPLACE INTO t_account_1 (account_id, amount, status) SELECT account_id, amount, status FROM t_account_1 WHERE amount = ?" parameters="1000" />
+    </rewrite-assertion>
+
+    <rewrite-assertion id="replace_select_with_all_columns_with_sharding_column_for_literals" db-type="MySQL">
+        <input sql="REPLACE INTO t_account (account_id, amount, status) SELECT account_id, amount, status FROM t_account WHERE account_id = 100" />
+        <output sql="REPLACE INTO t_account_0 (account_id, amount, status) SELECT account_id, amount, status FROM t_account_0 WHERE account_id = 100" />
+    </rewrite-assertion>
+
+    <rewrite-assertion id="replace_select_with_all_columns_without_sharding_column_for_literals" db-type="MySQL">
+        <input sql="REPLACE INTO t_account (account_id, amount, status) SELECT account_id, amount, status FROM t_account WHERE amount = 1000" />
+        <output sql="REPLACE INTO t_account_0 (account_id, amount, status) SELECT account_id, amount, status FROM t_account_0 WHERE amount = 1000" />
+        <output sql="REPLACE INTO t_account_1 (account_id, amount, status) SELECT account_id, amount, status FROM t_account_1 WHERE amount = 1000" />
+    </rewrite-assertion>
+
+    <rewrite-assertion id="replace_select_without_columns_with_sharding_column_for_parameters" db-type="MySQL">
+        <input sql="REPLACE INTO t_account SELECT account_id, amount, status FROM t_account WHERE account_id = ?" parameters="100" />
+        <output sql="REPLACE INTO t_account_0 SELECT account_id, amount, status FROM t_account_0 WHERE account_id = ?" parameters="100" />
+    </rewrite-assertion>
+
+    <rewrite-assertion id="replace_select_without_columns_without_sharding_column_for_parameters" db-type="MySQL">
+        <input sql="REPLACE INTO t_account SELECT account_id, amount, status FROM t_account WHERE amount = ?" parameters="1000" />
+        <output sql="REPLACE INTO t_account_0 SELECT account_id, amount, status FROM t_account_0 WHERE amount = ?" parameters="1000" />
+        <output sql="REPLACE INTO t_account_1 SELECT account_id, amount, status FROM t_account_1 WHERE amount = ?" parameters="1000" />
+    </rewrite-assertion>
+
+    <rewrite-assertion id="replace_select_without_columns_with_sharding_column_for_literals" db-type="MySQL">
+        <input sql="REPLACE INTO t_account SELECT account_id, amount, status FROM t_account WHERE account_id = 100" />
+        <output sql="REPLACE INTO t_account_0 SELECT account_id, amount, status FROM t_account_0 WHERE account_id = 100" />
+    </rewrite-assertion>
+
+    <rewrite-assertion id="replace_select_without_columns_without_sharding_column_for_literals" db-type="MySQL">
+        <input sql="REPLACE INTO t_account SELECT account_id, amount, status FROM t_account WHERE amount = 1000" />
+        <output sql="REPLACE INTO t_account_0 SELECT account_id, amount, status FROM t_account_0 WHERE amount = 1000" />
+        <output sql="REPLACE INTO t_account_1 SELECT account_id, amount, status FROM t_account_1 WHERE amount = 1000" />
+    </rewrite-assertion>
+
+    <rewrite-assertion id="replace_select_with_binding_table_with_all_columns_with_sharding_column_for_parameters" db-type="MySQL">
+        <input sql="REPLACE INTO t_account (account_id, amount, status) SELECT account_id, amount, status FROM t_account_detail WHERE account_id = ?" parameters="100" />
+        <output sql="REPLACE INTO t_account_0 (account_id, amount, status) SELECT account_id, amount, status FROM t_account_detail_0 WHERE account_id = ?" parameters="100" />
+    </rewrite-assertion>
+
+    <rewrite-assertion id="replace_select_with_binding_table_with_all_columns_without_sharding_column_for_parameters" db-type="MySQL">
+        <input sql="REPLACE INTO t_account (account_id, amount, status) SELECT account_id, amount, status FROM t_account_detail WHERE amount = ?" parameters="1000" />
+        <output sql="REPLACE INTO t_account_0 (account_id, amount, status) SELECT account_id, amount, status FROM t_account_detail_0 WHERE amount = ?" parameters="1000" />
+        <output sql="REPLACE INTO t_account_1 (account_id, amount, status) SELECT account_id, amount, status FROM t_account_detail_1 WHERE amount = ?" parameters="1000" />
+    </rewrite-assertion>
+
+    <rewrite-assertion id="replace_select_with_binding_table_with_all_columns_with_sharding_column_for_literals" db-type="MySQL">
+        <input sql="REPLACE INTO t_account (account_id, amount, status) SELECT account_id, amount, status FROM t_account_detail WHERE account_id = 100" />
+        <output sql="REPLACE INTO t_account_0 (account_id, amount, status) SELECT account_id, amount, status FROM t_account_detail_0 WHERE account_id = 100" />
+    </rewrite-assertion>
+
+    <rewrite-assertion id="replace_select_with_binding_table_with_all_columns_without_sharding_column_for_literals" db-type="MySQL">
+        <input sql="REPLACE INTO t_account (account_id, amount, status) SELECT account_id, amount, status FROM t_account_detail WHERE amount = 1000" />
+        <output sql="REPLACE INTO t_account_0 (account_id, amount, status) SELECT account_id, amount, status FROM t_account_detail_0 WHERE amount = 1000" />
+        <output sql="REPLACE INTO t_account_1 (account_id, amount, status) SELECT account_id, amount, status FROM t_account_detail_1 WHERE amount = 1000" />
+    </rewrite-assertion>
+
+    <rewrite-assertion id="replace_select_with_binding_table_without_columns_with_sharding_column_for_parameters" db-type="MySQL">
+        <input sql="REPLACE INTO t_account SELECT account_id, amount, status FROM t_account_detail WHERE account_id = ?" parameters="100" />
+        <output sql="REPLACE INTO t_account_0 SELECT account_id, amount, status FROM t_account_detail_0 WHERE account_id = ?" parameters="100" />
+    </rewrite-assertion>
+
+    <rewrite-assertion id="replace_select_with_binding_table_without_columns_without_sharding_column_for_parameters" db-type="MySQL">
+        <input sql="REPLACE INTO t_account SELECT account_id, amount, status FROM t_account_detail WHERE amount = ?" parameters="1000" />
+        <output sql="REPLACE INTO t_account_0 SELECT account_id, amount, status FROM t_account_detail_0 WHERE amount = ?" parameters="1000" />
+        <output sql="REPLACE INTO t_account_1 SELECT account_id, amount, status FROM t_account_detail_1 WHERE amount = ?" parameters="1000" />
+    </rewrite-assertion>
+
+    <rewrite-assertion id="replace_select_with_binding_table_without_columns_with_sharding_column_for_literals" db-type="MySQL">
+        <input sql="REPLACE INTO t_account SELECT account_id, amount, status FROM t_account_detail WHERE account_id = 100" />
+        <output sql="REPLACE INTO t_account_0 SELECT account_id, amount, status FROM t_account_detail_0 WHERE account_id = 100" />
+    </rewrite-assertion>
+
+    <rewrite-assertion id="replace_select_with_binding_table_without_columns_without_sharding_column_for_literals" db-type="MySQL">
+        <input sql="REPLACE INTO t_account SELECT account_id, amount, status FROM t_account_detail WHERE amount = 1000" />
+        <output sql="REPLACE INTO t_account_0 SELECT account_id, amount, status FROM t_account_detail_0 WHERE amount = 1000" />
+        <output sql="REPLACE INTO t_account_1 SELECT account_id, amount, status FROM t_account_detail_1 WHERE amount = 1000" />
+    </rewrite-assertion>
+
+    <rewrite-assertion id="replace_select_with_subquery_with_all_columns_with_sharding_column_for_parameters" db-type="MySQL">
+        <input sql="REPLACE INTO t_account (account_id, amount, status) SELECT t.account_id, t.amount, t.status FROM (SELECT account_id, amount, status FROM t_account WHERE account_id = ?) t WHERE t.account_id = ?" parameters="100, 100" />
+        <output sql="REPLACE INTO t_account_0 (account_id, amount, status) SELECT t.account_id, t.amount, t.status FROM (SELECT account_id, amount, status FROM t_account_0 WHERE account_id = ?) t WHERE t.account_id = ?" parameters="100, 100" />
+    </rewrite-assertion>
+
+    <rewrite-assertion id="replace_select_with_subquery_with_all_columns_with_sharding_column_for_literals" db-type="MySQL">
+        <input sql="REPLACE INTO t_account (account_id, amount, status) SELECT t.account_id, t.amount, t.status FROM (SELECT account_id, amount, status FROM t_account WHERE account_id = 100) t WHERE t.account_id = 100" />
+        <output sql="REPLACE INTO t_account_0 (account_id, amount, status) SELECT t.account_id, t.amount, t.status FROM (SELECT account_id, amount, status FROM t_account_0 WHERE account_id = 100) t WHERE t.account_id = 100" />
+    </rewrite-assertion>
+
+    <rewrite-assertion id="replace_select_with_subquery_without_columns_with_sharding_column_for_parameters" db-type="MySQL">
+        <input sql="REPLACE INTO t_account SELECT t.account_id, t.amount, t.status FROM (SELECT account_id, amount, status FROM t_account WHERE account_id = ?) t WHERE t.account_id = ?" parameters="100, 100" />
+        <output sql="REPLACE INTO t_account_0 SELECT t.account_id, t.amount, t.status FROM (SELECT account_id, amount, status FROM t_account_0 WHERE account_id = ?) t WHERE t.account_id = ?" parameters="100, 100" />
+    </rewrite-assertion>
+
+    <rewrite-assertion id="replace_select_with_subquery_without_columns_with_sharding_column_for_literals" db-type="MySQL">
+        <input sql="REPLACE INTO t_account SELECT t.account_id, t.amount, t.status FROM (SELECT account_id, amount, status FROM t_account WHERE account_id = 100) t WHERE t.account_id = 100" />
+        <output sql="REPLACE INTO t_account_0 SELECT t.account_id, t.amount, t.status FROM (SELECT account_id, amount, status FROM t_account_0 WHERE account_id = 100) t WHERE t.account_id = 100" />
+    </rewrite-assertion>
+
+    <rewrite-assertion id="replace_select_with_pagination_with_all_columns_with_sharding_column_for_parameters" db-type="MySQL">
+        <input sql="REPLACE INTO t_account (account_id, amount, status) SELECT account_id, amount, status FROM t_account WHERE account_id = ? LIMIT ?, ?" parameters="100, 1, 2" />
+        <output sql="REPLACE INTO t_account_0 (account_id, amount, status) SELECT account_id, amount, status FROM t_account_0 WHERE account_id = ? LIMIT ?, ?" parameters="100, 1, 2" />
+    </rewrite-assertion>
+
+    <rewrite-assertion id="replace_select_with_pagination_with_all_columns_without_sharding_column_for_parameters" db-type="MySQL">
+        <input sql="REPLACE INTO t_account (account_id, amount, status) SELECT account_id, amount, status FROM t_account WHERE amount = ? LIMIT ?, ?" parameters="100, 1, 2" />
+        <output sql="REPLACE INTO t_account_0 (account_id, amount, status) SELECT account_id, amount, status FROM t_account_0 WHERE amount = ? LIMIT ?, ?" parameters="100, 1, 2" />
+        <output sql="REPLACE INTO t_account_1 (account_id, amount, status) SELECT account_id, amount, status FROM t_account_1 WHERE amount = ? LIMIT ?, ?" parameters="100, 1, 2" />
+    </rewrite-assertion>
+
+    <rewrite-assertion id="replace_select_with_pagination_with_all_columns_with_sharding_column_for_literals" db-type="MySQL">
+        <input sql="REPLACE INTO t_account (account_id, amount, status) SELECT account_id, amount, status FROM t_account WHERE account_id = 100 LIMIT 1, 2" />
+        <output sql="REPLACE INTO t_account_0 (account_id, amount, status) SELECT account_id, amount, status FROM t_account_0 WHERE account_id = 100 LIMIT 1, 2" />
+    </rewrite-assertion>
+
+    <rewrite-assertion id="replace_select_with_pagination_with_all_columns_without_sharding_column_for_literals" db-type="MySQL">
+        <input sql="REPLACE INTO t_account (account_id, amount, status) SELECT account_id, amount, status FROM t_account WHERE amount = 100 LIMIT 1, 2" />
+        <output sql="REPLACE INTO t_account_0 (account_id, amount, status) SELECT account_id, amount, status FROM t_account_0 WHERE amount = 100 LIMIT 1, 2" />
+        <output sql="REPLACE INTO t_account_1 (account_id, amount, status) SELECT account_id, amount, status FROM t_account_1 WHERE amount = 100 LIMIT 1, 2" />
+    </rewrite-assertion>
+
+    <rewrite-assertion id="replace_select_with_pagination_without_columns_with_sharding_column_for_parameters" db-type="MySQL">
+        <input sql="REPLACE INTO t_account SELECT account_id, amount, status FROM t_account WHERE account_id = ? LIMIT ?, ?" parameters="100, 1, 2" />
+        <output sql="REPLACE INTO t_account_0 SELECT account_id, amount, status FROM t_account_0 WHERE account_id = ? LIMIT ?, ?" parameters="100, 1, 2" />
+    </rewrite-assertion>
+
+    <rewrite-assertion id="replace_select_with_pagination_without_columns_without_sharding_column_for_parameters" db-type="MySQL">
+        <input sql="REPLACE INTO t_account SELECT account_id, amount, status FROM t_account WHERE amount = ? LIMIT ?, ?" parameters="100, 1, 2" />
+        <output sql="REPLACE INTO t_account_0 SELECT account_id, amount, status FROM t_account_0 WHERE amount = ? LIMIT ?, ?" parameters="100, 1, 2" />
+        <output sql="REPLACE INTO t_account_1 SELECT account_id, amount, status FROM t_account_1 WHERE amount = ? LIMIT ?, ?" parameters="100, 1, 2" />
+    </rewrite-assertion>
+
+    <rewrite-assertion id="replace_select_with_pagination_without_columns_with_sharding_column_for_literals" db-type="MySQL">
+        <input sql="REPLACE INTO t_account SELECT account_id, amount, status FROM t_account WHERE account_id = 100 LIMIT 1, 2" />
+        <output sql="REPLACE INTO t_account_0 SELECT account_id, amount, status FROM t_account_0 WHERE account_id = 100 LIMIT 1, 2" />
+    </rewrite-assertion>
+
+    <rewrite-assertion id="replace_select_with_pagination_without_columns_without_sharding_column_for_literals" db-type="MySQL">
+        <input sql="REPLACE INTO t_account SELECT account_id, amount, status FROM t_account WHERE amount = 100 LIMIT 1, 2" />
+        <output sql="REPLACE INTO t_account_0 SELECT account_id, amount, status FROM t_account_0 WHERE amount = 100 LIMIT 1, 2" />
+        <output sql="REPLACE INTO t_account_1 SELECT account_id, amount, status FROM t_account_1 WHERE amount = 100 LIMIT 1, 2" />
+    </rewrite-assertion>
 </rewrite-assertions>
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 8a3df45..2eaec92 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
@@ -51,6 +51,7 @@ import org.apache.shardingsphere.sql.parser.autogen.MySQLStatementParser.Project
 import org.apache.shardingsphere.sql.parser.autogen.MySQLStatementParser.ProjectionsContext;
 import org.apache.shardingsphere.sql.parser.autogen.MySQLStatementParser.QualifiedShorthandContext;
 import org.apache.shardingsphere.sql.parser.autogen.MySQLStatementParser.ReplaceContext;
+import org.apache.shardingsphere.sql.parser.autogen.MySQLStatementParser.ReplaceSelectClauseContext;
 import org.apache.shardingsphere.sql.parser.autogen.MySQLStatementParser.ReplaceValuesClauseContext;
 import org.apache.shardingsphere.sql.parser.autogen.MySQLStatementParser.SelectClauseContext;
 import org.apache.shardingsphere.sql.parser.autogen.MySQLStatementParser.SelectContext;
@@ -202,6 +203,8 @@ public final class MySQLDMLVisitor extends MySQLVisitor implements DMLVisitor {
         InsertStatement result;
         if (null != ctx.replaceValuesClause()) {
             result = (InsertStatement) visit(ctx.replaceValuesClause());
+        } else if (null != ctx.replaceSelectClause()) {
+            result = (InsertStatement) visit(ctx.replaceSelectClause());
         } else {
             result = new InsertStatement();
             result.setSetAssignment((SetAssignmentSegment) visit(ctx.setAssignmentsClause()));
@@ -212,6 +215,19 @@ public final class MySQLDMLVisitor extends MySQLVisitor implements DMLVisitor {
     }
     
     @Override
+    public ASTNode visitReplaceSelectClause(final ReplaceSelectClauseContext ctx) {
+        InsertStatement result = new InsertStatement();
+        result.setInsertColumns(createInsertColumns(ctx.columnNames(), ctx.start.getStartIndex()));
+        result.setInsertSelect(createReplaceSelectSegment(ctx));
+        return result;
+    }
+    
+    private SubquerySegment createReplaceSelectSegment(final ReplaceSelectClauseContext ctx) {
+        SelectStatement selectStatement = (SelectStatement) visit(ctx.select());
+        return new SubquerySegment(ctx.select().start.getStartIndex(), ctx.select().stop.getStopIndex(), selectStatement);
+    }
+    
+    @Override
     public ASTNode visitReplaceValuesClause(final ReplaceValuesClauseContext ctx) {
         InsertStatement result = new InsertStatement();
         result.setInsertColumns(createInsertColumns(ctx.columnNames(), ctx.start.getStartIndex()));
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
index 5c42559..79743b1 100644
--- 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
@@ -832,4 +832,138 @@
             </value>
         </values>
     </insert>
+
+    <insert sql-case-id="replace_select_with_all_columns" parameters="100">
+        <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>
+        <select>
+            <table-reference>
+                <table-factor>
+                    <table name="t_order" start-index="87" stop-index="93" />
+                </table-factor>
+            </table-reference>
+            <projections start-index="56" stop-index="80">
+                <column-projection name="order_id" start-index="56" stop-index="63" />
+                <column-projection name="user_id" start-index="66" stop-index="72" />
+                <column-projection name="status" start-index="75" stop-index="80" />
+            </projections>
+            <where start-index="95" stop-index="112">
+                <and-predicate>
+                    <predicate start-index="101" stop-index="112" literal-stop-index="114">
+                        <column-left-value name="order_id" start-index="101" stop-index="108" />
+                        <operator type="=" />
+                        <compare-right-value>
+                            <parameter-marker-expression value="0" start-index="112" stop-index="112" />
+                            <literal-expression value="100" start-index="112" stop-index="114" />
+                        </compare-right-value>
+                    </predicate>
+                </and-predicate>
+            </where>
+        </select>
+    </insert>
+
+    <insert sql-case-id="replace_select_without_columns" parameters="100">
+        <table name="t_order" start-index="13" stop-index="19" />
+        <columns start-index="20" stop-index="20" />
+        <select>
+            <table-reference>
+                <table-factor>
+                    <table name="t_order" start-index="59" stop-index="65" />
+                </table-factor>
+            </table-reference>
+            <projections start-index="28" stop-index="52">
+                <column-projection name="order_id" start-index="28" stop-index="35" />
+                <column-projection name="user_id" start-index="38" stop-index="44" />
+                <column-projection name="status" start-index="47" stop-index="52" />
+            </projections>
+            <where start-index="67" stop-index="84">
+                <and-predicate>
+                    <predicate start-index="73" stop-index="84" literal-stop-index="86">
+                        <column-left-value name="order_id" start-index="73" stop-index="80" />
+                        <operator type="=" />
+                        <compare-right-value>
+                            <parameter-marker-expression value="0" start-index="84" stop-index="84" />
+                            <literal-expression value="100" start-index="84" stop-index="86" />
+                        </compare-right-value>
+                    </predicate>
+                </and-predicate>
+            </where>
+        </select>
+    </insert>
+
+    <insert sql-case-id="replace_select_with_generate_key_column" parameters="100">
+        <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>
+        <select>
+            <table-reference>
+                <table-factor>
+                    <table name="t_order_item" start-index="140" stop-index="151" />
+                </table-factor>
+            </table-reference>
+            <projections start-index="84" stop-index="133">
+                <column-projection name="item_id" start-index="84" stop-index="90" />
+                <column-projection name="order_id" start-index="93" stop-index="100" />
+                <column-projection name="user_id" start-index="103" stop-index="109" />
+                <expression-projection start-index="112" stop-index="119" />
+                <expression-projection start-index="122" stop-index="133" />
+            </projections>
+            <where start-index="153" stop-index="169">
+                <and-predicate>
+                    <predicate start-index="159" stop-index="169" literal-stop-index="171">
+                        <column-left-value name="item_id" start-index="159" stop-index="165" />
+                        <operator type="=" />
+                        <compare-right-value>
+                            <parameter-marker-expression value="0" start-index="169" stop-index="169" />
+                            <literal-expression value="100" start-index="169" stop-index="171" />
+                        </compare-right-value>
+                    </predicate>
+                </and-predicate>
+            </where>
+        </select>
+    </insert>
+
+    <insert sql-case-id="replace_select_without_generate_key_column" parameters="100">
+        <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>
+        <select>
+            <table-reference>
+                <table-factor>
+                    <table name="t_order_item" start-index="122" stop-index="133" />
+                </table-factor>
+            </table-reference>
+            <projections start-index="75" stop-index="115">
+                <column-projection name="order_id" start-index="75" stop-index="82" />
+                <column-projection name="user_id" start-index="85" stop-index="91" />
+                <expression-projection start-index="94" stop-index="101" />
+                <expression-projection start-index="104" stop-index="115" />
+            </projections>
+            <where start-index="135" stop-index="152">
+                <and-predicate>
+                    <predicate start-index="141" stop-index="152" literal-stop-index="154">
+                        <column-left-value name="order_id" start-index="141" stop-index="148" />
+                        <operator type="=" />
+                        <compare-right-value>
+                            <parameter-marker-expression value="0" start-index="152" stop-index="152" />
+                            <literal-expression value="100" start-index="152" stop-index="154" />
+                        </compare-right-value>
+                    </predicate>
+                </and-predicate>
+            </where>
+        </select>
+    </insert>
 </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
index 898c0d9..5dc070a 100644
--- 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
@@ -46,4 +46,8 @@
     <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-case id="replace_select_with_all_columns" value="REPLACE INTO t_order (order_id, user_id, status) SELECT order_id, user_id, status FROM t_order WHERE order_id = ?" db-types="MySQL" />
+    <sql-case id="replace_select_without_columns" value="REPLACE INTO t_order SELECT order_id, user_id, status FROM t_order WHERE order_id = ?" db-types="MySQL" />
+    <sql-case id="replace_select_with_generate_key_column" value="REPLACE INTO t_order_item(item_id, order_id, user_id, status, creation_date) SELECT item_id, order_id, user_id, 'insert', '2017-08-08' FROM t_order_item WHERE item_id = ?" db-types="MySQL" />
+    <sql-case id="replace_select_without_generate_key_column" value="REPLACE INTO t_order_item(order_id, user_id, status, creation_date) SELECT order_id, user_id, 'insert', '2017-08-08' FROM t_order_item WHERE order_id = ?" db-types="MySQL" />
 </sql-cases>