You are viewing a plain text version of this content. The canonical link for it is here.
Posted to notifications@shardingsphere.apache.org by ji...@apache.org on 2022/11/21 14:03:23 UTC
[shardingsphere] branch master updated: Update Oracle SQL XMLQUERY function parse (#22319)
This is an automated email from the ASF dual-hosted git repository.
jianglongtao 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 947c8c484b6 Update Oracle SQL XMLQUERY function parse (#22319)
947c8c484b6 is described below
commit 947c8c484b6eb6227891bc0500a52ce39f211584
Author: Zichao <57...@users.noreply.github.com>
AuthorDate: Tue Nov 22 03:03:06 2022 +1300
Update Oracle SQL XMLQUERY function parse (#22319)
---
.../src/main/antlr4/imports/oracle/BaseRule.g4 | 11 ++++++++++-
.../src/main/antlr4/imports/oracle/Keyword.g4 | 4 ++++
.../impl/OracleDMLStatementSQLVisitor.java | 8 ++++----
.../statement/impl/OracleStatementSQLVisitor.java | 23 +++++++++++++++++-----
....java => XmlQueryAndExistsFunctionSegment.java} | 4 ++--
test/parser/src/main/resources/case/dml/select.xml | 9 +++++++++
.../main/resources/sql/supported/dml/select.xml | 1 +
7 files changed, 48 insertions(+), 12 deletions(-)
diff --git a/sql-parser/dialect/oracle/src/main/antlr4/imports/oracle/BaseRule.g4 b/sql-parser/dialect/oracle/src/main/antlr4/imports/oracle/BaseRule.g4
index 56ec843dcc8..8231e3bfcae 100644
--- a/sql-parser/dialect/oracle/src/main/antlr4/imports/oracle/BaseRule.g4
+++ b/sql-parser/dialect/oracle/src/main/antlr4/imports/oracle/BaseRule.g4
@@ -1621,6 +1621,7 @@ xmlFunction
| xmlForestFunction
| xmlParseFunction
| xmlPiFunction
+ | xmlQueryFunction
;
xmlAggFunction
@@ -1632,7 +1633,7 @@ xmlColattvalFunction
;
xmlExistsFunction
- : XMLEXISTS LP_ STRING_ (PASSING (BY VALUE)? expr (AS alias)? (COMMA_ expr (AS alias)?)*)? RP_
+ : XMLEXISTS LP_ STRING_ xmlPassingClause? RP_
;
xmlForestFunction
@@ -1646,3 +1647,11 @@ xmlParseFunction
xmlPiFunction
: XMLPI LP_ (EVALNAME expr | (NAME)? identifier) (COMMA_ expr)? RP_
;
+
+xmlQueryFunction
+ : XMLQUERY LP_ STRING_ xmlPassingClause? RETURNING CONTENT (NULL ON EMPTY)? RP_
+ ;
+
+xmlPassingClause
+ : PASSING (BY VALUE)? expr (AS alias)? (COMMA_ expr (AS alias)?)*
+ ;
diff --git a/sql-parser/dialect/oracle/src/main/antlr4/imports/oracle/Keyword.g4 b/sql-parser/dialect/oracle/src/main/antlr4/imports/oracle/Keyword.g4
index 4d7bec212f0..67e019be8a9 100644
--- a/sql-parser/dialect/oracle/src/main/antlr4/imports/oracle/Keyword.g4
+++ b/sql-parser/dialect/oracle/src/main/antlr4/imports/oracle/Keyword.g4
@@ -719,3 +719,7 @@ WELLFORMED
XMLPI
: X M L P I
;
+
+XMLQUERY
+ : X M L Q U E R Y
+ ;
diff --git a/sql-parser/dialect/oracle/src/main/java/org/apache/shardingsphere/sql/parser/oracle/visitor/statement/impl/OracleDMLStatementSQLVisitor.java b/sql-parser/dialect/oracle/src/main/java/org/apache/shardingsphere/sql/parser/oracle/visitor/statement/impl/OracleDMLStatementSQLVisitor.java
index 980f6c8f943..2932d3df5c9 100644
--- a/sql-parser/dialect/oracle/src/main/java/org/apache/shardingsphere/sql/parser/oracle/visitor/statement/impl/OracleDMLStatementSQLVisitor.java
+++ b/sql-parser/dialect/oracle/src/main/java/org/apache/shardingsphere/sql/parser/oracle/visitor/statement/impl/OracleDMLStatementSQLVisitor.java
@@ -116,7 +116,7 @@ import org.apache.shardingsphere.sql.parser.sql.common.segment.dml.expr.BinaryOp
import org.apache.shardingsphere.sql.parser.sql.common.segment.dml.expr.DatetimeExpression;
import org.apache.shardingsphere.sql.parser.sql.common.segment.dml.expr.ExpressionSegment;
import org.apache.shardingsphere.sql.parser.sql.common.segment.dml.expr.FunctionSegment;
-import org.apache.shardingsphere.sql.parser.sql.common.segment.dml.expr.XmlExistsFunctionSegment;
+import org.apache.shardingsphere.sql.parser.sql.common.segment.dml.expr.XmlQueryAndExistsFunctionSegment;
import org.apache.shardingsphere.sql.parser.sql.common.segment.dml.expr.XmlPiFunctionSegment;
import org.apache.shardingsphere.sql.parser.sql.common.segment.dml.expr.complex.CommonExpressionSegment;
import org.apache.shardingsphere.sql.parser.sql.common.segment.dml.expr.complex.CommonTableExpressionSegment;
@@ -743,9 +743,9 @@ public final class OracleDMLStatementSQLVisitor extends OracleStatementSQLVisito
}
return new DatetimeProjectionSegment(datetimeExpression.getStartIndex(), datetimeExpression.getStopIndex(), datetimeExpression.getLeft(), datetimeExpression.getText());
}
- if (projection instanceof XmlExistsFunctionSegment) {
- XmlExistsFunctionSegment xmlExistsFunctionSegment = (XmlExistsFunctionSegment) projection;
- return new XmlExistsFunctionSegment(xmlExistsFunctionSegment.getStartIndex(), xmlExistsFunctionSegment.getStopIndex(),
+ if (projection instanceof XmlQueryAndExistsFunctionSegment) {
+ XmlQueryAndExistsFunctionSegment xmlExistsFunctionSegment = (XmlQueryAndExistsFunctionSegment) projection;
+ return new XmlQueryAndExistsFunctionSegment(xmlExistsFunctionSegment.getStartIndex(), xmlExistsFunctionSegment.getStopIndex(),
xmlExistsFunctionSegment.getFunctionName(), xmlExistsFunctionSegment.getXQueryString(), xmlExistsFunctionSegment.getText());
}
if (projection instanceof XmlPiFunctionSegment) {
diff --git a/sql-parser/dialect/oracle/src/main/java/org/apache/shardingsphere/sql/parser/oracle/visitor/statement/impl/OracleStatementSQLVisitor.java b/sql-parser/dialect/oracle/src/main/java/org/apache/shardingsphere/sql/parser/oracle/visitor/statement/impl/OracleStatementSQLVisitor.java
index 735467f7d88..f19b4b76839 100644
--- a/sql-parser/dialect/oracle/src/main/java/org/apache/shardingsphere/sql/parser/oracle/visitor/statement/impl/OracleStatementSQLVisitor.java
+++ b/sql-parser/dialect/oracle/src/main/java/org/apache/shardingsphere/sql/parser/oracle/visitor/statement/impl/OracleStatementSQLVisitor.java
@@ -75,6 +75,7 @@ import org.apache.shardingsphere.sql.parser.autogen.OracleStatementParser.XmlExi
import org.apache.shardingsphere.sql.parser.autogen.OracleStatementParser.XmlForestFunctionContext;
import org.apache.shardingsphere.sql.parser.autogen.OracleStatementParser.XmlParseFunctionContext;
import org.apache.shardingsphere.sql.parser.autogen.OracleStatementParser.XmlPiFunctionContext;
+import org.apache.shardingsphere.sql.parser.autogen.OracleStatementParser.XmlQueryFunctionContext;
import org.apache.shardingsphere.sql.parser.sql.common.enums.AggregationType;
import org.apache.shardingsphere.sql.parser.sql.common.enums.NullsOrderType;
import org.apache.shardingsphere.sql.parser.sql.common.enums.OrderDirection;
@@ -94,7 +95,7 @@ import org.apache.shardingsphere.sql.parser.sql.common.segment.dml.expr.Function
import org.apache.shardingsphere.sql.parser.sql.common.segment.dml.expr.InExpression;
import org.apache.shardingsphere.sql.parser.sql.common.segment.dml.expr.ListExpression;
import org.apache.shardingsphere.sql.parser.sql.common.segment.dml.expr.NotExpression;
-import org.apache.shardingsphere.sql.parser.sql.common.segment.dml.expr.XmlExistsFunctionSegment;
+import org.apache.shardingsphere.sql.parser.sql.common.segment.dml.expr.XmlQueryAndExistsFunctionSegment;
import org.apache.shardingsphere.sql.parser.sql.common.segment.dml.expr.XmlPiFunctionSegment;
import org.apache.shardingsphere.sql.parser.sql.common.segment.dml.expr.complex.CommonExpressionSegment;
import org.apache.shardingsphere.sql.parser.sql.common.segment.dml.expr.simple.LiteralExpressionSegment;
@@ -567,7 +568,10 @@ public abstract class OracleStatementSQLVisitor extends OracleStatementBaseVisit
if (null != ctx.xmlParseFunction()) {
return visit(ctx.xmlParseFunction());
}
- return visit(ctx.xmlPiFunction());
+ if (null != ctx.xmlPiFunction()) {
+ return visit(ctx.xmlPiFunction());
+ }
+ return visit(ctx.xmlQueryFunction());
}
@Override
@@ -585,9 +589,9 @@ public abstract class OracleStatementSQLVisitor extends OracleStatementBaseVisit
@Override
public ASTNode visitXmlExistsFunction(final XmlExistsFunctionContext ctx) {
- XmlExistsFunctionSegment result =
- new XmlExistsFunctionSegment(ctx.start.getStartIndex(), ctx.stop.getStopIndex(), ctx.XMLEXISTS().getText(), ctx.STRING_().getText(), getOriginalText(ctx));
- Collection<ExpressionSegment> expressionSegments = ctx.expr().stream().map(each -> (ExpressionSegment) visit(each)).collect(Collectors.toList());
+ XmlQueryAndExistsFunctionSegment result =
+ new XmlQueryAndExistsFunctionSegment(ctx.start.getStartIndex(), ctx.stop.getStopIndex(), ctx.XMLEXISTS().getText(), ctx.STRING_().getText(), getOriginalText(ctx));
+ Collection<ExpressionSegment> expressionSegments = ctx.xmlPassingClause().expr().stream().map(each -> (ExpressionSegment) visit(each)).collect(Collectors.toList());
result.getParameters().addAll(expressionSegments);
return result;
}
@@ -615,6 +619,15 @@ public abstract class OracleStatementSQLVisitor extends OracleStatementBaseVisit
(ExpressionSegment) visit(ctx.expr(0)), (ExpressionSegment) visit(ctx.expr(1)), getOriginalText(ctx));
}
+ @Override
+ public ASTNode visitXmlQueryFunction(final XmlQueryFunctionContext ctx) {
+ XmlQueryAndExistsFunctionSegment result =
+ new XmlQueryAndExistsFunctionSegment(ctx.start.getStartIndex(), ctx.stop.getStopIndex(), ctx.XMLQUERY().getText(), ctx.STRING_().getText(), getOriginalText(ctx));
+ Collection<ExpressionSegment> expressionSegments = ctx.xmlPassingClause().expr().stream().map(each -> (ExpressionSegment) visit(each)).collect(Collectors.toList());
+ result.getParameters().addAll(expressionSegments);
+ return result;
+ }
+
private Collection<ExpressionSegment> getExpressions(final AggregationFunctionContext ctx) {
return null == ctx.expr() ? Collections.emptyList() : ctx.expr().stream().map(each -> (ExpressionSegment) visit(each)).collect(Collectors.toList());
}
diff --git a/sql-parser/statement/src/main/java/org/apache/shardingsphere/sql/parser/sql/common/segment/dml/expr/XmlExistsFunctionSegment.java b/sql-parser/statement/src/main/java/org/apache/shardingsphere/sql/parser/sql/common/segment/dml/expr/XmlQueryAndExistsFunctionSegment.java
similarity index 91%
rename from sql-parser/statement/src/main/java/org/apache/shardingsphere/sql/parser/sql/common/segment/dml/expr/XmlExistsFunctionSegment.java
rename to sql-parser/statement/src/main/java/org/apache/shardingsphere/sql/parser/sql/common/segment/dml/expr/XmlQueryAndExistsFunctionSegment.java
index db2afa4ed86..8aa168ab30b 100644
--- a/sql-parser/statement/src/main/java/org/apache/shardingsphere/sql/parser/sql/common/segment/dml/expr/XmlExistsFunctionSegment.java
+++ b/sql-parser/statement/src/main/java/org/apache/shardingsphere/sql/parser/sql/common/segment/dml/expr/XmlQueryAndExistsFunctionSegment.java
@@ -27,12 +27,12 @@ import java.util.Collection;
import java.util.LinkedList;
/**
- * Xml Exists Function segment.
+ * Xml Query and Exists Function segment.
*/
@RequiredArgsConstructor
@Getter
@ToString
-public final class XmlExistsFunctionSegment implements ComplexExpressionSegment, ProjectionSegment {
+public final class XmlQueryAndExistsFunctionSegment implements ComplexExpressionSegment, ProjectionSegment {
private final int startIndex;
diff --git a/test/parser/src/main/resources/case/dml/select.xml b/test/parser/src/main/resources/case/dml/select.xml
index 55579545a4d..866b9ff3c10 100644
--- a/test/parser/src/main/resources/case/dml/select.xml
+++ b/test/parser/src/main/resources/case/dml/select.xml
@@ -4751,4 +4751,13 @@
<simple-table name="DUAL" start-index="96" stop-index="99" />
</from>
</select>
+
+ <select sql-case-id="select_xmlquery_function">
+ <projections start-index="7" stop-index="95">
+ <expression-projection text="XMLQUERY('//student[@age=20]' PASSING BY VALUE xcol AS x RETURNING CONTENT NULL ON EMPTY)" start-index="7" stop-index="95" />
+ </projections>
+ <from>
+ <simple-table name="x_table" start-index="102" stop-index="108" />
+ </from>
+ </select>
</sql-parser-test-cases>
diff --git a/test/parser/src/main/resources/sql/supported/dml/select.xml b/test/parser/src/main/resources/sql/supported/dml/select.xml
index cb616a51153..4eb82922b8f 100644
--- a/test/parser/src/main/resources/sql/supported/dml/select.xml
+++ b/test/parser/src/main/resources/sql/supported/dml/select.xml
@@ -151,4 +151,5 @@
<sql-case id="select_xmlforest_function" value="SELECT XMLFOREST(e.employee_id AS EVALNAME 'ID', e.last_name AS name, e.salary) FROM employees e WHERE employee_id = 204;" db-types="Oracle" />
<sql-case id="select_xmlparse_function" value="SELECT XMLPARSE(DOCUMENT 'DEPTXML' WELLFORMED) AS dept FROM DUAL;" db-types="Oracle" />
<sql-case id="select_xmlpi_function" value="SELECT XMLPI(NAME "Order analysisComp", 'imported, reconfigured, disassembled') AS 'XMLPI' FROM DUAL;" db-types="Oracle" />
+ <sql-case id="select_xmlquery_function" value="SELECT XMLQUERY('//student[@age=20]' PASSING BY VALUE xcol AS x RETURNING CONTENT NULL ON EMPTY) FROM x_table;" db-types="Oracle" />
</sql-cases>