You are viewing a plain text version of this content. The canonical link for it is here.
Posted to notifications@shardingsphere.apache.org by wu...@apache.org on 2023/06/16 06:19:19 UTC

[shardingsphere] branch master updated: Enhance MySQL select statements (#26321) (#26373)

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

wuweijie 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 5d1ce6baa09 Enhance MySQL select statements (#26321) (#26373)
5d1ce6baa09 is described below

commit 5d1ce6baa0984fcbea6a8eb2eb7d9b9471f5daf4
Author: niu niu <zi...@aliyun.com>
AuthorDate: Fri Jun 16 14:19:12 2023 +0800

    Enhance MySQL select statements (#26321) (#26373)
---
 .../src/main/antlr4/imports/mysql/DMLStatement.g4  |  1 +
 .../visitor/statement/MySQLStatementVisitor.java   | 16 ++++++++++++-
 .../src/main/resources/case/dml/select-combine.xml | 27 ++++++++++++++++++++++
 .../resources/sql/supported/dml/select-combine.xml |  1 +
 4 files changed, 44 insertions(+), 1 deletion(-)

diff --git a/parser/sql/dialect/mysql/src/main/antlr4/imports/mysql/DMLStatement.g4 b/parser/sql/dialect/mysql/src/main/antlr4/imports/mysql/DMLStatement.g4
index 79e30ba6f2c..65013369dfa 100644
--- a/parser/sql/dialect/mysql/src/main/antlr4/imports/mysql/DMLStatement.g4
+++ b/parser/sql/dialect/mysql/src/main/antlr4/imports/mysql/DMLStatement.g4
@@ -144,6 +144,7 @@ queryExpressionBody
 
 combineClause
     : UNION combineOption? (queryPrimary | queryExpressionParens)
+    | EXCEPT combineOption? (queryPrimary | queryExpressionParens)
     ;
 
 queryExpressionParens
diff --git a/parser/sql/dialect/mysql/src/main/java/org/apache/shardingsphere/sql/parser/mysql/visitor/statement/MySQLStatementVisitor.java b/parser/sql/dialect/mysql/src/main/java/org/apache/shardingsphere/sql/parser/mysql/visitor/statement/MySQLStatementVisitor.java
index d83554aa708..73729c52b66 100644
--- a/parser/sql/dialect/mysql/src/main/java/org/apache/shardingsphere/sql/parser/mysql/visitor/statement/MySQLStatementVisitor.java
+++ b/parser/sql/dialect/mysql/src/main/java/org/apache/shardingsphere/sql/parser/mysql/visitor/statement/MySQLStatementVisitor.java
@@ -714,11 +714,25 @@ public abstract class MySQLStatementVisitor extends MySQLStatementBaseVisitor<AS
             result.setCombine(createCombineSegment(ctx.combineClause(), left));
             return result;
         }
+        if (null != ctx.queryExpressionParens()) {
+            MySQLSelectStatement result = new MySQLSelectStatement();
+            MySQLSelectStatement left = (MySQLSelectStatement) visit(ctx.queryExpressionParens());
+            result.setProjections(left.getProjections());
+            result.setFrom(left.getFrom());
+            left.getTable().ifPresent(result::setTable);
+            result.setCombine(createCombineSegment(ctx.combineClause(), left));
+            return result;
+        }
         return visit(ctx.queryExpressionParens());
     }
     
     private CombineSegment createCombineSegment(final CombineClauseContext ctx, final MySQLSelectStatement left) {
-        CombineType combineType = null != ctx.combineOption() && null != ctx.combineOption().ALL() ? CombineType.UNION_ALL : CombineType.UNION;
+        CombineType combineType;
+        if (null != ctx.EXCEPT()) {
+            combineType = CombineType.EXCEPT;
+        } else {
+            combineType = null != ctx.combineOption() && null != ctx.combineOption().ALL() ? CombineType.UNION_ALL : CombineType.UNION;
+        }
         MySQLSelectStatement right = null != ctx.queryPrimary() ? (MySQLSelectStatement) visit(ctx.queryPrimary()) : (MySQLSelectStatement) visit(ctx.queryExpressionParens());
         return new CombineSegment(ctx.getStart().getStartIndex(), ctx.getStop().getStopIndex(), left, combineType, right);
     }
diff --git a/test/it/parser/src/main/resources/case/dml/select-combine.xml b/test/it/parser/src/main/resources/case/dml/select-combine.xml
index 6407f143602..a4a4985b378 100644
--- a/test/it/parser/src/main/resources/case/dml/select-combine.xml
+++ b/test/it/parser/src/main/resources/case/dml/select-combine.xml
@@ -17,6 +17,33 @@
   -->
 
 <sql-parser-test-cases>
+    <select sql-case-id="select_with_except">
+        <projections start-index="8" stop-index="8">
+            <shorthand-projection start-index="8" stop-index="8" />
+        </projections>
+        <from>
+            <simple-table name="t1" start-index="15" stop-index="16" />
+        </from>
+        <combine combine-type="EXCEPT" start-index="19" stop-index="43">
+            <left>
+                <projections start-index="8" stop-index="8">
+                    <shorthand-projection start-index="8" stop-index="8" />
+                </projections>
+                <from>
+                    <simple-table name="t1" start-index="15" stop-index="16" />
+                </from>
+            </left>
+            <right>
+                <projections start-index="34" stop-index="34">
+                    <shorthand-projection start-index="34" stop-index="34" />
+                </projections>
+                <from>
+                    <simple-table name="t2" start-index="41" stop-index="42" />
+                </from>
+            </right>
+        </combine>
+    </select>
+
     <select sql-case-id="select_union">
         <projections start-index="7" stop-index="7">
             <shorthand-projection start-index="7" stop-index="7" />
diff --git a/test/it/parser/src/main/resources/sql/supported/dml/select-combine.xml b/test/it/parser/src/main/resources/sql/supported/dml/select-combine.xml
index 1b9b19f43f0..6e4786ffdba 100644
--- a/test/it/parser/src/main/resources/sql/supported/dml/select-combine.xml
+++ b/test/it/parser/src/main/resources/sql/supported/dml/select-combine.xml
@@ -17,6 +17,7 @@
   -->
 
 <sql-cases>
+    <sql-case id="select_with_except" value="(SELECT * FROM t1) EXCEPT (SELECT * FROM t2)" db-types="MySQL" />
     <sql-case id="select_union" value="SELECT * FROM table1 UNION SELECT * FROM table2" db-types="MySQL,PostgreSQL,openGauss" />
     <sql-case id="select_union_all" value="SELECT * FROM table1 UNION ALL SELECT * FROM table2" db-types="MySQL,PostgreSQL,openGauss" />
     <sql-case id="select_union_all_order_by" value="SELECT * FROM table1 UNION ALL SELECT * FROM table2 ORDER BY id" db-types="MySQL,PostgreSQL,openGauss" />