[ASTERIXDB-3259][SQLPP] Add syntax for DATABASE creation/drop

- user model changes: yes
- storage format changes: no
- interface changes: yes

Details:
Add syntax for DATABASE creation/drop:
- CREATE DATABASE ident IF NOT EXISTS;
- DROP   DATABASE ident IF EXISTS;

Change-Id: Ie19364fb502b5478465e21b564d8387ff0f71694
Reviewed-on: https://asterix-gerrit.ics.uci.edu/c/asterixdb/+/17764
Reviewed-by: Ali Alsuliman <ali.al.solaiman@gmail.com>
Reviewed-by: Wail Alkowaileet <wael.y.k@gmail.com>
Integration-Tests: Jenkins <jenkins@fulliautomatix.ics.uci.edu>
Tested-by: Jenkins <jenkins@fulliautomatix.ics.uci.edu>
diff --git a/asterixdb/asterix-lang-common/src/main/java/org/apache/asterix/lang/common/base/Statement.java b/asterixdb/asterix-lang-common/src/main/java/org/apache/asterix/lang/common/base/Statement.java
index 1654118..404360c 100644
--- a/asterixdb/asterix-lang-common/src/main/java/org/apache/asterix/lang/common/base/Statement.java
+++ b/asterixdb/asterix-lang-common/src/main/java/org/apache/asterix/lang/common/base/Statement.java
@@ -66,6 +66,7 @@
     enum Kind {
         DATASET_DECL,
         DATAVERSE_DECL,
+        DATABASE_DROP,
         DATAVERSE_DROP,
         DATASET_DROP,
         DELETE,
@@ -82,6 +83,7 @@
         TYPE_DECL,
         TYPE_DROP,
         CREATE_INDEX,
+        CREATE_DATABASE,
         CREATE_DATAVERSE,
         CREATE_VIEW,
         CREATE_FULL_TEXT_FILTER,
diff --git a/asterixdb/asterix-lang-common/src/main/java/org/apache/asterix/lang/common/statement/CreateDatabaseStatement.java b/asterixdb/asterix-lang-common/src/main/java/org/apache/asterix/lang/common/statement/CreateDatabaseStatement.java
new file mode 100644
index 0000000..c0cd1e8
--- /dev/null
+++ b/asterixdb/asterix-lang-common/src/main/java/org/apache/asterix/lang/common/statement/CreateDatabaseStatement.java
@@ -0,0 +1,58 @@
+/*
+ * 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.asterix.lang.common.statement;
+
+import org.apache.asterix.common.exceptions.CompilationException;
+import org.apache.asterix.lang.common.base.AbstractStatement;
+import org.apache.asterix.lang.common.struct.Identifier;
+import org.apache.asterix.lang.common.visitor.base.ILangVisitor;
+
+public class CreateDatabaseStatement extends AbstractStatement {
+
+    private final Identifier databaseName;
+    private final boolean ifNotExists;
+
+    public CreateDatabaseStatement(Identifier databaseName, boolean ifNotExists) {
+        this.databaseName = databaseName;
+        this.ifNotExists = ifNotExists;
+    }
+
+    public Identifier getDatabaseName() {
+        return databaseName;
+    }
+
+    public boolean ifNotExists() {
+        return ifNotExists;
+    }
+
+    @Override
+    public Kind getKind() {
+        return Kind.CREATE_DATABASE;
+    }
+
+    @Override
+    public <R, T> R accept(ILangVisitor<R, T> visitor, T arg) throws CompilationException {
+        return visitor.visit(this, arg);
+    }
+
+    @Override
+    public byte getCategory() {
+        return Category.DDL;
+    }
+}
diff --git a/asterixdb/asterix-lang-common/src/main/java/org/apache/asterix/lang/common/statement/DatabaseDropStatement.java b/asterixdb/asterix-lang-common/src/main/java/org/apache/asterix/lang/common/statement/DatabaseDropStatement.java
new file mode 100644
index 0000000..41530e9
--- /dev/null
+++ b/asterixdb/asterix-lang-common/src/main/java/org/apache/asterix/lang/common/statement/DatabaseDropStatement.java
@@ -0,0 +1,58 @@
+/*
+ * 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.asterix.lang.common.statement;
+
+import org.apache.asterix.common.exceptions.CompilationException;
+import org.apache.asterix.lang.common.base.AbstractStatement;
+import org.apache.asterix.lang.common.struct.Identifier;
+import org.apache.asterix.lang.common.visitor.base.ILangVisitor;
+
+public class DatabaseDropStatement extends AbstractStatement {
+
+    private final Identifier databaseName;
+    private final boolean ifExists;
+
+    public DatabaseDropStatement(Identifier databaseName, boolean ifExists) {
+        this.databaseName = databaseName;
+        this.ifExists = ifExists;
+    }
+
+    public Identifier getDatabaseName() {
+        return databaseName;
+    }
+
+    public boolean ifExists() {
+        return ifExists;
+    }
+
+    @Override
+    public Kind getKind() {
+        return Kind.DATABASE_DROP;
+    }
+
+    @Override
+    public <R, T> R accept(ILangVisitor<R, T> visitor, T arg) throws CompilationException {
+        return visitor.visit(this, arg);
+    }
+
+    @Override
+    public byte getCategory() {
+        return Category.DDL;
+    }
+}
diff --git a/asterixdb/asterix-lang-common/src/main/java/org/apache/asterix/lang/common/visitor/FormatPrintVisitor.java b/asterixdb/asterix-lang-common/src/main/java/org/apache/asterix/lang/common/visitor/FormatPrintVisitor.java
index 23455f1..2bfcd23 100644
--- a/asterixdb/asterix-lang-common/src/main/java/org/apache/asterix/lang/common/visitor/FormatPrintVisitor.java
+++ b/asterixdb/asterix-lang-common/src/main/java/org/apache/asterix/lang/common/visitor/FormatPrintVisitor.java
@@ -71,6 +71,7 @@
 import org.apache.asterix.lang.common.statement.ConnectFeedStatement;
 import org.apache.asterix.lang.common.statement.CopyStatement;
 import org.apache.asterix.lang.common.statement.CreateAdapterStatement;
+import org.apache.asterix.lang.common.statement.CreateDatabaseStatement;
 import org.apache.asterix.lang.common.statement.CreateDataverseStatement;
 import org.apache.asterix.lang.common.statement.CreateFeedPolicyStatement;
 import org.apache.asterix.lang.common.statement.CreateFeedStatement;
@@ -81,6 +82,7 @@
 import org.apache.asterix.lang.common.statement.CreateLibraryStatement;
 import org.apache.asterix.lang.common.statement.CreateSynonymStatement;
 import org.apache.asterix.lang.common.statement.CreateViewStatement;
+import org.apache.asterix.lang.common.statement.DatabaseDropStatement;
 import org.apache.asterix.lang.common.statement.DatasetDecl;
 import org.apache.asterix.lang.common.statement.DataverseDecl;
 import org.apache.asterix.lang.common.statement.DataverseDropStatement;
@@ -713,6 +715,13 @@
     }
 
     @Override
+    public Void visit(CreateDatabaseStatement cds, Integer step) throws CompilationException {
+        out.println(skip(step) + "create database " + normalize(cds.getDatabaseName().getValue())
+                + generateIfNotExists(cds.ifNotExists()) + SEMICOLON);
+        return null;
+    }
+
+    @Override
     public Void visit(CreateDataverseStatement del, Integer step) throws CompilationException {
         out.print(CREATE + dataverseSymbol);
         out.print(generateDataverseName(del.getDataverseName()));
@@ -759,6 +768,13 @@
     }
 
     @Override
+    public Void visit(DatabaseDropStatement dds, Integer step) throws CompilationException {
+        out.println(skip(step) + "drop database " + normalize(dds.getDatabaseName().getValue())
+                + generateIfExists(dds.ifExists()) + SEMICOLON);
+        return null;
+    }
+
+    @Override
     public Void visit(DataverseDropStatement del, Integer step) throws CompilationException {
         out.print(skip(step) + "drop " + dataverseSymbol);
         out.print(generateDataverseName(del.getDataverseName()));
diff --git a/asterixdb/asterix-lang-common/src/main/java/org/apache/asterix/lang/common/visitor/base/AbstractQueryExpressionVisitor.java b/asterixdb/asterix-lang-common/src/main/java/org/apache/asterix/lang/common/visitor/base/AbstractQueryExpressionVisitor.java
index accf476..6c0eea9 100644
--- a/asterixdb/asterix-lang-common/src/main/java/org/apache/asterix/lang/common/visitor/base/AbstractQueryExpressionVisitor.java
+++ b/asterixdb/asterix-lang-common/src/main/java/org/apache/asterix/lang/common/visitor/base/AbstractQueryExpressionVisitor.java
@@ -31,6 +31,7 @@
 import org.apache.asterix.lang.common.statement.ConnectFeedStatement;
 import org.apache.asterix.lang.common.statement.CopyStatement;
 import org.apache.asterix.lang.common.statement.CreateAdapterStatement;
+import org.apache.asterix.lang.common.statement.CreateDatabaseStatement;
 import org.apache.asterix.lang.common.statement.CreateDataverseStatement;
 import org.apache.asterix.lang.common.statement.CreateFeedPolicyStatement;
 import org.apache.asterix.lang.common.statement.CreateFeedStatement;
@@ -41,6 +42,7 @@
 import org.apache.asterix.lang.common.statement.CreateLibraryStatement;
 import org.apache.asterix.lang.common.statement.CreateSynonymStatement;
 import org.apache.asterix.lang.common.statement.CreateViewStatement;
+import org.apache.asterix.lang.common.statement.DatabaseDropStatement;
 import org.apache.asterix.lang.common.statement.DatasetDecl;
 import org.apache.asterix.lang.common.statement.DataverseDecl;
 import org.apache.asterix.lang.common.statement.DataverseDropStatement;
@@ -168,6 +170,11 @@
     }
 
     @Override
+    public R visit(CreateDatabaseStatement cds, T arg) throws CompilationException {
+        return null;
+    }
+
+    @Override
     public R visit(CreateDataverseStatement del, T arg) throws CompilationException {
         return null;
     }
@@ -183,6 +190,11 @@
     }
 
     @Override
+    public R visit(DatabaseDropStatement dds, T arg) throws CompilationException {
+        return null;
+    }
+
+    @Override
     public R visit(DataverseDropStatement del, T arg) throws CompilationException {
         return null;
     }
diff --git a/asterixdb/asterix-lang-common/src/main/java/org/apache/asterix/lang/common/visitor/base/ILangVisitor.java b/asterixdb/asterix-lang-common/src/main/java/org/apache/asterix/lang/common/visitor/base/ILangVisitor.java
index 9ad247c..4f70cb0 100644
--- a/asterixdb/asterix-lang-common/src/main/java/org/apache/asterix/lang/common/visitor/base/ILangVisitor.java
+++ b/asterixdb/asterix-lang-common/src/main/java/org/apache/asterix/lang/common/visitor/base/ILangVisitor.java
@@ -49,6 +49,7 @@
 import org.apache.asterix.lang.common.statement.ConnectFeedStatement;
 import org.apache.asterix.lang.common.statement.CopyStatement;
 import org.apache.asterix.lang.common.statement.CreateAdapterStatement;
+import org.apache.asterix.lang.common.statement.CreateDatabaseStatement;
 import org.apache.asterix.lang.common.statement.CreateDataverseStatement;
 import org.apache.asterix.lang.common.statement.CreateFeedPolicyStatement;
 import org.apache.asterix.lang.common.statement.CreateFeedStatement;
@@ -59,6 +60,7 @@
 import org.apache.asterix.lang.common.statement.CreateLibraryStatement;
 import org.apache.asterix.lang.common.statement.CreateSynonymStatement;
 import org.apache.asterix.lang.common.statement.CreateViewStatement;
+import org.apache.asterix.lang.common.statement.DatabaseDropStatement;
 import org.apache.asterix.lang.common.statement.DatasetDecl;
 import org.apache.asterix.lang.common.statement.DataverseDecl;
 import org.apache.asterix.lang.common.statement.DataverseDropStatement;
@@ -154,6 +156,8 @@
 
     R visit(CreateIndexStatement cis, T arg) throws CompilationException;
 
+    R visit(CreateDatabaseStatement cds, T arg) throws CompilationException;
+
     R visit(CreateDataverseStatement del, T arg) throws CompilationException;
 
     R visit(CreateFullTextFilterStatement cis, T arg) throws CompilationException;
@@ -168,6 +172,8 @@
 
     R visit(NodeGroupDropStatement del, T arg) throws CompilationException;
 
+    R visit(DatabaseDropStatement dds, T arg) throws CompilationException;
+
     R visit(DataverseDropStatement del, T arg) throws CompilationException;
 
     R visit(TypeDropStatement del, T arg) throws CompilationException;
diff --git a/asterixdb/asterix-lang-sqlpp/src/main/javacc/SQLPP.jj b/asterixdb/asterix-lang-sqlpp/src/main/javacc/SQLPP.jj
index a7dc2d5..df1d461 100644
--- a/asterixdb/asterix-lang-sqlpp/src/main/javacc/SQLPP.jj
+++ b/asterixdb/asterix-lang-sqlpp/src/main/javacc/SQLPP.jj
@@ -133,6 +133,7 @@
 import org.apache.asterix.lang.common.statement.StartFeedStatement;
 import org.apache.asterix.lang.common.statement.StopFeedStatement;
 import org.apache.asterix.lang.common.statement.CreateAdapterStatement;
+import org.apache.asterix.lang.common.statement.CreateDatabaseStatement;
 import org.apache.asterix.lang.common.statement.CreateDataverseStatement;
 import org.apache.asterix.lang.common.statement.CreateFeedPolicyStatement;
 import org.apache.asterix.lang.common.statement.CreateFeedStatement;
@@ -142,6 +143,7 @@
 import org.apache.asterix.lang.common.statement.CreateFullTextFilterStatement;
 import org.apache.asterix.lang.common.statement.CreateFullTextConfigStatement;
 import org.apache.asterix.lang.common.statement.CreateViewStatement;
+import org.apache.asterix.lang.common.statement.DatabaseDropStatement;
 import org.apache.asterix.lang.common.statement.DatasetDecl;
 import org.apache.asterix.lang.common.statement.DataverseDecl;
 import org.apache.asterix.lang.common.statement.DataverseDropStatement;
@@ -974,6 +976,7 @@
     | stmt = CreateNodegroupStatement(startToken)
     | stmt = CreateDatasetStatement(startToken)
     | stmt = CreateIndexStatement(startToken)
+    | stmt = CreateDatabaseStatement(startToken)
     | stmt = CreateDataverseStatement(startToken)
     | stmt = CreateFunctionStatement(startToken, false)
     | stmt = CreateAdapterStatement(startToken)
@@ -1557,6 +1560,30 @@
     }
 }
 
+CreateDatabaseStatement CreateDatabaseStatement(Token startStmtToken) throws ParseException :
+{
+  CreateDatabaseStatement stmt = null;
+}
+{
+  <DATABASE> stmt = DatabaseSpecification(startStmtToken)
+  {
+    return stmt;
+  }
+}
+
+CreateDatabaseStatement DatabaseSpecification(Token startStmtToken) throws ParseException :
+{
+  String dbName = null;
+  boolean ifNotExists = false;
+}
+{
+  dbName = Identifier() ifNotExists = IfNotExists()
+  {
+    CreateDatabaseStatement stmt = new CreateDatabaseStatement(new Identifier(dbName), ifNotExists);
+    return addSourceLocation(stmt, startStmtToken);
+  }
+}
+
 CreateDataverseStatement CreateDataverseStatement(Token startStmtToken) throws ParseException :
 {
   CreateDataverseStatement stmt = null;
@@ -2253,6 +2280,7 @@
     | stmt = DropIndexStatement(startToken)
     | stmt = DropNodeGroupStatement(startToken)
     | stmt = DropTypeStatement(startToken)
+    | stmt = DropDatabaseStatement(startToken)
     | stmt = DropDataverseStatement(startToken)
     | stmt = DropAdapterStatement(startToken)
     | stmt = DropFunctionStatement(startToken)
@@ -2431,6 +2459,30 @@
   }
 }
 
+DatabaseDropStatement DropDatabaseStatement(Token startStmtToken) throws ParseException:
+{
+  DatabaseDropStatement stmt = null;
+}
+{
+  <DATABASE> stmt = DropDatabaseSpecification(startStmtToken)
+  {
+    return stmt;
+  }
+}
+
+DatabaseDropStatement DropDatabaseSpecification(Token startStmtToken) throws ParseException:
+{
+  String dbName = null;
+  boolean ifExists = false;
+}
+{
+  dbName = Identifier() ifExists = IfExists()
+  {
+    DatabaseDropStatement stmt = new DatabaseDropStatement(new Identifier(dbName), ifExists);
+    return addSourceLocation(stmt, startStmtToken);
+  }
+}
+
 DataverseDropStatement DropDataverseStatement(Token startStmtToken) throws ParseException:
 {
   DataverseDropStatement stmt = null;
@@ -5650,6 +5702,7 @@
   | <CORRELATE : "correlate">
   | <DATASET : "dataset">
   | <COLLECTION : "collection">
+  | <DATABASE : "database">
   | <DATAVERSE : "dataverse">
   | <DECLARE : "declare">
   | <DEFINITION : "definition">