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 043bd299fc0 [Oracle SQL] Support OE-5-214 for Oracle SQL (#27899)
043bd299fc0 is described below
commit 043bd299fc0c919550322529b44f36399a76afaa
Author: Liao Lanyu <[email protected]>
AuthorDate: Fri Aug 4 11:23:05 2023 +0800
[Oracle SQL] Support OE-5-214 for Oracle SQL (#27899)
* support select from collection table
* test
---
.../statement/type/OracleDMLStatementVisitor.java | 25 ++++++--
.../generic/table/CollectionTableSegment.java | 66 ++++++++++++++++++++++
.../asserts/segment/table/TableAssert.java | 17 ++++++
...ctedTable.java => ExpectedCollectionTable.java} | 21 +++----
.../jaxb/segment/impl/table/ExpectedTable.java | 3 +
.../parser/src/main/resources/case/dml/select.xml | 19 +++++++
.../main/resources/sql/supported/dml/select.xml | 1 +
7 files changed, 134 insertions(+), 18 deletions(-)
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 2f1feee1763..b052a7706d6 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
@@ -150,6 +150,7 @@ import
org.apache.shardingsphere.sql.parser.sql.common.segment.generic.InsertMul
import
org.apache.shardingsphere.sql.parser.sql.common.segment.generic.ModelSegment;
import
org.apache.shardingsphere.sql.parser.sql.common.segment.generic.OwnerSegment;
import
org.apache.shardingsphere.sql.parser.sql.common.segment.generic.WithSegment;
+import
org.apache.shardingsphere.sql.parser.sql.common.segment.generic.table.CollectionTableSegment;
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;
@@ -413,8 +414,20 @@ public final class OracleDMLStatementVisitor extends
OracleStatementVisitor impl
@Override
public ASTNode visitTableCollectionExpr(final TableCollectionExprContext
ctx) {
- OracleSelectStatement subquery = (OracleSelectStatement)
visit(ctx.collectionExpr().selectSubquery());
- return new
SubquerySegment(ctx.collectionExpr().selectSubquery().start.getStartIndex(),
ctx.collectionExpr().selectSubquery().stop.getStopIndex(), subquery);
+ if (null != ctx.collectionExpr().selectSubquery()) {
+ OracleSelectStatement subquery = (OracleSelectStatement)
visit(ctx.collectionExpr().selectSubquery());
+ return new
SubquerySegment(ctx.collectionExpr().selectSubquery().start.getStartIndex(),
ctx.collectionExpr().selectSubquery().stop.getStopIndex(), subquery);
+ }
+ if (null != ctx.collectionExpr().functionCall()) {
+ return visit(ctx.collectionExpr().functionCall());
+ }
+ if (null != ctx.collectionExpr().columnName()) {
+ return visit(ctx.collectionExpr().columnName());
+ }
+ if (null != ctx.collectionExpr().expr()) {
+ return visit(ctx.collectionExpr().expr());
+ }
+ throw new UnsupportedOperationException("Unhandled table collection
expr");
}
@Override
@@ -986,8 +999,12 @@ public final class OracleDMLStatementVisitor extends
OracleStatementVisitor impl
SubquerySegment subquerySegment = new
SubquerySegment(ctx.lateralClause().selectSubquery().start.getStartIndex(),
ctx.lateralClause().selectSubquery().stop.getStopIndex(), subquery);
result = new SubqueryTableSegment(subquerySegment);
} else {
- SubquerySegment subquerySegment = (SubquerySegment)
visit(ctx.tableCollectionExpr());
- result = new SubqueryTableSegment(subquerySegment);
+ if (null !=
ctx.tableCollectionExpr().collectionExpr().selectSubquery()) {
+ SubquerySegment subquerySegment = (SubquerySegment)
visit(ctx.tableCollectionExpr());
+ result = new SubqueryTableSegment(subquerySegment);
+ } else {
+ result = new CollectionTableSegment((ExpressionSegment)
visit(ctx.tableCollectionExpr()));
+ }
}
return result;
}
diff --git
a/parser/sql/statement/src/main/java/org/apache/shardingsphere/sql/parser/sql/common/segment/generic/table/CollectionTableSegment.java
b/parser/sql/statement/src/main/java/org/apache/shardingsphere/sql/parser/sql/common/segment/generic/table/CollectionTableSegment.java
new file mode 100644
index 00000000000..88da1cfbc84
--- /dev/null
+++
b/parser/sql/statement/src/main/java/org/apache/shardingsphere/sql/parser/sql/common/segment/generic/table/CollectionTableSegment.java
@@ -0,0 +1,66 @@
+/*
+ * 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.generic.table;
+
+import lombok.Getter;
+import lombok.RequiredArgsConstructor;
+import lombok.Setter;
+import
org.apache.shardingsphere.sql.parser.sql.common.segment.dml.expr.ExpressionSegment;
+import
org.apache.shardingsphere.sql.parser.sql.common.segment.generic.AliasSegment;
+import
org.apache.shardingsphere.sql.parser.sql.common.value.identifier.IdentifierValue;
+
+import java.util.Optional;
+
+@RequiredArgsConstructor
+@Getter
+public final class CollectionTableSegment implements TableSegment {
+
+ private final ExpressionSegment expressionSegment;
+
+ @Setter
+ private AliasSegment alias;
+
+ @Override
+ public Optional<String> getAliasName() {
+ return null == alias ? Optional.empty() :
Optional.ofNullable(alias.getIdentifier().getValue());
+ }
+
+ @Override
+ public Optional<IdentifierValue> getAlias() {
+ return Optional.ofNullable(alias).map(AliasSegment::getIdentifier);
+ }
+
+ /**
+ * Get alias segment.
+ *
+ * @return alias segment
+ */
+ public Optional<AliasSegment> getAliasSegment() {
+ return Optional.ofNullable(alias);
+ }
+
+ @Override
+ public int getStartIndex() {
+ return expressionSegment.getStartIndex();
+ }
+
+ @Override
+ public int getStopIndex() {
+ return expressionSegment.getStopIndex();
+ }
+}
diff --git
a/test/it/parser/src/main/java/org/apache/shardingsphere/test/it/sql/parser/internal/asserts/segment/table/TableAssert.java
b/test/it/parser/src/main/java/org/apache/shardingsphere/test/it/sql/parser/internal/asserts/segment/table/TableAssert.java
index 3229a525d5d..ca21f9b371c 100644
---
a/test/it/parser/src/main/java/org/apache/shardingsphere/test/it/sql/parser/internal/asserts/segment/table/TableAssert.java
+++
b/test/it/parser/src/main/java/org/apache/shardingsphere/test/it/sql/parser/internal/asserts/segment/table/TableAssert.java
@@ -21,6 +21,7 @@ import com.google.common.base.Strings;
import lombok.AccessLevel;
import lombok.NoArgsConstructor;
import
org.apache.shardingsphere.sql.parser.sql.common.segment.dml.expr.XmlTableFunctionSegment;
+import
org.apache.shardingsphere.sql.parser.sql.common.segment.generic.table.CollectionTableSegment;
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;
@@ -35,6 +36,7 @@ import
org.apache.shardingsphere.test.it.sql.parser.internal.asserts.segment.own
import
org.apache.shardingsphere.test.it.sql.parser.internal.asserts.statement.dml.impl.SelectStatementAssert;
import
org.apache.shardingsphere.test.it.sql.parser.internal.cases.parser.jaxb.segment.impl.column.ExpectedColumn;
import
org.apache.shardingsphere.test.it.sql.parser.internal.cases.parser.jaxb.segment.impl.expr.ExpectedXmlTableFunction;
+import
org.apache.shardingsphere.test.it.sql.parser.internal.cases.parser.jaxb.segment.impl.table.ExpectedCollectionTable;
import
org.apache.shardingsphere.test.it.sql.parser.internal.cases.parser.jaxb.segment.impl.table.ExpectedJoinTable;
import
org.apache.shardingsphere.test.it.sql.parser.internal.cases.parser.jaxb.segment.impl.table.ExpectedSimpleTable;
import
org.apache.shardingsphere.test.it.sql.parser.internal.cases.parser.jaxb.segment.impl.table.ExpectedSubqueryTable;
@@ -72,11 +74,26 @@ public final class TableAssert {
assertIs(assertContext, (SubqueryTableSegment) actual,
expected.getSubqueryTable());
} else if (actual instanceof XmlTableSegment) {
assertIs(assertContext, (XmlTableSegment) actual,
expected.getXmlTable());
+ } else if (actual instanceof CollectionTableSegment) {
+ assertIs(assertContext, (CollectionTableSegment) actual,
expected.getCollectionTable());
} else {
throw new UnsupportedOperationException(String.format("Unsupported
table segment type `%s`.", actual.getClass()));
}
}
+ /**
+ * Assert actual collection table segment is correct with expected
collection table.
+ *
+ * @param assertContext assert context
+ * @param actual actual collection table
+ * @param expected expected collection table
+ */
+ private static void assertIs(final SQLCaseAssertContext assertContext,
final CollectionTableSegment actual, final ExpectedCollectionTable expected) {
+ if (null != expected.getExpectedExpression()) {
+ ExpressionAssert.assertExpression(assertContext,
actual.getExpressionSegment(), expected.getExpectedExpression());
+ }
+ }
+
/**
* Assert actual xml table segment is correct with expected xml table.
*
diff --git
a/test/it/parser/src/main/java/org/apache/shardingsphere/test/it/sql/parser/internal/cases/parser/jaxb/segment/impl/table/ExpectedTable.java
b/test/it/parser/src/main/java/org/apache/shardingsphere/test/it/sql/parser/internal/cases/parser/jaxb/segment/impl/table/ExpectedCollectionTable.java
similarity index 72%
copy from
test/it/parser/src/main/java/org/apache/shardingsphere/test/it/sql/parser/internal/cases/parser/jaxb/segment/impl/table/ExpectedTable.java
copy to
test/it/parser/src/main/java/org/apache/shardingsphere/test/it/sql/parser/internal/cases/parser/jaxb/segment/impl/table/ExpectedCollectionTable.java
index c34ef4fc687..2031eb45704 100644
---
a/test/it/parser/src/main/java/org/apache/shardingsphere/test/it/sql/parser/internal/cases/parser/jaxb/segment/impl/table/ExpectedTable.java
+++
b/test/it/parser/src/main/java/org/apache/shardingsphere/test/it/sql/parser/internal/cases/parser/jaxb/segment/impl/table/ExpectedCollectionTable.java
@@ -20,25 +20,18 @@ package
org.apache.shardingsphere.test.it.sql.parser.internal.cases.parser.jaxb.
import lombok.Getter;
import lombok.Setter;
import
org.apache.shardingsphere.test.it.sql.parser.internal.cases.parser.jaxb.segment.AbstractExpectedDelimiterSQLSegment;
+import
org.apache.shardingsphere.test.it.sql.parser.internal.cases.parser.jaxb.segment.impl.expr.ExpectedExpression;
+import javax.xml.bind.annotation.XmlAttribute;
import javax.xml.bind.annotation.XmlElement;
-/**
- * Expected tables.
- */
@Getter
@Setter
-public final class ExpectedTable extends AbstractExpectedDelimiterSQLSegment {
-
- @XmlElement(name = "simple-table")
- private ExpectedSimpleTable simpleTable;
-
- @XmlElement(name = "subquery-table")
- private ExpectedSubqueryTable subqueryTable;
+public final class ExpectedCollectionTable extends
AbstractExpectedDelimiterSQLSegment {
- @XmlElement(name = "join-table")
- private ExpectedJoinTable joinTable;
+ @XmlAttribute
+ private String alias;
- @XmlElement(name = "xml-table")
- private ExpectedXmlTable xmlTable;
+ @XmlElement
+ private ExpectedExpression expectedExpression;
}
diff --git
a/test/it/parser/src/main/java/org/apache/shardingsphere/test/it/sql/parser/internal/cases/parser/jaxb/segment/impl/table/ExpectedTable.java
b/test/it/parser/src/main/java/org/apache/shardingsphere/test/it/sql/parser/internal/cases/parser/jaxb/segment/impl/table/ExpectedTable.java
index c34ef4fc687..e102dd9bdae 100644
---
a/test/it/parser/src/main/java/org/apache/shardingsphere/test/it/sql/parser/internal/cases/parser/jaxb/segment/impl/table/ExpectedTable.java
+++
b/test/it/parser/src/main/java/org/apache/shardingsphere/test/it/sql/parser/internal/cases/parser/jaxb/segment/impl/table/ExpectedTable.java
@@ -41,4 +41,7 @@ public final class ExpectedTable extends
AbstractExpectedDelimiterSQLSegment {
@XmlElement(name = "xml-table")
private ExpectedXmlTable xmlTable;
+
+ @XmlElement(name = "collection-table")
+ private ExpectedCollectionTable collectionTable;
}
diff --git a/test/it/parser/src/main/resources/case/dml/select.xml
b/test/it/parser/src/main/resources/case/dml/select.xml
index b60855fae9f..0d5ea310bb3 100644
--- a/test/it/parser/src/main/resources/case/dml/select.xml
+++ b/test/it/parser/src/main/resources/case/dml/select.xml
@@ -6490,4 +6490,23 @@
<simple-table name="short_orders" alias="o" start-index="49"
stop-index="62" literal-start-index="49" literal-stop-index="62" />
</from>
</select>
+
+ <select sql-case-id="select_with_collection_table">
+ <projections start-index="7" stop-index="14" literal-start-index="7"
literal-stop-index="14">
+ <expression-projection text="VALUE(p)" start-index="7"
stop-index="14">
+ <function function-name="value" start-index="7"
stop-index="14" />
+ </expression-projection>
+ </projections>
+ <from>
+ <join-table join-type="COMMA">
+ <left>
+ <simple-table name="warehouses" alias="w" start-index="21"
stop-index="32" />
+ </left>
+ <right>
+ <collection-table alias="p" start-index="37"
stop-index="50">
+ </collection-table>>
+ </right>
+ </join-table>
+ </from>
+ </select>
</sql-parser-test-cases>
diff --git a/test/it/parser/src/main/resources/sql/supported/dml/select.xml
b/test/it/parser/src/main/resources/sql/supported/dml/select.xml
index 27e0dfc222d..512d6e7e07d 100644
--- a/test/it/parser/src/main/resources/sql/supported/dml/select.xml
+++ b/test/it/parser/src/main/resources/sql/supported/dml/select.xml
@@ -205,4 +205,5 @@
<sql-case id="select_with_xml_functions" value="SELECT
INSERTCHILDXML(warehouse_spec, '/Warehouse/Building', 'Owner',
XMLType('<Owner>LesserCo</Owner>')), SYS_DBURIGEN(employee_id, email),
INSERTCHILDXMLAFTER(warehouse_spec, '/Warehouse/Building','Owner[2]',
XMLType('<Owner>ThirdOwner</Owner>')),
INSERTCHILDXMLBEFORE(warehouse_spec, '/Warehouse/Building','Owner[2]',
XMLType('<Owner>ThirdOwner</Owner>')),
INSERTXMLAFTER(warehouse_spec,'/Warehouse/Building/Owner[1]', [...]
<sql-case id="select_with_more_xml_functions" value="SELECT
XMLCOMMENT('OrderAnalysisComp imported, reconfigured, disassembled'),
XMLCONCAT(XMLELEMENT('First', e.first_name), XMLELEMENT('Last', e.last_name))
AS 'Result', XMLPATCH(XMLTYPE('xml')), XMLDIFF(XMLTYPE('xml'),XMLTYPE('xml2')),
XMLELEMENT('Emp', XMLATTRIBUTES(e.employee_id, e.last_name)),
XMLSEQUENCE(EXTRACT(warehouse_spec, '/Warehouse/*')) FROM DUAL"
db-types="Oracle" />
<sql-case id="select_with_nested_object" value="SELECT
o.item.line_item_id, o.item.quantity FROM short_orders o;" db-types="Oracle" />
+ <sql-case id="select_with_collection_table" value="SELECT VALUE(p) FROM
warehouses w, TABLE(XMLSEQUENCE(EXTRACT(warehouse_spec, '/Warehouse/*'))) p;"
db-types="Oracle" />
</sql-cases>