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 7e1dcff57e8 [Oracle SQL] Support parsing create type for Oracle 
(#27872)
7e1dcff57e8 is described below

commit 7e1dcff57e8d50aae9963c90416475ea8f60dc3a
Author: Liao Lanyu <1435078...@qq.com>
AuthorDate: Thu Aug 3 11:02:13 2023 +0800

    [Oracle SQL] Support parsing create type for Oracle (#27872)
    
    * support OE-4-6 OE-4-7 OE-4-8
    
    * support OE-4-6 OE-4-7 OE-4-8 test
    
    * check style
    
    * support basic create type
    
    * support basic create type
    
    * support basic create type test
    
    * check style
    
    * check style
---
 .../src/main/antlr4/imports/oracle/BaseRule.g4     |  3 +-
 .../src/main/antlr4/imports/oracle/DDLStatement.g4 | 48 +++++++++++++++++++++
 .../main/antlr4/imports/oracle/OracleKeyword.g4    |  4 ++
 .../sql/parser/autogen/OracleStatement.g4          |  1 +
 .../visitor/statement/OracleStatementVisitor.java  | 16 ++++---
 .../statement/type/OracleDDLStatementVisitor.java  | 50 ++++++++++++++++++++++
 .../segment/ddl/type/TypeDefinitionSegment.java    | 36 ++++++++++++++++
 .../ddl/OracleCreateNestedTableTypeStatement.java  | 42 ++++++++++++++++++
 .../ddl/OracleCreateObjectTypeStatement.java       | 47 ++++++++++++++++++++
 .../oracle/ddl/OracleCreateSubTypeStatement.java   | 44 +++++++++++++++++++
 .../ddl/OracleCreateVarrayTypeStatement.java       | 48 +++++++++++++++++++++
 .../src/main/resources/case/ddl/create-type.xml    |  4 ++
 .../resources/case/dml/select-special-function.xml | 45 +++++++++++++++++++
 .../resources/sql/supported/ddl/create-type.xml    |  4 ++
 .../sql/supported/dml/select-special-function.xml  |  1 +
 15 files changed, 386 insertions(+), 7 deletions(-)

diff --git 
a/parser/sql/dialect/oracle/src/main/antlr4/imports/oracle/BaseRule.g4 
b/parser/sql/dialect/oracle/src/main/antlr4/imports/oracle/BaseRule.g4
index fb3cc4501ab..6817513d448 100644
--- a/parser/sql/dialect/oracle/src/main/antlr4/imports/oracle/BaseRule.g4
+++ b/parser/sql/dialect/oracle/src/main/antlr4/imports/oracle/BaseRule.g4
@@ -803,7 +803,8 @@ formatFunction
     ;
 
 castFunction
-    : (CAST | XMLCAST) LP_ expr AS dataType RP_
+    : CAST LP_ ((MULTISET subquery) | expr) AS dataType RP_
+    | XMLCAST LP_ expr AS dataType RP_
     ;
 
 charFunction
diff --git 
a/parser/sql/dialect/oracle/src/main/antlr4/imports/oracle/DDLStatement.g4 
b/parser/sql/dialect/oracle/src/main/antlr4/imports/oracle/DDLStatement.g4
index c59e0c8dc30..5ad5a16348a 100644
--- a/parser/sql/dialect/oracle/src/main/antlr4/imports/oracle/DDLStatement.g4
+++ b/parser/sql/dialect/oracle/src/main/antlr4/imports/oracle/DDLStatement.g4
@@ -31,6 +31,54 @@ createIndex
     : CREATE createIndexSpecification INDEX indexName ON 
createIndexDefinitionClause usableSpecification? invalidationSpecification?
     ;
 
+createType
+    : CREATE (OR REPLACE)? (EDITIONABLE | NONEDITIONABLE)? TYPE plsqlTypeSource
+    ;
+
+plsqlTypeSource
+    : typeName (objectBaseTypeDef | objectSubTypeDef)
+    ;
+
+objectBaseTypeDef
+    : (IS | AS) (objectTypeDef | varrayTypeSpec | nestedTableTypeSpec)
+    ;
+
+objectTypeDef
+    : OBJECT LP_ dataTypeDefinition (COMMA_ dataTypeDefinition)* RP_ 
finalClause? instantiableClause? persistableClause?
+    ;
+
+finalClause
+    : NOT? FINAL
+    ;
+
+instantiableClause
+    : NOT? INSTANTIABLE
+    ;
+
+persistableClause
+    : NOT? PERSISTABLE
+    ;
+
+varrayTypeSpec
+    : VARRAY (LP_ INTEGER_ RP_)? OF typeSpec
+    ;
+
+nestedTableTypeSpec
+    : TABLE OF typeSpec
+    ;
+
+typeSpec
+    : ((LP_ dataType RP_) | dataType) (NOT NULL)? persistableClause?
+    ;
+
+dataTypeDefinition
+    : name dataType
+    ;
+
+objectSubTypeDef
+    : UNDER typeName LP_ dataTypeDefinition (COMMA_ dataTypeDefinition)* RP_ 
finalClause? instantiableClause?
+    ;
+
 alterTable
     : ALTER TABLE tableName memOptimizeClause alterDefinitionClause 
enableDisableClauses
     ;
diff --git 
a/parser/sql/dialect/oracle/src/main/antlr4/imports/oracle/OracleKeyword.g4 
b/parser/sql/dialect/oracle/src/main/antlr4/imports/oracle/OracleKeyword.g4
index a50ea097c3c..58f8b3c66f4 100644
--- a/parser/sql/dialect/oracle/src/main/antlr4/imports/oracle/OracleKeyword.g4
+++ b/parser/sql/dialect/oracle/src/main/antlr4/imports/oracle/OracleKeyword.g4
@@ -7711,3 +7711,7 @@ CLUSTER_DETAILS
 CLUSTER_DISTANCE
     : C L U S T E R UL_ D I S T A N C E
     ;
+
+PERSISTABLE
+    : P E R S I S T A B L E
+    ;
diff --git 
a/parser/sql/dialect/oracle/src/main/antlr4/org/apache/shardingsphere/sql/parser/autogen/OracleStatement.g4
 
b/parser/sql/dialect/oracle/src/main/antlr4/org/apache/shardingsphere/sql/parser/autogen/OracleStatement.g4
index 4f86a13c915..a6f5e666847 100644
--- 
a/parser/sql/dialect/oracle/src/main/antlr4/org/apache/shardingsphere/sql/parser/autogen/OracleStatement.g4
+++ 
b/parser/sql/dialect/oracle/src/main/antlr4/org/apache/shardingsphere/sql/parser/autogen/OracleStatement.g4
@@ -145,6 +145,7 @@ execute
     | dropCluster
     | systemAction
     | alterType
+    | createType
     | createCluster
     ) SEMI_?
     ;
diff --git 
a/parser/sql/dialect/oracle/src/main/java/org/apache/shardingsphere/sql/parser/oracle/visitor/statement/OracleStatementVisitor.java
 
b/parser/sql/dialect/oracle/src/main/java/org/apache/shardingsphere/sql/parser/oracle/visitor/statement/OracleStatementVisitor.java
index 155b54c98d2..009256afeac 100644
--- 
a/parser/sql/dialect/oracle/src/main/java/org/apache/shardingsphere/sql/parser/oracle/visitor/statement/OracleStatementVisitor.java
+++ 
b/parser/sql/dialect/oracle/src/main/java/org/apache/shardingsphere/sql/parser/oracle/visitor/statement/OracleStatementVisitor.java
@@ -870,18 +870,22 @@ public abstract class OracleStatementVisitor extends 
OracleStatementBaseVisitor<
     
     @Override
     public final ASTNode visitCastFunction(final CastFunctionContext ctx) {
-        calculateParameterCount(Collections.singleton(ctx.expr()));
         FunctionSegment result;
         if (null != ctx.CAST()) {
             result = new FunctionSegment(ctx.getStart().getStartIndex(), 
ctx.getStop().getStopIndex(), ctx.CAST().getText(), getOriginalText(ctx));
         } else {
             result = new FunctionSegment(ctx.getStart().getStartIndex(), 
ctx.getStop().getStopIndex(), ctx.XMLCAST().getText(), getOriginalText(ctx));
         }
-        ASTNode exprSegment = visit(ctx.expr());
-        if (exprSegment instanceof ColumnSegment) {
-            result.getParameters().add((ColumnSegment) exprSegment);
-        } else if (exprSegment instanceof LiteralExpressionSegment) {
-            result.getParameters().add((LiteralExpressionSegment) exprSegment);
+        if (null != ctx.MULTISET()) {
+            result.getParameters()
+                    .add(new SubqueryExpressionSegment(new 
SubquerySegment(ctx.subquery().start.getStartIndex(), 
ctx.subquery().stop.getStopIndex(), (OracleSelectStatement) 
visit(ctx.subquery()))));
+        } else {
+            ASTNode exprSegment = visit(ctx.expr());
+            if (exprSegment instanceof ColumnSegment) {
+                result.getParameters().add((ColumnSegment) exprSegment);
+            } else if (exprSegment instanceof LiteralExpressionSegment) {
+                result.getParameters().add((LiteralExpressionSegment) 
exprSegment);
+            }
         }
         result.getParameters().add((DataTypeSegment) visit(ctx.dataType()));
         return result;
diff --git 
a/parser/sql/dialect/oracle/src/main/java/org/apache/shardingsphere/sql/parser/oracle/visitor/statement/type/OracleDDLStatementVisitor.java
 
b/parser/sql/dialect/oracle/src/main/java/org/apache/shardingsphere/sql/parser/oracle/visitor/statement/type/OracleDDLStatementVisitor.java
index ca861172e02..e9070e11924 100644
--- 
a/parser/sql/dialect/oracle/src/main/java/org/apache/shardingsphere/sql/parser/oracle/visitor/statement/type/OracleDDLStatementVisitor.java
+++ 
b/parser/sql/dialect/oracle/src/main/java/org/apache/shardingsphere/sql/parser/oracle/visitor/statement/type/OracleDDLStatementVisitor.java
@@ -19,6 +19,7 @@ package 
org.apache.shardingsphere.sql.parser.oracle.visitor.statement.type;
 
 import org.apache.shardingsphere.sql.parser.api.ASTNode;
 import 
org.apache.shardingsphere.sql.parser.api.visitor.statement.type.DDLStatementVisitor;
+import org.apache.shardingsphere.sql.parser.autogen.OracleStatementParser;
 import 
org.apache.shardingsphere.sql.parser.autogen.OracleStatementParser.AddColumnSpecificationContext;
 import 
org.apache.shardingsphere.sql.parser.autogen.OracleStatementParser.AddConstraintSpecificationContext;
 import 
org.apache.shardingsphere.sql.parser.autogen.OracleStatementParser.AlterAnalyticViewContext;
@@ -162,6 +163,7 @@ import 
org.apache.shardingsphere.sql.parser.sql.common.segment.ddl.constraint.al
 import 
org.apache.shardingsphere.sql.parser.sql.common.segment.ddl.index.IndexSegment;
 import 
org.apache.shardingsphere.sql.parser.sql.common.segment.ddl.index.IndexTypeSegment;
 import 
org.apache.shardingsphere.sql.parser.sql.common.segment.ddl.packages.PackageSegment;
+import 
org.apache.shardingsphere.sql.parser.sql.common.segment.ddl.type.TypeDefinitionSegment;
 import 
org.apache.shardingsphere.sql.parser.sql.common.segment.ddl.type.TypeSegment;
 import 
org.apache.shardingsphere.sql.parser.sql.common.segment.dml.column.ColumnSegment;
 import 
org.apache.shardingsphere.sql.parser.sql.common.segment.dml.expr.FunctionSegment;
@@ -220,15 +222,19 @@ import 
org.apache.shardingsphere.sql.parser.sql.dialect.statement.oracle.ddl.Ora
 import 
org.apache.shardingsphere.sql.parser.sql.dialect.statement.oracle.ddl.OracleCreateIndexStatement;
 import 
org.apache.shardingsphere.sql.parser.sql.dialect.statement.oracle.ddl.OracleCreateInmemoryJoinGroupStatement;
 import 
org.apache.shardingsphere.sql.parser.sql.dialect.statement.oracle.ddl.OracleCreateLockdownProfileStatement;
+import 
org.apache.shardingsphere.sql.parser.sql.dialect.statement.oracle.ddl.OracleCreateNestedTableTypeStatement;
+import 
org.apache.shardingsphere.sql.parser.sql.dialect.statement.oracle.ddl.OracleCreateObjectTypeStatement;
 import 
org.apache.shardingsphere.sql.parser.sql.dialect.statement.oracle.ddl.OracleCreatePFileStatement;
 import 
org.apache.shardingsphere.sql.parser.sql.dialect.statement.oracle.ddl.OracleCreateProcedureStatement;
 import 
org.apache.shardingsphere.sql.parser.sql.dialect.statement.oracle.ddl.OracleCreateRestorePointStatement;
 import 
org.apache.shardingsphere.sql.parser.sql.dialect.statement.oracle.ddl.OracleCreateRollbackSegmentStatement;
 import 
org.apache.shardingsphere.sql.parser.sql.dialect.statement.oracle.ddl.OracleCreateSPFileStatement;
 import 
org.apache.shardingsphere.sql.parser.sql.dialect.statement.oracle.ddl.OracleCreateSequenceStatement;
+import 
org.apache.shardingsphere.sql.parser.sql.dialect.statement.oracle.ddl.OracleCreateSubTypeStatement;
 import 
org.apache.shardingsphere.sql.parser.sql.dialect.statement.oracle.ddl.OracleCreateSynonymStatement;
 import 
org.apache.shardingsphere.sql.parser.sql.dialect.statement.oracle.ddl.OracleCreateTableStatement;
 import 
org.apache.shardingsphere.sql.parser.sql.dialect.statement.oracle.ddl.OracleCreateTablespaceStatement;
+import 
org.apache.shardingsphere.sql.parser.sql.dialect.statement.oracle.ddl.OracleCreateVarrayTypeStatement;
 import 
org.apache.shardingsphere.sql.parser.sql.dialect.statement.oracle.ddl.OracleDisassociateStatisticsStatement;
 import 
org.apache.shardingsphere.sql.parser.sql.dialect.statement.oracle.ddl.OracleDropClusterStatement;
 import 
org.apache.shardingsphere.sql.parser.sql.dialect.statement.oracle.ddl.OracleDropContextStatement;
@@ -274,6 +280,7 @@ import 
org.apache.shardingsphere.sql.parser.sql.dialect.statement.oracle.ddl.Ora
 import java.util.Collection;
 import java.util.Collections;
 import java.util.LinkedList;
+import java.util.stream.Collectors;
 
 /**
  * DDL statement visitor for Oracle.
@@ -298,6 +305,49 @@ public final class OracleDDLStatementVisitor extends 
OracleStatementVisitor impl
         return result;
     }
     
+    @Override
+    public ASTNode visitCreateType(final 
OracleStatementParser.CreateTypeContext ctx) {
+        boolean isReplace = null != ctx.REPLACE();
+        boolean isEditionable = null == ctx.NONEDITIONABLE();
+        TypeSegment typeSegment = (TypeSegment) 
visit(ctx.plsqlTypeSource().typeName());
+        if (null != ctx.plsqlTypeSource().objectSubTypeDef()) {
+            OracleStatementParser.ObjectSubTypeDefContext 
objectSubTypeDefContext = ctx.plsqlTypeSource().objectSubTypeDef();
+            return new OracleCreateSubTypeStatement(isReplace, isEditionable,
+                    null == objectSubTypeDefContext.finalClause() || null == 
objectSubTypeDefContext.finalClause().NOT(),
+                    null == objectSubTypeDefContext.instantiableClause() || 
null == objectSubTypeDefContext.instantiableClause().NOT(),
+                    typeSegment,
+                    
objectSubTypeDefContext.dataTypeDefinition().stream().map(definition -> 
(TypeDefinitionSegment) visit(definition)).collect(Collectors.toList()));
+        } else {
+            if (null != 
ctx.plsqlTypeSource().objectBaseTypeDef().objectTypeDef()) {
+                OracleStatementParser.ObjectTypeDefContext 
objectTypeDefContext = 
ctx.plsqlTypeSource().objectBaseTypeDef().objectTypeDef();
+                return new OracleCreateObjectTypeStatement(isReplace, 
isEditionable, null == objectTypeDefContext.finalClause() || null == 
objectTypeDefContext.finalClause().NOT(),
+                        null == objectTypeDefContext.instantiableClause() || 
null == objectTypeDefContext.instantiableClause().NOT(),
+                        null == objectTypeDefContext.persistableClause() || 
null == objectTypeDefContext.persistableClause().NOT(),
+                        typeSegment, 
objectTypeDefContext.dataTypeDefinition().stream().map(definition -> 
(TypeDefinitionSegment) visit(definition)).collect(Collectors.toList()));
+            } else if (null != 
ctx.plsqlTypeSource().objectBaseTypeDef().varrayTypeSpec()) {
+                OracleStatementParser.VarrayTypeSpecContext 
varrayTypeSpecContext = 
ctx.plsqlTypeSource().objectBaseTypeDef().varrayTypeSpec();
+                return new OracleCreateVarrayTypeStatement(isReplace, 
isEditionable,
+                        null == varrayTypeSpecContext.INTEGER_() ? -1 : 
Integer.parseInt(varrayTypeSpecContext.INTEGER_().getText()),
+                        null != varrayTypeSpecContext.typeSpec().NULL(),
+                        null == 
varrayTypeSpecContext.typeSpec().persistableClause() || null == 
varrayTypeSpecContext.typeSpec().persistableClause().NOT(),
+                        typeSegment,
+                        (DataTypeSegment) 
visit(varrayTypeSpecContext.typeSpec().dataType()));
+            } else {
+                OracleStatementParser.NestedTableTypeSpecContext 
nestedTableTypeSpecContext = 
ctx.plsqlTypeSource().objectBaseTypeDef().nestedTableTypeSpec();
+                return new OracleCreateNestedTableTypeStatement(isReplace, 
isEditionable,
+                        null != nestedTableTypeSpecContext.typeSpec().NULL(),
+                        null == 
nestedTableTypeSpecContext.typeSpec().persistableClause() || null == 
nestedTableTypeSpecContext.typeSpec().persistableClause().NOT(),
+                        typeSegment,
+                        (DataTypeSegment) 
visit(nestedTableTypeSpecContext.typeSpec().dataType()));
+            }
+        }
+    }
+    
+    @Override
+    public ASTNode visitDataTypeDefinition(final 
OracleStatementParser.DataTypeDefinitionContext ctx) {
+        return new TypeDefinitionSegment(ctx.getStart().getStartIndex(), 
ctx.getStop().getStopIndex(), ctx.name().getText(), (DataTypeSegment) 
visit(ctx.dataType()));
+    }
+    
     @Override
     public ASTNode visitCreateDefinitionClause(final 
CreateDefinitionClauseContext ctx) {
         CollectionValue<CreateDefinitionSegment> result = new 
CollectionValue<>();
diff --git 
a/parser/sql/statement/src/main/java/org/apache/shardingsphere/sql/parser/sql/common/segment/ddl/type/TypeDefinitionSegment.java
 
b/parser/sql/statement/src/main/java/org/apache/shardingsphere/sql/parser/sql/common/segment/ddl/type/TypeDefinitionSegment.java
new file mode 100644
index 00000000000..10ab20da81c
--- /dev/null
+++ 
b/parser/sql/statement/src/main/java/org/apache/shardingsphere/sql/parser/sql/common/segment/ddl/type/TypeDefinitionSegment.java
@@ -0,0 +1,36 @@
+/*
+ * 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.ddl.type;
+
+import lombok.Getter;
+import lombok.RequiredArgsConstructor;
+import 
org.apache.shardingsphere.sql.parser.sql.common.segment.ddl.CreateDefinitionSegment;
+import 
org.apache.shardingsphere.sql.parser.sql.common.segment.generic.DataTypeSegment;
+
+@RequiredArgsConstructor
+@Getter
+public final class TypeDefinitionSegment implements CreateDefinitionSegment {
+    
+    private final int startIndex;
+    
+    private final int stopIndex;
+    
+    private final String attributeName;
+    
+    private final DataTypeSegment dataType;
+}
diff --git 
a/parser/sql/statement/src/main/java/org/apache/shardingsphere/sql/parser/sql/dialect/statement/oracle/ddl/OracleCreateNestedTableTypeStatement.java
 
b/parser/sql/statement/src/main/java/org/apache/shardingsphere/sql/parser/sql/dialect/statement/oracle/ddl/OracleCreateNestedTableTypeStatement.java
new file mode 100644
index 00000000000..58f8b2551fe
--- /dev/null
+++ 
b/parser/sql/statement/src/main/java/org/apache/shardingsphere/sql/parser/sql/dialect/statement/oracle/ddl/OracleCreateNestedTableTypeStatement.java
@@ -0,0 +1,42 @@
+/*
+ * 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.dialect.statement.oracle.ddl;
+
+import lombok.Getter;
+import lombok.RequiredArgsConstructor;
+import 
org.apache.shardingsphere.sql.parser.sql.common.segment.ddl.type.TypeSegment;
+import 
org.apache.shardingsphere.sql.parser.sql.common.segment.generic.DataTypeSegment;
+import 
org.apache.shardingsphere.sql.parser.sql.common.statement.ddl.CreateTypeStatement;
+import 
org.apache.shardingsphere.sql.parser.sql.dialect.statement.oracle.OracleStatement;
+
+@Getter
+@RequiredArgsConstructor
+public final class OracleCreateNestedTableTypeStatement extends 
CreateTypeStatement implements OracleStatement {
+    
+    private final boolean isReplace;
+    
+    private final boolean editionable;
+    
+    private final boolean notNull;
+    
+    private final boolean isPersistable;
+    
+    private final TypeSegment typeSegment;
+    
+    private final DataTypeSegment dataType;
+}
diff --git 
a/parser/sql/statement/src/main/java/org/apache/shardingsphere/sql/parser/sql/dialect/statement/oracle/ddl/OracleCreateObjectTypeStatement.java
 
b/parser/sql/statement/src/main/java/org/apache/shardingsphere/sql/parser/sql/dialect/statement/oracle/ddl/OracleCreateObjectTypeStatement.java
new file mode 100644
index 00000000000..5b2682b6ffc
--- /dev/null
+++ 
b/parser/sql/statement/src/main/java/org/apache/shardingsphere/sql/parser/sql/dialect/statement/oracle/ddl/OracleCreateObjectTypeStatement.java
@@ -0,0 +1,47 @@
+/*
+ * 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.dialect.statement.oracle.ddl;
+
+import lombok.Getter;
+import lombok.RequiredArgsConstructor;
+import 
org.apache.shardingsphere.sql.parser.sql.common.segment.ddl.type.TypeDefinitionSegment;
+import 
org.apache.shardingsphere.sql.parser.sql.common.segment.ddl.type.TypeSegment;
+import 
org.apache.shardingsphere.sql.parser.sql.common.statement.ddl.CreateTypeStatement;
+import 
org.apache.shardingsphere.sql.parser.sql.dialect.statement.oracle.OracleStatement;
+
+import java.util.Collection;
+
+@Getter
+@RequiredArgsConstructor
+public final class OracleCreateObjectTypeStatement extends CreateTypeStatement 
implements OracleStatement {
+    
+    private final boolean isReplace;
+    
+    private final boolean isEditionable;
+    
+    private final boolean isFinal;
+    
+    private final boolean isInstantiable;
+    
+    private final boolean isPersistable;
+    
+    private final TypeSegment typeSegment;
+    
+    private final Collection<TypeDefinitionSegment> typeDefinitions;
+    
+}
diff --git 
a/parser/sql/statement/src/main/java/org/apache/shardingsphere/sql/parser/sql/dialect/statement/oracle/ddl/OracleCreateSubTypeStatement.java
 
b/parser/sql/statement/src/main/java/org/apache/shardingsphere/sql/parser/sql/dialect/statement/oracle/ddl/OracleCreateSubTypeStatement.java
new file mode 100644
index 00000000000..65f07e49814
--- /dev/null
+++ 
b/parser/sql/statement/src/main/java/org/apache/shardingsphere/sql/parser/sql/dialect/statement/oracle/ddl/OracleCreateSubTypeStatement.java
@@ -0,0 +1,44 @@
+/*
+ * 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.dialect.statement.oracle.ddl;
+
+import lombok.Getter;
+import lombok.RequiredArgsConstructor;
+import 
org.apache.shardingsphere.sql.parser.sql.common.segment.ddl.type.TypeDefinitionSegment;
+import 
org.apache.shardingsphere.sql.parser.sql.common.segment.ddl.type.TypeSegment;
+import 
org.apache.shardingsphere.sql.parser.sql.common.statement.ddl.CreateTypeStatement;
+import 
org.apache.shardingsphere.sql.parser.sql.dialect.statement.oracle.OracleStatement;
+
+import java.util.Collection;
+
+@Getter
+@RequiredArgsConstructor
+public final class OracleCreateSubTypeStatement extends CreateTypeStatement 
implements OracleStatement {
+    
+    private final boolean isReplace;
+    
+    private final boolean isEditionable;
+    
+    private final boolean isFinal;
+    
+    private final boolean isInstantiable;
+    
+    private final TypeSegment typeSegment;
+    
+    private final Collection<TypeDefinitionSegment> typeDefinitions;
+}
diff --git 
a/parser/sql/statement/src/main/java/org/apache/shardingsphere/sql/parser/sql/dialect/statement/oracle/ddl/OracleCreateVarrayTypeStatement.java
 
b/parser/sql/statement/src/main/java/org/apache/shardingsphere/sql/parser/sql/dialect/statement/oracle/ddl/OracleCreateVarrayTypeStatement.java
new file mode 100644
index 00000000000..f0d4a0f6c1b
--- /dev/null
+++ 
b/parser/sql/statement/src/main/java/org/apache/shardingsphere/sql/parser/sql/dialect/statement/oracle/ddl/OracleCreateVarrayTypeStatement.java
@@ -0,0 +1,48 @@
+/*
+ * 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.dialect.statement.oracle.ddl;
+
+import lombok.Getter;
+import lombok.RequiredArgsConstructor;
+import lombok.Setter;
+import 
org.apache.shardingsphere.sql.parser.sql.common.segment.ddl.type.TypeSegment;
+import 
org.apache.shardingsphere.sql.parser.sql.common.segment.generic.DataTypeSegment;
+import 
org.apache.shardingsphere.sql.parser.sql.common.statement.ddl.CreateTypeStatement;
+import 
org.apache.shardingsphere.sql.parser.sql.dialect.statement.oracle.OracleStatement;
+
+@Getter
+@Setter
+@RequiredArgsConstructor
+public final class OracleCreateVarrayTypeStatement extends CreateTypeStatement 
implements OracleStatement {
+    
+    private final boolean isReplace;
+    
+    private final boolean editionable;
+    
+    /** default -1 means that the size is not specified. */
+    private final int size;
+    
+    private final boolean notNull;
+    
+    private final boolean isPersistable;
+    
+    private final TypeSegment typeSegment;
+    
+    private final DataTypeSegment dataType;
+    
+}
diff --git a/test/it/parser/src/main/resources/case/ddl/create-type.xml 
b/test/it/parser/src/main/resources/case/ddl/create-type.xml
index a742a4be41e..ccd68182b57 100644
--- a/test/it/parser/src/main/resources/case/ddl/create-type.xml
+++ b/test/it/parser/src/main/resources/case/ddl/create-type.xml
@@ -18,4 +18,8 @@
 
 <sql-parser-test-cases>
     <create-type sql-case-id="create_type" />
+    <create-type sql-case-id="create_type_as_table" />
+    <create-type sql-case-id="create_type_as_varray" />
+    <create-type sql-case-id="create_type_as_object" />
+    <create-type sql-case-id="create_sub_type" />
 </sql-parser-test-cases>
diff --git 
a/test/it/parser/src/main/resources/case/dml/select-special-function.xml 
b/test/it/parser/src/main/resources/case/dml/select-special-function.xml
index 8663b827d83..765f66aafa4 100644
--- a/test/it/parser/src/main/resources/case/dml/select-special-function.xml
+++ b/test/it/parser/src/main/resources/case/dml/select-special-function.xml
@@ -81,6 +81,51 @@
             </expression-projection>
         </projections>
     </select>
+    <select sql-case-id="select_cast_multiset">
+        <projections start-index="7" stop-index="119">
+            <expression-projection text="CAST(MULTISET(SELECT cust_address 
FROM customers c WHERE c.customer_id = cd.customer_id) as 
cust_address_tab_typ)" start-index="7" stop-index="119">
+                <expr>
+                    <function function-name="CAST" start-index="7" 
stop-index="119" text="CAST(MULTISET(SELECT cust_address FROM customers c WHERE 
c.customer_id = cd.customer_id) as cust_address_tab_typ)">
+                        <parameter>
+                            <subquery start-index="20" stop-index="94">
+                                <select>
+                                    <from start-index="46" stop-index="54">
+                                        <simple-table name="customers" 
alias="c" start-index="46" stop-index="56"/>
+                                    </from>
+                                    <projections start-index="28" 
stop-index="39">
+                                        <column-projection name="cust_address" 
start-index="28" stop-index="39"/>
+                                    </projections>
+                                    <where start-index="58" stop-index="93">
+                                        <expr>
+                                            <binary-operation-expression 
start-index="64" stop-index="93">
+                                                <left>
+                                                    <column name="customer_id" 
start-index="64" stop-index="76">
+                                                        <owner 
start-index="64" stop-index="64" name="c" />
+                                                    </column>
+                                                </left>
+                                                <operator>=</operator>
+                                                <right>
+                                                    <column name="customer_id" 
start-index="80" stop-index="93">
+                                                        <owner 
start-index="80" stop-index="81" name="cd" />
+                                                    </column>
+                                                </right>
+                                            </binary-operation-expression>
+                                        </expr>
+                                    </where>
+                                </select>
+                            </subquery>
+                        </parameter>
+                        <parameter>
+                            <data-type value="cust_address_tab_typ" 
start-index="99" stop-index="118" />
+                        </parameter>
+                    </function>
+                </expr>
+            </expression-projection>
+        </projections>
+        <from>
+            <simple-table name="customer" start-index="126" stop-index="133" />
+        </from>
+    </select>
     <select sql-case-id="select_convert_function">
         <projections start-index="7" stop-index="33">
             <expression-projection text="CONVERT('2020-10-01', DATE)" 
start-index="7" stop-index="33">
diff --git 
a/test/it/parser/src/main/resources/sql/supported/ddl/create-type.xml 
b/test/it/parser/src/main/resources/sql/supported/ddl/create-type.xml
index b5a181b7b41..4f8b9286a60 100644
--- a/test/it/parser/src/main/resources/sql/supported/ddl/create-type.xml
+++ b/test/it/parser/src/main/resources/sql/supported/ddl/create-type.xml
@@ -18,4 +18,8 @@
 
 <sql-cases>
     <sql-case id="create_type" value="create type avg_state as (total bigint, 
count bigint)" db-types="PostgreSQL,openGauss" />
+    <sql-case id="create_type_as_table" value="CREATE TYPE address_book_t AS 
TABLE OF cust_address_typ;" db-types="Oracle" />
+    <sql-case id="create_type_as_varray" value="CREATE TYPE address_array_t AS 
VARRAY(3) OF cust_address_typ;" db-types="Oracle" />
+    <sql-case id="create_type_as_object" value="CREATE TYPE person_t AS OBJECT 
(name VARCHAR2(100), ssn NUMBER) NOT FINAL;" db-types="Oracle" />
+    <sql-case id="create_sub_type" value="CREATE TYPE employee_t UNDER 
person_t (department_id NUMBER, salary NUMBER) NOT FINAL;" db-types="Oracle" />
 </sql-cases>
diff --git 
a/test/it/parser/src/main/resources/sql/supported/dml/select-special-function.xml
 
b/test/it/parser/src/main/resources/sql/supported/dml/select-special-function.xml
index d6f4c165697..d9233bfb53c 100644
--- 
a/test/it/parser/src/main/resources/sql/supported/dml/select-special-function.xml
+++ 
b/test/it/parser/src/main/resources/sql/supported/dml/select-special-function.xml
@@ -21,6 +21,7 @@
     <sql-case id="select_window_function" value="SELECT order_id, ROW_NUMBER() 
OVER() FROM t_order" db-types="MySQL" />
     <sql-case id="select_cast_function" value="SELECT CAST('1' AS UNSIGNED)" 
db-types="MySQL" />
     <sql-case id="select_cast" value="SELECT CAST(c AT TIME ZONE 'UTC' AS 
DATETIME)" db-types="MySQL" />
+    <sql-case id="select_cast_multiset" value="select CAST(MULTISET(SELECT 
cust_address FROM customers c WHERE c.customer_id = cd.customer_id) as 
cust_address_tab_typ) from customer;" db-types="Oracle" />
     <sql-case id="select_convert_function" value="SELECT CONVERT('2020-10-01', 
DATE)" db-types="MySQL" />
     <sql-case id="select_position" value="SELECT POSITION('bar' IN 
'foobarbar')" db-types="MySQL" />
     <sql-case id="select_substring" value="SELECT SUBSTRING('foobarbar' from 
4)" db-types="MySQL" />

Reply via email to