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 '"'" 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 '"', 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>