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

lujingshang 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 87f9a5c  Fix problem about delete multi table , select into and select 
lock statement. (#8160)
87f9a5c is described below

commit 87f9a5ce9f3878483b110811b5f24b0c67fe0dd9
Author: Albert Li <[email protected]>
AuthorDate: Wed Nov 18 09:45:31 2020 +0800

    Fix problem about delete multi table , select into and select lock 
statement. (#8160)
    
    * Fix parse problem in delete multi table statement and select into 
statement (#7978)
      * Added missing logic for selectWithInto when visit select.
      * Added test cases for select-into statements; case 
'select_into_out_file_with_fields_and_escaped'
        and 'select_into_with_lock_before_into' are supported in MySQL 8.0 but 
not in MySQL 5.7.
      * Table names should split with COMMA_ (',') in multipleTablesClause.
      * Added test cases for delete multi table statements.
    
    * Replace multipleTableNames with tableAliasRefList (#7978)
      * Use name tableAliasRefList like MySQL source code do, and delete unused 
multipleTableNames
    
    * Support of table for select lock statement in MySQL (#7978)
      * Fix definition of lockClause
      * Add test cases for select lock statement
      * Add assertLockClause for SelectStatementTestCase
      * For table rewriting, change definition of LockSegment and add 
extractTablesFromLock in TableExtractor
    
    * Support table assert for DeleteStatementTestCase (#7978)
    
    * Add missing test case for Oracle and PostgreSQL. And fix problem when 
parsing select for update statement in Oracle. (#7978)
    
    * Format code, remove extra black lines. (#7978)
    
    * Format code, add new line at end of file.
    
    * Rename ofTables to tables in LockSegment, and initialize it directly in 
the class.
---
 .../src/main/antlr4/imports/mysql/DMLStatement.g4  |   9 +-
 .../statement/impl/MySQLStatementSQLVisitor.java   |  29 ++-
 .../impl/OracleDMLStatementSQLVisitor.java         |   6 +
 .../sql/common/extractor/TableExtractor.java       |   9 +
 .../common/segment/dml/predicate/LockSegment.java  |   6 +
 .../sql/common/extractor/TableExtractorTest.java   |  77 +++++++
 .../asserts/segment/lock/LockClauseAssert.java     |  56 +++++
 .../asserts/segment/table/TableAssert.java         |  21 +-
 .../statement/dml/impl/DeleteStatementAssert.java  |  21 +-
 .../statement/dml/impl/SelectStatementAssert.java  |  13 ++
 .../segment/impl/lock/ExpectedLockClause.java}     |  23 +-
 .../statement/dml/SelectStatementTestCase.java     |   8 +-
 .../src/main/resources/case/dml/delete.xml         |  60 +++++-
 .../src/main/resources/case/dml/select-into.xml    | 188 +++++++++++++++++
 .../src/main/resources/case/dml/select-lock.xml    | 232 +++++++++++++++++++++
 .../src/main/resources/case/dml/select.xml         |  21 --
 .../main/resources/sql/supported/dml/delete.xml    |   4 +-
 .../resources/sql/supported/dml/select-into.xml    |  30 +++
 .../resources/sql/supported/dml/select-lock.xml    |  27 +++
 .../main/resources/sql/supported/dml/select.xml    |   1 -
 .../main/resources/sql/unsupported/unsupported.xml |   3 +-
 21 files changed, 782 insertions(+), 62 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 c42e117..28513e9 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
@@ -108,10 +108,6 @@ multipleTablesClause
     : tableAliasRefList FROM tableReferences | FROM tableAliasRefList USING 
tableReferences
     ;
 
-multipleTableNames
-    : tableName DOT_ASTERISK_? (COMMA_ tableName DOT_ASTERISK_?)*
-    ;
-
 select
     : queryExpression lockClauseList?
     | queryExpressionParens
@@ -363,8 +359,7 @@ selectIntoExpression
     ;
 
 lockClause
-    : FOR lockStrength lockedRowAction?
-    | FOR lockStrength
+    : FOR lockStrength tableLockingList? lockedRowAction?
     | LOCK IN SHARE MODE
     ;
 
@@ -389,5 +384,5 @@ tableIdentOptWild
     ;
 
 tableAliasRefList
-    : tableIdentOptWild+
+    : tableIdentOptWild (COMMA_ tableIdentOptWild)*
     ;
diff --git 
a/shardingsphere-sql-parser/shardingsphere-sql-parser-dialect/shardingsphere-sql-parser-mysql/src/main/java/org/apache/shardingsphere/sql/parser/mysql/visitor/statement/impl/MySQLStatementSQLVisitor.java
 
b/shardingsphere-sql-parser/shardingsphere-sql-parser-dialect/shardingsphere-sql-parser-mysql/src/main/java/org/apache/shardingsphere/sql/parser/mysql/visitor/statement/impl/MySQLStatementSQLVisitor.java
index 8faddd9..84c0cc3 100644
--- 
a/shardingsphere-sql-parser/shardingsphere-sql-parser-dialect/shardingsphere-sql-parser-mysql/src/main/java/org/apache/shardingsphere/sql/parser/mysql/visitor/statement/impl/MySQLStatementSQLVisitor.java
+++ 
b/shardingsphere-sql-parser/shardingsphere-sql-parser-dialect/shardingsphere-sql-parser-mysql/src/main/java/org/apache/shardingsphere/sql/parser/mysql/visitor/statement/impl/MySQLStatementSQLVisitor.java
@@ -63,7 +63,6 @@ import 
org.apache.shardingsphere.sql.parser.autogen.MySQLStatementParser.SetAssi
 import 
org.apache.shardingsphere.sql.parser.autogen.MySQLStatementParser.SingleTableClauseContext;
 import 
org.apache.shardingsphere.sql.parser.autogen.MySQLStatementParser.StringLiteralsContext;
 import 
org.apache.shardingsphere.sql.parser.autogen.MySQLStatementParser.NumberLiteralsContext;
-import 
org.apache.shardingsphere.sql.parser.autogen.MySQLStatementParser.TableAliasRefListContext;
 import 
org.apache.shardingsphere.sql.parser.autogen.MySQLStatementParser.TableFactorContext;
 import 
org.apache.shardingsphere.sql.parser.autogen.MySQLStatementParser.TableReferenceContext;
 import 
org.apache.shardingsphere.sql.parser.autogen.MySQLStatementParser.TableReferencesContext;
@@ -90,6 +89,8 @@ import 
org.apache.shardingsphere.sql.parser.autogen.MySQLStatementParser.ExprCon
 import 
org.apache.shardingsphere.sql.parser.autogen.MySQLStatementParser.BooleanPrimaryContext;
 import 
org.apache.shardingsphere.sql.parser.autogen.MySQLStatementParser.PredicateContext;
 import 
org.apache.shardingsphere.sql.parser.autogen.MySQLStatementParser.SimpleExprContext;
+import 
org.apache.shardingsphere.sql.parser.autogen.MySQLStatementParser.SelectWithIntoContext;
+import 
org.apache.shardingsphere.sql.parser.autogen.MySQLStatementParser.TableAliasRefListContext;
 import 
org.apache.shardingsphere.sql.parser.autogen.MySQLStatementParser.BitExprContext;
 import 
org.apache.shardingsphere.sql.parser.autogen.MySQLStatementParser.SubqueryContext;
 import org.apache.shardingsphere.sql.parser.autogen.MySQLStatementParser;
@@ -544,7 +545,13 @@ public abstract class MySQLStatementSQLVisitor extends 
MySQLStatementBaseVisitor
 
     @Override
     public ASTNode visitLockClauseList(final LockClauseListContext ctx) {
-        return new LockSegment(ctx.getStart().getStartIndex(), 
ctx.getStop().getStopIndex());
+        LockSegment result = new LockSegment(ctx.getStart().getStartIndex(), 
ctx.getStop().getStopIndex());
+        for (MySQLStatementParser.LockClauseContext each : ctx.lockClause()) {
+            if (null != each.tableLockingList()) {
+                
result.getTables().addAll(generateTablesFromTableAliasRefList(each.tableLockingList().tableAliasRefList()));
+            }
+        }
+        return result;
     }
 
     @Override
@@ -565,6 +572,18 @@ public abstract class MySQLStatementSQLVisitor extends 
MySQLStatementBaseVisitor
     }
 
     @Override
+    public ASTNode visitSelectWithInto(final SelectWithIntoContext ctx) {
+        if (null != ctx.selectWithInto()) {
+            return visit(ctx.selectWithInto());
+        }
+        MySQLSelectStatement result = (MySQLSelectStatement) 
visit(ctx.queryExpression());
+        if (null != ctx.lockClauseList()) {
+            result.setLock((LockSegment) visit(ctx.lockClauseList()));
+        }
+        return result;
+    }
+
+    @Override
     public ASTNode visitQueryExpressionBody(final QueryExpressionBodyContext 
ctx) {
         if (1 == ctx.getChildCount() && ctx.getChild(0) instanceof 
QueryPrimaryContext) {
             return visit(ctx.queryPrimary());
@@ -1049,11 +1068,11 @@ public abstract class MySQLStatementSQLVisitor extends 
MySQLStatementBaseVisitor
         DeleteMultiTableSegment result = new DeleteMultiTableSegment();
         TableSegment relateTableSource = (TableSegment) 
visit(ctx.tableReferences());
         result.setRelationTable(relateTableSource);
-        
result.setActualDeleteTables(generateTablesFromTableMultipleTableNames(ctx.tableAliasRefList()));
+        
result.setActualDeleteTables(generateTablesFromTableAliasRefList(ctx.tableAliasRefList()));
         return result;
     }
     
-    private List<SimpleTableSegment> 
generateTablesFromTableMultipleTableNames(final TableAliasRefListContext ctx) {
+    private List<SimpleTableSegment> generateTablesFromTableAliasRefList(final 
TableAliasRefListContext ctx) {
         List<SimpleTableSegment> result = new LinkedList<>();
         for (MySQLStatementParser.TableIdentOptWildContext each : 
ctx.tableIdentOptWild()) {
             result.add((SimpleTableSegment) visit(each.tableName()));
@@ -1070,6 +1089,8 @@ public abstract class MySQLStatementSQLVisitor extends 
MySQLStatementBaseVisitor
             if (null != ctx.lockClauseList()) {
                 result.setLock((LockSegment) visit(ctx.lockClauseList()));
             }
+        } else if (null != ctx.selectWithInto()) {
+            result = (MySQLSelectStatement) visit(ctx.selectWithInto());
         } else {
             result = (MySQLSelectStatement) visit(ctx.getChild(0));
         }
diff --git 
a/shardingsphere-sql-parser/shardingsphere-sql-parser-dialect/shardingsphere-sql-parser-oracle/src/main/java/org/apache/shardingsphere/sql/parser/oracle/visitor/statement/impl/OracleDMLStatementSQLVisitor.java
 
b/shardingsphere-sql-parser/shardingsphere-sql-parser-dialect/shardingsphere-sql-parser-oracle/src/main/java/org/apache/shardingsphere/sql/parser/oracle/visitor/statement/impl/OracleDMLStatementSQLVisitor.java
index 980711c..35ceabb 100644
--- 
a/shardingsphere-sql-parser/shardingsphere-sql-parser-dialect/shardingsphere-sql-parser-oracle/src/main/java/org/apache/shardingsphere/sql/parser/oracle/visitor/statement/impl/OracleDMLStatementSQLVisitor.java
+++ 
b/shardingsphere-sql-parser/shardingsphere-sql-parser-dialect/shardingsphere-sql-parser-oracle/src/main/java/org/apache/shardingsphere/sql/parser/oracle/visitor/statement/impl/OracleDMLStatementSQLVisitor.java
@@ -53,6 +53,7 @@ import 
org.apache.shardingsphere.sql.parser.autogen.OracleStatementParser.TableR
 import 
org.apache.shardingsphere.sql.parser.autogen.OracleStatementParser.UnionClauseContext;
 import 
org.apache.shardingsphere.sql.parser.autogen.OracleStatementParser.UpdateContext;
 import 
org.apache.shardingsphere.sql.parser.autogen.OracleStatementParser.WhereClauseContext;
+import 
org.apache.shardingsphere.sql.parser.autogen.OracleStatementParser.LockClauseContext;
 import 
org.apache.shardingsphere.sql.parser.sql.common.segment.dml.assignment.AssignmentSegment;
 import 
org.apache.shardingsphere.sql.parser.sql.common.segment.dml.assignment.InsertValuesSegment;
 import 
org.apache.shardingsphere.sql.parser.sql.common.segment.dml.assignment.SetAssignmentSegment;
@@ -463,4 +464,9 @@ public final class OracleDMLStatementSQLVisitor extends 
OracleStatementSQLVisito
     public ASTNode visitSubquery(final SubqueryContext ctx) {
         return visit(ctx.unionClause());
     }
+
+    @Override
+    public ASTNode visitLockClause(final LockClauseContext ctx) {
+        return new LockSegment(ctx.getStart().getStartIndex(), 
ctx.getStop().getStopIndex());
+    }
 }
diff --git 
a/shardingsphere-sql-parser/shardingsphere-sql-parser-statement/src/main/java/org/apache/shardingsphere/sql/parser/sql/common/extractor/TableExtractor.java
 
b/shardingsphere-sql-parser/shardingsphere-sql-parser-statement/src/main/java/org/apache/shardingsphere/sql/parser/sql/common/extractor/TableExtractor.java
index 15c3b70..edac300 100644
--- 
a/shardingsphere-sql-parser/shardingsphere-sql-parser-statement/src/main/java/org/apache/shardingsphere/sql/parser/sql/common/extractor/TableExtractor.java
+++ 
b/shardingsphere-sql-parser/shardingsphere-sql-parser-statement/src/main/java/org/apache/shardingsphere/sql/parser/sql/common/extractor/TableExtractor.java
@@ -34,6 +34,7 @@ import 
org.apache.shardingsphere.sql.parser.sql.common.segment.dml.item.Projecti
 import 
org.apache.shardingsphere.sql.parser.sql.common.segment.dml.item.SubqueryProjectionSegment;
 import 
org.apache.shardingsphere.sql.parser.sql.common.segment.dml.order.item.ColumnOrderByItemSegment;
 import 
org.apache.shardingsphere.sql.parser.sql.common.segment.dml.order.item.OrderByItemSegment;
+import 
org.apache.shardingsphere.sql.parser.sql.common.segment.dml.predicate.LockSegment;
 import 
org.apache.shardingsphere.sql.parser.sql.common.segment.generic.OwnerAvailable;
 import 
org.apache.shardingsphere.sql.parser.sql.common.segment.generic.OwnerSegment;
 import 
org.apache.shardingsphere.sql.parser.sql.common.segment.generic.table.DeleteMultiTableSegment;
@@ -47,6 +48,7 @@ import 
org.apache.shardingsphere.sql.parser.sql.common.statement.dml.InsertState
 import 
org.apache.shardingsphere.sql.parser.sql.common.statement.dml.SelectStatement;
 import 
org.apache.shardingsphere.sql.parser.sql.common.statement.dml.UpdateStatement;
 import 
org.apache.shardingsphere.sql.parser.sql.dialect.handler.ddl.CreateTableStatementHandler;
+import 
org.apache.shardingsphere.sql.parser.sql.dialect.handler.dml.SelectStatementHandler;
 
 import java.util.Collection;
 import java.util.LinkedList;
@@ -81,6 +83,9 @@ public final class TableExtractor {
         if (selectStatement.getOrderBy().isPresent()) {
             
extractTablesFromOrderByItems(selectStatement.getOrderBy().get().getOrderByItems());
         }
+        if 
(SelectStatementHandler.getLockSegment(selectStatement).isPresent()) {
+            
extractTablesFromLock(SelectStatementHandler.getLockSegment(selectStatement).get());
+        }
     }
     
     private void extractTablesFromTableSegment(final TableSegment 
tableSegment) {
@@ -174,6 +179,10 @@ public final class TableExtractor {
             }
         }
     }
+
+    private void extractTablesFromLock(final LockSegment lockSegment) {
+        rewriteTables.addAll(lockSegment.getTables());
+    }
     
     /**
      * Extract table that should be rewrited from DeleteStatement.
diff --git 
a/shardingsphere-sql-parser/shardingsphere-sql-parser-statement/src/main/java/org/apache/shardingsphere/sql/parser/sql/common/segment/dml/predicate/LockSegment.java
 
b/shardingsphere-sql-parser/shardingsphere-sql-parser-statement/src/main/java/org/apache/shardingsphere/sql/parser/sql/common/segment/dml/predicate/LockSegment.java
index 73f208b..92ad7ba 100644
--- 
a/shardingsphere-sql-parser/shardingsphere-sql-parser-statement/src/main/java/org/apache/shardingsphere/sql/parser/sql/common/segment/dml/predicate/LockSegment.java
+++ 
b/shardingsphere-sql-parser/shardingsphere-sql-parser-statement/src/main/java/org/apache/shardingsphere/sql/parser/sql/common/segment/dml/predicate/LockSegment.java
@@ -20,6 +20,10 @@ package 
org.apache.shardingsphere.sql.parser.sql.common.segment.dml.predicate;
 import lombok.Getter;
 import lombok.RequiredArgsConstructor;
 import org.apache.shardingsphere.sql.parser.sql.common.segment.SQLSegment;
+import 
org.apache.shardingsphere.sql.parser.sql.common.segment.generic.table.SimpleTableSegment;
+
+import java.util.LinkedList;
+import java.util.List;
 
 /**
  * Lock segment.
@@ -32,4 +36,6 @@ public final class LockSegment implements SQLSegment {
     private final int startIndex;
 
     private final int stopIndex;
+
+    private List<SimpleTableSegment> tables = new LinkedList<>();
 }
diff --git 
a/shardingsphere-sql-parser/shardingsphere-sql-parser-statement/src/test/java/org/apache/shardingsphere/sql/parser/sql/common/extractor/TableExtractorTest.java
 
b/shardingsphere-sql-parser/shardingsphere-sql-parser-statement/src/test/java/org/apache/shardingsphere/sql/parser/sql/common/extractor/TableExtractorTest.java
new file mode 100644
index 0000000..008c3d5
--- /dev/null
+++ 
b/shardingsphere-sql-parser/shardingsphere-sql-parser-statement/src/test/java/org/apache/shardingsphere/sql/parser/sql/common/extractor/TableExtractorTest.java
@@ -0,0 +1,77 @@
+/*
+ * 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.common.extractor;
+
+import 
org.apache.shardingsphere.sql.parser.sql.common.segment.dml.predicate.LockSegment;
+import 
org.apache.shardingsphere.sql.parser.sql.common.segment.generic.table.SimpleTableSegment;
+import 
org.apache.shardingsphere.sql.parser.sql.common.segment.generic.table.TableNameSegment;
+import 
org.apache.shardingsphere.sql.parser.sql.common.value.identifier.IdentifierValue;
+import 
org.apache.shardingsphere.sql.parser.sql.dialect.statement.mysql.dml.MySQLSelectStatement;
+import org.junit.Before;
+import org.junit.Test;
+
+import java.util.Iterator;
+import java.util.Optional;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.assertNotNull;
+
+public class TableExtractorTest {
+
+    private TableExtractor tableExtractor;
+
+    @Before
+    public void init() {
+        tableExtractor = new TableExtractor();
+    }
+
+    @Test
+    public void assertExtractTablesFromSelectLockWithEmptyValue() {
+        MySQLSelectStatement selectStatement = new MySQLSelectStatement();
+        tableExtractor.extractTablesFromSelect(selectStatement);
+        assertTrue(tableExtractor.getRewriteTables().isEmpty());
+    }
+
+    @Test
+    public void assertExtractTablesFromSelectLockWithValue() {
+        MySQLSelectStatement selectStatement = new MySQLSelectStatement();
+        LockSegment lockSegment = new LockSegment(108, 154);
+        selectStatement.setLock(lockSegment);
+        lockSegment.getTables().add(new SimpleTableSegment(122, 128, new 
IdentifierValue("t_order")));
+        lockSegment.getTables().add(new SimpleTableSegment(143, 154, new 
IdentifierValue("t_order_item")));
+        tableExtractor.extractTablesFromSelect(selectStatement);
+        assertNotNull(tableExtractor.getRewriteTables());
+        assertEquals(2, tableExtractor.getRewriteTables().size());
+        Iterator<SimpleTableSegment> tableSegmentIterator = 
tableExtractor.getRewriteTables().iterator();
+        assertTableSegment(tableSegmentIterator.next(), 122, 128, "t_order");
+        assertTableSegment(tableSegmentIterator.next(), 143, 154, 
"t_order_item");
+    }
+
+    private void assertTableSegment(final SimpleTableSegment actual,
+                                    final int expectedStartIndex, final int 
expectedStopIndex, final String expectedTableName) {
+        assertEquals(expectedStartIndex, actual.getStartIndex());
+        assertEquals(expectedStopIndex, actual.getStopIndex());
+        Optional<String> actualTableName = 
Optional.ofNullable(actual.getTableName())
+                                                    
.map(TableNameSegment::getIdentifier)
+                                                    
.map(IdentifierValue::getValue);
+        assertTrue(actualTableName.isPresent());
+        assertEquals(expectedTableName, actualTableName.get());
+    }
+
+}
diff --git 
a/shardingsphere-sql-parser/shardingsphere-sql-parser-test/src/main/java/org/apache/shardingsphere/test/sql/parser/parameterized/asserts/segment/lock/LockClauseAssert.java
 
b/shardingsphere-sql-parser/shardingsphere-sql-parser-test/src/main/java/org/apache/shardingsphere/test/sql/parser/parameterized/asserts/segment/lock/LockClauseAssert.java
new file mode 100644
index 0000000..de9d0c6
--- /dev/null
+++ 
b/shardingsphere-sql-parser/shardingsphere-sql-parser-test/src/main/java/org/apache/shardingsphere/test/sql/parser/parameterized/asserts/segment/lock/LockClauseAssert.java
@@ -0,0 +1,56 @@
+/*
+ * 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.test.sql.parser.parameterized.asserts.segment.lock;
+
+import lombok.AccessLevel;
+import lombok.NoArgsConstructor;
+import 
org.apache.shardingsphere.sql.parser.sql.common.segment.dml.predicate.LockSegment;
+import 
org.apache.shardingsphere.sql.parser.sql.common.segment.generic.table.SimpleTableSegment;
+import 
org.apache.shardingsphere.test.sql.parser.parameterized.asserts.SQLCaseAssertContext;
+import 
org.apache.shardingsphere.test.sql.parser.parameterized.asserts.segment.SQLSegmentAssert;
+import 
org.apache.shardingsphere.test.sql.parser.parameterized.asserts.segment.table.TableAssert;
+import 
org.apache.shardingsphere.test.sql.parser.parameterized.jaxb.cases.domain.segment.impl.lock.ExpectedLockClause;
+import 
org.apache.shardingsphere.test.sql.parser.parameterized.jaxb.cases.domain.segment.impl.table.ExpectedSimpleTable;
+
+import java.util.List;
+
+import static org.junit.Assert.assertTrue;
+
+/**
+ * Lock clause assert.
+ */
+@NoArgsConstructor(access = AccessLevel.PRIVATE)
+public final class LockClauseAssert {
+
+    /**
+     * Assert lock segment index and forTables.
+     * @param assertContext assert context
+     * @param actual actual lock
+     * @param expected expected lock
+     */
+    public static void assertIs(final SQLCaseAssertContext assertContext, 
final LockSegment actual, final ExpectedLockClause expected) {
+        SQLSegmentAssert.assertIs(assertContext, actual, expected);
+        List<SimpleTableSegment> actualTables = actual.getTables();
+        List<ExpectedSimpleTable> expectedTables = expected.getTables();
+        if (actualTables.isEmpty()) {
+            assertTrue(assertContext.getText("lock tables should not exist."), 
expectedTables.isEmpty());
+            return;
+        }
+        TableAssert.assertIs(assertContext, actualTables, expectedTables);
+    }
+}
diff --git 
a/shardingsphere-sql-parser/shardingsphere-sql-parser-test/src/main/java/org/apache/shardingsphere/test/sql/parser/parameterized/asserts/segment/table/TableAssert.java
 
b/shardingsphere-sql-parser/shardingsphere-sql-parser-test/src/main/java/org/apache/shardingsphere/test/sql/parser/parameterized/asserts/segment/table/TableAssert.java
index 08ba69e..2f955ac 100644
--- 
a/shardingsphere-sql-parser/shardingsphere-sql-parser-test/src/main/java/org/apache/shardingsphere/test/sql/parser/parameterized/asserts/segment/table/TableAssert.java
+++ 
b/shardingsphere-sql-parser/shardingsphere-sql-parser-test/src/main/java/org/apache/shardingsphere/test/sql/parser/parameterized/asserts/segment/table/TableAssert.java
@@ -21,7 +21,6 @@ import lombok.AccessLevel;
 import lombok.NoArgsConstructor;
 import 
org.apache.shardingsphere.sql.parser.sql.common.segment.generic.OwnerSegment;
 import 
org.apache.shardingsphere.sql.parser.sql.common.segment.generic.SchemaSegment;
-import 
org.apache.shardingsphere.sql.parser.sql.common.segment.generic.table.DeleteMultiTableSegment;
 import 
org.apache.shardingsphere.sql.parser.sql.common.segment.generic.table.JoinTableSegment;
 import 
org.apache.shardingsphere.sql.parser.sql.common.segment.generic.table.SimpleTableSegment;
 import 
org.apache.shardingsphere.sql.parser.sql.common.segment.generic.table.SubqueryTableSegment;
@@ -64,10 +63,9 @@ public final class TableAssert {
             assertIs(assertContext, (SimpleTableSegment) actual, 
expected.getSimpleTable());
         } else if (actual instanceof SubqueryTableSegment) {
             assertIs(assertContext, (SubqueryTableSegment) actual, 
expected.getSubqueryTable());
-        } else if (actual instanceof DeleteMultiTableSegment) {
-            return;
         } else {
-            return;
+            throw new UnsupportedOperationException(
+                    String.format("Unsupported table segment type `%s`.", 
actual.getClass()));
         }
     }
 
@@ -135,6 +133,21 @@ public final class TableAssert {
     }
 
     /**
+     * Assert actual simple table segments with expected simple tables.
+     *
+     * @param assertContext assert context
+     * @param actualTables actual simple tables
+     * @param expectedTables expected simple tables
+     */
+    public static void assertIs(final SQLCaseAssertContext assertContext, 
final List<SimpleTableSegment> actualTables, final List<ExpectedSimpleTable> 
expectedTables) {
+        assertThat(assertContext.getText("tables size should be the same."),
+                actualTables.size(), is(expectedTables.size()));
+        for (int i = 0; i < actualTables.size(); i++) {
+            assertIs(assertContext, actualTables.get(i), 
expectedTables.get(i));
+        }
+    }
+
+    /**
      * Assert actual table segment is correct with expected table owner.
      *
      * @param assertContext assert context
diff --git 
a/shardingsphere-sql-parser/shardingsphere-sql-parser-test/src/main/java/org/apache/shardingsphere/test/sql/parser/parameterized/asserts/statement/dml/impl/DeleteStatementAssert.java
 
b/shardingsphere-sql-parser/shardingsphere-sql-parser-test/src/main/java/org/apache/shardingsphere/test/sql/parser/parameterized/asserts/statement/dml/impl/DeleteStatementAssert.java
index e515529..457e9fe 100644
--- 
a/shardingsphere-sql-parser/shardingsphere-sql-parser-test/src/main/java/org/apache/shardingsphere/test/sql/parser/parameterized/asserts/statement/dml/impl/DeleteStatementAssert.java
+++ 
b/shardingsphere-sql-parser/shardingsphere-sql-parser-test/src/main/java/org/apache/shardingsphere/test/sql/parser/parameterized/asserts/statement/dml/impl/DeleteStatementAssert.java
@@ -23,6 +23,8 @@ import 
org.apache.shardingsphere.sql.parser.sql.common.segment.dml.order.OrderBy
 import 
org.apache.shardingsphere.sql.parser.sql.common.segment.dml.pagination.limit.LimitSegment;
 import 
org.apache.shardingsphere.sql.parser.sql.common.segment.generic.OutputSegment;
 import 
org.apache.shardingsphere.sql.parser.sql.common.segment.generic.WithSegment;
+import 
org.apache.shardingsphere.sql.parser.sql.common.segment.generic.table.DeleteMultiTableSegment;
+import 
org.apache.shardingsphere.sql.parser.sql.common.segment.generic.table.SimpleTableSegment;
 import 
org.apache.shardingsphere.sql.parser.sql.common.statement.dml.DeleteStatement;
 import 
org.apache.shardingsphere.sql.parser.sql.dialect.handler.dml.DeleteStatementHandler;
 import 
org.apache.shardingsphere.test.sql.parser.parameterized.asserts.SQLCaseAssertContext;
@@ -30,14 +32,19 @@ import 
org.apache.shardingsphere.test.sql.parser.parameterized.asserts.segment.S
 import 
org.apache.shardingsphere.test.sql.parser.parameterized.asserts.segment.limit.LimitClauseAssert;
 import 
org.apache.shardingsphere.test.sql.parser.parameterized.asserts.segment.orderby.OrderByClauseAssert;
 import 
org.apache.shardingsphere.test.sql.parser.parameterized.asserts.segment.output.OutputClauseAssert;
+import 
org.apache.shardingsphere.test.sql.parser.parameterized.asserts.segment.table.TableAssert;
 import 
org.apache.shardingsphere.test.sql.parser.parameterized.asserts.segment.where.WhereClauseAssert;
 import 
org.apache.shardingsphere.test.sql.parser.parameterized.asserts.segment.with.WithClauseAssert;
 import 
org.apache.shardingsphere.test.sql.parser.parameterized.jaxb.cases.domain.statement.dml.DeleteStatementTestCase;
 
+import java.util.LinkedList;
+import java.util.List;
 import java.util.Optional;
 
 import static org.junit.Assert.assertFalse;
 import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.assertNull;
+import static org.junit.Assert.assertNotNull;
 
 /**
  * Delete statement assert.
@@ -72,7 +79,19 @@ public final class DeleteStatementAssert {
     }
     
     private static void assertTable(final SQLCaseAssertContext assertContext, 
final DeleteStatement actual, final DeleteStatementTestCase expected) {
-//        TODO to support table assert
+        if (null != expected.getTables() && !expected.getTables().isEmpty()) {
+            assertNotNull(assertContext.getText("Actual table segment should 
exist."), actual.getTableSegment());
+            List<SimpleTableSegment> actualTableSegments = new LinkedList<>();
+            if (actual.getTableSegment() instanceof SimpleTableSegment) {
+                actualTableSegments.add((SimpleTableSegment) 
actual.getTableSegment());
+            } else if (actual.getTableSegment() instanceof 
DeleteMultiTableSegment) {
+                DeleteMultiTableSegment deleteMultiTableSegment = 
(DeleteMultiTableSegment) actual.getTableSegment();
+                
actualTableSegments.addAll(deleteMultiTableSegment.getActualDeleteTables());
+            }
+            TableAssert.assertIs(assertContext, actualTableSegments, 
expected.getTables());
+        } else {
+            assertNull(assertContext.getText("Actual table should not 
exist."), actual.getTableSegment());
+        }
     }
     
     private static void assertOutput(final SQLCaseAssertContext assertContext, 
final DeleteStatement actual, final DeleteStatementTestCase expected) {
diff --git 
a/shardingsphere-sql-parser/shardingsphere-sql-parser-test/src/main/java/org/apache/shardingsphere/test/sql/parser/parameterized/asserts/statement/dml/impl/SelectStatementAssert.java
 
b/shardingsphere-sql-parser/shardingsphere-sql-parser-test/src/main/java/org/apache/shardingsphere/test/sql/parser/parameterized/asserts/statement/dml/impl/SelectStatementAssert.java
index ac8ff2c..38a9a62 100644
--- 
a/shardingsphere-sql-parser/shardingsphere-sql-parser-test/src/main/java/org/apache/shardingsphere/test/sql/parser/parameterized/asserts/statement/dml/impl/SelectStatementAssert.java
+++ 
b/shardingsphere-sql-parser/shardingsphere-sql-parser-test/src/main/java/org/apache/shardingsphere/test/sql/parser/parameterized/asserts/statement/dml/impl/SelectStatementAssert.java
@@ -20,12 +20,14 @@ package 
org.apache.shardingsphere.test.sql.parser.parameterized.asserts.statemen
 import lombok.AccessLevel;
 import lombok.NoArgsConstructor;
 import 
org.apache.shardingsphere.sql.parser.sql.common.segment.dml.pagination.limit.LimitSegment;
+import 
org.apache.shardingsphere.sql.parser.sql.common.segment.dml.predicate.LockSegment;
 import 
org.apache.shardingsphere.sql.parser.sql.common.statement.dml.SelectStatement;
 import 
org.apache.shardingsphere.sql.parser.sql.dialect.handler.dml.SelectStatementHandler;
 import 
org.apache.shardingsphere.test.sql.parser.parameterized.asserts.SQLCaseAssertContext;
 import 
org.apache.shardingsphere.test.sql.parser.parameterized.asserts.segment.SQLSegmentAssert;
 import 
org.apache.shardingsphere.test.sql.parser.parameterized.asserts.segment.groupby.GroupByClauseAssert;
 import 
org.apache.shardingsphere.test.sql.parser.parameterized.asserts.segment.limit.LimitClauseAssert;
+import 
org.apache.shardingsphere.test.sql.parser.parameterized.asserts.segment.lock.LockClauseAssert;
 import 
org.apache.shardingsphere.test.sql.parser.parameterized.asserts.segment.orderby.OrderByClauseAssert;
 import 
org.apache.shardingsphere.test.sql.parser.parameterized.asserts.segment.projection.ProjectionAssert;
 import 
org.apache.shardingsphere.test.sql.parser.parameterized.asserts.segment.table.TableAssert;
@@ -57,6 +59,7 @@ public final class SelectStatementAssert {
         assertOrderByClause(assertContext, actual, expected);
         assertLimitClause(assertContext, actual, expected);
         assertTable(assertContext, actual, expected);
+        assertLockClause(assertContext, actual, expected);
 //        TODO support table assert
     }
     
@@ -113,4 +116,14 @@ public final class SelectStatementAssert {
             assertFalse(assertContext.getText("Actual limit segment should not 
exist."), limitSegment.isPresent());
         }
     }
+
+    private static void assertLockClause(final SQLCaseAssertContext 
assertContext, final SelectStatement actual, final SelectStatementTestCase 
expected) {
+        Optional<LockSegment> actualLock = 
SelectStatementHandler.getLockSegment(actual);
+        if (null != expected.getLockClause()) {
+            assertTrue(assertContext.getText("Actual lock segment should 
exist."), actualLock.isPresent());
+            LockClauseAssert.assertIs(assertContext, actualLock.get(), 
expected.getLockClause());
+        } else {
+            assertFalse(assertContext.getText("Actual lock segment should not 
exist."), actualLock.isPresent());
+        }
+    }
 }
diff --git 
a/shardingsphere-sql-parser/shardingsphere-sql-parser-statement/src/main/java/org/apache/shardingsphere/sql/parser/sql/common/segment/dml/predicate/LockSegment.java
 
b/shardingsphere-sql-parser/shardingsphere-sql-parser-test/src/main/java/org/apache/shardingsphere/test/sql/parser/parameterized/jaxb/cases/domain/segment/impl/lock/ExpectedLockClause.java
similarity index 55%
copy from 
shardingsphere-sql-parser/shardingsphere-sql-parser-statement/src/main/java/org/apache/shardingsphere/sql/parser/sql/common/segment/dml/predicate/LockSegment.java
copy to 
shardingsphere-sql-parser/shardingsphere-sql-parser-test/src/main/java/org/apache/shardingsphere/test/sql/parser/parameterized/jaxb/cases/domain/segment/impl/lock/ExpectedLockClause.java
index 73f208b..90cce97 100644
--- 
a/shardingsphere-sql-parser/shardingsphere-sql-parser-statement/src/main/java/org/apache/shardingsphere/sql/parser/sql/common/segment/dml/predicate/LockSegment.java
+++ 
b/shardingsphere-sql-parser/shardingsphere-sql-parser-test/src/main/java/org/apache/shardingsphere/test/sql/parser/parameterized/jaxb/cases/domain/segment/impl/lock/ExpectedLockClause.java
@@ -15,21 +15,24 @@
  * limitations under the License.
  */
 
-package org.apache.shardingsphere.sql.parser.sql.common.segment.dml.predicate;
+package 
org.apache.shardingsphere.test.sql.parser.parameterized.jaxb.cases.domain.segment.impl.lock;
 
 import lombok.Getter;
-import lombok.RequiredArgsConstructor;
-import org.apache.shardingsphere.sql.parser.sql.common.segment.SQLSegment;
+import lombok.Setter;
+import 
org.apache.shardingsphere.test.sql.parser.parameterized.jaxb.cases.domain.segment.AbstractExpectedSQLSegment;
+import 
org.apache.shardingsphere.test.sql.parser.parameterized.jaxb.cases.domain.segment.impl.table.ExpectedSimpleTable;
+
+import javax.xml.bind.annotation.XmlElement;
+import java.util.LinkedList;
+import java.util.List;
 
 /**
- * Lock segment.
+ * Expected lock clause.
  */
-
-@RequiredArgsConstructor
 @Getter
-public final class LockSegment implements SQLSegment {
-
-    private final int startIndex;
+@Setter
+public final class ExpectedLockClause extends AbstractExpectedSQLSegment {
 
-    private final int stopIndex;
+    @XmlElement(name = "table")
+    private final List<ExpectedSimpleTable> tables = new LinkedList<>();
 }
diff --git 
a/shardingsphere-sql-parser/shardingsphere-sql-parser-test/src/main/java/org/apache/shardingsphere/test/sql/parser/parameterized/jaxb/cases/domain/statement/dml/SelectStatementTestCase.java
 
b/shardingsphere-sql-parser/shardingsphere-sql-parser-test/src/main/java/org/apache/shardingsphere/test/sql/parser/parameterized/jaxb/cases/domain/statement/dml/SelectStatementTestCase.java
index cc5822a..41dc800 100644
--- 
a/shardingsphere-sql-parser/shardingsphere-sql-parser-test/src/main/java/org/apache/shardingsphere/test/sql/parser/parameterized/jaxb/cases/domain/statement/dml/SelectStatementTestCase.java
+++ 
b/shardingsphere-sql-parser/shardingsphere-sql-parser-test/src/main/java/org/apache/shardingsphere/test/sql/parser/parameterized/jaxb/cases/domain/statement/dml/SelectStatementTestCase.java
@@ -20,13 +20,13 @@ package 
org.apache.shardingsphere.test.sql.parser.parameterized.jaxb.cases.domai
 import lombok.Getter;
 import lombok.Setter;
 import 
org.apache.shardingsphere.test.sql.parser.parameterized.jaxb.cases.domain.segment.impl.limit.ExpectedLimitClause;
+import 
org.apache.shardingsphere.test.sql.parser.parameterized.jaxb.cases.domain.segment.impl.lock.ExpectedLockClause;
 import 
org.apache.shardingsphere.test.sql.parser.parameterized.jaxb.cases.domain.segment.impl.orderby.ExpectedOrderByClause;
 import 
org.apache.shardingsphere.test.sql.parser.parameterized.jaxb.cases.domain.segment.impl.predicate.ExpectedWhereClause;
 import 
org.apache.shardingsphere.test.sql.parser.parameterized.jaxb.cases.domain.segment.impl.projection.ExpectedProjections;
 import 
org.apache.shardingsphere.test.sql.parser.parameterized.jaxb.cases.domain.segment.impl.table.ExpectedTable;
 import 
org.apache.shardingsphere.test.sql.parser.parameterized.jaxb.cases.domain.statement.SQLParserTestCase;
 
-import javax.xml.bind.annotation.XmlAttribute;
 import javax.xml.bind.annotation.XmlElement;
 
 /**
@@ -36,9 +36,6 @@ import javax.xml.bind.annotation.XmlElement;
 @Setter
 public final class SelectStatementTestCase extends SQLParserTestCase {
     
-    @XmlAttribute(name = "lock-clause")
-    private boolean lockClause;
-    
     @XmlElement(name = "from")
     private ExpectedTable from;
 
@@ -56,4 +53,7 @@ public final class SelectStatementTestCase extends 
SQLParserTestCase {
     
     @XmlElement(name = "limit")
     private ExpectedLimitClause limitClause;
+
+    @XmlElement(name = "lock")
+    private ExpectedLockClause lockClause;
 }
diff --git 
a/shardingsphere-sql-parser/shardingsphere-sql-parser-test/src/main/resources/case/dml/delete.xml
 
b/shardingsphere-sql-parser/shardingsphere-sql-parser-test/src/main/resources/case/dml/delete.xml
index bf42319..2e2d288 100644
--- 
a/shardingsphere-sql-parser/shardingsphere-sql-parser-test/src/main/resources/case/dml/delete.xml
+++ 
b/shardingsphere-sql-parser/shardingsphere-sql-parser-test/src/main/resources/case/dml/delete.xml
@@ -111,16 +111,15 @@
     </delete>
 
     <delete sql-case-id="delete_with_alias" parameters="'init'">
-        <table name="o" start-index="7" stop-index="7" />
-        <table name="t_order" alias="o" start-index="14" stop-index="25" />
-        <where start-index="27" stop-index="40" literal-stop-index="46">
+        <table name="t_order" alias="o" start-index="12" stop-index="23" />
+        <where start-index="25" stop-index="38" literal-stop-index="44">
             <and-predicate>
-                <predicate start-index="33" stop-index="40" 
literal-stop-index="45">
-                    <column-left-value name="status" start-index="33" 
stop-index="38" />
+                <predicate start-index="31" stop-index="38" 
literal-stop-index="43">
+                    <column-left-value name="status" start-index="31" 
stop-index="36" />
                     <operator type="=" />
                     <compare-right-value>
-                        <parameter-marker-expression value="0" 
start-index="40" stop-index="40" />
-                        <literal-expression value="init" start-index="40" 
stop-index="45" />
+                        <parameter-marker-expression value="0" 
start-index="38" stop-index="38" />
+                        <literal-expression value="init" start-index="38" 
stop-index="43" />
                     </compare-right-value>
                 </predicate>
             </and-predicate>
@@ -357,4 +356,51 @@
             </and-predicate>
         </where>
     </delete>
+
+    <delete sql-case-id="delete_multi_tables" parameters="1">
+        <where start-index="56" stop-index="124">
+            <and-predicate>
+                <predicate start-index="62" stop-index="101">
+                    <column-left-value name="order_id" start-index="62" 
stop-index="77">
+                        <owner name="t_order" start-index="62" 
stop-index="68"/>
+                    </column-left-value>
+                    <operator type="="/>
+                    <column-right-value name="order_id" start-index="62" 
stop-index="77">
+                        <owner name="t_order" start-index="62" 
stop-index="68"/>
+                    </column-right-value>
+                </predicate>
+                <predicate start-index="107" stop-index="124">
+                    <column-left-value name="status" start-index="107" 
stop-index="120">
+                        <owner name="t_order" start-index="107" 
stop-index="113"/>
+                    </column-left-value>
+                    <operator type="="/>
+                    <compare-right-value>
+                        <parameter-marker-expression value="0" 
start-index="124" stop-index="124"/>
+                        <literal-expression value="1" start-index="124" 
stop-index="124"/>
+                    </compare-right-value>
+                </predicate>
+            </and-predicate>
+        </where>
+        <table name="t_order" start-index="7" stop-index="13"/>
+        <table name="t_order_item" start-index="16" stop-index="27"/>
+    </delete>
+
+    <delete sql-case-id="delete_multi_tables_with_using" parameters="1">
+        <where start-index="115" stop-index="138">
+            <and-predicate>
+                <predicate start-index="121" stop-index="138">
+                    <column-left-value name="status" start-index="121" 
stop-index="134">
+                        <owner name="t_order" start-index="121" 
stop-index="127"/>
+                    </column-left-value>
+                    <operator type="="/>
+                    <compare-right-value>
+                        <parameter-marker-expression value="0" 
start-index="138" stop-index="138"/>
+                        <literal-expression value="1" start-index="138" 
stop-index="138"/>
+                    </compare-right-value>
+                </predicate>
+            </and-predicate>
+        </where>
+        <table name="t_order" start-index="12" stop-index="18"/>
+        <table name="t_order_item" start-index="21" stop-index="32"/>
+    </delete>
 </sql-parser-test-cases>
diff --git 
a/shardingsphere-sql-parser/shardingsphere-sql-parser-test/src/main/resources/case/dml/select-into.xml
 
b/shardingsphere-sql-parser/shardingsphere-sql-parser-test/src/main/resources/case/dml/select-into.xml
new file mode 100644
index 0000000..86bead0
--- /dev/null
+++ 
b/shardingsphere-sql-parser/shardingsphere-sql-parser-test/src/main/resources/case/dml/select-into.xml
@@ -0,0 +1,188 @@
+<?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>
+    <select sql-case-id="select_into_before_from" parameters="1">
+        <from start-index="30" stop-index="36">
+            <simple-table name="t_order" start-index="30" stop-index="36"/>
+        </from>
+        <projections distinct-row="false" start-index="7" stop-index="12">
+            <column-projection name="status" start-index="7" stop-index="12"/>
+        </projections>
+        <where start-index="38" stop-index="55">
+            <and-predicate>
+                <predicate start-index="44" stop-index="55">
+                    <column-left-value name="order_id" start-index="44" 
stop-index="51"/>
+                    <operator type="="/>
+                    <compare-right-value>
+                        <parameter-marker-expression value="0" 
start-index="55" stop-index="55"/>
+                        <literal-expression value="1" start-index="55" 
stop-index="55"/>
+                    </compare-right-value>
+                </predicate>
+            </and-predicate>
+        </where>
+    </select>
+
+    <select sql-case-id="select_into_after_from" parameters="1">
+        <from start-index="19" stop-index="25">
+            <simple-table name="t_order" start-index="19" stop-index="25"/>
+        </from>
+        <projections distinct-row="false" start-index="7" stop-index="12">
+            <column-projection name="status" start-index="7" stop-index="12"/>
+        </projections>
+        <where start-index="27" stop-index="44">
+            <and-predicate>
+                <predicate start-index="33" stop-index="44">
+                    <column-left-value name="order_id" start-index="33" 
stop-index="40"/>
+                    <operator type="="/>
+                    <compare-right-value>
+                        <parameter-marker-expression value="0" 
start-index="44" stop-index="44"/>
+                        <literal-expression value="1" start-index="44" 
stop-index="44"/>
+                    </compare-right-value>
+                </predicate>
+            </and-predicate>
+        </where>
+    </select>
+
+    <select sql-case-id="select_into_multi_variable" parameters="1">
+        <from start-index="28" stop-index="34">
+            <simple-table name="t_order" start-index="28" stop-index="34"/>
+        </from>
+        <projections distinct-row="false" start-index="7" stop-index="21">
+            <column-projection name="user_id" start-index="7" stop-index="13"/>
+            <column-projection name="status" start-index="16" stop-index="21"/>
+        </projections>
+        <where start-index="36" stop-index="53">
+            <and-predicate>
+                <predicate start-index="42" stop-index="53">
+                    <column-left-value name="order_id" start-index="42" 
stop-index="49"/>
+                    <operator type="="/>
+                    <compare-right-value>
+                        <parameter-marker-expression value="0" 
start-index="53" stop-index="53"/>
+                        <literal-expression value="1" start-index="53" 
stop-index="53"/>
+                    </compare-right-value>
+                </predicate>
+            </and-predicate>
+        </where>
+    </select>
+
+    <select sql-case-id="select_into_out_file" parameters="2">
+        <from start-index="14" stop-index="20">
+            <simple-table name="t_order" start-index="14" stop-index="20"/>
+        </from>
+        <projections distinct-row="false" start-index="7" stop-index="7">
+            <shorthand-projection start-index="7" stop-index="7"/>
+        </projections>
+        <limit start-index="22" stop-index="28">
+            <row-count value="2" parameter-index="0" start-index="28" 
stop-index="28"/>
+        </limit>
+    </select>
+
+    <select sql-case-id="select_into_out_file_with_charset" parameters="2">
+        <from start-index="14" stop-index="20">
+            <simple-table name="t_order" start-index="14" stop-index="20"/>
+        </from>
+        <projections distinct-row="false" start-index="7" stop-index="7">
+            <shorthand-projection start-index="7" stop-index="7"/>
+        </projections>
+        <limit start-index="22" stop-index="28">
+            <row-count value="2" parameter-index="0" start-index="28" 
stop-index="28"/>
+        </limit>
+    </select>
+
+    <select sql-case-id="select_into_out_file_with_fields" parameters="2">
+        <from start-index="14" stop-index="20">
+            <simple-table name="t_order" start-index="14" stop-index="20"/>
+        </from>
+        <projections distinct-row="false" start-index="7" stop-index="7">
+            <shorthand-projection start-index="7" stop-index="7"/>
+        </projections>
+        <limit start-index="22" stop-index="28">
+            <row-count value="2" parameter-index="0" start-index="28" 
stop-index="28"/>
+        </limit>
+    </select>
+
+    <select sql-case-id="select_into_out_file_with_fields_and_escaped" 
parameters="2">
+        <from start-index="28" stop-index="34">
+            <simple-table name="t_order" start-index="28" stop-index="34"/>
+        </from>
+        <projections distinct-row="false" start-index="7" stop-index="21">
+            <column-projection name="user_id" start-index="7" stop-index="13"/>
+            <column-projection name="status" start-index="16" stop-index="21"/>
+        </projections>
+        <limit start-index="36" stop-index="42">
+            <row-count value="2" parameter-index="0" start-index="42" 
stop-index="42"/>
+        </limit>
+    </select>
+
+    <select sql-case-id="select_into_out_file_with_lines" parameters="2">
+        <from start-index="14" stop-index="20">
+            <simple-table name="t_order" start-index="14" stop-index="20"/>
+        </from>
+        <projections distinct-row="false" start-index="7" stop-index="7">
+            <shorthand-projection start-index="7" stop-index="7"/>
+        </projections>
+        <limit start-index="22" stop-index="28">
+            <row-count value="2" parameter-index="0" start-index="28" 
stop-index="28"/>
+        </limit>
+    </select>
+
+    <select sql-case-id="select_into_with_lock_after_into" parameters="1">
+        <from start-index="19" stop-index="25">
+            <simple-table name="t_order" start-index="19" stop-index="25"/>
+        </from>
+        <projections distinct-row="false" start-index="7" stop-index="12">
+            <column-projection name="status" start-index="7" stop-index="12"/>
+        </projections>
+        <where start-index="27" stop-index="44">
+            <and-predicate>
+                <predicate start-index="33" stop-index="44">
+                    <column-left-value name="order_id" start-index="33" 
stop-index="40"/>
+                    <operator type="="/>
+                    <compare-right-value>
+                        <parameter-marker-expression value="0" 
start-index="44" stop-index="44"/>
+                        <literal-expression value="1" start-index="44" 
stop-index="44"/>
+                    </compare-right-value>
+                </predicate>
+            </and-predicate>
+        </where>
+        <lock start-index="57" stop-index="66"/>
+    </select>
+
+    <select sql-case-id="select_into_with_lock_before_into" parameters="1">
+        <from start-index="19" stop-index="25">
+            <simple-table name="t_order" start-index="19" stop-index="25"/>
+        </from>
+        <projections distinct-row="false" start-index="7" stop-index="12">
+            <column-projection name="status" start-index="7" stop-index="12"/>
+        </projections>
+        <where start-index="27" stop-index="44">
+            <and-predicate>
+                <predicate start-index="33" stop-index="44">
+                    <column-left-value name="order_id" start-index="33" 
stop-index="40"/>
+                    <operator type="="/>
+                    <compare-right-value>
+                        <parameter-marker-expression value="0" 
start-index="44" stop-index="44"/>
+                        <literal-expression value="1" start-index="44" 
stop-index="44"/>
+                    </compare-right-value>
+                </predicate>
+            </and-predicate>
+        </where>
+        <lock start-index="46" stop-index="55"/>
+    </select>
+</sql-parser-test-cases>
diff --git 
a/shardingsphere-sql-parser/shardingsphere-sql-parser-test/src/main/resources/case/dml/select-lock.xml
 
b/shardingsphere-sql-parser/shardingsphere-sql-parser-test/src/main/resources/case/dml/select-lock.xml
new file mode 100644
index 0000000..10ff4ad
--- /dev/null
+++ 
b/shardingsphere-sql-parser/shardingsphere-sql-parser-test/src/main/resources/case/dml/select-lock.xml
@@ -0,0 +1,232 @@
+<?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>
+    <select sql-case-id="select_lock_with_lock_in" parameters="1">
+        <where start-index="22" stop-index="39">
+            <and-predicate>
+                <predicate start-index="28" stop-index="39">
+                    <column-left-value name="order_id" start-index="28" 
stop-index="35"/>
+                    <operator type="="/>
+                    <compare-right-value>
+                        <parameter-marker-expression value="0" 
start-index="39" stop-index="39"/>
+                        <literal-expression value="1" start-index="39" 
stop-index="39"/>
+                    </compare-right-value>
+                </predicate>
+            </and-predicate>
+        </where>
+        <from start-index="14" stop-index="20">
+            <simple-table name="t_order" start-index="14" stop-index="20"/>
+        </from>
+        <projections distinct-row="false" start-index="7" stop-index="7">
+            <shorthand-projection start-index="7" stop-index="7"/>
+        </projections>
+        <lock start-index="41" stop-index="58"/>
+    </select>
+
+    <select sql-case-id="select_lock_with_for_update" parameters="1">
+        <where start-index="22" stop-index="39">
+            <and-predicate>
+                <predicate start-index="28" stop-index="39">
+                    <column-left-value name="order_id" start-index="28" 
stop-index="35"/>
+                    <operator type="="/>
+                    <compare-right-value>
+                        <parameter-marker-expression value="0" 
start-index="39" stop-index="39"/>
+                        <literal-expression value="1" start-index="39" 
stop-index="39"/>
+                    </compare-right-value>
+                </predicate>
+            </and-predicate>
+        </where>
+        <from start-index="14" stop-index="20">
+            <simple-table name="t_order" start-index="14" stop-index="20"/>
+        </from>
+        <projections distinct-row="false" start-index="7" stop-index="7">
+            <shorthand-projection start-index="7" stop-index="7"/>
+        </projections>
+        <lock start-index="41" stop-index="50"/>
+    </select>
+
+    <select sql-case-id="select_lock_with_for_share" parameters="1">
+        <where start-index="22" stop-index="39">
+            <and-predicate>
+                <predicate start-index="28" stop-index="39">
+                    <column-left-value name="order_id" start-index="28" 
stop-index="35"/>
+                    <operator type="="/>
+                    <compare-right-value>
+                        <parameter-marker-expression value="0" 
start-index="39" stop-index="39"/>
+                        <literal-expression value="1" start-index="39" 
stop-index="39"/>
+                    </compare-right-value>
+                </predicate>
+            </and-predicate>
+        </where>
+        <from start-index="14" stop-index="20">
+            <simple-table name="t_order" start-index="14" stop-index="20"/>
+        </from>
+        <projections distinct-row="false" start-index="7" stop-index="7">
+            <shorthand-projection start-index="7" stop-index="7"/>
+        </projections>
+        <lock start-index="41" stop-index="49"/>
+    </select>
+
+    <select sql-case-id="select_lock_with_nowait" parameters="1">
+        <where start-index="22" stop-index="39">
+            <and-predicate>
+                <predicate start-index="28" stop-index="39">
+                    <column-left-value name="order_id" start-index="28" 
stop-index="35"/>
+                    <operator type="="/>
+                    <compare-right-value>
+                        <parameter-marker-expression value="0" 
start-index="39" stop-index="39"/>
+                        <literal-expression value="1" start-index="39" 
stop-index="39"/>
+                    </compare-right-value>
+                </predicate>
+            </and-predicate>
+        </where>
+        <from start-index="14" stop-index="20">
+            <simple-table name="t_order" start-index="14" stop-index="20"/>
+        </from>
+        <projections distinct-row="false" start-index="7" stop-index="7">
+            <shorthand-projection start-index="7" stop-index="7"/>
+        </projections>
+        <lock start-index="41" stop-index="57"/>
+    </select>
+
+    <select sql-case-id="select_lock_with_skip_locked" parameters="1">
+        <where start-index="22" stop-index="39">
+            <and-predicate>
+                <predicate start-index="28" stop-index="39">
+                    <column-left-value name="order_id" start-index="28" 
stop-index="35"/>
+                    <operator type="="/>
+                    <compare-right-value>
+                        <parameter-marker-expression value="0" 
start-index="39" stop-index="39"/>
+                        <literal-expression value="1" start-index="39" 
stop-index="39"/>
+                    </compare-right-value>
+                </predicate>
+            </and-predicate>
+        </where>
+        <from start-index="14" stop-index="20">
+            <simple-table name="t_order" start-index="14" stop-index="20"/>
+        </from>
+        <projections distinct-row="false" start-index="7" stop-index="7">
+            <shorthand-projection start-index="7" stop-index="7"/>
+        </projections>
+        <lock start-index="41" stop-index="62"/>
+    </select>
+
+    <select sql-case-id="select_lock_with_of" parameters="1">
+        <where start-index="36" stop-index="106">
+            <and-predicate>
+                <predicate start-index="42" stop-index="81">
+                    <column-left-value name="order_id" start-index="42" 
stop-index="57">
+                        <owner name="t_order" start-index="42" 
stop-index="48"/>
+                    </column-left-value>
+                    <operator type="="/>
+                    <column-right-value name="order_id" start-index="42" 
stop-index="57">
+                        <owner name="t_order" start-index="42" 
stop-index="48"/>
+                    </column-right-value>
+                </predicate>
+                <predicate start-index="87" stop-index="106">
+                    <column-left-value name="order_id" start-index="87" 
stop-index="102">
+                        <owner name="t_order" start-index="87" 
stop-index="93"/>
+                    </column-left-value>
+                    <operator type="="/>
+                    <compare-right-value>
+                        <parameter-marker-expression value="0" 
start-index="106" stop-index="106"/>
+                        <literal-expression value="1" start-index="106" 
stop-index="106"/>
+                    </compare-right-value>
+                </predicate>
+            </and-predicate>
+        </where>
+        <from start-index="14" stop-index="34">
+            <join-table start-index="14" stop-index="34">
+                <left start-index="14" stop-index="20">
+                    <simple-table name="t_order" start-index="14" 
stop-index="20"/>
+                </left>
+                <right start-index="23" stop-index="34">
+                    <simple-table name="t_order_item" start-index="23" 
stop-index="34"/>
+                </right>
+            </join-table>
+        </from>
+        <projections distinct-row="false" start-index="7" stop-index="7">
+            <shorthand-projection start-index="7" stop-index="7"/>
+        </projections>
+        <lock start-index="108" stop-index="154">
+            <table name="t_order" start-index="122" stop-index="128"/>
+            <table name="t_order_item" start-index="143" stop-index="154"/>
+        </lock>
+    </select>
+
+    <select sql-case-id="select_lock_with_of_multi_tables" parameters="1">
+        <where start-index="44" stop-index="151">
+            <and-predicate>
+                <predicate start-index="50" stop-index="89">
+                    <column-left-value name="order_id" start-index="50" 
stop-index="65">
+                        <owner name="t_order" start-index="50" 
stop-index="56"/>
+                    </column-left-value>
+                    <operator type="="/>
+                    <column-right-value name="order_id" start-index="50" 
stop-index="65">
+                        <owner name="t_order" start-index="50" 
stop-index="56"/>
+                    </column-right-value>
+                </predicate>
+                <predicate start-index="95" stop-index="126">
+                    <column-left-value name="user_id" start-index="95" 
stop-index="109">
+                        <owner name="t_order" start-index="95" 
stop-index="101"/>
+                    </column-left-value>
+                    <operator type="="/>
+                    <column-right-value name="user_id" start-index="95" 
stop-index="109">
+                        <owner name="t_order" start-index="95" 
stop-index="101"/>
+                    </column-right-value>
+                </predicate>
+                <predicate start-index="132" stop-index="151">
+                    <column-left-value name="order_id" start-index="132" 
stop-index="147">
+                        <owner name="t_order" start-index="132" 
stop-index="138"/>
+                    </column-left-value>
+                    <operator type="="/>
+                    <compare-right-value>
+                        <parameter-marker-expression value="0" 
start-index="151" stop-index="151"/>
+                        <literal-expression value="1" start-index="151" 
stop-index="151"/>
+                    </compare-right-value>
+                </predicate>
+            </and-predicate>
+        </where>
+        <from start-index="14" stop-index="42">
+            <join-table start-index="14" stop-index="42">
+                <left start-index="14" stop-index="34">
+                    <join-table start-index="14" stop-index="34">
+                        <left start-index="14" stop-index="20">
+                            <simple-table name="t_order" start-index="14" 
stop-index="20"/>
+                        </left>
+                        <right start-index="23" stop-index="34">
+                            <simple-table name="t_order_item" start-index="23" 
stop-index="34"/>
+                        </right>
+                    </join-table>
+                </left>
+                <right start-index="37" stop-index="42">
+                    <simple-table name="t_user" start-index="37" 
stop-index="42"/>
+                </right>
+            </join-table>
+        </from>
+        <projections distinct-row="false" start-index="7" stop-index="7">
+            <shorthand-projection start-index="7" stop-index="7"/>
+        </projections>
+        <lock start-index="153" stop-index="207">
+            <table name="t_order" start-index="167" stop-index="173"/>
+            <table name="t_order_item" start-index="176" stop-index="187"/>
+            <table name="t_user" start-index="202" stop-index="207"/>
+        </lock>
+    </select>
+</sql-parser-test-cases>
diff --git 
a/shardingsphere-sql-parser/shardingsphere-sql-parser-test/src/main/resources/case/dml/select.xml
 
b/shardingsphere-sql-parser/shardingsphere-sql-parser-test/src/main/resources/case/dml/select.xml
index a47938a..7bef203 100644
--- 
a/shardingsphere-sql-parser/shardingsphere-sql-parser-test/src/main/resources/case/dml/select.xml
+++ 
b/shardingsphere-sql-parser/shardingsphere-sql-parser-test/src/main/resources/case/dml/select.xml
@@ -1790,27 +1790,6 @@
         </where>
     </select>
 
-    <select sql-case-id="select_for_update" parameters="10">
-        <from>
-            <simple-table name="t_order" start-index="14" stop-index="20" />
-        </from>
-        <projections start-index="7" stop-index="7">
-            <shorthand-projection start-index="7" stop-index="7" />
-        </projections>
-        <where start-index="22" stop-index="38" literal-stop-index="39">
-            <and-predicate>
-                <predicate start-index="28" stop-index="38" 
literal-stop-index="39">
-                    <column-left-value name="user_id" start-index="28" 
stop-index="34"  literal-stop-index="34" />
-                    <operator type="=" />
-                    <compare-right-value>
-                        <parameter-marker-expression value="0" 
start-index="38" stop-index="38" />
-                        <literal-expression value="10" start-index="38" 
stop-index="39" />
-                    </compare-right-value>
-                </predicate>
-            </and-predicate>
-        </where>
-    </select>
-
     <select sql-case-id="select_database">
         <projections start-index="7" stop-index="16">
             <expression-projection start-index="7" stop-index="16" />
diff --git 
a/shardingsphere-sql-parser/shardingsphere-sql-parser-test/src/main/resources/sql/supported/dml/delete.xml
 
b/shardingsphere-sql-parser/shardingsphere-sql-parser-test/src/main/resources/sql/supported/dml/delete.xml
index 15a9484..739d86c 100644
--- 
a/shardingsphere-sql-parser/shardingsphere-sql-parser-test/src/main/resources/sql/supported/dml/delete.xml
+++ 
b/shardingsphere-sql-parser/shardingsphere-sql-parser-test/src/main/resources/sql/supported/dml/delete.xml
@@ -22,7 +22,7 @@
     <sql-case id="delete_with_special_character_without_sharding_value" 
value="DELETE FROM `t_order` WHERE `status`='init'" db-types="MySQL" />
     <sql-case id="delete_with_special_comments_return_without_sharding_value" 
value="DELETE /*+ index(status) */ ONLY t_order WHERE status=1 RETURN * LOG 
ERRORS INTO TABLE_LOG" db-types="Oracle" />
     <sql-case 
id="delete_with_special_comments_returning_without_sharding_value" 
value="DELETE /*+ index(status) */ ONLY (t_order) WHERE status=1 RETURNING *" 
db-types="Oracle" />
-    <sql-case id="delete_with_alias" value="DELETE o FROM t_order AS o WHERE 
status=?" db-types="MySQL,Oracle,SQLServer"/>
+    <sql-case id="delete_with_alias" value="DELETE FROM t_order AS o WHERE 
status=?" db-types="MySQL,Oracle,SQLServer"/>
     <sql-case id="delete_with_order_by_row_count" value="DELETE FROM t_order 
WHERE order_id = ? AND user_id = ? AND status=? ORDER BY order_id LIMIT ?" 
db-types="MySQL"/>
     <sql-case id="delete_with_output_clause" value="DELETE FROM t_order OUTPUT 
DELETED.order_id, DELETED.user_id INTO @MyTableVar (temp_order_id, 
temp_user_id) WHERE order_id = ?" db-types="SQLServer" />
     <sql-case id="delete_with_output_clause_without_output_table_columns" 
value="DELETE FROM t_order OUTPUT DELETED.order_id, DELETED.user_id INTO 
@MyTableVar WHERE order_id = ?" db-types="SQLServer" />
@@ -32,4 +32,6 @@
     <sql-case id="delete_with_top_percent" value="DELETE TOP(10) PERCENT FROM 
t_order WHERE order_id = ?" db-types="SQLServer" />
     <sql-case id="delete_with_with_clause" value="WITH cte (order_id, user_id) 
AS (SELECT order_id, user_id FROM t_order) DELETE t_order FROM cte WHERE 
t_order.order_id = cte.order_id" db-types="SQLServer" />
     <sql-case id="delete_without_columns_with_with_clause" value="WITH cte AS 
(SELECT order_id, user_id FROM t_order) DELETE t_order FROM cte WHERE 
t_order.order_id = cte.order_id" db-types="SQLServer" />
+    <sql-case id="delete_multi_tables" value="DELETE t_order, t_order_item 
from t_order, t_order_item where t_order.order_id = t_order_item.order_id and 
t_order.status = ?" db-types="MySQL"/>
+    <sql-case id="delete_multi_tables_with_using" value="DELETE from t_order, 
t_order_item using t_order left join t_order_item on t_order.order_id = 
t_order_item.order_id where t_order.status = ?" db-types="MySQL"/>
 </sql-cases>
diff --git 
a/shardingsphere-sql-parser/shardingsphere-sql-parser-test/src/main/resources/sql/supported/dml/select-into.xml
 
b/shardingsphere-sql-parser/shardingsphere-sql-parser-test/src/main/resources/sql/supported/dml/select-into.xml
new file mode 100644
index 0000000..d64f957
--- /dev/null
+++ 
b/shardingsphere-sql-parser/shardingsphere-sql-parser-test/src/main/resources/sql/supported/dml/select-into.xml
@@ -0,0 +1,30 @@
+<?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="select_into_before_from" value="SELECT status INTO @var1 
FROM t_order WHERE order_id = ?" db-types="MySQL"/>
+    <sql-case id="select_into_after_from" value="SELECT status FROM t_order 
WHERE order_id = ? INTO @var1" db-types="MySQL"/>
+    <sql-case id="select_into_multi_variable" value="SELECT user_id, status 
FROM t_order WHERE order_id = ? INTO @var1, @var2" db-types="MySQL"/>
+    <sql-case id="select_into_out_file" value="SELECT * FROM t_order LIMIT ? 
INTO OUTFILE '/tmp/tmp.txt'" db-types="MySQL"/>
+    <sql-case id="select_into_out_file_with_charset" value="SELECT * FROM 
t_order LIMIT ? INTO OUTFILE '/tmp/tmp.txt' CHARACTER SET utf8" 
db-types="MySQL"/>
+    <sql-case id="select_into_out_file_with_fields" value="SELECT * FROM 
t_order LIMIT ? INTO OUTFILE '/tmp/tmp.txt'  FIELDS TERMINATED BY ',' 
OPTIONALLY ENCLOSED BY '&quot;'" db-types="MySQL"/>
+    <sql-case id="select_into_out_file_with_fields_and_escaped" value="SELECT 
user_id, status FROM t_order LIMIT ? INTO OUTFILE '/tmp/tmp.txt'  FIELDS 
TERMINATED BY ',' OPTIONALLY ENCLOSED BY '&quot;', ESCAPED BY '\'" 
db-types="MySQL"/>
+    <sql-case id="select_into_out_file_with_lines" value="SELECT * FROM 
t_order LIMIT ? INTO OUTFILE '/tmp/tmp.txt'  LINES TERMINATED BY '\n'" 
db-types="MySQL"/>
+    <sql-case id="select_into_with_lock_after_into" value="SELECT status FROM 
t_order WHERE order_id = ? INTO @var1 FOR UPDATE " db-types="MySQL"/>
+    <sql-case id="select_into_with_lock_before_into" value="SELECT status FROM 
t_order WHERE order_id = ? FOR UPDATE INTO @var1" db-types="MySQL"/>
+</sql-cases>
diff --git 
a/shardingsphere-sql-parser/shardingsphere-sql-parser-test/src/main/resources/sql/supported/dml/select-lock.xml
 
b/shardingsphere-sql-parser/shardingsphere-sql-parser-test/src/main/resources/sql/supported/dml/select-lock.xml
new file mode 100644
index 0000000..24c09de
--- /dev/null
+++ 
b/shardingsphere-sql-parser/shardingsphere-sql-parser-test/src/main/resources/sql/supported/dml/select-lock.xml
@@ -0,0 +1,27 @@
+<?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="select_lock_with_lock_in" value="SELECT * FROM t_order WHERE 
order_id = ? LOCK IN SHARE MODE" db-types="MySQL"/>
+    <sql-case id="select_lock_with_for_update" value="SELECT * FROM t_order 
WHERE order_id = ? FOR UPDATE" db-types="MySQL,Oracle,PostgreSQL"/>
+    <sql-case id="select_lock_with_for_share" value="SELECT * FROM t_order 
WHERE order_id = ? FOR SHARE" db-types="MySQL"/>
+    <sql-case id="select_lock_with_nowait" value="SELECT * FROM t_order WHERE 
order_id = ? FOR UPDATE NOWAIT" db-types="MySQL"/>
+    <sql-case id="select_lock_with_skip_locked" value="SELECT * FROM t_order 
WHERE order_id = ? FOR UPDATE SKIP LOCKED" db-types="MySQL"/>
+    <sql-case id="select_lock_with_of" value="SELECT * FROM t_order, 
t_order_item WHERE t_order.order_id = t_order_item.order_id AND 
t_order.order_id = ? FOR UPDATE OF t_order FOR SHARE OF t_order_item" 
db-types="MySQL"/>
+    <sql-case id="select_lock_with_of_multi_tables" value="SELECT * FROM 
t_order, t_order_item, t_user WHERE t_order.order_id = t_order_item.order_id 
AND t_order.user_id = t_user.user_id AND t_order.order_id = ? FOR UPDATE OF 
t_order, t_order_item FOR SHARE OF t_user" db-types="MySQL"/>
+</sql-cases>
diff --git 
a/shardingsphere-sql-parser/shardingsphere-sql-parser-test/src/main/resources/sql/supported/dml/select.xml
 
b/shardingsphere-sql-parser/shardingsphere-sql-parser-test/src/main/resources/sql/supported/dml/select.xml
index a7798a3..e7001e1 100644
--- 
a/shardingsphere-sql-parser/shardingsphere-sql-parser-test/src/main/resources/sql/supported/dml/select.xml
+++ 
b/shardingsphere-sql-parser/shardingsphere-sql-parser-test/src/main/resources/sql/supported/dml/select.xml
@@ -52,7 +52,6 @@
     <sql-case id="select_special_function_nested" value="SELECT 
sum(if(status=0, 1, 0)) func_status FROM t_order WHERE user_id = ? AND order_id 
= ?" db-types="MySQL" />
     <sql-case id="select_with_interval_function" value="SELECT 
INTERVAL(status,1,5) func_status FROM t_order WHERE user_id = ? AND order_id = 
?" db-types="MySQL" />
     <sql-case id="select_with_left_function" value="SELECT CONCAT(LEFT(status, 
7), 'test') FROM t_order_item WHERE user_id = 10" db-types="MySQL" />
-    <sql-case id="select_for_update" value="SELECT * FROM t_order WHERE 
user_id = ? FOR UPDATE" lock-clause="true"/>
     <sql-case id="select_database" value="SELECT DATABASE()" db-types="MySQL" 
/>
     <sql-case id="select_with_mod_function" value="SELECT * FROM t_order WHERE 
MOD(order_id, 1) = 1" db-types="MySQL" />
     <sql-case id="select_with_date_format_function" value="SELECT * FROM 
t_order WHERE DATE_FORMAT(current_date, '%Y-%m-%d') = '2019-12-18'" 
db-types="MySQL" />
diff --git 
a/shardingsphere-sql-parser/shardingsphere-sql-parser-test/src/main/resources/sql/unsupported/unsupported.xml
 
b/shardingsphere-sql-parser/shardingsphere-sql-parser-test/src/main/resources/sql/unsupported/unsupported.xml
index 68719c5..a960d9b 100644
--- 
a/shardingsphere-sql-parser/shardingsphere-sql-parser-test/src/main/resources/sql/unsupported/unsupported.xml
+++ 
b/shardingsphere-sql-parser/shardingsphere-sql-parser-test/src/main/resources/sql/unsupported/unsupported.xml
@@ -29,6 +29,5 @@
     <!--<sql-case id="assertSelectWithModelIn" value="SELECT 
order_id_value,order_item_id_value FROM (select 1001 as order_id_value, 100001 
as order_item_id_value from dual) MODEL RETURN UPDATED ROWS DIMENSION 
BY(order_item_id_value) MEASURES(order_id_value) RULES(order_id_value[1] = 
10001)" db-types="Oracle" />-->
     <!--<sql-case id="assertInsertWithAll" value="INSERT ALL INTO TABLE_XXX 
(field1) VALUES (field1) SELECT field1 FROM TABLE_XXX2" db-types="Oracle" />-->
     <!--<sql-case id="assertInsertWithFirst" value="INSERT FIRST INTO 
TABLE_XXX (field1) VALUES (field1) SELECT field1 FROM TABLE_XXX2" 
db-types="Oracle" />-->
-    <!--<sql-case id="assertDeleteMultipleTable" value="DELETE TABLE_XXX1, 
TABLE_xxx2 FROM TABLE_XXX1 JOIN TABLE_XXX2" db-types="MySQL" />-->
-    <!--<sql-case id="assertDeleteMultipleTableWithUsing" value="DELETE FROM 
TABLE_XXX1, TABLE_xxx2 USING TABLE_XXX1 JOIN TABLE_XXX2" db-types="MySQL" />-->
+    <!--<sql-case id="assertDeleteTableAlias" value="DELETE ALIAS_XXX FROM 
TABLES_XXX AS ALIAS_XXX" db-types="MySQL,Oracle,SQLServer"/>-->
 </sql-cases>

Reply via email to