You are viewing a plain text version of this content. The canonical link for it is here.
Posted to notifications@shardingsphere.apache.org by du...@apache.org on 2022/11/22 08:49:37 UTC

[shardingsphere] branch master updated: Update Oracle SQL XMLSERIALIZE function parse (#22332)

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 d3b1a878503 Update Oracle SQL XMLSERIALIZE function parse (#22332)
d3b1a878503 is described below

commit d3b1a87850334c1333358a82b8de32f98d5fb5bc
Author: Zichao <57...@users.noreply.github.com>
AuthorDate: Tue Nov 22 21:49:27 2022 +1300

    Update Oracle SQL XMLSERIALIZE function parse (#22332)
    
    * Update Oracle SQL XMLSERIALIZE function parse
    
    * Update Oracle SQL XMLSERIALIZE function parse
    
    * Update Oracle SQL XMLSERIALIZE function parse
    
    * Update Oracle SQL XMLSERIALIZE function parse
---
 .../src/main/antlr4/imports/oracle/BaseRule.g4     |  5 +++
 .../src/main/antlr4/imports/oracle/Keyword.g4      | 20 +++++++++
 .../impl/OracleDMLStatementSQLVisitor.java         |  7 +++
 .../statement/impl/OracleStatementSQLVisitor.java  | 17 +++++++-
 .../dml/expr/XmlSerializeFunctionSegment.java      | 51 ++++++++++++++++++++++
 test/parser/src/main/resources/case/dml/select.xml |  9 ++++
 .../main/resources/sql/supported/dml/select.xml    |  1 +
 7 files changed, 109 insertions(+), 1 deletion(-)

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 b42b5dd1b2d..7c222d79596 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
@@ -1623,6 +1623,7 @@ xmlFunction
     | xmlPiFunction
     | xmlQueryFunction
     | xmlRootFunction
+    | xmlSerializeFunction
     ;
 
 xmlAggFunction
@@ -1660,3 +1661,7 @@ xmlPassingClause
 xmlRootFunction
     : XMLROOT LP_ expr COMMA_ VERSION (expr | NO VALUE) (COMMA_ STANDALONE (YES | NO | NO VALUE))? RP_
     ;
+
+xmlSerializeFunction
+    : XMLSERIALIZE LP_ (DOCUMENT | CONTENT) expr (AS dataType)? (ENCODING STRING_)? (VERSION stringLiterals)? (NO IDENT | IDENT (SIZE EQ_ INTEGER_)?)? ((HIDE | SHOW) DEFAULT)? RP_
+    ;
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 483a182f2d3..6a8bd228e15 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
@@ -731,3 +731,23 @@ XMLROOT
 STANDALONE
     : S T A N D A L O N E
     ;
+
+XMLSERIALIZE
+    : X M L S E R I A L I Z E
+    ;
+
+ENCODING
+    : E N C O D I N G
+    ;
+
+IDENT
+    : I D E N T
+    ;
+
+HIDE
+    : H I D E
+    ;
+
+SHOW
+    : S H O W
+    ;
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 2932d3df5c9..bef92b029b9 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
@@ -118,6 +118,7 @@ import org.apache.shardingsphere.sql.parser.sql.common.segment.dml.expr.Expressi
 import org.apache.shardingsphere.sql.parser.sql.common.segment.dml.expr.FunctionSegment;
 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.XmlSerializeFunctionSegment;
 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;
 import org.apache.shardingsphere.sql.parser.sql.common.segment.dml.expr.simple.LiteralExpressionSegment;
@@ -757,6 +758,12 @@ public final class OracleDMLStatementSQLVisitor extends OracleStatementSQLVisito
             return new XmlPiFunctionSegment(xmlPiFunctionSegment.getStartIndex(), xmlPiFunctionSegment.getStopIndex(), xmlPiFunctionSegment.getFunctionName(),
                     xmlPiFunctionSegment.getEvalNameValueExpr(), xmlPiFunctionSegment.getValueExpr(), xmlPiFunctionSegment.getText());
         }
+        if (projection instanceof XmlSerializeFunctionSegment) {
+            XmlSerializeFunctionSegment xmlSerializeFunctionSegment = (XmlSerializeFunctionSegment) projection;
+            return new XmlSerializeFunctionSegment(xmlSerializeFunctionSegment.getStartIndex(), xmlSerializeFunctionSegment.getStopIndex(), xmlSerializeFunctionSegment.getFunctionName(),
+                    xmlSerializeFunctionSegment.getParameter(), xmlSerializeFunctionSegment.getDataType(), xmlSerializeFunctionSegment.getEncoding(), xmlSerializeFunctionSegment.getVersion(),
+                    xmlSerializeFunctionSegment.getIdentSize(), xmlSerializeFunctionSegment.getText());
+        }
         LiteralExpressionSegment column = (LiteralExpressionSegment) projection;
         ExpressionProjectionSegment result = null == alias ? new ExpressionProjectionSegment(column.getStartIndex(), column.getStopIndex(), String.valueOf(column.getLiterals()), column)
                 : new ExpressionProjectionSegment(column.getStartIndex(), ctx.alias().stop.getStopIndex(), String.valueOf(column.getLiterals()), column);
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 dc778b0eaa0..19f41dd26f1 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
@@ -77,6 +77,7 @@ import org.apache.shardingsphere.sql.parser.autogen.OracleStatementParser.XmlPar
 import org.apache.shardingsphere.sql.parser.autogen.OracleStatementParser.XmlPiFunctionContext;
 import org.apache.shardingsphere.sql.parser.autogen.OracleStatementParser.XmlQueryFunctionContext;
 import org.apache.shardingsphere.sql.parser.autogen.OracleStatementParser.XmlRootFunctionContext;
+import org.apache.shardingsphere.sql.parser.autogen.OracleStatementParser.XmlSerializeFunctionContext;
 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;
@@ -98,6 +99,7 @@ import org.apache.shardingsphere.sql.parser.sql.common.segment.dml.expr.ListExpr
 import org.apache.shardingsphere.sql.parser.sql.common.segment.dml.expr.NotExpression;
 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.XmlSerializeFunctionSegment;
 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;
 import org.apache.shardingsphere.sql.parser.sql.common.segment.dml.expr.simple.ParameterMarkerExpressionSegment;
@@ -575,7 +577,10 @@ public abstract class OracleStatementSQLVisitor extends OracleStatementBaseVisit
         if (null != ctx.xmlQueryFunction()) {
             return visit(ctx.xmlQueryFunction());
         }
-        return visit(ctx.xmlRootFunction());
+        if (null != ctx.xmlRootFunction()) {
+            return visit(ctx.xmlRootFunction());
+        }
+        return visit(ctx.xmlSerializeFunction());
     }
     
     @Override
@@ -640,6 +645,16 @@ public abstract class OracleStatementSQLVisitor extends OracleStatementBaseVisit
         return result;
     }
     
+    @Override
+    public ASTNode visitXmlSerializeFunction(final XmlSerializeFunctionContext ctx) {
+        String dataType = null == ctx.dataType() ? null : ctx.dataType().getText();
+        String encoding = null == ctx.STRING_() ? null : ctx.STRING_().getText();
+        String version = null == ctx.stringLiterals() ? null : ctx.stringLiterals().getText();
+        String identSize = null == ctx.INTEGER_() ? null : ctx.INTEGER_().getText();
+        return new XmlSerializeFunctionSegment(ctx.start.getStartIndex(), ctx.stop.getStopIndex(), ctx.XMLSERIALIZE().getText(), (ExpressionSegment) visit(ctx.expr()),
+                dataType, encoding, version, identSize, getOriginalText(ctx));
+    }
+    
     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/XmlSerializeFunctionSegment.java b/sql-parser/statement/src/main/java/org/apache/shardingsphere/sql/parser/sql/common/segment/dml/expr/XmlSerializeFunctionSegment.java
new file mode 100644
index 00000000000..9e50b848038
--- /dev/null
+++ b/sql-parser/statement/src/main/java/org/apache/shardingsphere/sql/parser/sql/common/segment/dml/expr/XmlSerializeFunctionSegment.java
@@ -0,0 +1,51 @@
+/*
+ * 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.segment.dml.expr;
+
+import lombok.Getter;
+import lombok.RequiredArgsConstructor;
+import lombok.ToString;
+import org.apache.shardingsphere.sql.parser.sql.common.segment.dml.expr.complex.ComplexExpressionSegment;
+import org.apache.shardingsphere.sql.parser.sql.common.segment.dml.item.ProjectionSegment;
+
+/**
+ * Xml serialize function segment.
+ */
+@RequiredArgsConstructor
+@Getter
+@ToString
+public final class XmlSerializeFunctionSegment implements ComplexExpressionSegment, ProjectionSegment {
+    
+    private final int startIndex;
+    
+    private final int stopIndex;
+    
+    private final String functionName;
+    
+    private final ExpressionSegment parameter;
+    
+    private final String dataType;
+    
+    private final String encoding;
+    
+    private final String version;
+    
+    private final String identSize;
+    
+    private final String text;
+}
diff --git a/test/parser/src/main/resources/case/dml/select.xml b/test/parser/src/main/resources/case/dml/select.xml
index a8e89f3e0ef..8ca0bc89015 100644
--- a/test/parser/src/main/resources/case/dml/select.xml
+++ b/test/parser/src/main/resources/case/dml/select.xml
@@ -4769,4 +4769,13 @@
             <simple-table name="DUAL" start-index="83" stop-index="86" />
         </from>
     </select>
+
+    <select sql-case-id="select_xmlserialize_function">
+        <projections start-index="7" stop-index="96">
+            <expression-projection text="XMLSERIALIZE(DOCUMENT c2 AS BLOB ENCODING 'UTF-8' VERSION 'a' IDENT SIZE = 0 SHOW DEFAULT)" start-index="7" stop-index="96" />
+        </projections>
+        <from>
+            <simple-table name="b" start-index="103" stop-index="103" />
+        </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 e9ff9369438..973c59fe0c2 100644
--- a/test/parser/src/main/resources/sql/supported/dml/select.xml
+++ b/test/parser/src/main/resources/sql/supported/dml/select.xml
@@ -153,4 +153,5 @@
     <sql-case id="select_xmlpi_function" value="SELECT XMLPI(NAME &quot;Order analysisComp&quot;, '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-case id="select_xmlroot_function" value="SELECT XMLROOT(XMLType('143598'), VERSION '1.0', STANDALONE YES) AS 'XMLROOT' FROM DUAL;" db-types="Oracle" />
+    <sql-case id="select_xmlserialize_function" value="SELECT XMLSERIALIZE(DOCUMENT c2 AS BLOB ENCODING 'UTF-8' VERSION 'a' IDENT SIZE = 0 SHOW DEFAULT) FROM b;" db-types="Oracle" />
 </sql-cases>