This is an automated email from the ASF dual-hosted git repository.
duanzhengqiang 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 1401f1e207d Fix oracle select union sql parse (#29001)
1401f1e207d is described below
commit 1401f1e207db4d169180b969ac679dcc4f1247fb
Author: niu niu <[email protected]>
AuthorDate: Sat Nov 11 08:26:57 2023 +0800
Fix oracle select union sql parse (#29001)
* Fix oracle select union sql parse
* Format code
* Remove combineClause loop visit
---
.../src/main/antlr4/imports/oracle/DMLStatement.g4 | 2 +-
.../statement/type/OracleDMLStatementVisitor.java | 30 +++--
.../src/main/resources/case/dml/select-combine.xml | 125 +++++++++++++++++++++
.../resources/sql/supported/dml/select-combine.xml | 3 +
4 files changed, 151 insertions(+), 9 deletions(-)
diff --git
a/parser/sql/dialect/oracle/src/main/antlr4/imports/oracle/DMLStatement.g4
b/parser/sql/dialect/oracle/src/main/antlr4/imports/oracle/DMLStatement.g4
index c511e5458f6..de4f968a4ed 100644
--- a/parser/sql/dialect/oracle/src/main/antlr4/imports/oracle/DMLStatement.g4
+++ b/parser/sql/dialect/oracle/src/main/antlr4/imports/oracle/DMLStatement.g4
@@ -136,7 +136,7 @@ select
;
selectSubquery
- : (queryBlock | selectCombineClause | parenthesisSelectSubquery)
pivotClause? orderByClause? rowLimitingClause
+ : (selectCombineClause | queryBlock | parenthesisSelectSubquery)
pivotClause? orderByClause? rowLimitingClause
;
selectCombineClause
diff --git
a/parser/sql/dialect/oracle/src/main/java/org/apache/shardingsphere/sql/parser/oracle/visitor/statement/type/OracleDMLStatementVisitor.java
b/parser/sql/dialect/oracle/src/main/java/org/apache/shardingsphere/sql/parser/oracle/visitor/statement/type/OracleDMLStatementVisitor.java
index 18a08899175..00d19ef9aff 100644
---
a/parser/sql/dialect/oracle/src/main/java/org/apache/shardingsphere/sql/parser/oracle/visitor/statement/type/OracleDMLStatementVisitor.java
+++
b/parser/sql/dialect/oracle/src/main/java/org/apache/shardingsphere/sql/parser/oracle/visitor/statement/type/OracleDMLStatementVisitor.java
@@ -108,6 +108,7 @@ import
org.apache.shardingsphere.sql.parser.autogen.OracleStatementParser.UsingC
import
org.apache.shardingsphere.sql.parser.autogen.OracleStatementParser.WhereClauseContext;
import
org.apache.shardingsphere.sql.parser.autogen.OracleStatementParser.WithClauseContext;
import
org.apache.shardingsphere.sql.parser.oracle.visitor.statement.OracleStatementVisitor;
+import org.apache.shardingsphere.sql.parser.sql.common.enums.CombineType;
import org.apache.shardingsphere.sql.parser.sql.common.enums.JoinType;
import org.apache.shardingsphere.sql.parser.sql.common.enums.OrderDirection;
import
org.apache.shardingsphere.sql.parser.sql.common.segment.dal.VariableSegment;
@@ -117,6 +118,7 @@ import
org.apache.shardingsphere.sql.parser.sql.common.segment.dml.assignment.In
import
org.apache.shardingsphere.sql.parser.sql.common.segment.dml.assignment.SetAssignmentSegment;
import
org.apache.shardingsphere.sql.parser.sql.common.segment.dml.column.ColumnSegment;
import
org.apache.shardingsphere.sql.parser.sql.common.segment.dml.column.InsertColumnsSegment;
+import
org.apache.shardingsphere.sql.parser.sql.common.segment.dml.combine.CombineSegment;
import
org.apache.shardingsphere.sql.parser.sql.common.segment.dml.expr.BetweenExpression;
import
org.apache.shardingsphere.sql.parser.sql.common.segment.dml.expr.BinaryOperationExpression;
import
org.apache.shardingsphere.sql.parser.sql.common.segment.dml.expr.CaseWhenExpression;
@@ -649,18 +651,16 @@ public final class OracleDMLStatementVisitor extends
OracleStatementVisitor impl
@Override
public ASTNode visitSelectCombineClause(final SelectCombineClauseContext
ctx) {
- OracleSelectStatement result;
- if (null != ctx.queryBlock()) {
- result = (OracleSelectStatement) visit(ctx.queryBlock());
- } else {
- result = (OracleSelectStatement)
visit(ctx.parenthesisSelectSubquery());
+ OracleSelectStatement result = new OracleSelectStatement();
+ OracleSelectStatement left = null != ctx.queryBlock() ?
(OracleSelectStatement) visit(ctx.queryBlock()) : (OracleSelectStatement)
visit(ctx.parenthesisSelectSubquery());
+ if (null != ctx.selectSubquery()) {
+ result.setProjections(left.getProjections());
+ result.setFrom(left.getFrom());
+ setSelectCombineClause(ctx, result, left);
}
if (null != ctx.orderByClause()) {
result.setOrderBy((OrderBySegment) visit(ctx.orderByClause()));
}
- for (SelectSubqueryContext each : ctx.selectSubquery()) {
- visit(each);
- }
return result;
}
@@ -669,6 +669,20 @@ public final class OracleDMLStatementVisitor extends
OracleStatementVisitor impl
return visit(ctx.selectSubquery());
}
+ private void setSelectCombineClause(final SelectCombineClauseContext ctx,
final OracleSelectStatement result, final OracleSelectStatement left) {
+ CombineType combineType;
+ if (null != ctx.UNION(0) && null != ctx.ALL(0)) {
+ combineType = CombineType.UNION_ALL;
+ } else if (null != ctx.UNION(0)) {
+ combineType = CombineType.UNION;
+ } else if (null != ctx.INTERSECT(0)) {
+ combineType = CombineType.INTERSECT;
+ } else {
+ combineType = CombineType.MINUS;
+ }
+ result.setCombine(new CombineSegment(ctx.getStart().getStartIndex(),
ctx.getStop().getStopIndex(), left, combineType, (OracleSelectStatement)
visit(ctx.selectSubquery(0))));
+ }
+
@Override
public ASTNode visitWithClause(final WithClauseContext ctx) {
Collection<CommonTableExpressionSegment> commonTableExpressions = new
LinkedList<>();
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 a4a4985b378..22db627e62c 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
@@ -893,4 +893,129 @@
</right>
</combine>
</select>
+
+ <select sql-case-id="select_union_all_where">
+ <projections start-index="7" stop-index="7">
+ <shorthand-projection start-index="7" stop-index="7" />
+ </projections>
+ <from>
+ <simple-table name="TEST_TABLE_1" start-index="14" stop-index="25"
/>
+ </from>
+ <combine combine-type="UNION_ALL" start-index="0" stop-index="88">
+ <left>
+ <projections start-index="7" stop-index="7">
+ <shorthand-projection start-index="7" stop-index="7" />
+ </projections>
+ <from>
+ <simple-table name="TEST_TABLE_1" start-index="14"
stop-index="25" />
+ </from>
+ <where start-index="27" stop-index="38">
+ <expr>
+ <binary-operation-expression start-index="33"
stop-index="38">
+ <left>
+ <column name="ID" start-index="33"
stop-index="34" />
+ </left>
+ <right>
+ <literal-expression value="1" start-index="38"
stop-index="38" />
+ </right>
+ <operator>=</operator>
+ </binary-operation-expression>
+ </expr>
+ </where>
+ </left>
+ <right>
+ <projections start-index="57" stop-index="57">
+ <shorthand-projection start-index="57" stop-index="57" />
+ </projections>
+ <from>
+ <simple-table name="TEST_TABLE_2" start-index="64"
stop-index="75" />
+ </from>
+ <where start-index="77" stop-index="88">
+ <expr>
+ <binary-operation-expression start-index="83"
stop-index="88">
+ <left>
+ <column name="ID" start-index="83"
stop-index="84" />
+ </left>
+ <right>
+ <literal-expression value="2" start-index="88"
stop-index="88" />
+ </right>
+ <operator>=</operator>
+ </binary-operation-expression>
+ </expr>
+ </where>
+ </right>
+ </combine>
+ </select>
+
+ <select sql-case-id="select_union_all_minus">
+ <projections start-index="7" stop-index="7">
+ <shorthand-projection start-index="7" stop-index="7" />
+ </projections>
+ <from>
+ <simple-table name="TEST_TABLE_1" start-index="14" stop-index="25"
/>
+ </from>
+ <combine combine-type="UNION_ALL" start-index="0" stop-index="95">
+ <left>
+ <projections start-index="7" stop-index="7">
+ <shorthand-projection start-index="7" stop-index="7" />
+ </projections>
+ <from>
+ <simple-table name="TEST_TABLE_1" start-index="14"
stop-index="25" />
+ </from>
+ </left>
+ <right>
+ <projections start-index="44" stop-index="44">
+ <shorthand-projection start-index="44" stop-index="44" />
+ </projections>
+ <from>
+ <simple-table name="TEST_TABLE_2" start-index="51"
stop-index="62" />
+ </from>
+ <combine combine-type="MINUS" start-index="37" stop-index="95">
+ <left>
+ <projections start-index="44" stop-index="44">
+ <shorthand-projection start-index="44"
stop-index="44" />
+ </projections>
+ <from>
+ <simple-table name="TEST_TABLE_2" start-index="51"
stop-index="62" />
+ </from>
+ </left>
+ <right>
+ <projections start-index="77" stop-index="77">
+ <shorthand-projection start-index="77"
stop-index="77" />
+ </projections>
+ <from>
+ <simple-table name="TEST_TABLE_3" start-index="84"
stop-index="95" />
+ </from>
+ </right>
+ </combine>
+ </right>
+ </combine>
+ </select>
+
+ <select sql-case-id="select_union_subquery">
+ <projections start-index="8" stop-index="14">
+ <column-projection name="TEST_ID" start-index="8" stop-index="14"
/>
+ </projections>
+ <from>
+ <simple-table name="TEST_TABLE" start-index="22" stop-index="31" />
+ </from>
+ <combine combine-type="UNION" start-index="0" stop-index="71">
+ <left>
+ <projections start-index="8" stop-index="14">
+ <column-projection name="TEST_ID" start-index="8"
stop-index="14" />
+ </projections>
+ <from>
+ <simple-table name="TEST_TABLE" start-index="22"
stop-index="31" />
+ </from>
+ </left>
+ <right>
+ <projections start-index="48" stop-index="54">
+ <column-projection name="TEST_ID" start-index="48"
stop-index="54" />
+ </projections>
+ <from>
+ <simple-table name="TEST_TABLE" start-index="61"
stop-index="70" />
+ </from>
+ </right>
+ </combine>
+ </select>
</sql-parser-test-cases>
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 6e4786ffdba..2b55b07faa5 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
@@ -38,4 +38,7 @@
<sql-case id="select_except_intersect" value="SELECT * FROM table1 EXCEPT
SELECT * FROM table2 INTERSECT SELECT * FROM table3"
db-types="PostgreSQL,openGauss" />
<sql-case id="select_except_intersect_union" value="SELECT * FROM table1
EXCEPT SELECT * FROM table2 INTERSECT SELECT * FROM table3 UNION SELECT * FROM
table4" db-types="PostgreSQL,openGauss" />
<sql-case id="select_sub_union" value="SELECT * FROM table1 UNION (SELECT
* FROM table2 UNION SELECT * FROM table3)"
db-types="MySQL,PostgreSQL,openGauss" />
+ <sql-case id="select_union_all_where" value="SELECT * FROM TEST_TABLE_1
WHERE ID = 1 UNION ALL SELECT * FROM TEST_TABLE_2 WHERE ID = 2"
db-types="Oracle" />
+ <sql-case id="select_union_all_minus" value="SELECT * FROM TEST_TABLE_1
UNION ALL SELECT * FROM TEST_TABLE_2 MINUS SELECT * FROM TEST_TABLE_3"
db-types="Oracle" />
+ <sql-case id="select_union_subquery" value="(SELECT TEST_ID FROM
TEST_TABLE) UNION (SELECT TEST_ID FROM TEST_TABLE)" db-types="Oracle" />
</sql-cases>