You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@asterixdb.apache.org by dl...@apache.org on 2020/11/02 19:26:03 UTC

[asterixdb] branch master updated (820e6f0 -> b317f37)

This is an automated email from the ASF dual-hosted git repository.

dlych pushed a change to branch master
in repository https://gitbox.apache.org/repos/asf/asterixdb.git.


    from 820e6f0  [NO ISSUE][*DB][API] Handle REJECTED status on query cancellation
     new 95fa33c  [NO ISSUE][COMP] Prohibit empty names of database objects
     new b317f37  Merge commit '95fa33c'

The 2 revisions listed above as "new" are entirely new to this
repository and will be described in separate emails.  The revisions
listed as "add" were already present in the repository and have only
been added to this reference.


Summary of changes:
 .../asterix/app/translator/QueryTranslator.java    | 20 ++++++++
 .../invalid-dataset-name.1.ddl.sqlpp               | 29 +++++++++++
 .../invalid-dataset-name.2.ddl.sqlpp               | 29 +++++++++++
 .../invalid-dataset-name.3.ddl.sqlpp}              |  0
 .../invalid-dataverse-name.1.ddl.sqlpp             | 24 ++++++++++
 .../invalid-dataverse-name.2.ddl.sqlpp             | 24 ++++++++++
 .../invalid-feed-name.1.ddl.sqlpp                  | 42 ++++++++++++++++
 .../invalid-feed-name.2.ddl.sqlpp                  | 42 ++++++++++++++++
 .../invalid-feed-name.3.ddl.sqlpp}                 |  0
 .../invalid-feed-policy-name.1.ddl.sqlpp           | 30 ++++++++++++
 .../invalid-feed-policy-name.2.ddl.sqlpp           | 30 ++++++++++++
 .../invalid-feed-policy-name.3.ddl.sqlpp}          |  0
 .../invalid-index-name.1.ddl.sqlpp                 | 31 ++++++++++++
 .../invalid-index-name.2.ddl.sqlpp                 | 31 ++++++++++++
 .../invalid-index-name.3.ddl.sqlpp}                |  0
 .../invalid-nodegroup-name.1.ddl.sqlpp             | 24 ++++++++++
 .../invalid-nodegroup-name.2.ddl.sqlpp             | 24 ++++++++++
 .../invalid-type-name.1.ddl.sqlpp                  | 31 ++++++++++++
 .../invalid-type-name.2.ddl.sqlpp                  | 31 ++++++++++++
 .../invalid-type-name.3.ddl.sqlpp}                 |  0
 .../invalid-udf-name/invalid-udf-name.1.ddl.sqlpp  | 31 ++++++++++++
 .../invalid-udf-name/invalid-udf-name.2.ddl.sqlpp  | 31 ++++++++++++
 .../invalid-udf-name/invalid-udf-name.3.ddl.sqlpp} |  0
 .../test/resources/runtimets/testsuite_sqlpp.xml   | 56 ++++++++++++++++++++++
 .../asterix/common/exceptions/ErrorCode.java       |  4 +-
 .../src/main/resources/asx_errormsg/en.properties  |  3 +-
 26 files changed, 564 insertions(+), 3 deletions(-)
 create mode 100644 asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/ddl/invalid-dataset-name/invalid-dataset-name.1.ddl.sqlpp
 create mode 100644 asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/ddl/invalid-dataset-name/invalid-dataset-name.2.ddl.sqlpp
 copy asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/{meta/query_dataset_with_meta_failure/query_dataset_with_meta_failure.4.ddl.sqlpp => ddl/invalid-dataset-name/invalid-dataset-name.3.ddl.sqlpp} (100%)
 create mode 100644 asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/ddl/invalid-dataverse-name/invalid-dataverse-name.1.ddl.sqlpp
 create mode 100644 asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/ddl/invalid-dataverse-name/invalid-dataverse-name.2.ddl.sqlpp
 create mode 100644 asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/ddl/invalid-feed-name/invalid-feed-name.1.ddl.sqlpp
 create mode 100644 asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/ddl/invalid-feed-name/invalid-feed-name.2.ddl.sqlpp
 copy asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/{meta/query_dataset_with_meta_failure/query_dataset_with_meta_failure.4.ddl.sqlpp => ddl/invalid-feed-name/invalid-feed-name.3.ddl.sqlpp} (100%)
 create mode 100644 asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/ddl/invalid-feed-policy-name/invalid-feed-policy-name.1.ddl.sqlpp
 create mode 100644 asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/ddl/invalid-feed-policy-name/invalid-feed-policy-name.2.ddl.sqlpp
 copy asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/{meta/query_dataset_with_meta_failure/query_dataset_with_meta_failure.4.ddl.sqlpp => ddl/invalid-feed-policy-name/invalid-feed-policy-name.3.ddl.sqlpp} (100%)
 create mode 100644 asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/ddl/invalid-index-name/invalid-index-name.1.ddl.sqlpp
 create mode 100644 asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/ddl/invalid-index-name/invalid-index-name.2.ddl.sqlpp
 copy asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/{meta/query_dataset_with_meta_failure/query_dataset_with_meta_failure.4.ddl.sqlpp => ddl/invalid-index-name/invalid-index-name.3.ddl.sqlpp} (100%)
 create mode 100644 asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/ddl/invalid-nodegroup-name/invalid-nodegroup-name.1.ddl.sqlpp
 create mode 100644 asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/ddl/invalid-nodegroup-name/invalid-nodegroup-name.2.ddl.sqlpp
 create mode 100644 asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/ddl/invalid-type-name/invalid-type-name.1.ddl.sqlpp
 create mode 100644 asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/ddl/invalid-type-name/invalid-type-name.2.ddl.sqlpp
 copy asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/{meta/query_dataset_with_meta_failure/query_dataset_with_meta_failure.4.ddl.sqlpp => ddl/invalid-type-name/invalid-type-name.3.ddl.sqlpp} (100%)
 create mode 100644 asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/ddl/invalid-udf-name/invalid-udf-name.1.ddl.sqlpp
 create mode 100644 asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/ddl/invalid-udf-name/invalid-udf-name.2.ddl.sqlpp
 copy asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/{meta/query_dataset_with_meta_failure/query_dataset_with_meta_failure.4.ddl.sqlpp => ddl/invalid-udf-name/invalid-udf-name.3.ddl.sqlpp} (100%)


[asterixdb] 01/02: [NO ISSUE][COMP] Prohibit empty names of database objects

Posted by dl...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

dlych pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/asterixdb.git

commit 95fa33cbf348bce64534d1dcb5a1089d11ecc515
Author: Dmitry Lychagin <dm...@couchbase.com>
AuthorDate: Tue Oct 20 14:23:35 2020 -0700

    [NO ISSUE][COMP] Prohibit empty names of database objects
    
    - user model changes: no
    - storage format changes: no
    - interface changes: no
    
    Details:
    - Disallow creation of database objects with empty names
      or names that start with a space character
    
    Change-Id: I6b5f99eec54b0882d05a0afdf925f9f6e56f0f00
    Reviewed-on: https://asterix-gerrit.ics.uci.edu/c/asterixdb/+/8484
    Integration-Tests: Jenkins <je...@fulliautomatix.ics.uci.edu>
    Tested-by: Jenkins <je...@fulliautomatix.ics.uci.edu>
    Reviewed-by: Dmitry Lychagin <dm...@couchbase.com>
    Reviewed-by: Ali Alsuliman <al...@gmail.com>
---
 .../asterix/app/translator/QueryTranslator.java    | 18 +++++++
 .../invalid-dataset-name.1.ddl.sqlpp               | 29 +++++++++++
 .../invalid-dataset-name.2.ddl.sqlpp               | 29 +++++++++++
 .../invalid-dataset-name.3.ddl.sqlpp               | 20 ++++++++
 .../invalid-dataverse-name.1.ddl.sqlpp             | 24 ++++++++++
 .../invalid-dataverse-name.2.ddl.sqlpp             | 24 ++++++++++
 .../invalid-feed-name.1.ddl.sqlpp                  | 42 ++++++++++++++++
 .../invalid-feed-name.2.ddl.sqlpp                  | 42 ++++++++++++++++
 .../invalid-feed-name.3.ddl.sqlpp                  | 20 ++++++++
 .../invalid-feed-policy-name.1.ddl.sqlpp           | 30 ++++++++++++
 .../invalid-feed-policy-name.2.ddl.sqlpp           | 30 ++++++++++++
 .../invalid-feed-policy-name.3.ddl.sqlpp           | 20 ++++++++
 .../invalid-index-name.1.ddl.sqlpp                 | 31 ++++++++++++
 .../invalid-index-name.2.ddl.sqlpp                 | 31 ++++++++++++
 .../invalid-index-name.3.ddl.sqlpp                 | 20 ++++++++
 .../invalid-nodegroup-name.1.ddl.sqlpp             | 24 ++++++++++
 .../invalid-nodegroup-name.2.ddl.sqlpp             | 24 ++++++++++
 .../invalid-type-name.1.ddl.sqlpp                  | 31 ++++++++++++
 .../invalid-type-name.2.ddl.sqlpp                  | 31 ++++++++++++
 .../invalid-type-name.3.ddl.sqlpp                  | 20 ++++++++
 .../invalid-udf-name/invalid-udf-name.1.ddl.sqlpp  | 31 ++++++++++++
 .../invalid-udf-name/invalid-udf-name.2.ddl.sqlpp  | 31 ++++++++++++
 .../invalid-udf-name/invalid-udf-name.3.ddl.sqlpp  | 20 ++++++++
 .../test/resources/runtimets/testsuite_sqlpp.xml   | 56 ++++++++++++++++++++++
 .../asterix/common/exceptions/ErrorCode.java       |  1 +
 .../src/main/resources/asx_errormsg/en.properties  |  1 +
 26 files changed, 680 insertions(+)

diff --git a/asterixdb/asterix-app/src/main/java/org/apache/asterix/app/translator/QueryTranslator.java b/asterixdb/asterix-app/src/main/java/org/apache/asterix/app/translator/QueryTranslator.java
index d49996a..d29a5f5 100644
--- a/asterixdb/asterix-app/src/main/java/org/apache/asterix/app/translator/QueryTranslator.java
+++ b/asterixdb/asterix-app/src/main/java/org/apache/asterix/app/translator/QueryTranslator.java
@@ -491,7 +491,9 @@ public class QueryTranslator extends AbstractLangTranslator implements IStatemen
     protected void handleCreateDataverseStatement(MetadataProvider metadataProvider, Statement stmt,
             IRequestParameters requestParameters) throws Exception {
         CreateDataverseStatement stmtCreateDataverse = (CreateDataverseStatement) stmt;
+        SourceLocation sourceLoc = stmtCreateDataverse.getSourceLocation();
         String dvName = stmtCreateDataverse.getDataverseName().getValue();
+        validateDatabaseObjectName(dvName, sourceLoc);
         MetadataTransactionContext mdTxnCtx = MetadataManager.INSTANCE.beginTransaction();
         metadataProvider.setMetadataTxnContext(mdTxnCtx);
         lockManager.acquireDataverseReadLock(metadataProvider.getLocks(), dvName);
@@ -569,6 +571,7 @@ public class QueryTranslator extends AbstractLangTranslator implements IStatemen
         SourceLocation sourceLoc = dd.getSourceLocation();
         String dataverseName = getActiveDataverse(dd.getDataverse());
         String datasetName = dd.getName().getValue();
+        validateDatabaseObjectName(datasetName, sourceLoc);
         DatasetType dsType = dd.getDatasetType();
         TypeExpression itemTypeExpr = dd.getItemType();
         String itemTypeDataverseName, itemTypeName;
@@ -911,6 +914,7 @@ public class QueryTranslator extends AbstractLangTranslator implements IStatemen
         String dataverseName = getActiveDataverse(stmtCreateIndex.getDataverseName());
         String datasetName = stmtCreateIndex.getDatasetName().getValue();
         String indexName = stmtCreateIndex.getIndexName().getValue();
+        validateDatabaseObjectName(indexName, sourceLoc);
         IndexType indexType = stmtCreateIndex.getIndexType();
         List<Integer> keySourceIndicators = stmtCreateIndex.getFieldSourceIndicators();
         MetadataTransactionContext mdTxnCtx = MetadataManager.INSTANCE.beginTransaction();
@@ -1344,6 +1348,7 @@ public class QueryTranslator extends AbstractLangTranslator implements IStatemen
         SourceLocation sourceLoc = stmtCreateType.getSourceLocation();
         String dataverseName = getActiveDataverse(stmtCreateType.getDataverseName());
         String typeName = stmtCreateType.getIdent().getValue();
+        validateDatabaseObjectName(typeName, sourceLoc);
         MetadataTransactionContext mdTxnCtx = MetadataManager.INSTANCE.beginTransaction();
         metadataProvider.setMetadataTxnContext(mdTxnCtx);
         MetadataLockUtil.createTypeBegin(lockManager, metadataProvider.getLocks(), dataverseName,
@@ -1932,6 +1937,7 @@ public class QueryTranslator extends AbstractLangTranslator implements IStatemen
         CreateFunctionStatement cfs = (CreateFunctionStatement) stmt;
         SourceLocation sourceLoc = cfs.getSourceLocation();
         FunctionSignature signature = cfs.getFunctionSignature();
+        validateDatabaseObjectName(signature.getName(), sourceLoc);
         String dataverse = getActiveDataverseName(signature.getNamespace());
         signature.setNamespace(dataverse);
 
@@ -2235,6 +2241,7 @@ public class QueryTranslator extends AbstractLangTranslator implements IStatemen
         SourceLocation sourceLoc = cfs.getSourceLocation();
         String dataverseName = getActiveDataverse(cfs.getDataverseName());
         String feedName = cfs.getFeedName().getValue();
+        validateDatabaseObjectName(feedName, sourceLoc);
         MetadataTransactionContext mdTxnCtx = MetadataManager.INSTANCE.beginTransaction();
         metadataProvider.setMetadataTxnContext(mdTxnCtx);
         MetadataLockUtil.createFeedBegin(lockManager, metadataProvider.getLocks(), dataverseName,
@@ -2276,6 +2283,7 @@ public class QueryTranslator extends AbstractLangTranslator implements IStatemen
         SourceLocation sourceLoc = cfps.getSourceLocation();
         dataverse = getActiveDataverse(null);
         policy = cfps.getPolicyName();
+        validateDatabaseObjectName(policy, sourceLoc);
         MetadataLockUtil.createFeedPolicyBegin(lockManager, metadataProvider.getLocks(), dataverse,
                 dataverse + "." + policy);
         try {
@@ -2872,6 +2880,7 @@ public class QueryTranslator extends AbstractLangTranslator implements IStatemen
         NodegroupDecl stmtCreateNodegroup = (NodegroupDecl) stmt;
         SourceLocation sourceLoc = stmtCreateNodegroup.getSourceLocation();
         String ngName = stmtCreateNodegroup.getNodegroupName().getValue();
+        validateDatabaseObjectName(ngName, sourceLoc);
 
         MetadataTransactionContext mdTxnCtx = MetadataManager.INSTANCE.beginTransaction();
         metadataProvider.setMetadataTxnContext(mdTxnCtx);
@@ -3281,4 +3290,13 @@ public class QueryTranslator extends AbstractLangTranslator implements IStatemen
             throws CompilationException {
         ExternalDataUtils.validateAdapterSpecificProperties(configuration, srcLoc, warningCollector);
     }
+
+    public static void validateDatabaseObjectName(String name, SourceLocation sourceLoc) throws CompilationException {
+        if (name == null || name.isEmpty()) {
+            throw new CompilationException(ErrorCode.INVALID_DATABASE_OBJECT_NAME, sourceLoc, "<empty>");
+        }
+        if (Character.isWhitespace(name.codePointAt(0))) {
+            throw new CompilationException(ErrorCode.INVALID_DATABASE_OBJECT_NAME, sourceLoc, name);
+        }
+    }
 }
diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/ddl/invalid-dataset-name/invalid-dataset-name.1.ddl.sqlpp b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/ddl/invalid-dataset-name/invalid-dataset-name.1.ddl.sqlpp
new file mode 100644
index 0000000..f5c4588
--- /dev/null
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/ddl/invalid-dataset-name/invalid-dataset-name.1.ddl.sqlpp
@@ -0,0 +1,29 @@
+/*
+ * 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.
+ */
+
+/*
+ * Empty dataset name -> Error
+ */
+
+drop dataverse test if exists;
+create dataverse test;
+
+use test;
+
+create dataset ``(id int not unknown) primary key id;
\ No newline at end of file
diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/ddl/invalid-dataset-name/invalid-dataset-name.2.ddl.sqlpp b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/ddl/invalid-dataset-name/invalid-dataset-name.2.ddl.sqlpp
new file mode 100644
index 0000000..1bc445a
--- /dev/null
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/ddl/invalid-dataset-name/invalid-dataset-name.2.ddl.sqlpp
@@ -0,0 +1,29 @@
+/*
+ * 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.
+ */
+
+/*
+ * Dataset name starts with a space character -> Error
+ */
+
+drop dataverse test if exists;
+create dataverse test;
+
+use test;
+
+create dataset ` a`(id int not unknown) primary key id;
\ No newline at end of file
diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/ddl/invalid-dataset-name/invalid-dataset-name.3.ddl.sqlpp b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/ddl/invalid-dataset-name/invalid-dataset-name.3.ddl.sqlpp
new file mode 100644
index 0000000..dc10acd
--- /dev/null
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/ddl/invalid-dataset-name/invalid-dataset-name.3.ddl.sqlpp
@@ -0,0 +1,20 @@
+/*
+ * 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.
+ */
+
+drop dataverse test if exists;
diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/ddl/invalid-dataverse-name/invalid-dataverse-name.1.ddl.sqlpp b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/ddl/invalid-dataverse-name/invalid-dataverse-name.1.ddl.sqlpp
new file mode 100644
index 0000000..7322b6d
--- /dev/null
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/ddl/invalid-dataverse-name/invalid-dataverse-name.1.ddl.sqlpp
@@ -0,0 +1,24 @@
+/*
+ * 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.
+ */
+
+/*
+ * Empty dataverse name -> Error
+ */
+
+create dataverse ``;
\ No newline at end of file
diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/ddl/invalid-dataverse-name/invalid-dataverse-name.2.ddl.sqlpp b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/ddl/invalid-dataverse-name/invalid-dataverse-name.2.ddl.sqlpp
new file mode 100644
index 0000000..623e40d
--- /dev/null
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/ddl/invalid-dataverse-name/invalid-dataverse-name.2.ddl.sqlpp
@@ -0,0 +1,24 @@
+/*
+ * 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.
+ */
+
+/*
+ * Dataverse name starts with a space character -> Error
+ */
+
+create dataverse ` a`;
\ No newline at end of file
diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/ddl/invalid-feed-name/invalid-feed-name.1.ddl.sqlpp b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/ddl/invalid-feed-name/invalid-feed-name.1.ddl.sqlpp
new file mode 100644
index 0000000..783a940
--- /dev/null
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/ddl/invalid-feed-name/invalid-feed-name.1.ddl.sqlpp
@@ -0,0 +1,42 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+/*
+ * Empty feed name -> Error
+ */
+
+drop dataverse test if exists;
+create dataverse test;
+
+use test;
+
+create type Tweet as closed
+{
+  id: int64
+};
+
+create dataset Tweets0(Tweet) primary key id;
+
+create feed `` with {
+ "adapter-name" : "socket_adapter",
+ "sockets" : "127.0.0.1:10001",
+ "address-type" : "IP",
+ "type-name" : "Tweet",
+ "format" : "adm"
+};
\ No newline at end of file
diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/ddl/invalid-feed-name/invalid-feed-name.2.ddl.sqlpp b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/ddl/invalid-feed-name/invalid-feed-name.2.ddl.sqlpp
new file mode 100644
index 0000000..6d59d03
--- /dev/null
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/ddl/invalid-feed-name/invalid-feed-name.2.ddl.sqlpp
@@ -0,0 +1,42 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+/*
+ * Feed name starts with a space character -> Error
+ */
+
+drop dataverse test if exists;
+create dataverse test;
+
+use test;
+
+create type Tweet as closed
+{
+  id: int64
+};
+
+create dataset Tweets0(Tweet) primary key id;
+
+create feed ` a` with {
+ "adapter-name" : "socket_adapter",
+ "sockets" : "127.0.0.1:10001",
+ "address-type" : "IP",
+ "type-name" : "Tweet",
+ "format" : "adm"
+};
\ No newline at end of file
diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/ddl/invalid-feed-name/invalid-feed-name.3.ddl.sqlpp b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/ddl/invalid-feed-name/invalid-feed-name.3.ddl.sqlpp
new file mode 100644
index 0000000..dc10acd
--- /dev/null
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/ddl/invalid-feed-name/invalid-feed-name.3.ddl.sqlpp
@@ -0,0 +1,20 @@
+/*
+ * 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.
+ */
+
+drop dataverse test if exists;
diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/ddl/invalid-feed-policy-name/invalid-feed-policy-name.1.ddl.sqlpp b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/ddl/invalid-feed-policy-name/invalid-feed-policy-name.1.ddl.sqlpp
new file mode 100644
index 0000000..3a9f7fc
--- /dev/null
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/ddl/invalid-feed-policy-name/invalid-feed-policy-name.1.ddl.sqlpp
@@ -0,0 +1,30 @@
+/*
+ * 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.
+ */
+
+/*
+ * Empty feed policy name -> Error
+ */
+
+drop dataverse test if exists;
+create dataverse test;
+
+use test;
+
+create ingestion policy `` from path 'data/feed-policy/policy.properties'
+  definition 'someString';
\ No newline at end of file
diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/ddl/invalid-feed-policy-name/invalid-feed-policy-name.2.ddl.sqlpp b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/ddl/invalid-feed-policy-name/invalid-feed-policy-name.2.ddl.sqlpp
new file mode 100644
index 0000000..c5d3179
--- /dev/null
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/ddl/invalid-feed-policy-name/invalid-feed-policy-name.2.ddl.sqlpp
@@ -0,0 +1,30 @@
+/*
+ * 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.
+ */
+
+/*
+ * Feed policy name starts with a space character -> Error
+ */
+
+drop dataverse test if exists;
+create dataverse test;
+
+use test;
+
+create ingestion policy ` a` from path 'data/feed-policy/policy.properties'
+  definition 'someString';
\ No newline at end of file
diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/ddl/invalid-feed-policy-name/invalid-feed-policy-name.3.ddl.sqlpp b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/ddl/invalid-feed-policy-name/invalid-feed-policy-name.3.ddl.sqlpp
new file mode 100644
index 0000000..dc10acd
--- /dev/null
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/ddl/invalid-feed-policy-name/invalid-feed-policy-name.3.ddl.sqlpp
@@ -0,0 +1,20 @@
+/*
+ * 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.
+ */
+
+drop dataverse test if exists;
diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/ddl/invalid-index-name/invalid-index-name.1.ddl.sqlpp b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/ddl/invalid-index-name/invalid-index-name.1.ddl.sqlpp
new file mode 100644
index 0000000..ffad79e
--- /dev/null
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/ddl/invalid-index-name/invalid-index-name.1.ddl.sqlpp
@@ -0,0 +1,31 @@
+/*
+ * 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.
+ */
+
+/*
+ * Empty index name -> Error
+ */
+
+drop dataverse test if exists;
+create dataverse test;
+
+use test;
+
+create dataset t1(id int not unknown, x int not unknown) primary key id;
+
+create index `` on t1(x);
\ No newline at end of file
diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/ddl/invalid-index-name/invalid-index-name.2.ddl.sqlpp b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/ddl/invalid-index-name/invalid-index-name.2.ddl.sqlpp
new file mode 100644
index 0000000..6e0bd7d
--- /dev/null
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/ddl/invalid-index-name/invalid-index-name.2.ddl.sqlpp
@@ -0,0 +1,31 @@
+/*
+ * 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.
+ */
+
+/*
+ * Index name starts with a space character -> Error
+ */
+
+drop dataverse test if exists;
+create dataverse test;
+
+use test;
+
+create dataset t1(id int not unknown, x int not unknown) primary key id;
+
+create index ` a` on t1(x);
\ No newline at end of file
diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/ddl/invalid-index-name/invalid-index-name.3.ddl.sqlpp b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/ddl/invalid-index-name/invalid-index-name.3.ddl.sqlpp
new file mode 100644
index 0000000..dc10acd
--- /dev/null
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/ddl/invalid-index-name/invalid-index-name.3.ddl.sqlpp
@@ -0,0 +1,20 @@
+/*
+ * 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.
+ */
+
+drop dataverse test if exists;
diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/ddl/invalid-nodegroup-name/invalid-nodegroup-name.1.ddl.sqlpp b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/ddl/invalid-nodegroup-name/invalid-nodegroup-name.1.ddl.sqlpp
new file mode 100644
index 0000000..ad1de03
--- /dev/null
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/ddl/invalid-nodegroup-name/invalid-nodegroup-name.1.ddl.sqlpp
@@ -0,0 +1,24 @@
+/*
+ * 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.
+ */
+
+/*
+ * Empty node group name -> Error
+ */
+
+create nodegroup `` if not exists on asterix_nc1;
\ No newline at end of file
diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/ddl/invalid-nodegroup-name/invalid-nodegroup-name.2.ddl.sqlpp b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/ddl/invalid-nodegroup-name/invalid-nodegroup-name.2.ddl.sqlpp
new file mode 100644
index 0000000..315d287
--- /dev/null
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/ddl/invalid-nodegroup-name/invalid-nodegroup-name.2.ddl.sqlpp
@@ -0,0 +1,24 @@
+/*
+ * 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.
+ */
+
+/*
+ * Node group name starts with a space character -> Error
+ */
+
+create nodegroup ` a` if not exists on asterix_nc1;
\ No newline at end of file
diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/ddl/invalid-type-name/invalid-type-name.1.ddl.sqlpp b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/ddl/invalid-type-name/invalid-type-name.1.ddl.sqlpp
new file mode 100644
index 0000000..ddaac27
--- /dev/null
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/ddl/invalid-type-name/invalid-type-name.1.ddl.sqlpp
@@ -0,0 +1,31 @@
+/*
+ * 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.
+ */
+
+/*
+ * Empty type name -> Error
+ */
+
+drop dataverse test if exists;
+create dataverse test;
+
+use test;
+
+create type `` as closed {
+  id: int
+};
\ No newline at end of file
diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/ddl/invalid-type-name/invalid-type-name.2.ddl.sqlpp b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/ddl/invalid-type-name/invalid-type-name.2.ddl.sqlpp
new file mode 100644
index 0000000..5ec9f83
--- /dev/null
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/ddl/invalid-type-name/invalid-type-name.2.ddl.sqlpp
@@ -0,0 +1,31 @@
+/*
+ * 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.
+ */
+
+/*
+ * Type name starts with a space character -> Error
+ */
+
+drop dataverse test if exists;
+create dataverse test;
+
+use test;
+
+create type ` a` as closed {
+  id: int
+};
\ No newline at end of file
diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/ddl/invalid-type-name/invalid-type-name.3.ddl.sqlpp b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/ddl/invalid-type-name/invalid-type-name.3.ddl.sqlpp
new file mode 100644
index 0000000..dc10acd
--- /dev/null
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/ddl/invalid-type-name/invalid-type-name.3.ddl.sqlpp
@@ -0,0 +1,20 @@
+/*
+ * 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.
+ */
+
+drop dataverse test if exists;
diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/ddl/invalid-udf-name/invalid-udf-name.1.ddl.sqlpp b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/ddl/invalid-udf-name/invalid-udf-name.1.ddl.sqlpp
new file mode 100644
index 0000000..0c9b27d
--- /dev/null
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/ddl/invalid-udf-name/invalid-udf-name.1.ddl.sqlpp
@@ -0,0 +1,31 @@
+/*
+ * 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.
+ */
+
+/*
+ * Empty function name -> Error
+ */
+
+drop dataverse test if exists;
+create dataverse test;
+
+use test;
+
+create function ``() {
+  1
+};
\ No newline at end of file
diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/ddl/invalid-udf-name/invalid-udf-name.2.ddl.sqlpp b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/ddl/invalid-udf-name/invalid-udf-name.2.ddl.sqlpp
new file mode 100644
index 0000000..fb6e8e4
--- /dev/null
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/ddl/invalid-udf-name/invalid-udf-name.2.ddl.sqlpp
@@ -0,0 +1,31 @@
+/*
+ * 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.
+ */
+
+/*
+ * Function name starts with a space character -> Error
+ */
+
+drop dataverse test if exists;
+create dataverse test;
+
+use test;
+
+create function ` a`() {
+  1
+};
\ No newline at end of file
diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/ddl/invalid-udf-name/invalid-udf-name.3.ddl.sqlpp b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/ddl/invalid-udf-name/invalid-udf-name.3.ddl.sqlpp
new file mode 100644
index 0000000..dc10acd
--- /dev/null
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/ddl/invalid-udf-name/invalid-udf-name.3.ddl.sqlpp
@@ -0,0 +1,20 @@
+/*
+ * 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.
+ */
+
+drop dataverse test if exists;
diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/testsuite_sqlpp.xml b/asterixdb/asterix-app/src/test/resources/runtimets/testsuite_sqlpp.xml
index 6d50376..032097a 100644
--- a/asterixdb/asterix-app/src/test/resources/runtimets/testsuite_sqlpp.xml
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/testsuite_sqlpp.xml
@@ -3911,6 +3911,62 @@
       </compilation-unit>
     </test-case>
     <test-case FilePath="ddl">
+      <compilation-unit name="invalid-dataverse-name">
+        <output-dir compare="Text">none</output-dir>
+        <expected-error>ASX1115: Invalid name for a database object: "&lt;empty&gt;"</expected-error>
+        <expected-error>ASX1115: Invalid name for a database object: " a"</expected-error>
+      </compilation-unit>
+    </test-case>
+    <test-case FilePath="ddl">
+      <compilation-unit name="invalid-dataset-name">
+        <output-dir compare="Text">none</output-dir>
+        <expected-error>ASX1115: Invalid name for a database object: "&lt;empty&gt;"</expected-error>
+        <expected-error>ASX1115: Invalid name for a database object: " a"</expected-error>
+      </compilation-unit>
+    </test-case>
+    <test-case FilePath="ddl">
+      <compilation-unit name="invalid-feed-name">
+        <output-dir compare="Text">none</output-dir>
+        <expected-error>ASX1115: Invalid name for a database object: "&lt;empty&gt;"</expected-error>
+        <expected-error>ASX1115: Invalid name for a database object: " a"</expected-error>
+      </compilation-unit>
+    </test-case>
+    <test-case FilePath="ddl">
+      <compilation-unit name="invalid-feed-policy-name">
+        <output-dir compare="Text">none</output-dir>
+        <expected-error>ASX1115: Invalid name for a database object: "&lt;empty&gt;"</expected-error>
+        <expected-error>ASX1115: Invalid name for a database object: " a"</expected-error>
+      </compilation-unit>
+    </test-case>
+    <test-case FilePath="ddl">
+      <compilation-unit name="invalid-index-name">
+        <output-dir compare="Text">none</output-dir>
+        <expected-error>ASX1115: Invalid name for a database object: "&lt;empty&gt;"</expected-error>
+        <expected-error>ASX1115: Invalid name for a database object: " a"</expected-error>
+      </compilation-unit>
+    </test-case>
+    <test-case FilePath="ddl">
+      <compilation-unit name="invalid-nodegroup-name">
+        <output-dir compare="Text">none</output-dir>
+        <expected-error>ASX1115: Invalid name for a database object: "&lt;empty&gt;"</expected-error>
+        <expected-error>ASX1115: Invalid name for a database object: " a"</expected-error>
+      </compilation-unit>
+    </test-case>
+    <test-case FilePath="ddl">
+      <compilation-unit name="invalid-type-name">
+        <output-dir compare="Text">none</output-dir>
+        <expected-error>ASX1115: Invalid name for a database object: "&lt;empty&gt;"</expected-error>
+        <expected-error>ASX1115: Invalid name for a database object: " a"</expected-error>
+      </compilation-unit>
+    </test-case>
+    <test-case FilePath="ddl">
+      <compilation-unit name="invalid-udf-name">
+        <output-dir compare="Text">none</output-dir>
+        <expected-error>ASX1115: Invalid name for a database object: "&lt;empty&gt;"</expected-error>
+        <expected-error>ASX1115: Invalid name for a database object: " a"</expected-error>
+      </compilation-unit>
+    </test-case>
+    <test-case FilePath="ddl">
       <compilation-unit name="dataset-and-index-same-dataverse">
         <output-dir compare="Text">dataset-and-index-same-dataverse</output-dir>
       </compilation-unit>
diff --git a/asterixdb/asterix-common/src/main/java/org/apache/asterix/common/exceptions/ErrorCode.java b/asterixdb/asterix-common/src/main/java/org/apache/asterix/common/exceptions/ErrorCode.java
index 1d18cf6..21c3416 100644
--- a/asterixdb/asterix-common/src/main/java/org/apache/asterix/common/exceptions/ErrorCode.java
+++ b/asterixdb/asterix-common/src/main/java/org/apache/asterix/common/exceptions/ErrorCode.java
@@ -203,6 +203,7 @@ public class ErrorCode {
     public static final int INVALID_PROPERTY_FORMAT = 1112;
     public static final int INVALID_REGEX_PATTERN = 1113;
     public static final int EXTERNAL_SOURCE_CONFIGURATION_RETURNED_NO_FILES = 1114;
+    public static final int INVALID_DATABASE_OBJECT_NAME = 1115;
 
     // Feed errors
     public static final int DATAFLOW_ILLEGAL_STATE = 3001;
diff --git a/asterixdb/asterix-common/src/main/resources/asx_errormsg/en.properties b/asterixdb/asterix-common/src/main/resources/asx_errormsg/en.properties
index a2780ba..5012c7a 100644
--- a/asterixdb/asterix-common/src/main/resources/asx_errormsg/en.properties
+++ b/asterixdb/asterix-common/src/main/resources/asx_errormsg/en.properties
@@ -198,6 +198,7 @@
 1112 = Invalid format for property \"%1$s\"
 1113 = Invalid pattern %1$s
 1114 = The provided external dataset configuration returned no files from the external source
+1115 = Invalid name for a database object: \"%1$s\"
 
 # Feed Errors
 3001 = Illegal state.


[asterixdb] 02/02: Merge commit '95fa33c'

Posted by dl...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

dlych pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/asterixdb.git

commit b317f37e2618a8571c8d20ec23f091900dd04d85
Merge: 820e6f0 95fa33c
Author: Dmitry Lychagin <dm...@couchbase.com>
AuthorDate: Fri Oct 30 11:35:16 2020 -0700

    Merge commit '95fa33c'
    
    Change-Id: I756837cde80d423cd068924c248dc36856345c10

 .../asterix/app/translator/QueryTranslator.java    | 20 ++++++++
 .../invalid-dataset-name.1.ddl.sqlpp               | 29 +++++++++++
 .../invalid-dataset-name.2.ddl.sqlpp               | 29 +++++++++++
 .../invalid-dataset-name.3.ddl.sqlpp               | 20 ++++++++
 .../invalid-dataverse-name.1.ddl.sqlpp             | 24 ++++++++++
 .../invalid-dataverse-name.2.ddl.sqlpp             | 24 ++++++++++
 .../invalid-feed-name.1.ddl.sqlpp                  | 42 ++++++++++++++++
 .../invalid-feed-name.2.ddl.sqlpp                  | 42 ++++++++++++++++
 .../invalid-feed-name.3.ddl.sqlpp                  | 20 ++++++++
 .../invalid-feed-policy-name.1.ddl.sqlpp           | 30 ++++++++++++
 .../invalid-feed-policy-name.2.ddl.sqlpp           | 30 ++++++++++++
 .../invalid-feed-policy-name.3.ddl.sqlpp           | 20 ++++++++
 .../invalid-index-name.1.ddl.sqlpp                 | 31 ++++++++++++
 .../invalid-index-name.2.ddl.sqlpp                 | 31 ++++++++++++
 .../invalid-index-name.3.ddl.sqlpp                 | 20 ++++++++
 .../invalid-nodegroup-name.1.ddl.sqlpp             | 24 ++++++++++
 .../invalid-nodegroup-name.2.ddl.sqlpp             | 24 ++++++++++
 .../invalid-type-name.1.ddl.sqlpp                  | 31 ++++++++++++
 .../invalid-type-name.2.ddl.sqlpp                  | 31 ++++++++++++
 .../invalid-type-name.3.ddl.sqlpp                  | 20 ++++++++
 .../invalid-udf-name/invalid-udf-name.1.ddl.sqlpp  | 31 ++++++++++++
 .../invalid-udf-name/invalid-udf-name.2.ddl.sqlpp  | 31 ++++++++++++
 .../invalid-udf-name/invalid-udf-name.3.ddl.sqlpp  | 20 ++++++++
 .../test/resources/runtimets/testsuite_sqlpp.xml   | 56 ++++++++++++++++++++++
 .../asterix/common/exceptions/ErrorCode.java       |  4 +-
 .../src/main/resources/asx_errormsg/en.properties  |  3 +-
 26 files changed, 684 insertions(+), 3 deletions(-)

diff --cc asterixdb/asterix-app/src/main/java/org/apache/asterix/app/translator/QueryTranslator.java
index 5339d94,d29a5f5..ec43870
--- a/asterixdb/asterix-app/src/main/java/org/apache/asterix/app/translator/QueryTranslator.java
+++ b/asterixdb/asterix-app/src/main/java/org/apache/asterix/app/translator/QueryTranslator.java
@@@ -515,10 -491,17 +515,13 @@@ public class QueryTranslator extends Ab
      protected void handleCreateDataverseStatement(MetadataProvider metadataProvider, Statement stmt,
              IRequestParameters requestParameters) throws Exception {
          CreateDataverseStatement stmtCreateDataverse = (CreateDataverseStatement) stmt;
 -        SourceLocation sourceLoc = stmtCreateDataverse.getSourceLocation();
 -        String dvName = stmtCreateDataverse.getDataverseName().getValue();
 -        validateDatabaseObjectName(dvName, sourceLoc);
 -        MetadataTransactionContext mdTxnCtx = MetadataManager.INSTANCE.beginTransaction();
 -        metadataProvider.setMetadataTxnContext(mdTxnCtx);
 -        lockManager.acquireDataverseReadLock(metadataProvider.getLocks(), dvName);
 +        DataverseName dvName = stmtCreateDataverse.getDataverseName();
++        for (String dvNamePart : dvName.getParts()) {
++            validateDatabaseObjectName(dvNamePart, stmtCreateDataverse.getSourceLocation());
++        }
 +        lockUtil.createDataverseBegin(lockManager, metadataProvider.getLocks(), dvName);
          try {
 -            doCreateDataverseStatement(mdTxnCtx, metadataProvider, stmtCreateDataverse);
 -        } catch (Exception e) {
 -            abort(e, e, mdTxnCtx);
 -            throw e;
 +            doCreateDataverseStatement(metadataProvider, stmtCreateDataverse, requestParameters);
          } finally {
              metadataProvider.getLocks().unlock();
          }
@@@ -589,13 -565,16 +592,14 @@@
      }
  
      public void handleCreateDatasetStatement(MetadataProvider metadataProvider, Statement stmt,
 -            IHyracksClientConnection hcc, IRequestParameters requestParameters) throws CompilationException, Exception {
 -        MutableObject<ProgressState> progress = new MutableObject<>(ProgressState.NO_PROGRESS);
 +            IHyracksClientConnection hcc, IRequestParameters requestParameters) throws Exception {
          DatasetDecl dd = (DatasetDecl) stmt;
 -        SourceLocation sourceLoc = dd.getSourceLocation();
 -        String dataverseName = getActiveDataverse(dd.getDataverse());
 +        DataverseName dataverseName = getActiveDataverseName(dd.getDataverse());
          String datasetName = dd.getName().getValue();
 -        validateDatabaseObjectName(datasetName, sourceLoc);
 -        DatasetType dsType = dd.getDatasetType();
++        validateDatabaseObjectName(datasetName, stmt.getSourceLocation());
          TypeExpression itemTypeExpr = dd.getItemType();
 -        String itemTypeDataverseName, itemTypeName;
 +        DataverseName itemTypeDataverseName;
 +        String itemTypeName;
          boolean itemTypeAnonymous;
          switch (itemTypeExpr.getTypeKind()) {
              case TYPEREFERENCE:
@@@ -961,23 -910,21 +965,25 @@@
      public void handleCreateIndexStatement(MetadataProvider metadataProvider, Statement stmt,
              IHyracksClientConnection hcc, IRequestParameters requestParameters) throws Exception {
          CreateIndexStatement stmtCreateIndex = (CreateIndexStatement) stmt;
 -        SourceLocation sourceLoc = stmtCreateIndex.getSourceLocation();
 -        String dataverseName = getActiveDataverse(stmtCreateIndex.getDataverseName());
 +        DataverseName dataverseName = getActiveDataverseName(stmtCreateIndex.getDataverseName());
          String datasetName = stmtCreateIndex.getDatasetName().getValue();
+         String indexName = stmtCreateIndex.getIndexName().getValue();
 -        validateDatabaseObjectName(indexName, sourceLoc);
 -        IndexType indexType = stmtCreateIndex.getIndexType();
 -        List<Integer> keySourceIndicators = stmtCreateIndex.getFieldSourceIndicators();
++        validateDatabaseObjectName(indexName, stmt.getSourceLocation());
 +        lockUtil.createIndexBegin(lockManager, metadataProvider.getLocks(), dataverseName, datasetName);
 +        try {
 +            doCreateIndex(metadataProvider, stmtCreateIndex, dataverseName, datasetName, hcc, requestParameters);
 +        } finally {
 +            metadataProvider.getLocks().unlock();
 +        }
 +    }
 +
 +    protected void doCreateIndex(MetadataProvider metadataProvider, CreateIndexStatement stmtCreateIndex,
 +            DataverseName dataverseName, String datasetName, IHyracksClientConnection hcc,
 +            IRequestParameters requestParameters) throws Exception {
 +        SourceLocation sourceLoc = stmtCreateIndex.getSourceLocation();
          MetadataTransactionContext mdTxnCtx = MetadataManager.INSTANCE.beginTransaction();
 +        boolean bActiveTxn = true;
          metadataProvider.setMetadataTxnContext(mdTxnCtx);
 -        String datasetFullyQualifiedName = dataverseName + "." + datasetName;
 -        boolean isSecondaryPrimary = stmtCreateIndex.getFieldExprs().isEmpty();
 -        Dataset ds;
 -        Index index;
 -        MetadataLockUtil.createIndexBegin(lockManager, metadataProvider.getLocks(), dataverseName,
 -                datasetFullyQualifiedName);
          try {
              // Check if the dataverse exists
              Dataverse dv = MetadataManager.INSTANCE.getDataverse(mdTxnCtx, dataverseName);
@@@ -1386,11 -1346,13 +1392,12 @@@
      protected void handleCreateTypeStatement(MetadataProvider metadataProvider, Statement stmt) throws Exception {
          TypeDecl stmtCreateType = (TypeDecl) stmt;
          SourceLocation sourceLoc = stmtCreateType.getSourceLocation();
 -        String dataverseName = getActiveDataverse(stmtCreateType.getDataverseName());
 +        DataverseName dataverseName = getActiveDataverseName(stmtCreateType.getDataverseName());
          String typeName = stmtCreateType.getIdent().getValue();
+         validateDatabaseObjectName(typeName, sourceLoc);
          MetadataTransactionContext mdTxnCtx = MetadataManager.INSTANCE.beginTransaction();
          metadataProvider.setMetadataTxnContext(mdTxnCtx);
 -        MetadataLockUtil.createTypeBegin(lockManager, metadataProvider.getLocks(), dataverseName,
 -                dataverseName + "." + typeName);
 +        lockUtil.createTypeBegin(lockManager, metadataProvider.getLocks(), dataverseName, typeName);
          try {
              Dataverse dv = MetadataManager.INSTANCE.getDataverse(mdTxnCtx, dataverseName);
              if (dv == null) {
@@@ -1967,378 -1933,44 +1974,379 @@@
          }
      }
  
 -    protected void handleCreateFunctionStatement(MetadataProvider metadataProvider, Statement stmt) throws Exception {
 +    protected void handleDeclareFunctionStatement(Statement stmt) {
 +        FunctionDecl fds = (FunctionDecl) stmt;
 +        FunctionSignature signature = fds.getSignature();
 +        signature.setDataverseName(getActiveDataverseName(signature.getDataverseName()));
 +        declaredFunctions.add(fds);
 +    }
 +
 +    public void handleCreateFunctionStatement(MetadataProvider metadataProvider, Statement stmt,
 +            IStatementRewriter stmtRewriter) throws Exception {
          CreateFunctionStatement cfs = (CreateFunctionStatement) stmt;
 -        SourceLocation sourceLoc = cfs.getSourceLocation();
          FunctionSignature signature = cfs.getFunctionSignature();
 -        validateDatabaseObjectName(signature.getName(), sourceLoc);
 -        String dataverse = getActiveDataverseName(signature.getNamespace());
 -        signature.setNamespace(dataverse);
++        validateDatabaseObjectName(signature.getName(), stmt.getSourceLocation());
 +        DataverseName dataverseName = getActiveDataverseName(signature.getDataverseName());
 +        signature.setDataverseName(dataverseName);
 +        DataverseName libraryDataverseName = null;
 +        String libraryName = cfs.getLibraryName();
 +        if (libraryName != null) {
 +            libraryDataverseName = cfs.getLibraryDataverseName();
 +            if (libraryDataverseName == null) {
 +                libraryDataverseName = dataverseName;
 +            }
 +        }
 +
 +        lockUtil.createFunctionBegin(lockManager, metadataProvider.getLocks(), dataverseName, signature.getName(),
 +                libraryDataverseName, libraryName);
 +        try {
 +            doCreateFunction(metadataProvider, cfs, signature, stmtRewriter);
 +        } finally {
 +            metadataProvider.getLocks().unlock();
 +            metadataProvider.setDefaultDataverse(activeDataverse);
 +        }
 +    }
  
 +    protected void doCreateFunction(MetadataProvider metadataProvider, CreateFunctionStatement cfs,
 +            FunctionSignature functionSignature, IStatementRewriter stmtRewriter) throws Exception {
 +        DataverseName dataverseName = functionSignature.getDataverseName();
 +        SourceLocation sourceLoc = cfs.getSourceLocation();
          MetadataTransactionContext mdTxnCtx = MetadataManager.INSTANCE.beginTransaction();
          metadataProvider.setMetadataTxnContext(mdTxnCtx);
 -        MetadataLockUtil.functionStatementBegin(lockManager, metadataProvider.getLocks(), dataverse,
 -                dataverse + "." + signature.getName());
          try {
 -            Dataverse dv = MetadataManager.INSTANCE.getDataverse(mdTxnCtx, dataverse);
 +            Dataverse dv = MetadataManager.INSTANCE.getDataverse(mdTxnCtx, dataverseName);
              if (dv == null) {
 -                throw new CompilationException(ErrorCode.UNKNOWN_DATAVERSE, sourceLoc, dataverse);
 +                throw new CompilationException(ErrorCode.UNKNOWN_DATAVERSE, sourceLoc, dataverseName);
 +            }
 +            List<TypeSignature> existingInlineTypes;
 +            Function existingFunction = MetadataManager.INSTANCE.getFunction(mdTxnCtx, functionSignature);
 +            if (existingFunction != null) {
 +                if (cfs.getReplaceIfExists()) {
 +                    if (cfs.getIfNotExists()) {
 +                        throw new CompilationException(ErrorCode.PARSE_ERROR, cfs.getSourceLocation(), "IF NOT EXISTS");
 +                    }
 +                } else if (cfs.getIfNotExists()) {
 +                    MetadataManager.INSTANCE.commitTransaction(mdTxnCtx);
 +                    return;
 +                } else {
 +                    throw new CompilationException(ErrorCode.FUNCTION_EXISTS, cfs.getSourceLocation(),
 +                            functionSignature.toString(false));
 +                }
 +                existingInlineTypes = TypeUtil.getFunctionInlineTypes(existingFunction);
 +            } else {
 +                existingInlineTypes = Collections.emptyList();
 +            }
 +
 +            Map<TypeSignature, Datatype> newInlineTypes;
 +            Function function;
 +            if (cfs.isExternal()) {
 +                List<Pair<VarIdentifier, TypeExpression>> paramList = cfs.getParameters();
 +                int paramCount = paramList.size();
 +                List<String> paramNames = new ArrayList<>(paramCount);
 +                List<TypeSignature> paramTypes = new ArrayList<>(paramCount);
 +                LinkedHashSet<TypeSignature> depTypes = new LinkedHashSet<>();
 +                newInlineTypes = new HashMap<>();
 +
 +                for (int i = 0; i < paramCount; i++) {
 +                    Pair<VarIdentifier, TypeExpression> paramPair = paramList.get(i);
 +                    TypeSignature paramTypeSignature;
 +                    TypeSignature paramDepTypeSignature;
 +                    Datatype paramInlineTypeEntity;
 +                    TypeExpression paramTypeExpr = paramPair.getSecond();
 +                    if (paramTypeExpr != null) {
 +                        Triple<TypeSignature, TypeSignature, Datatype> paramTypeInfo = translateFunctionParameterType(
 +                                functionSignature, i, paramTypeExpr, sourceLoc, metadataProvider, mdTxnCtx);
 +                        paramTypeSignature = paramTypeInfo.first;
 +                        paramDepTypeSignature = paramTypeInfo.second;
 +                        paramInlineTypeEntity = paramTypeInfo.third;
 +                    } else {
 +                        paramTypeSignature = null; // == any
 +                        paramDepTypeSignature = null;
 +                        paramInlineTypeEntity = null;
 +                    }
 +                    paramTypes.add(paramTypeSignature); // null == any
 +                    if (paramDepTypeSignature != null) {
 +                        depTypes.add(paramDepTypeSignature);
 +                    }
 +                    if (paramInlineTypeEntity != null) {
 +                        newInlineTypes.put(paramTypeSignature, paramInlineTypeEntity);
 +                    }
 +                    VarIdentifier paramName = paramPair.getFirst();
 +                    paramNames.add(stmtRewriter.toFunctionParameterName(paramName));
 +                }
 +
 +                TypeSignature returnTypeSignature;
 +                TypeSignature returnDepTypeSignature;
 +                Datatype returnInlineTypeEntity;
 +                TypeExpression returnTypeExpr = cfs.getReturnType();
 +                if (returnTypeExpr != null) {
 +                    Triple<TypeSignature, TypeSignature, Datatype> returnTypeInfo = translateFunctionParameterType(
 +                            functionSignature, -1, returnTypeExpr, sourceLoc, metadataProvider, mdTxnCtx);
 +                    returnTypeSignature = returnTypeInfo.first;
 +                    returnDepTypeSignature = returnTypeInfo.second;
 +                    returnInlineTypeEntity = returnTypeInfo.third;
 +                } else {
 +                    returnTypeSignature = null; // == any
 +                    returnDepTypeSignature = null;
 +                    returnInlineTypeEntity = null;
 +                }
 +                if (returnDepTypeSignature != null) {
 +                    depTypes.add(returnDepTypeSignature);
 +                }
 +                if (returnInlineTypeEntity != null) {
 +                    newInlineTypes.put(returnTypeSignature, returnInlineTypeEntity);
 +                }
 +
 +                DataverseName libraryDataverseName = cfs.getLibraryDataverseName();
 +                if (libraryDataverseName == null) {
 +                    libraryDataverseName = dataverseName;
 +                }
 +                String libraryName = cfs.getLibraryName();
 +                Library library = MetadataManager.INSTANCE.getLibrary(mdTxnCtx, libraryDataverseName, libraryName);
 +                if (library == null) {
 +                    throw new CompilationException(ErrorCode.UNKNOWN_LIBRARY, sourceLoc, libraryName);
 +                }
 +
 +                ExternalFunctionLanguage language =
 +                        ExternalFunctionCompilerUtil.getExternalFunctionLanguage(library.getLanguage());
 +                List<String> externalIdentifier = cfs.getExternalIdentifier();
 +                ExternalFunctionCompilerUtil.validateExternalIdentifier(externalIdentifier, language,
 +                        cfs.getSourceLocation());
 +                List<List<Triple<DataverseName, String, String>>> dependencies =
 +                        FunctionUtil.getExternalFunctionDependencies(depTypes);
 +
 +                function = new Function(functionSignature, paramNames, paramTypes, returnTypeSignature, null,
 +                        FunctionKind.SCALAR.toString(), library.getLanguage(), libraryDataverseName, libraryName,
 +                        externalIdentifier, cfs.getNullCall(), cfs.getDeterministic(), cfs.getResources(),
 +                        dependencies);
 +            } else {
 +                List<Pair<VarIdentifier, TypeExpression>> paramList = cfs.getParameters();
 +                int paramCount = paramList.size();
 +                List<VarIdentifier> paramVars = new ArrayList<>(paramCount);
 +                List<String> paramNames = new ArrayList<>(paramCount);
 +                for (Pair<VarIdentifier, TypeExpression> paramPair : paramList) {
 +                    VarIdentifier paramName = paramPair.getFirst();
 +                    paramVars.add(paramName);
 +                    paramNames.add(stmtRewriter.toFunctionParameterName(paramName));
 +                    if (paramPair.getSecond() != null) {
 +                        throw new CompilationException(ErrorCode.COMPILATION_ILLEGAL_STATE, sourceLoc,
 +                                paramName.toString());
 +                    }
 +                }
 +
 +                //Check whether the function is use-able
 +                metadataProvider.setDefaultDataverse(dv);
 +                Query wrappedQuery = new Query(false);
 +                wrappedQuery.setSourceLocation(sourceLoc);
 +                wrappedQuery.setBody(cfs.getFunctionBodyExpression());
 +                wrappedQuery.setTopLevel(false);
 +                apiFramework.reWriteQuery(declaredFunctions, metadataProvider, wrappedQuery, sessionOutput, false,
 +                        paramVars, warningCollector);
 +                List<List<Triple<DataverseName, String, String>>> dependencies = FunctionUtil.getFunctionDependencies(
 +                        rewriterFactory.createQueryRewriter(), cfs.getFunctionBodyExpression(), metadataProvider);
 +
 +                newInlineTypes = Collections.emptyMap();
 +                function = new Function(functionSignature, paramNames, null, null, cfs.getFunctionBody(),
 +                        FunctionKind.SCALAR.toString(), compilationProvider.getParserFactory().getLanguage(), null,
 +                        null, null, null, null, null, dependencies);
 +            }
 +
 +            if (existingFunction == null) {
 +                // add new function and its inline types
 +                for (Datatype newInlineType : newInlineTypes.values()) {
 +                    MetadataManager.INSTANCE.addDatatype(mdTxnCtx, newInlineType);
 +                }
 +                MetadataManager.INSTANCE.addFunction(mdTxnCtx, function);
 +            } else {
 +                // replace existing function and its inline types
 +                for (TypeSignature existingInlineType : existingInlineTypes) {
 +                    Datatype newInlineType =
 +                            newInlineTypes.isEmpty() ? null : newInlineTypes.remove(existingInlineType);
 +                    if (newInlineType == null) {
 +                        MetadataManager.INSTANCE.dropDatatype(mdTxnCtx, existingInlineType.getDataverseName(),
 +                                existingInlineType.getName());
 +                    } else {
 +                        MetadataManager.INSTANCE.updateDatatype(mdTxnCtx, newInlineType);
 +                    }
 +                }
 +                for (Datatype inlineType : newInlineTypes.values()) {
 +                    MetadataManager.INSTANCE.addDatatype(mdTxnCtx, inlineType);
 +                }
 +                MetadataManager.INSTANCE.updateFunction(mdTxnCtx, function);
 +            }
 +            if (LOGGER.isInfoEnabled()) {
 +                LOGGER.info("Installed function: " + functionSignature);
 +            }
 +            MetadataManager.INSTANCE.commitTransaction(mdTxnCtx);
 +        } catch (Exception e) {
 +            abort(e, e, mdTxnCtx);
 +            throw e;
 +        }
 +    }
 +
 +    private Triple<TypeSignature, TypeSignature, Datatype> translateFunctionParameterType(
 +            FunctionSignature functionSignature, int paramIdx, TypeExpression paramTypeExpr, SourceLocation sourceLoc,
 +            MetadataProvider metadataProvider, MetadataTransactionContext mdTxnCtx) throws AlgebricksException {
 +        TypeSignature paramTypeSignature, depTypeSignature;
 +        Datatype paramInlineTypeEntity = null;
 +        switch (paramTypeExpr.getTypeKind()) {
 +            case TYPEREFERENCE:
 +                TypeReferenceExpression paramTypeRefExpr = (TypeReferenceExpression) paramTypeExpr;
 +                String paramTypeName = paramTypeRefExpr.getIdent().second.getValue();
 +                BuiltinType builtinType = BuiltinTypeMap.getBuiltinType(paramTypeName);
 +                if (builtinType != null) {
 +                    // built-in type
 +                    paramTypeSignature = new TypeSignature(builtinType);
 +                    depTypeSignature = null;
 +                } else {
 +                    // user-defined type
 +                    DataverseName paramTypeDataverseName = paramTypeRefExpr.getIdent().first;
 +                    if (paramTypeDataverseName == null) {
 +                        paramTypeDataverseName = functionSignature.getDataverseName();
 +                    }
 +                    Datatype paramTypeEntity = metadataProvider.findTypeEntity(paramTypeDataverseName, paramTypeName);
 +                    if (paramTypeEntity == null || paramTypeEntity.getIsAnonymous()) {
 +                        throw new CompilationException(ErrorCode.UNKNOWN_TYPE, sourceLoc, paramTypeName);
 +                    }
 +                    paramTypeSignature = depTypeSignature = new TypeSignature(paramTypeDataverseName, paramTypeName);
 +                }
 +                break;
 +            case ORDEREDLIST:
 +            case UNORDEREDLIST:
 +                DataverseName paramTypeDataverseName = functionSignature.getDataverseName();
 +                paramTypeName = TypeUtil.createFunctionParameterTypeName(functionSignature.getName(),
 +                        functionSignature.getArity(), paramIdx);
 +                IAType paramType = translateType(paramTypeDataverseName, paramTypeName, paramTypeExpr, mdTxnCtx);
 +                paramTypeSignature = new TypeSignature(paramTypeDataverseName, paramTypeName);
 +                depTypeSignature =
 +                        FunctionUtil.getTypeDependencyFromFunctionParameter(paramTypeExpr, paramTypeDataverseName);
 +                paramInlineTypeEntity = new Datatype(paramTypeDataverseName, paramTypeName, paramType, true);
 +                break;
 +            default:
 +                throw new CompilationException(ErrorCode.COMPILATION_ILLEGAL_STATE, sourceLoc);
 +        }
 +
 +        return new Triple<>(paramTypeSignature, depTypeSignature, paramInlineTypeEntity);
 +    }
 +
 +    protected void handleFunctionDropStatement(MetadataProvider metadataProvider, Statement stmt) throws Exception {
 +        FunctionDropStatement stmtDropFunction = (FunctionDropStatement) stmt;
 +        FunctionSignature signature = stmtDropFunction.getFunctionSignature();
 +        DataverseName dataverseName = getActiveDataverseName(signature.getDataverseName());
 +        signature.setDataverseName(dataverseName);
 +        lockUtil.dropFunctionBegin(lockManager, metadataProvider.getLocks(), dataverseName, signature.getName());
 +        try {
 +            doDropFunction(metadataProvider, stmtDropFunction, signature);
 +        } finally {
 +            metadataProvider.getLocks().unlock();
 +        }
 +    }
 +
 +    protected boolean doDropFunction(MetadataProvider metadataProvider, FunctionDropStatement stmtDropFunction,
 +            FunctionSignature signature) throws Exception {
 +        DataverseName dataverseName = signature.getDataverseName();
 +        SourceLocation sourceLoc = stmtDropFunction.getSourceLocation();
 +        MetadataTransactionContext mdTxnCtx = MetadataManager.INSTANCE.beginTransaction();
 +        metadataProvider.setMetadataTxnContext(mdTxnCtx);
 +        try {
 +            Dataverse dataverse = MetadataManager.INSTANCE.getDataverse(mdTxnCtx, dataverseName);
 +            if (dataverse == null) {
 +                if (stmtDropFunction.getIfExists()) {
 +                    MetadataManager.INSTANCE.commitTransaction(mdTxnCtx);
 +                    return false;
 +                } else {
 +                    throw new CompilationException(ErrorCode.UNKNOWN_DATAVERSE, sourceLoc, dataverseName);
 +                }
 +            }
 +            Function function = MetadataManager.INSTANCE.getFunction(mdTxnCtx, signature);
 +            if (function == null) {
 +                if (stmtDropFunction.getIfExists()) {
 +                    MetadataManager.INSTANCE.commitTransaction(mdTxnCtx);
 +                    return false;
 +                } else {
 +                    throw new CompilationException(ErrorCode.UNKNOWN_FUNCTION, sourceLoc, signature.toString());
 +                }
              }
  
 -            //Check whether the function is use-able
 -            metadataProvider.setDefaultDataverse(dv);
 -            Query wrappedQuery = new Query(false);
 -            wrappedQuery.setSourceLocation(sourceLoc);
 -            wrappedQuery.setBody(cfs.getFunctionBodyExpression());
 -            wrappedQuery.setTopLevel(false);
 -            List<VarIdentifier> paramVars = new ArrayList<>();
 -            for (String v : cfs.getParamList()) {
 -                paramVars.add(new VarIdentifier(v));
 +            List<TypeSignature> inlineTypes = TypeUtil.getFunctionInlineTypes(function);
 +
 +            MetadataManager.INSTANCE.dropFunction(mdTxnCtx, signature);
 +            for (TypeSignature inlineType : inlineTypes) {
 +                MetadataManager.INSTANCE.dropDatatype(mdTxnCtx, inlineType.getDataverseName(), inlineType.getName());
 +            }
 +            MetadataManager.INSTANCE.commitTransaction(mdTxnCtx);
 +            return true;
 +        } catch (Exception e) {
 +            abort(e, e, mdTxnCtx);
 +            throw e;
 +        }
 +    }
 +
 +    protected void handleCreateAdapterStatement(MetadataProvider metadataProvider, Statement stmt) throws Exception {
 +        CreateAdapterStatement cas = (CreateAdapterStatement) stmt;
 +        DataverseName dataverseName = getActiveDataverseName(cas.getDataverseName());
 +        DataverseName libraryDataverseName = cas.getLibraryDataverseName();
 +        if (libraryDataverseName == null) {
 +            libraryDataverseName = dataverseName;
 +        }
 +        String libraryName = cas.getLibraryName();
 +        lockUtil.createAdapterBegin(lockManager, metadataProvider.getLocks(), dataverseName, cas.getAdapterName(),
 +                libraryDataverseName, libraryName);
 +        try {
 +            doCreateAdapter(metadataProvider, cas);
 +        } finally {
 +            metadataProvider.getLocks().unlock();
 +        }
 +    }
 +
 +    protected void doCreateAdapter(MetadataProvider metadataProvider, CreateAdapterStatement cas) throws Exception {
 +        SourceLocation sourceLoc = cas.getSourceLocation();
 +        MetadataTransactionContext mdTxnCtx = MetadataManager.INSTANCE.beginTransaction();
 +        metadataProvider.setMetadataTxnContext(mdTxnCtx);
 +        try {
 +            DataverseName dataverseName = getActiveDataverseName(cas.getDataverseName());
 +            Dataverse dv = MetadataManager.INSTANCE.getDataverse(mdTxnCtx, dataverseName);
 +            if (dv == null) {
 +                throw new CompilationException(ErrorCode.UNKNOWN_DATAVERSE, sourceLoc, dataverseName);
 +            }
 +            String adapterName = cas.getAdapterName();
 +            DatasourceAdapter adapter = MetadataManager.INSTANCE.getAdapter(mdTxnCtx, dataverseName, adapterName);
 +            if (adapter != null) {
 +                if (cas.getIfNotExists()) {
 +                    MetadataManager.INSTANCE.commitTransaction(mdTxnCtx);
 +                    return;
 +                }
 +                throw new CompilationException(ErrorCode.ADAPTER_EXISTS, sourceLoc, adapterName);
              }
 -            apiFramework.reWriteQuery(declaredFunctions, metadataProvider, wrappedQuery, sessionOutput, false,
 -                    paramVars, warningCollector);
  
 -            List<List<List<String>>> dependencies = FunctionUtil.getFunctionDependencies(
 -                    rewriterFactory.createQueryRewriter(), cfs.getFunctionBodyExpression(), metadataProvider);
 +            DataverseName libraryDataverseName = cas.getLibraryDataverseName();
 +            if (libraryDataverseName == null) {
 +                libraryDataverseName = dataverseName;
 +            }
 +            String libraryName = cas.getLibraryName();
 +            Library library = MetadataManager.INSTANCE.getLibrary(mdTxnCtx, libraryDataverseName, libraryName);
 +            if (library == null) {
 +                throw new CompilationException(ErrorCode.UNKNOWN_LIBRARY, sourceLoc, libraryName);
 +            }
 +            // Add adapters
 +            ExternalFunctionLanguage language =
 +                    ExternalFunctionCompilerUtil.getExternalFunctionLanguage(library.getLanguage());
 +            List<String> externalIdentifier = cas.getExternalIdentifier();
 +            ExternalFunctionCompilerUtil.validateExternalIdentifier(externalIdentifier, language,
 +                    cas.getSourceLocation());
  
 -            Function function = new Function(signature, cfs.getParamList(), Function.RETURNTYPE_VOID,
 -                    cfs.getFunctionBody(), getFunctionLanguage(), FunctionKind.SCALAR.toString(), dependencies);
 -            MetadataManager.INSTANCE.addFunction(mdTxnCtx, function);
 +            if (language != ExternalFunctionLanguage.JAVA) {
 +                throw new CompilationException(ErrorCode.UNSUPPORTED_ADAPTER_LANGUAGE, cas.getSourceLocation(),
 +                        language.name());
 +            }
 +            String adapterFactoryClass = externalIdentifier.get(0);
  
 +            adapter = new DatasourceAdapter(new AdapterIdentifier(dataverseName, adapterName),
 +                    IDataSourceAdapter.AdapterType.EXTERNAL, adapterFactoryClass, libraryDataverseName, libraryName);
 +            MetadataManager.INSTANCE.addAdapter(mdTxnCtx, adapter);
 +            if (LOGGER.isInfoEnabled()) {
 +                LOGGER.info("Installed adapter: " + adapterName);
 +            }
              MetadataManager.INSTANCE.commitTransaction(mdTxnCtx);
          } catch (Exception e) {
              abort(e, e, mdTxnCtx);
@@@ -2874,11 -2239,13 +2882,12 @@@
      protected void handleCreateFeedStatement(MetadataProvider metadataProvider, Statement stmt) throws Exception {
          CreateFeedStatement cfs = (CreateFeedStatement) stmt;
          SourceLocation sourceLoc = cfs.getSourceLocation();
 -        String dataverseName = getActiveDataverse(cfs.getDataverseName());
 +        DataverseName dataverseName = getActiveDataverseName(cfs.getDataverseName());
          String feedName = cfs.getFeedName().getValue();
+         validateDatabaseObjectName(feedName, sourceLoc);
          MetadataTransactionContext mdTxnCtx = MetadataManager.INSTANCE.beginTransaction();
          metadataProvider.setMetadataTxnContext(mdTxnCtx);
 -        MetadataLockUtil.createFeedBegin(lockManager, metadataProvider.getLocks(), dataverseName,
 -                dataverseName + "." + feedName);
 +        lockUtil.createFeedBegin(lockManager, metadataProvider.getLocks(), dataverseName, feedName);
          try {
              Feed feed =
                      MetadataManager.INSTANCE.getFeed(metadataProvider.getMetadataTxnContext(), dataverseName, feedName);
@@@ -2912,9 -2281,11 +2921,10 @@@
          MetadataTransactionContext mdTxnCtx = null;
          CreateFeedPolicyStatement cfps = (CreateFeedPolicyStatement) stmt;
          SourceLocation sourceLoc = cfps.getSourceLocation();
 -        dataverse = getActiveDataverse(null);
 -        policy = cfps.getPolicyName();
 -        validateDatabaseObjectName(policy, sourceLoc);
 -        MetadataLockUtil.createFeedPolicyBegin(lockManager, metadataProvider.getLocks(), dataverse,
 -                dataverse + "." + policy);
 +        DataverseName dataverseName = getActiveDataverseName(null);
 +        String policyName = cfps.getPolicyName();
++        validateDatabaseObjectName(policyName, sourceLoc);
 +        lockUtil.createFeedPolicyBegin(lockManager, metadataProvider.getLocks(), dataverseName, policyName);
          try {
              mdTxnCtx = MetadataManager.INSTANCE.beginTransaction();
              metadataProvider.setMetadataTxnContext(mdTxnCtx);
diff --cc asterixdb/asterix-common/src/main/java/org/apache/asterix/common/exceptions/ErrorCode.java
index 3aae2e1,21c3416..38150f5
--- a/asterixdb/asterix-common/src/main/java/org/apache/asterix/common/exceptions/ErrorCode.java
+++ b/asterixdb/asterix-common/src/main/java/org/apache/asterix/common/exceptions/ErrorCode.java
@@@ -203,23 -203,8 +203,23 @@@ public class ErrorCode 
      public static final int INVALID_PROPERTY_FORMAT = 1112;
      public static final int INVALID_REGEX_PATTERN = 1113;
      public static final int EXTERNAL_SOURCE_CONFIGURATION_RETURNED_NO_FILES = 1114;
-     public static final int SYNONYM_EXISTS = 1115;
+     public static final int INVALID_DATABASE_OBJECT_NAME = 1115;
 -
 +    public static final int UNKNOWN_SYNONYM = 1116;
 +    public static final int UNKNOWN_LIBRARY = 1117;
 +    public static final int COMPILATION_GROUPING_SETS_OVERFLOW = 1118;
 +    public static final int COMPILATION_GROUPING_OPERATION_INVALID_ARG = 1119;
 +    public static final int COMPILATION_UNEXPECTED_ALIAS = 1120;
 +    public static final int COMPILATION_ILLEGAL_USE_OF_FILTER_CLAUSE = 1121;
 +    public static final int COMPILATION_BAD_FUNCTION_DEFINITION = 1122;
 +    public static final int FUNCTION_EXISTS = 1123;
 +    public static final int ADAPTER_EXISTS = 1124;
 +    public static final int UNKNOWN_ADAPTER = 1125;
 +    public static final int INVALID_EXTERNAL_IDENTIFIER_SIZE = 1126;
 +    public static final int UNSUPPORTED_ADAPTER_LANGUAGE = 1127;
 +    public static final int INCONSISTENT_FILTER_INDICATOR = 1128;
 +    public static final int UNSUPPORTED_GBY_OBY_SELECT_COMBO = 1129;
 +    public static final int ILLEGAL_RIGHT_OUTER_JOIN = 1130;
- 
++    public static final int SYNONYM_EXISTS = 1131;
      // Feed errors
      public static final int DATAFLOW_ILLEGAL_STATE = 3001;
      public static final int UTIL_DATAFLOW_UTILS_TUPLE_TOO_LARGE = 3002;
diff --cc asterixdb/asterix-common/src/main/resources/asx_errormsg/en.properties
index 40caeb8,5012c7a..a02c50b
--- a/asterixdb/asterix-common/src/main/resources/asx_errormsg/en.properties
+++ b/asterixdb/asterix-common/src/main/resources/asx_errormsg/en.properties
@@@ -200,22 -198,7 +200,23 @@@
  1112 = Invalid format for property \"%1$s\"
  1113 = Invalid pattern %1$s
  1114 = The provided external dataset configuration returned no files from the external source
- 1115 = A synonym with this name %1$s already exists
+ 1115 = Invalid name for a database object: \"%1$s\"
 +1116 = Cannot find synonym with name %1$s
 +1117 = Unknown library %1$s
 +1118 = Too many grouping sets in group by clause: %1$s. Maximum allowed: %2$s.
 +1119 = Invalid argument to grouping() function
 +1120 = Unexpected alias: %1$s
 +1121 = Illegal use of aggregate FILTER clause
 +1122 = Error compiling function %1$s. %2$s
 +1123 = A function with this name %1$s already exists
 +1124 = An adapter with this name %1$s already exists
 +1125 = Cannot find adapter with name %1$s
 +1126 = Invalid number of elements in external identifier. Expected %1$s elements for %2$s language
 +1127 = Unsupported adapter language: %1$s
 +1128 = Filter field is not defined properly
 +1129 = Cannot compile SELECT variable.* with GROUP BY GROUPING SETS/ROLLUP/CUBE followed by ORDER BY/LIMIT
 +1130 = Illegal use of RIGHT OUTER JOIN
++1131 = A synonym with this name %1$s already exists
  
  # Feed Errors
  3001 = Illegal state.