From acc4af53e1f8fbefc27a265da82580b473dfbbde Mon Sep 17 00:00:00 2001
From: JiaqiYan <chakk6870@gmail.com>
Date: Sun, 5 Nov 2023 23:08:57 +0800
Subject: [PATCH 1/2] Support Oracle CREATE PROFILE SQL

---
 .../antlr4/imports/oracle/DDLStatement.g4     |  4 +++
 .../antlr4/imports/oracle/OracleKeyword.g4    |  4 +++
 .../sql/parser/autogen/OracleStatement.g4     |  1 +
 .../type/OracleDDLStatementVisitor.java       |  7 +++++
 .../core/database/visitor/SQLVisitorRule.java |  4 ++-
 .../ddl/OracleCreateProfileStatement.java     | 27 +++++++++++++++++++
 .../parser/jaxb/RootSQLParserTestCases.java   |  4 +++
 .../ddl/CreateProfileStatementTestCase.java   | 26 ++++++++++++++++++
 .../resources/case/ddl/create-profile.xml     | 22 +++++++++++++++
 .../sql/supported/ddl/create-profile.xml      | 26 ++++++++++++++++++
 10 files changed, 124 insertions(+), 1 deletion(-)
 create mode 100644 parser/sql/statement/src/main/java/org/apache/shardingsphere/sql/parser/sql/dialect/statement/oracle/ddl/OracleCreateProfileStatement.java
 create mode 100644 test/it/parser/src/main/java/org/apache/shardingsphere/test/it/sql/parser/internal/cases/parser/jaxb/statement/ddl/CreateProfileStatementTestCase.java
 create mode 100644 test/it/parser/src/main/resources/case/ddl/create-profile.xml
 create mode 100644 test/it/parser/src/main/resources/sql/supported/ddl/create-profile.xml

diff --git a/parser/sql/dialect/oracle/src/main/antlr4/imports/oracle/DDLStatement.g4 b/parser/sql/dialect/oracle/src/main/antlr4/imports/oracle/DDLStatement.g4
index cbedb007733c6..72fe6fa482b88 100644
--- a/parser/sql/dialect/oracle/src/main/antlr4/imports/oracle/DDLStatement.g4
+++ b/parser/sql/dialect/oracle/src/main/antlr4/imports/oracle/DDLStatement.g4
@@ -4126,3 +4126,7 @@ plsqlLibrarySource
 agentClause
     : (AGENT agentDblink)? (CREDENTIAL credentialName)?
     ;
+
+createProfile
+    : CREATE MANDATORY? PROFILE profileName LIMIT (resourceParameters | passwordParameters)+ (CONTAINER EQ_ (CURRENT | ALL))?
+    ;
\ No newline at end of file
diff --git a/parser/sql/dialect/oracle/src/main/antlr4/imports/oracle/OracleKeyword.g4 b/parser/sql/dialect/oracle/src/main/antlr4/imports/oracle/OracleKeyword.g4
index 8297e15532967..a01bf3bb14855 100644
--- a/parser/sql/dialect/oracle/src/main/antlr4/imports/oracle/OracleKeyword.g4
+++ b/parser/sql/dialect/oracle/src/main/antlr4/imports/oracle/OracleKeyword.g4
@@ -7743,3 +7743,7 @@ PERSISTABLE
 DB_RECOVERY_FILE_DEST_SIZE
     : D B UL_ R E C O V E R Y UL_ F I L E UL_ D E S T UL_ S I Z E
     ;
+
+MANDATORY
+    : M A N D A  T O R Y
+    ;
\ No newline at end of file
diff --git a/parser/sql/dialect/oracle/src/main/antlr4/org/apache/shardingsphere/sql/parser/autogen/OracleStatement.g4 b/parser/sql/dialect/oracle/src/main/antlr4/org/apache/shardingsphere/sql/parser/autogen/OracleStatement.g4
index 5066afe35acdc..4e80413b7d51c 100644
--- a/parser/sql/dialect/oracle/src/main/antlr4/org/apache/shardingsphere/sql/parser/autogen/OracleStatement.g4
+++ b/parser/sql/dialect/oracle/src/main/antlr4/org/apache/shardingsphere/sql/parser/autogen/OracleStatement.g4
@@ -156,5 +156,6 @@ execute
     | createJava
     | plsqlBlock
     | createLibrary
+    | createProfile
     ) SEMI_?
     ;
diff --git a/parser/sql/dialect/oracle/src/main/java/org/apache/shardingsphere/sql/parser/oracle/visitor/statement/type/OracleDDLStatementVisitor.java b/parser/sql/dialect/oracle/src/main/java/org/apache/shardingsphere/sql/parser/oracle/visitor/statement/type/OracleDDLStatementVisitor.java
index ab47e143b642d..ba8930fd98ccb 100644
--- a/parser/sql/dialect/oracle/src/main/java/org/apache/shardingsphere/sql/parser/oracle/visitor/statement/type/OracleDDLStatementVisitor.java
+++ b/parser/sql/dialect/oracle/src/main/java/org/apache/shardingsphere/sql/parser/oracle/visitor/statement/type/OracleDDLStatementVisitor.java
@@ -91,6 +91,7 @@
 import org.apache.shardingsphere.sql.parser.autogen.OracleStatementParser.CreateMaterializedViewLogContext;
 import org.apache.shardingsphere.sql.parser.autogen.OracleStatementParser.CreatePFileContext;
 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.CreateRestorePointContext;
 import org.apache.shardingsphere.sql.parser.autogen.OracleStatementParser.CreateRollbackSegmentContext;
 import org.apache.shardingsphere.sql.parser.autogen.OracleStatementParser.CreateSPFileContext;
@@ -257,6 +258,7 @@
 import org.apache.shardingsphere.sql.parser.sql.dialect.statement.oracle.ddl.OracleCreateObjectTypeStatement;
 import org.apache.shardingsphere.sql.parser.sql.dialect.statement.oracle.ddl.OracleCreatePFileStatement;
 import org.apache.shardingsphere.sql.parser.sql.dialect.statement.oracle.ddl.OracleCreateProcedureStatement;
+import org.apache.shardingsphere.sql.parser.sql.dialect.statement.oracle.ddl.OracleCreateProfileStatement;
 import org.apache.shardingsphere.sql.parser.sql.dialect.statement.oracle.ddl.OracleCreateRestorePointStatement;
 import org.apache.shardingsphere.sql.parser.sql.dialect.statement.oracle.ddl.OracleCreateRollbackSegmentStatement;
 import org.apache.shardingsphere.sql.parser.sql.dialect.statement.oracle.ddl.OracleCreateSPFileStatement;
@@ -1349,4 +1351,9 @@ public ASTNode visitCreateJava(final CreateJavaContext ctx) {
     public ASTNode visitCreateLibrary(final CreateLibraryContext ctx) {
         return new OracleCreateLibraryStatement();
     }
+    
+    @Override
+    public ASTNode visitCreateProfile(final CreateProfileContext ctx) {
+        return new OracleCreateProfileStatement();
+    }
 }
diff --git a/parser/sql/engine/src/main/java/org/apache/shardingsphere/sql/parser/core/database/visitor/SQLVisitorRule.java b/parser/sql/engine/src/main/java/org/apache/shardingsphere/sql/parser/core/database/visitor/SQLVisitorRule.java
index 1fcaa758edf48..dbe1f719e70a7 100644
--- a/parser/sql/engine/src/main/java/org/apache/shardingsphere/sql/parser/core/database/visitor/SQLVisitorRule.java
+++ b/parser/sql/engine/src/main/java/org/apache/shardingsphere/sql/parser/core/database/visitor/SQLVisitorRule.java
@@ -699,7 +699,9 @@ public enum SQLVisitorRule {
     
     PLSQL_BLOCK("PlsqlBlock", SQLStatementType.DDL),
     
-    CREATE_LIBRARY("CreateLibrary", SQLStatementType.DDL);
+    CREATE_LIBRARY("CreateLibrary", SQLStatementType.DDL),
+    
+    CREATE_PROFILE("CreateProfile", SQLStatementType.DDL);
     
     private final String name;
     
diff --git a/parser/sql/statement/src/main/java/org/apache/shardingsphere/sql/parser/sql/dialect/statement/oracle/ddl/OracleCreateProfileStatement.java b/parser/sql/statement/src/main/java/org/apache/shardingsphere/sql/parser/sql/dialect/statement/oracle/ddl/OracleCreateProfileStatement.java
new file mode 100644
index 0000000000000..b75cabcf61fc6
--- /dev/null
+++ b/parser/sql/statement/src/main/java/org/apache/shardingsphere/sql/parser/sql/dialect/statement/oracle/ddl/OracleCreateProfileStatement.java
@@ -0,0 +1,27 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.shardingsphere.sql.parser.sql.dialect.statement.oracle.ddl;
+
+import org.apache.shardingsphere.sql.parser.sql.common.statement.AbstractSQLStatement;
+import org.apache.shardingsphere.sql.parser.sql.dialect.statement.oracle.OracleStatement;
+
+/**
+ * Oracle create profile statement.
+ */
+public final class OracleCreateProfileStatement extends AbstractSQLStatement implements OracleStatement {
+}
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 ad4863f610d07..7f4e6c03692b2 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
@@ -191,6 +191,7 @@
 import org.apache.shardingsphere.test.it.sql.parser.internal.cases.parser.jaxb.statement.ddl.CreatePFileStatementTestCase;
 import org.apache.shardingsphere.test.it.sql.parser.internal.cases.parser.jaxb.statement.ddl.CreatePolicyStatementTestCase;
 import org.apache.shardingsphere.test.it.sql.parser.internal.cases.parser.jaxb.statement.ddl.CreateProcedureStatementTestCase;
+import org.apache.shardingsphere.test.it.sql.parser.internal.cases.parser.jaxb.statement.ddl.CreateProfileStatementTestCase;
 import org.apache.shardingsphere.test.it.sql.parser.internal.cases.parser.jaxb.statement.ddl.CreatePublicationStatementTestCase;
 import org.apache.shardingsphere.test.it.sql.parser.internal.cases.parser.jaxb.statement.ddl.CreateRestorePointStatementTestCase;
 import org.apache.shardingsphere.test.it.sql.parser.internal.cases.parser.jaxb.statement.ddl.CreateRollbackSegmentStatementTestCase;
@@ -1720,6 +1721,9 @@ public final class RootSQLParserTestCases {
     @XmlElement(name = "create-library")
     private final List<CreateLibraryStatementTestCase> createLibraryStatementTestCases = new LinkedList<>();
     
+    @XmlElement(name = "create-profile")
+    private final List<CreateProfileStatementTestCase> createProfileStatementTestCases = new LinkedList<>();
+    
     /**
      * Get all SQL parser test cases.
      *
diff --git a/test/it/parser/src/main/java/org/apache/shardingsphere/test/it/sql/parser/internal/cases/parser/jaxb/statement/ddl/CreateProfileStatementTestCase.java b/test/it/parser/src/main/java/org/apache/shardingsphere/test/it/sql/parser/internal/cases/parser/jaxb/statement/ddl/CreateProfileStatementTestCase.java
new file mode 100644
index 0000000000000..201dd2c2618f4
--- /dev/null
+++ b/test/it/parser/src/main/java/org/apache/shardingsphere/test/it/sql/parser/internal/cases/parser/jaxb/statement/ddl/CreateProfileStatementTestCase.java
@@ -0,0 +1,26 @@
+/*
+ * 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;
+
+import org.apache.shardingsphere.test.it.sql.parser.internal.cases.parser.jaxb.SQLParserTestCase;
+
+/**
+ * Create profile statement test case.
+ */
+public final class CreateProfileStatementTestCase extends SQLParserTestCase {
+}
diff --git a/test/it/parser/src/main/resources/case/ddl/create-profile.xml b/test/it/parser/src/main/resources/case/ddl/create-profile.xml
new file mode 100644
index 0000000000000..4e26e12cfeec3
--- /dev/null
+++ b/test/it/parser/src/main/resources/case/ddl/create-profile.xml
@@ -0,0 +1,22 @@
+<?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-profile sql-case-id="create_mandatory_profile" />
+    <create-profile sql-case-id="create_limit_profile" />
+</sql-parser-test-cases>
diff --git a/test/it/parser/src/main/resources/sql/supported/ddl/create-profile.xml b/test/it/parser/src/main/resources/sql/supported/ddl/create-profile.xml
new file mode 100644
index 0000000000000..b7241dd86237d
--- /dev/null
+++ b/test/it/parser/src/main/resources/sql/supported/ddl/create-profile.xml
@@ -0,0 +1,26 @@
+<?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_mandatory_profile" value="CREATE MANDATORY PROFILE c##cdb_profile LIMIT PASSWORD_VERIFY_FUNCTION my_mandatory_function
+                                         CONTAINER = ALL;" db-types="Oracle" />
+    <sql-case id="create_limit_profile" value="CREATE PROFILE prof LIMIT
+                                         FAILED_LOGIN_ATTEMPTS 4
+                                         PASSWORD_LOCK_TIME 30
+                                         PASSWORD_LIFE_TIME 180;" db-types="Oracle" />
+</sql-cases>

From 2336d7a13de2dbc415b187366de1d2a4a91c40a9 Mon Sep 17 00:00:00 2001
From: JiaqiYan <chakk6870@gmail.com>
Date: Mon, 6 Nov 2023 22:41:00 +0800
Subject: [PATCH 2/2] resolve conflict and format code

---
 .../oracle/src/main/antlr4/imports/oracle/DDLStatement.g4    | 1 +
 .../oracle/src/main/antlr4/imports/oracle/OracleKeyword.g4   | 4 ++--
 .../visitor/statement/type/OracleDDLStatementVisitor.java    | 5 ++---
 .../sql/parser/core/database/visitor/SQLVisitorRule.java     | 4 ++--
 .../internal/cases/parser/jaxb/RootSQLParserTestCases.java   | 4 ++--
 5 files changed, 9 insertions(+), 9 deletions(-)

diff --git a/parser/sql/dialect/oracle/src/main/antlr4/imports/oracle/DDLStatement.g4 b/parser/sql/dialect/oracle/src/main/antlr4/imports/oracle/DDLStatement.g4
index 5ec767a8868e4..1d1ca80e835fa 100644
--- a/parser/sql/dialect/oracle/src/main/antlr4/imports/oracle/DDLStatement.g4
+++ b/parser/sql/dialect/oracle/src/main/antlr4/imports/oracle/DDLStatement.g4
@@ -4144,3 +4144,4 @@ datafileSpecClause
 createProfile
     : CREATE MANDATORY? PROFILE profileName LIMIT (resourceParameters | passwordParameters)+ (CONTAINER EQ_ (CURRENT | ALL))?
     ;
+
diff --git a/parser/sql/dialect/oracle/src/main/antlr4/imports/oracle/OracleKeyword.g4 b/parser/sql/dialect/oracle/src/main/antlr4/imports/oracle/OracleKeyword.g4
index a01bf3bb14855..79d5e31517f25 100644
--- a/parser/sql/dialect/oracle/src/main/antlr4/imports/oracle/OracleKeyword.g4
+++ b/parser/sql/dialect/oracle/src/main/antlr4/imports/oracle/OracleKeyword.g4
@@ -7745,5 +7745,5 @@ DB_RECOVERY_FILE_DEST_SIZE
     ;
 
 MANDATORY
-    : M A N D A  T O R Y
-    ;
\ No newline at end of file
+    : M A N D A T O R Y
+    ;
diff --git a/parser/sql/dialect/oracle/src/main/java/org/apache/shardingsphere/sql/parser/oracle/visitor/statement/type/OracleDDLStatementVisitor.java b/parser/sql/dialect/oracle/src/main/java/org/apache/shardingsphere/sql/parser/oracle/visitor/statement/type/OracleDDLStatementVisitor.java
index 798554918aac0..35cf88cca759f 100644
--- a/parser/sql/dialect/oracle/src/main/java/org/apache/shardingsphere/sql/parser/oracle/visitor/statement/type/OracleDDLStatementVisitor.java
+++ b/parser/sql/dialect/oracle/src/main/java/org/apache/shardingsphere/sql/parser/oracle/visitor/statement/type/OracleDDLStatementVisitor.java
@@ -1353,13 +1353,12 @@ public ASTNode visitCreateJava(final CreateJavaContext ctx) {
     public ASTNode visitCreateLibrary(final CreateLibraryContext ctx) {
         return new OracleCreateLibraryStatement();
     }
-
+    
     @Override
     public ASTNode visitSwitch(final SwitchContext ctx) {
         return new OracleSwitchStatement();
     }
-
-
+    
     @Override
     public ASTNode visitCreateProfile(final CreateProfileContext ctx) {
         return new OracleCreateProfileStatement();
diff --git a/parser/sql/engine/src/main/java/org/apache/shardingsphere/sql/parser/core/database/visitor/SQLVisitorRule.java b/parser/sql/engine/src/main/java/org/apache/shardingsphere/sql/parser/core/database/visitor/SQLVisitorRule.java
index 9913d769133de..66345c7e728f1 100644
--- a/parser/sql/engine/src/main/java/org/apache/shardingsphere/sql/parser/core/database/visitor/SQLVisitorRule.java
+++ b/parser/sql/engine/src/main/java/org/apache/shardingsphere/sql/parser/core/database/visitor/SQLVisitorRule.java
@@ -700,9 +700,9 @@ public enum SQLVisitorRule {
     PLSQL_BLOCK("PlsqlBlock", SQLStatementType.DDL),
     
     CREATE_LIBRARY("CreateLibrary", SQLStatementType.DDL),
-
+    
     SWITCH("Switch", SQLStatementType.DDL),
-
+    
     CREATE_PROFILE("CreateProfile", SQLStatementType.DDL);
     
     private final String name;
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 978cb53e79876..2374134bcde5e 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
@@ -1724,10 +1724,10 @@ public final class RootSQLParserTestCases {
     
     @XmlElement(name = "switch")
     private final List<SwitchStatementTestCase> switchStatementTestCases = new LinkedList<>();
-
+    
     @XmlElement(name = "create-profile")
     private final List<CreateProfileStatementTestCase> createProfileStatementTestCases = new LinkedList<>();
-
+    
     /**
      * Get all SQL parser test cases.
      *