This is an automated email from the ASF dual-hosted git repository.
FlyingZC 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 54c9ec5a7ee Refactor MySQL prepared DDL parameter handling (#39356)
54c9ec5a7ee is described below
commit 54c9ec5a7eebf2c0ada644039f5fe924ae0b7469
Author: Zhengqiang Duan <[email protected]>
AuthorDate: Thu Aug 6 17:21:41 2026 +0800
Refactor MySQL prepared DDL parameter handling (#39356)
* Refactor MySQL prepared DDL parameter handling
* Refactor Oracle create package parsing
---
.../binary/execute/MySQLComStmtExecutePacket.java | 9 +-
.../execute/MySQLComStmtExecutePacketTest.java | 22 +++++
.../core/database/visitor/SQLVisitorRule.java | 2 +
.../statement/type/MySQLDDLStatementVisitor.java | 9 +-
.../statement/MySQLStatementVisitorTest.java | 7 ++
.../oracle/src/main/antlr4/imports/oracle/PLSQL.g4 | 30 ++++++
.../sql/parser/autogen/OracleStatement.g4 | 1 +
.../statement/type/OracleDDLStatementVisitor.java | 61 ++++++++++++
.../type/OracleDDLStatementVisitorTest.java | 44 ++++++++-
.../ddl/pkg/OracleCreatePackageStatement.java | 102 +++++++++++++++++++++
.../dialect/oracle/OracleDDLStatementAssert.java | 5 +
.../type/OracleCreatePackageStatementAssert.java | 52 +++++++++++
.../cases/parser/jaxb/RootSQLParserTestCases.java | 4 +
.../OracleCreatePackageStatementTestCase.java | 55 +++++++++++
.../src/main/resources/case/ddl/create-package.xml | 35 +++++++
.../resources/sql/supported/ddl/create-package.xml | 23 +++++
16 files changed, 457 insertions(+), 4 deletions(-)
diff --git
a/database/protocol/dialect/mysql/src/main/java/org/apache/shardingsphere/database/protocol/mysql/packet/command/query/binary/execute/MySQLComStmtExecutePacket.java
b/database/protocol/dialect/mysql/src/main/java/org/apache/shardingsphere/database/protocol/mysql/packet/command/query/binary/execute/MySQLComStmtExecutePacket.java
index 6f2692071c4..ae6ac371c1d 100644
---
a/database/protocol/dialect/mysql/src/main/java/org/apache/shardingsphere/database/protocol/mysql/packet/command/query/binary/execute/MySQLComStmtExecutePacket.java
+++
b/database/protocol/dialect/mysql/src/main/java/org/apache/shardingsphere/database/protocol/mysql/packet/command/query/binary/execute/MySQLComStmtExecutePacket.java
@@ -28,7 +28,9 @@ import
org.apache.shardingsphere.database.protocol.mysql.packet.command.query.bi
import
org.apache.shardingsphere.database.protocol.mysql.packet.command.query.binary.execute.protocol.MySQLBinaryProtocolValueFactory;
import
org.apache.shardingsphere.database.protocol.mysql.payload.MySQLPacketPayload;
+import java.sql.Date;
import java.sql.SQLException;
+import java.sql.Timestamp;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
@@ -124,7 +126,12 @@ public final class MySQLComStmtExecutePacket extends
MySQLCommandPacket {
if (isStringParameterType(parameterType) &&
isBinaryColumnType(parameterColumnTypes, paramIndex)) {
return payload.readStringLenencByBytes();
}
- return binaryProtocolValue.read(payload, (unsignedFlag &
UNSIGNED_FLAG) == UNSIGNED_FLAG);
+ Object result = binaryProtocolValue.read(payload, (unsignedFlag &
UNSIGNED_FLAG) == UNSIGNED_FLAG);
+ return isDateParameter(parameterColumnTypes, paramIndex,
parameterType) && result instanceof Timestamp ? new Date(((Timestamp)
result).getTime()) : result;
+ }
+
+ private boolean isDateParameter(final List<MySQLBinaryColumnType>
parameterColumnTypes, final int paramIndex, final MySQLBinaryColumnType
parameterType) {
+ return MySQLBinaryColumnType.DATE == parameterType ||
MySQLBinaryColumnType.DATE == getParameterColumnType(parameterColumnTypes,
paramIndex);
}
private MySQLBinaryColumnType getParameterColumnType(final
List<MySQLBinaryColumnType> parameterColumnTypes, final int paramIndex) {
diff --git
a/database/protocol/dialect/mysql/src/test/java/org/apache/shardingsphere/database/protocol/mysql/packet/command/query/binary/execute/MySQLComStmtExecutePacketTest.java
b/database/protocol/dialect/mysql/src/test/java/org/apache/shardingsphere/database/protocol/mysql/packet/command/query/binary/execute/MySQLComStmtExecutePacketTest.java
index 34bcc3bdd89..0f9bef8c4be 100644
---
a/database/protocol/dialect/mysql/src/test/java/org/apache/shardingsphere/database/protocol/mysql/packet/command/query/binary/execute/MySQLComStmtExecutePacketTest.java
+++
b/database/protocol/dialect/mysql/src/test/java/org/apache/shardingsphere/database/protocol/mysql/packet/command/query/binary/execute/MySQLComStmtExecutePacketTest.java
@@ -29,6 +29,7 @@ import org.junit.jupiter.params.provider.Arguments;
import org.junit.jupiter.params.provider.MethodSource;
import java.nio.charset.StandardCharsets;
+import java.sql.Date;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.Collections;
@@ -37,6 +38,7 @@ import java.util.stream.Stream;
import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.Matchers.is;
+import static org.hamcrest.Matchers.isA;
import static org.junit.jupiter.api.Assertions.assertArrayEquals;
import static org.junit.jupiter.api.Assertions.assertThrows;
import static org.junit.jupiter.api.Assertions.assertNull;
@@ -107,6 +109,26 @@ class MySQLComStmtExecutePacketTest {
assertThat(actual.readParameters(parameterTypes,
Collections.singleton(0), Collections.emptyList()),
is(Collections.singletonList(null)));
}
+ @Test
+ void assertReadParametersWithDateParameter() throws SQLException {
+ byte[] data = {0x01, 0x00, 0x00, 0x00, 0x09, 0x01, 0x00, 0x00, 0x00,
0x00, 0x01, 0x0a, 0x00, 0x04, (byte) 0xe1, 0x07, 0x08, 0x08};
+ MySQLPacketPayload payload = new
MySQLPacketPayload(Unpooled.wrappedBuffer(data), StandardCharsets.UTF_8);
+ MySQLComStmtExecutePacket actual = new
MySQLComStmtExecutePacket(payload, 1);
+ Object actualValue =
actual.readParameters(actual.getNewParameterTypes(), Collections.emptySet(),
Collections.singletonList(MySQLBinaryColumnType.DATE)).get(0);
+ assertThat(actualValue, isA(Date.class));
+ assertThat(actualValue, is(Date.valueOf("2017-08-08")));
+ }
+
+ @Test
+ void assertReadParametersWithDatetimeParameterBoundToDateColumn() throws
SQLException {
+ byte[] data = {0x01, 0x00, 0x00, 0x00, 0x09, 0x01, 0x00, 0x00, 0x00,
0x00, 0x01, 0x0c, 0x00, 0x04, (byte) 0xe1, 0x07, 0x08, 0x08};
+ MySQLPacketPayload payload = new
MySQLPacketPayload(Unpooled.wrappedBuffer(data), StandardCharsets.UTF_8);
+ MySQLComStmtExecutePacket actual = new
MySQLComStmtExecutePacket(payload, 1);
+ Object actualValue =
actual.readParameters(actual.getNewParameterTypes(), Collections.emptySet(),
Collections.singletonList(MySQLBinaryColumnType.DATE)).get(0);
+ assertThat(actualValue, isA(Date.class));
+ assertThat(actualValue, is(Date.valueOf("2017-08-08")));
+ }
+
@ParameterizedTest(name = "{0}")
@MethodSource("stringParameterTypesBoundToBlobColumnsArguments")
void assertReadParametersWithStringTypeBoundToBlobColumn(final String
name, final MySQLBinaryColumnType parameterType,
diff --git
a/parser/sql/engine/core/src/main/java/org/apache/shardingsphere/sql/parser/engine/core/database/visitor/SQLVisitorRule.java
b/parser/sql/engine/core/src/main/java/org/apache/shardingsphere/sql/parser/engine/core/database/visitor/SQLVisitorRule.java
index 3b042b3a844..122c7f6e69d 100644
---
a/parser/sql/engine/core/src/main/java/org/apache/shardingsphere/sql/parser/engine/core/database/visitor/SQLVisitorRule.java
+++
b/parser/sql/engine/core/src/main/java/org/apache/shardingsphere/sql/parser/engine/core/database/visitor/SQLVisitorRule.java
@@ -103,6 +103,8 @@ public enum SQLVisitorRule {
CREATE_PROCEDURE("CreateProcedure", SQLStatementType.DDL),
+ CREATE_PACKAGE("CreatePackage", SQLStatementType.DDL),
+
CREATE_PUBLICATION("CreatePublication", SQLStatementType.DDL),
ALTER_PUBLICATION("AlterPublication", SQLStatementType.DDL),
diff --git
a/parser/sql/engine/dialect/mysql/src/main/java/org/apache/shardingsphere/sql/parser/engine/mysql/visitor/statement/type/MySQLDDLStatementVisitor.java
b/parser/sql/engine/dialect/mysql/src/main/java/org/apache/shardingsphere/sql/parser/engine/mysql/visitor/statement/type/MySQLDDLStatementVisitor.java
index 7849b048cce..0f7dcc7a49b 100644
---
a/parser/sql/engine/dialect/mysql/src/main/java/org/apache/shardingsphere/sql/parser/engine/mysql/visitor/statement/type/MySQLDDLStatementVisitor.java
+++
b/parser/sql/engine/dialect/mysql/src/main/java/org/apache/shardingsphere/sql/parser/engine/mysql/visitor/statement/type/MySQLDDLStatementVisitor.java
@@ -280,17 +280,22 @@ public final class MySQLDDLStatementVisitor extends
MySQLStatementVisitor implem
}
}
}
- return CreateTableStatement.builder()
+ SelectStatement selectStatement = null ==
ctx.duplicateAsQueryExpression() ? null : (SelectStatement)
visit(ctx.duplicateAsQueryExpression().select());
+ CreateTableStatement result = CreateTableStatement.builder()
.databaseType(getDatabaseType())
.table((SimpleTableSegment) visit(ctx.tableName()))
.ifNotExists(null != ctx.ifNotExists())
.temporary(null != ctx.TEMPORARY())
.likeTable(null == ctx.createLikeClause() ? null :
(SimpleTableSegment) visit(ctx.createLikeClause()))
.createTableOption(null == ctx.createTableOptions() ? null :
(CreateTableOptionSegment) visit(ctx.createTableOptions()))
- .selectStatement(null == ctx.duplicateAsQueryExpression() ?
null : (SelectStatement) visit(ctx.duplicateAsQueryExpression().select()))
+ .selectStatement(selectStatement)
.columnDefinitions(columnDefinitions)
.constraintDefinitions(constraintDefinitions)
.build();
+ if (null != selectStatement) {
+ result.addParameterMarkers(selectStatement.getParameterMarkers());
+ }
+ return result;
}
@Override
diff --git
a/parser/sql/engine/dialect/mysql/src/test/java/org/apache/shardingsphere/sql/parser/engine/mysql/visitor/statement/MySQLStatementVisitorTest.java
b/parser/sql/engine/dialect/mysql/src/test/java/org/apache/shardingsphere/sql/parser/engine/mysql/visitor/statement/MySQLStatementVisitorTest.java
index 2de19c09282..a7e1df80c60 100644
---
a/parser/sql/engine/dialect/mysql/src/test/java/org/apache/shardingsphere/sql/parser/engine/mysql/visitor/statement/MySQLStatementVisitorTest.java
+++
b/parser/sql/engine/dialect/mysql/src/test/java/org/apache/shardingsphere/sql/parser/engine/mysql/visitor/statement/MySQLStatementVisitorTest.java
@@ -57,6 +57,13 @@ class MySQLStatementVisitorTest {
assertThat(from.getTableName().getIdentifier().getValue(),
is("source_table"));
}
+ @Test
+ void assertVisitCreateTableAsSelectWithParameterMarkers() {
+ CreateTableStatement statement = (CreateTableStatement) parse("CREATE
TABLE t_projection AS SELECT id, name FROM source_table WHERE status = ? AND
type IN (?, ?)");
+ assertThat(statement.getParameterCount(), is(3));
+ assertThat(statement.getParameterMarkers().size(), is(3));
+ }
+
@Test
void assertVisitCreateTableAsSelectWithWindowFunction() {
CreateTableStatement statement = (CreateTableStatement) parse(
diff --git
a/parser/sql/engine/dialect/oracle/src/main/antlr4/imports/oracle/PLSQL.g4
b/parser/sql/engine/dialect/oracle/src/main/antlr4/imports/oracle/PLSQL.g4
index ec9e6b4346d..ddac69a9771 100644
--- a/parser/sql/engine/dialect/oracle/src/main/antlr4/imports/oracle/PLSQL.g4
+++ b/parser/sql/engine/dialect/oracle/src/main/antlr4/imports/oracle/PLSQL.g4
@@ -66,6 +66,36 @@ createProcedure
: CREATE (OR REPLACE)? (EDITIONABLE | NONEDITIONABLE)? PROCEDURE
plsqlProcedureSource
;
+createPackage
+ : CREATE (OR REPLACE)? (EDITIONABLE | NONEDITIONABLE)? PACKAGE
(plsqlPackageSource | BODY plsqlPackageBodySource)
+ ;
+
+plsqlPackageSource
+ : packageIfNotExists? (schemaName DOT_)? packageName sharingClause?
(defaultCollationClause | invokerRightsClause | accessibleByClause)* (IS | AS)
+ packageSpecificationItem* END packageName? SEMI_?
+ ;
+
+packageSpecificationItem
+ : typeDefinition
+ | cursorDeclaration
+ | itemDeclaration
+ | functionDeclaration SEMI_
+ | procedureDeclaration SEMI_
+ | pragma
+ ;
+
+plsqlPackageBodySource
+ : packageIfNotExists? (schemaName DOT_)? packageName (IS | AS)
declareItem*? packageInitialization? END packageName? SEMI_?
+ ;
+
+packageIfNotExists
+ : IF NOT EXISTS
+ ;
+
+packageInitialization
+ : BEGIN plsqlStatements (EXCEPTION exceptionHandler+)?
+ ;
+
plsqlProcedureSource
: (schemaName DOT_)? procedureName (LP_ parameterDeclaration (COMMA_
parameterDeclaration)* RP_)? sharingClause?
((defaultCollationClause | invokerRightsClause | accessibleByClause)*)?
(IS | AS) (callSpec | declareSection? body)
diff --git
a/parser/sql/engine/dialect/oracle/src/main/antlr4/org/apache/shardingsphere/sql/parser/autogen/OracleStatement.g4
b/parser/sql/engine/dialect/oracle/src/main/antlr4/org/apache/shardingsphere/sql/parser/autogen/OracleStatement.g4
index e5f811a9b9a..eab2f43ad52 100644
---
a/parser/sql/engine/dialect/oracle/src/main/antlr4/org/apache/shardingsphere/sql/parser/autogen/OracleStatement.g4
+++
b/parser/sql/engine/dialect/oracle/src/main/antlr4/org/apache/shardingsphere/sql/parser/autogen/OracleStatement.g4
@@ -69,6 +69,7 @@ execute
| alterDimension
| dropDimension
| createFunction
+ | createPackage
| dropDatabaseLink
| dropDirectory
| dropView
diff --git
a/parser/sql/engine/dialect/oracle/src/main/java/org/apache/shardingsphere/sql/parser/engine/oracle/visitor/statement/type/OracleDDLStatementVisitor.java
b/parser/sql/engine/dialect/oracle/src/main/java/org/apache/shardingsphere/sql/parser/engine/oracle/visitor/statement/type/OracleDDLStatementVisitor.java
index da647e8ef00..1520e38b017 100644
---
a/parser/sql/engine/dialect/oracle/src/main/java/org/apache/shardingsphere/sql/parser/engine/oracle/visitor/statement/type/OracleDDLStatementVisitor.java
+++
b/parser/sql/engine/dialect/oracle/src/main/java/org/apache/shardingsphere/sql/parser/engine/oracle/visitor/statement/type/OracleDDLStatementVisitor.java
@@ -23,6 +23,7 @@ import org.antlr.v4.runtime.tree.ParseTree;
import org.apache.shardingsphere.database.connector.core.type.DatabaseType;
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;
@@ -99,6 +100,7 @@ import
org.apache.shardingsphere.sql.parser.autogen.OracleStatementParser.Create
import
org.apache.shardingsphere.sql.parser.autogen.OracleStatementParser.CreateOperatorContext;
import
org.apache.shardingsphere.sql.parser.autogen.OracleStatementParser.CreateOutlineContext;
import
org.apache.shardingsphere.sql.parser.autogen.OracleStatementParser.CreatePFileContext;
+import
org.apache.shardingsphere.sql.parser.autogen.OracleStatementParser.CreatePackageContext;
import
org.apache.shardingsphere.sql.parser.autogen.OracleStatementParser.CreateProcedureContext;
import
org.apache.shardingsphere.sql.parser.autogen.OracleStatementParser.CreateProfileContext;
import
org.apache.shardingsphere.sql.parser.autogen.OracleStatementParser.CreateRelationalTableClauseContext;
@@ -187,6 +189,7 @@ import
org.apache.shardingsphere.sql.parser.autogen.OracleStatementParser.Packag
import
org.apache.shardingsphere.sql.parser.autogen.OracleStatementParser.ParameterDeclarationContext;
import
org.apache.shardingsphere.sql.parser.autogen.OracleStatementParser.PlsqlBlockContext;
import
org.apache.shardingsphere.sql.parser.autogen.OracleStatementParser.PlsqlFunctionSourceContext;
+import
org.apache.shardingsphere.sql.parser.autogen.OracleStatementParser.PlsqlPackageSourceContext;
import
org.apache.shardingsphere.sql.parser.autogen.OracleStatementParser.PlsqlProcedureSourceContext;
import
org.apache.shardingsphere.sql.parser.autogen.OracleStatementParser.PlsqlStatementsContext;
import
org.apache.shardingsphere.sql.parser.autogen.OracleStatementParser.PlsqlTriggerSourceContext;
@@ -228,6 +231,7 @@ import
org.apache.shardingsphere.sql.parser.statement.core.segment.ddl.index.Ind
import
org.apache.shardingsphere.sql.parser.statement.core.segment.ddl.index.IndexTypeSegment;
import
org.apache.shardingsphere.sql.parser.statement.core.segment.ddl.packages.PackageSegment;
import
org.apache.shardingsphere.sql.parser.statement.core.segment.ddl.routine.FunctionNameSegment;
+import
org.apache.shardingsphere.sql.parser.statement.core.segment.ddl.routine.RoutineBodySegment;
import
org.apache.shardingsphere.sql.parser.statement.core.segment.ddl.tablespace.TablespaceSegment;
import
org.apache.shardingsphere.sql.parser.statement.core.segment.ddl.type.TypeDefinitionSegment;
import
org.apache.shardingsphere.sql.parser.statement.core.segment.ddl.type.TypeSegment;
@@ -349,6 +353,9 @@ import
org.apache.shardingsphere.sql.parser.statement.oracle.ddl.lockdown.Oracle
import
org.apache.shardingsphere.sql.parser.statement.oracle.ddl.outline.OracleAlterOutlineStatement;
import
org.apache.shardingsphere.sql.parser.statement.oracle.ddl.outline.OracleCreateOutlineStatement;
import
org.apache.shardingsphere.sql.parser.statement.oracle.ddl.outline.OracleDropOutlineStatement;
+import
org.apache.shardingsphere.sql.parser.statement.oracle.ddl.pkg.OracleCreatePackageStatement;
+import
org.apache.shardingsphere.sql.parser.statement.oracle.ddl.pkg.OracleCreatePackageStatement.Authorization;
+import
org.apache.shardingsphere.sql.parser.statement.oracle.ddl.pkg.OracleCreatePackageStatement.Edition;
import
org.apache.shardingsphere.sql.parser.statement.oracle.ddl.procedure.OracleCreateProcedureStatement;
import
org.apache.shardingsphere.sql.parser.statement.oracle.ddl.profile.OracleAlterProfileStatement;
import
org.apache.shardingsphere.sql.parser.statement.oracle.ddl.profile.OracleCreateProfileStatement;
@@ -845,6 +852,60 @@ public final class OracleDDLStatementVisitor extends
OracleStatementVisitor impl
return new DropPackageStatement(getDatabaseType());
}
+ @Override
+ public ASTNode visitCreatePackage(final CreatePackageContext ctx) {
+ OracleStatementParser.PlsqlPackageBodySourceContext body =
ctx.plsqlPackageBodySource();
+ if (null != body) {
+ body.declareItem().forEach(this::visit);
+ }
+ RoutineBodySegment initialization = null;
+ if (null != body && null != body.packageInitialization()) {
+ OracleStatementParser.PackageInitializationContext
packageInitialization = body.packageInitialization();
+ visitPlsqlStatementList(packageInitialization.plsqlStatements());
+ for (ExceptionHandlerContext each :
packageInitialization.exceptionHandler()) {
+ visitPlsqlStatementList(each.plsqlStatements());
+ }
+ initialization = new
RoutineBodySegment(packageInitialization.start.getStartIndex(),
packageInitialization.stop.getStopIndex());
+ }
+
getSqlStatementsInPlsql().sort(Comparator.comparingInt(SQLStatementSegment::getStartIndex));
+
getProcedureCallNames().sort(Comparator.comparingInt(ProcedureCallNameSegment::getStartIndex));
+
getDynamicSqlStatementExpressions().sort(Comparator.comparingInt(ExpressionSegment::getStartIndex));
+ PlsqlPackageSourceContext specification = ctx.plsqlPackageSource();
+ PackageSegment packageName = null == specification
+ ? createPackageNameSegment(body.schemaName(),
body.packageName(0))
+ : createPackageNameSegment(specification.schemaName(),
specification.packageName(0));
+ OracleCreatePackageStatement result = new OracleCreatePackageStatement(
+ getDatabaseType(), packageName, null != body, null !=
ctx.REPLACE(),
+ null == specification ? null != body.packageIfNotExists() :
null != specification.packageIfNotExists(),
+ getEdition(ctx), getAuthorization(specification),
initialization);
+ result.getSqlStatements().addAll(getSqlStatementsInPlsql());
+ result.getProcedureCallNames().addAll(getProcedureCallNames());
+
result.getDynamicSqlStatementExpressions().addAll(getDynamicSqlStatementExpressions());
+ return result;
+ }
+
+ private PackageSegment createPackageNameSegment(final SchemaNameContext
schemaName, final PackageNameContext packageName) {
+ PackageSegment result = (PackageSegment) visit(packageName);
+ if (null != schemaName) {
+ result.setOwner(new OwnerSegment(schemaName.start.getStartIndex(),
schemaName.stop.getStopIndex(), (IdentifierValue)
visit(schemaName.identifier())));
+ }
+ return result;
+ }
+
+ private Edition getEdition(final CreatePackageContext ctx) {
+ if (null != ctx.EDITIONABLE()) {
+ return Edition.EDITIONABLE;
+ }
+ return null == ctx.NONEDITIONABLE() ? null : Edition.NONEDITIONABLE;
+ }
+
+ private Authorization getAuthorization(final PlsqlPackageSourceContext
ctx) {
+ if (null == ctx || ctx.invokerRightsClause().isEmpty()) {
+ return null;
+ }
+ return null == ctx.invokerRightsClause(0).CURRENT_USER() ?
Authorization.DEFINER : Authorization.CURRENT_USER;
+ }
+
@Override
public ASTNode visitAlterPackage(final AlterPackageContext ctx) {
return new AlterPackageStatement(getDatabaseType());
diff --git
a/parser/sql/engine/dialect/oracle/src/test/java/org/apache/shardingsphere/sql/parser/engine/oracle/visitor/statement/type/OracleDDLStatementVisitorTest.java
b/parser/sql/engine/dialect/oracle/src/test/java/org/apache/shardingsphere/sql/parser/engine/oracle/visitor/statement/type/OracleDDLStatementVisitorTest.java
index d63d6224ab4..226af9e7209 100644
---
a/parser/sql/engine/dialect/oracle/src/test/java/org/apache/shardingsphere/sql/parser/engine/oracle/visitor/statement/type/OracleDDLStatementVisitorTest.java
+++
b/parser/sql/engine/dialect/oracle/src/test/java/org/apache/shardingsphere/sql/parser/engine/oracle/visitor/statement/type/OracleDDLStatementVisitorTest.java
@@ -21,10 +21,14 @@ import
org.apache.shardingsphere.sql.parser.engine.api.CacheOption;
import org.apache.shardingsphere.sql.parser.engine.api.SQLParserEngine;
import
org.apache.shardingsphere.sql.parser.engine.api.SQLStatementVisitorEngine;
import
org.apache.shardingsphere.sql.parser.statement.core.statement.type.ddl.table.CreateTableStatement;
+import
org.apache.shardingsphere.sql.parser.statement.oracle.ddl.pkg.OracleCreatePackageStatement;
+import
org.apache.shardingsphere.sql.parser.statement.oracle.ddl.pkg.OracleCreatePackageStatement.Authorization;
+import
org.apache.shardingsphere.sql.parser.statement.oracle.ddl.pkg.OracleCreatePackageStatement.Edition;
import org.junit.jupiter.api.Test;
import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.Matchers.is;
+import static org.junit.jupiter.api.Assertions.assertFalse;
import static org.junit.jupiter.api.Assertions.assertTrue;
class OracleDDLStatementVisitorTest {
@@ -68,7 +72,45 @@ class OracleDDLStatementVisitorTest {
assertTrue(actual.getSelectStatement().isPresent());
}
+ @Test
+ void assertVisitCreatePackage() {
+ OracleCreatePackageStatement actual = parseCreatePackage(
+ "CREATE OR REPLACE EDITIONABLE PACKAGE IF NOT EXISTS
foo_schema.foo_pkg AUTHID CURRENT_USER AS g_public NUMBER := 1; PROCEDURE
set_value(p_value IN NUMBER); END foo_pkg;");
+ assertThat(actual.getPackageName().getIdentifier().getValue(),
is("foo_pkg"));
+
assertThat(actual.getPackageName().getOwner().get().getIdentifier().getValue(),
is("foo_schema"));
+ assertFalse(actual.isBody());
+ assertTrue(actual.isReplace());
+ assertTrue(actual.isIfNotExists());
+ assertThat(actual.getEdition().get(), is(Edition.EDITIONABLE));
+ assertThat(actual.getAuthorization().get(),
is(Authorization.CURRENT_USER));
+ assertFalse(actual.getInitialization().isPresent());
+ }
+
+ @Test
+ void assertVisitCreatePackageBody() {
+ OracleCreatePackageStatement actual = parseCreatePackage("CREATE OR
REPLACE NONEDITIONABLE PACKAGE BODY foo_schema.foo_pkg AS"
+ + " PROCEDURE set_value(p_value IN NUMBER) AS BEGIN INSERT
INTO t_order VALUES (p_value); END;"
+ + " BEGIN UPDATE t_order SET order_id = 1; END foo_pkg;");
+ assertThat(actual.getPackageName().getIdentifier().getValue(),
is("foo_pkg"));
+
assertThat(actual.getPackageName().getOwner().get().getIdentifier().getValue(),
is("foo_schema"));
+ assertTrue(actual.isBody());
+ assertTrue(actual.isReplace());
+ assertFalse(actual.isIfNotExists());
+ assertThat(actual.getEdition().get(), is(Edition.NONEDITIONABLE));
+ assertFalse(actual.getAuthorization().isPresent());
+ assertTrue(actual.getInitialization().isPresent());
+ assertThat(actual.getSqlStatements().size(), is(2));
+ }
+
private CreateTableStatement parse(final String sql) {
- return (CreateTableStatement) new
SQLStatementVisitorEngine("Oracle").visit(new SQLParserEngine("Oracle",
CACHE_OPTION).parse(sql, false));
+ return (CreateTableStatement) parseStatement(sql);
+ }
+
+ private OracleCreatePackageStatement parseCreatePackage(final String sql) {
+ return (OracleCreatePackageStatement) parseStatement(sql);
+ }
+
+ private Object parseStatement(final String sql) {
+ return new SQLStatementVisitorEngine("Oracle").visit(new
SQLParserEngine("Oracle", CACHE_OPTION).parse(sql, false));
}
}
diff --git
a/parser/sql/statement/dialect/oracle/src/main/java/org/apache/shardingsphere/sql/parser/statement/oracle/ddl/pkg/OracleCreatePackageStatement.java
b/parser/sql/statement/dialect/oracle/src/main/java/org/apache/shardingsphere/sql/parser/statement/oracle/ddl/pkg/OracleCreatePackageStatement.java
new file mode 100644
index 00000000000..7ce313184fc
--- /dev/null
+++
b/parser/sql/statement/dialect/oracle/src/main/java/org/apache/shardingsphere/sql/parser/statement/oracle/ddl/pkg/OracleCreatePackageStatement.java
@@ -0,0 +1,102 @@
+/*
+ * 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.statement.oracle.ddl.pkg;
+
+import lombok.Getter;
+import org.apache.shardingsphere.database.connector.core.type.DatabaseType;
+import
org.apache.shardingsphere.sql.parser.statement.core.segment.ddl.packages.PackageSegment;
+import
org.apache.shardingsphere.sql.parser.statement.core.segment.ddl.routine.RoutineBodySegment;
+import
org.apache.shardingsphere.sql.parser.statement.core.segment.dml.expr.ExpressionSegment;
+import
org.apache.shardingsphere.sql.parser.statement.core.segment.procedure.ProcedureCallNameSegment;
+import
org.apache.shardingsphere.sql.parser.statement.core.segment.procedure.SQLStatementSegment;
+import
org.apache.shardingsphere.sql.parser.statement.core.statement.type.ddl.DDLStatement;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Optional;
+
+/**
+ * Create package statement for Oracle.
+ */
+@Getter
+public final class OracleCreatePackageStatement extends DDLStatement {
+
+ private final PackageSegment packageName;
+
+ private final boolean body;
+
+ private final boolean replace;
+
+ private final boolean ifNotExists;
+
+ private final Optional<Edition> edition;
+
+ private final Optional<Authorization> authorization;
+
+ private final Optional<RoutineBodySegment> initialization;
+
+ private final List<SQLStatementSegment> sqlStatements = new ArrayList<>();
+
+ private final List<ProcedureCallNameSegment> procedureCallNames = new
ArrayList<>();
+
+ private final List<ExpressionSegment> dynamicSqlStatementExpressions = new
ArrayList<>();
+
+ /**
+ * Construct an Oracle create package statement.
+ *
+ * @param databaseType database type
+ * @param packageName package name
+ * @param body whether this statement creates a package body
+ * @param replace whether existing package should be replaced
+ * @param ifNotExists whether creation should be skipped when the package
exists
+ * @param edition edition mode, or {@code null} when unspecified
+ * @param authorization authorization mode, or {@code null} when
unspecified
+ * @param initialization package initialization body, or {@code null} when
absent
+ */
+ public OracleCreatePackageStatement(final DatabaseType databaseType, final
PackageSegment packageName, final boolean body, final boolean replace,
+ final boolean ifNotExists, final
Edition edition, final Authorization authorization, final RoutineBodySegment
initialization) {
+ super(databaseType);
+ this.packageName = packageName;
+ this.body = body;
+ this.replace = replace;
+ this.ifNotExists = ifNotExists;
+ this.edition = Optional.ofNullable(edition);
+ this.authorization = Optional.ofNullable(authorization);
+ this.initialization = Optional.ofNullable(initialization);
+ }
+
+ /**
+ * Oracle package edition mode.
+ */
+ public enum Edition {
+
+ EDITIONABLE,
+
+ NONEDITIONABLE
+ }
+
+ /**
+ * Oracle package authorization mode.
+ */
+ public enum Authorization {
+
+ CURRENT_USER,
+
+ DEFINER
+ }
+}
diff --git
a/test/it/parser/src/main/java/org/apache/shardingsphere/test/it/sql/parser/internal/asserts/statement/ddl/dialect/oracle/OracleDDLStatementAssert.java
b/test/it/parser/src/main/java/org/apache/shardingsphere/test/it/sql/parser/internal/asserts/statement/ddl/dialect/oracle/OracleDDLStatementAssert.java
index 93f647d35bf..9beebbe4e75 100644
---
a/test/it/parser/src/main/java/org/apache/shardingsphere/test/it/sql/parser/internal/asserts/statement/ddl/dialect/oracle/OracleDDLStatementAssert.java
+++
b/test/it/parser/src/main/java/org/apache/shardingsphere/test/it/sql/parser/internal/asserts/statement/ddl/dialect/oracle/OracleDDLStatementAssert.java
@@ -27,6 +27,7 @@ import
org.apache.shardingsphere.sql.parser.statement.oracle.ddl.OracleAuditStat
import
org.apache.shardingsphere.sql.parser.statement.oracle.ddl.OracleNoAuditStatement;
import
org.apache.shardingsphere.sql.parser.statement.oracle.ddl.OraclePurgeStatement;
import
org.apache.shardingsphere.sql.parser.statement.oracle.ddl.flashback.OracleFlashbackTableStatement;
+import
org.apache.shardingsphere.sql.parser.statement.oracle.ddl.pkg.OracleCreatePackageStatement;
import
org.apache.shardingsphere.sql.parser.statement.oracle.ddl.statistics.OracleAssociateStatisticsStatement;
import
org.apache.shardingsphere.sql.parser.statement.oracle.ddl.statistics.OracleDisassociateStatisticsStatement;
import
org.apache.shardingsphere.test.it.sql.parser.internal.asserts.SQLCaseAssertContext;
@@ -35,6 +36,7 @@ import
org.apache.shardingsphere.test.it.sql.parser.internal.asserts.statement.d
import
org.apache.shardingsphere.test.it.sql.parser.internal.asserts.statement.ddl.dialect.oracle.type.OracleAnalyzeStatementAssert;
import
org.apache.shardingsphere.test.it.sql.parser.internal.asserts.statement.ddl.dialect.oracle.type.OracleAssociateStatisticsStatementAssert;
import
org.apache.shardingsphere.test.it.sql.parser.internal.asserts.statement.ddl.dialect.oracle.type.OracleAuditStatementAssert;
+import
org.apache.shardingsphere.test.it.sql.parser.internal.asserts.statement.ddl.dialect.oracle.type.OracleCreatePackageStatementAssert;
import
org.apache.shardingsphere.test.it.sql.parser.internal.asserts.statement.ddl.dialect.oracle.type.OracleDisassociateStatisticsStatementAssert;
import
org.apache.shardingsphere.test.it.sql.parser.internal.asserts.statement.ddl.dialect.oracle.type.OracleFlashbackTableStatementAssert;
import
org.apache.shardingsphere.test.it.sql.parser.internal.asserts.statement.ddl.dialect.oracle.type.OracleNoAuditStatementAssert;
@@ -44,6 +46,7 @@ import
org.apache.shardingsphere.test.it.sql.parser.internal.cases.parser.jaxb.s
import
org.apache.shardingsphere.test.it.sql.parser.internal.cases.parser.jaxb.statement.ddl.dialect.oracle.OracleAlterSystemStatementTestCase;
import
org.apache.shardingsphere.test.it.sql.parser.internal.cases.parser.jaxb.statement.ddl.dialect.oracle.OracleAnalyzeStatementTestCase;
import
org.apache.shardingsphere.test.it.sql.parser.internal.cases.parser.jaxb.statement.ddl.dialect.oracle.OracleAuditStatementTestCase;
+import
org.apache.shardingsphere.test.it.sql.parser.internal.cases.parser.jaxb.statement.ddl.dialect.oracle.OracleCreatePackageStatementTestCase;
import
org.apache.shardingsphere.test.it.sql.parser.internal.cases.parser.jaxb.statement.ddl.dialect.oracle.OracleNoAuditStatementTestCase;
import
org.apache.shardingsphere.test.it.sql.parser.internal.cases.parser.jaxb.statement.ddl.dialect.oracle.OraclePurgeStatementTestCase;
import
org.apache.shardingsphere.test.it.sql.parser.internal.cases.parser.jaxb.statement.ddl.dialect.oracle.flashback.OracleFlashbackTableStatementTestCase;
@@ -76,6 +79,8 @@ public final class OracleDDLStatementAssert {
OracleDisassociateStatisticsStatementAssert.assertIs(assertContext,
(OracleDisassociateStatisticsStatement) actual,
(OracleDisassociateStatisticsStatementTestCase) expected);
} else if (actual instanceof OracleAuditStatement) {
OracleAuditStatementAssert.assertIs(assertContext,
(OracleAuditStatement) actual, (OracleAuditStatementTestCase) expected);
+ } else if (actual instanceof OracleCreatePackageStatement) {
+ OracleCreatePackageStatementAssert.assertIs(assertContext,
(OracleCreatePackageStatement) actual, (OracleCreatePackageStatementTestCase)
expected);
} else if (actual instanceof OracleNoAuditStatement) {
OracleNoAuditStatementAssert.assertIs(assertContext,
(OracleNoAuditStatement) actual, (OracleNoAuditStatementTestCase) expected);
} else if (actual instanceof OracleFlashbackTableStatement) {
diff --git
a/test/it/parser/src/main/java/org/apache/shardingsphere/test/it/sql/parser/internal/asserts/statement/ddl/dialect/oracle/type/OracleCreatePackageStatementAssert.java
b/test/it/parser/src/main/java/org/apache/shardingsphere/test/it/sql/parser/internal/asserts/statement/ddl/dialect/oracle/type/OracleCreatePackageStatementAssert.java
new file mode 100644
index 00000000000..76bdd1892a0
--- /dev/null
+++
b/test/it/parser/src/main/java/org/apache/shardingsphere/test/it/sql/parser/internal/asserts/statement/ddl/dialect/oracle/type/OracleCreatePackageStatementAssert.java
@@ -0,0 +1,52 @@
+/*
+ * 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.test.it.sql.parser.internal.asserts.statement.ddl.dialect.oracle.type;
+
+import lombok.AccessLevel;
+import lombok.NoArgsConstructor;
+import
org.apache.shardingsphere.sql.parser.statement.oracle.ddl.pkg.OracleCreatePackageStatement;
+import
org.apache.shardingsphere.test.it.sql.parser.internal.asserts.SQLCaseAssertContext;
+import
org.apache.shardingsphere.test.it.sql.parser.internal.asserts.segment.packages.PackageAssert;
+import
org.apache.shardingsphere.test.it.sql.parser.internal.cases.parser.jaxb.statement.ddl.dialect.oracle.OracleCreatePackageStatementTestCase;
+
+import static org.hamcrest.MatcherAssert.assertThat;
+import static org.hamcrest.Matchers.is;
+
+/**
+ * Create package statement assert for Oracle.
+ */
+@NoArgsConstructor(access = AccessLevel.PRIVATE)
+public final class OracleCreatePackageStatementAssert {
+
+ /**
+ * Assert create package statement is correct with expected parser result.
+ *
+ * @param assertContext assert context
+ * @param actual actual create package statement
+ * @param expected expected create package statement test case
+ */
+ public static void assertIs(final SQLCaseAssertContext assertContext,
final OracleCreatePackageStatement actual, final
OracleCreatePackageStatementTestCase expected) {
+ PackageAssert.assertIs(assertContext, actual.getPackageName(),
expected.getPackageName());
+ assertThat(assertContext.getText("Package body assertion error: "),
actual.isBody(), is(expected.isBody()));
+ assertThat(assertContext.getText("Package replacement assertion error:
"), actual.isReplace(), is(expected.isReplace()));
+ assertThat(assertContext.getText("Package IF NOT EXISTS assertion
error: "), actual.isIfNotExists(), is(expected.isIfNotExists()));
+ assertThat(assertContext.getText("Package edition assertion error: "),
actual.getEdition().map(Enum::name).orElse(null), is(expected.getEdition()));
+ assertThat(assertContext.getText("Package authorization assertion
error: "), actual.getAuthorization().map(Enum::name).orElse(null),
is(expected.getAuthorization()));
+ assertThat(assertContext.getText("Package initialization assertion
error: "), actual.getInitialization().isPresent(),
is(expected.isHasInitialization()));
+ }
+}
diff --git
a/test/it/parser/src/main/java/org/apache/shardingsphere/test/it/sql/parser/internal/cases/parser/jaxb/RootSQLParserTestCases.java
b/test/it/parser/src/main/java/org/apache/shardingsphere/test/it/sql/parser/internal/cases/parser/jaxb/RootSQLParserTestCases.java
index 7cf51cdbfdd..f028486af0d 100644
---
a/test/it/parser/src/main/java/org/apache/shardingsphere/test/it/sql/parser/internal/cases/parser/jaxb/RootSQLParserTestCases.java
+++
b/test/it/parser/src/main/java/org/apache/shardingsphere/test/it/sql/parser/internal/cases/parser/jaxb/RootSQLParserTestCases.java
@@ -168,6 +168,7 @@ import
org.apache.shardingsphere.test.it.sql.parser.internal.cases.parser.jaxb.s
import
org.apache.shardingsphere.test.it.sql.parser.internal.cases.parser.jaxb.statement.ddl.dialect.oracle.OracleAlterSystemStatementTestCase;
import
org.apache.shardingsphere.test.it.sql.parser.internal.cases.parser.jaxb.statement.ddl.dialect.oracle.OracleAnalyzeStatementTestCase;
import
org.apache.shardingsphere.test.it.sql.parser.internal.cases.parser.jaxb.statement.ddl.dialect.oracle.OracleAuditStatementTestCase;
+import
org.apache.shardingsphere.test.it.sql.parser.internal.cases.parser.jaxb.statement.ddl.dialect.oracle.OracleCreatePackageStatementTestCase;
import
org.apache.shardingsphere.test.it.sql.parser.internal.cases.parser.jaxb.statement.ddl.dialect.oracle.OracleDropPackageStatementTestCase;
import
org.apache.shardingsphere.test.it.sql.parser.internal.cases.parser.jaxb.statement.ddl.dialect.oracle.OracleNoAuditStatementTestCase;
import
org.apache.shardingsphere.test.it.sql.parser.internal.cases.parser.jaxb.statement.ddl.dialect.oracle.OraclePurgeStatementTestCase;
@@ -993,6 +994,9 @@ public final class RootSQLParserTestCases {
@XmlElement(name = "drop-package")
private final List<OracleDropPackageStatementTestCase>
dropPackageTestCases = new LinkedList<>();
+ @XmlElement(name = "create-package")
+ private final List<OracleCreatePackageStatementTestCase>
createPackageTestCases = new LinkedList<>();
+
@XmlElement(name = "create-dimension")
private final List<OracleCreateDimensionStatementTestCase>
createDimensionTestCases = new LinkedList<>();
diff --git
a/test/it/parser/src/main/java/org/apache/shardingsphere/test/it/sql/parser/internal/cases/parser/jaxb/statement/ddl/dialect/oracle/OracleCreatePackageStatementTestCase.java
b/test/it/parser/src/main/java/org/apache/shardingsphere/test/it/sql/parser/internal/cases/parser/jaxb/statement/ddl/dialect/oracle/OracleCreatePackageStatementTestCase.java
new file mode 100644
index 00000000000..187056b29eb
--- /dev/null
+++
b/test/it/parser/src/main/java/org/apache/shardingsphere/test/it/sql/parser/internal/cases/parser/jaxb/statement/ddl/dialect/oracle/OracleCreatePackageStatementTestCase.java
@@ -0,0 +1,55 @@
+/*
+ * 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.test.it.sql.parser.internal.cases.parser.jaxb.statement.ddl.dialect.oracle;
+
+import lombok.Getter;
+import lombok.Setter;
+import
org.apache.shardingsphere.test.it.sql.parser.internal.cases.parser.jaxb.SQLParserTestCase;
+import
org.apache.shardingsphere.test.it.sql.parser.internal.cases.parser.jaxb.segment.impl.packages.ExpectedPackage;
+
+import javax.xml.bind.annotation.XmlAttribute;
+import javax.xml.bind.annotation.XmlElement;
+
+/**
+ * Create package statement test case for Oracle.
+ */
+@Getter
+@Setter
+public final class OracleCreatePackageStatementTestCase extends
SQLParserTestCase {
+
+ @XmlElement(name = "package")
+ private ExpectedPackage packageName;
+
+ @XmlAttribute
+ private boolean body;
+
+ @XmlAttribute
+ private boolean replace;
+
+ @XmlAttribute(name = "if-not-exists")
+ private boolean ifNotExists;
+
+ @XmlAttribute
+ private String edition;
+
+ @XmlAttribute
+ private String authorization;
+
+ @XmlAttribute(name = "has-initialization")
+ private boolean hasInitialization;
+}
diff --git a/test/it/parser/src/main/resources/case/ddl/create-package.xml
b/test/it/parser/src/main/resources/case/ddl/create-package.xml
new file mode 100644
index 00000000000..b2832f53512
--- /dev/null
+++ b/test/it/parser/src/main/resources/case/ddl/create-package.xml
@@ -0,0 +1,35 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ ~ 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.
+ -->
+
+<sql-parser-test-cases>
+ <create-package sql-case-id="create_or_replace_editionable_package"
replace="true" edition="EDITIONABLE" authorization="CURRENT_USER">
+ <package name="foo_pkg" start-index="49" stop-index="55">
+ <owner name="foo_schema" start-index="38" stop-index="47" />
+ </package>
+ </create-package>
+
+ <create-package
sql-case-id="create_or_replace_noneditionable_package_body" body="true"
replace="true" edition="NONEDITIONABLE" has-initialization="true">
+ <package name="foo_pkg" start-index="57" stop-index="63">
+ <owner name="foo_schema" start-index="46" stop-index="55" />
+ </package>
+ </create-package>
+
+ <create-package sql-case-id="create_package_body_if_not_exists"
body="true" if-not-exists="true">
+ <package name="foo_pkg" start-index="34" stop-index="40" />
+ </create-package>
+</sql-parser-test-cases>
diff --git
a/test/it/parser/src/main/resources/sql/supported/ddl/create-package.xml
b/test/it/parser/src/main/resources/sql/supported/ddl/create-package.xml
new file mode 100644
index 00000000000..62221d2c2eb
--- /dev/null
+++ b/test/it/parser/src/main/resources/sql/supported/ddl/create-package.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ ~ 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.
+ -->
+
+<sql-cases>
+ <sql-case id="create_or_replace_editionable_package" value="CREATE OR
REPLACE EDITIONABLE PACKAGE foo_schema.foo_pkg AUTHID CURRENT_USER AS g_public
NUMBER := 1; PROCEDURE set_value(p_value IN NUMBER); FUNCTION get_value RETURN
NUMBER; END foo_pkg;" db-types="Oracle" />
+ <sql-case id="create_or_replace_noneditionable_package_body" value="CREATE
OR REPLACE NONEDITIONABLE PACKAGE BODY foo_schema.foo_pkg AS g_private NUMBER
:= 0; PROCEDURE set_value(p_value IN NUMBER) AS BEGIN g_private := p_value;
END; FUNCTION get_value RETURN NUMBER AS BEGIN RETURN g_private; END; BEGIN
g_private := 5; END foo_pkg;" db-types="Oracle" />
+ <sql-case id="create_package_body_if_not_exists" value="CREATE PACKAGE
BODY IF NOT EXISTS foo_pkg AS PROCEDURE p AS BEGIN NULL; END; END foo_pkg;"
db-types="Oracle" />
+</sql-cases>