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>

Reply via email to