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" />