[NO ISSUE][COMP] Add and collect dependent datasets

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

Details:

- Collect dataset/synonym/function for CREATE DATASET AS <QUERY> statement
- check SELECT on dependent collections
- Abort the dataset creation transaction in case of failure.

Ext-ref: MB-62587
Change-Id: I1a9ce0b883d85356ce6f2dc014d5e5b3dc948707
Reviewed-on: https://asterix-gerrit.ics.uci.edu/c/asterixdb/+/18468
Integration-Tests: Jenkins <jenkins@fulliautomatix.ics.uci.edu>
Tested-by: Jenkins <jenkins@fulliautomatix.ics.uci.edu>
Reviewed-by: Janhavi Tripurwar <janhavi.tripurwar@couchbase.com>
Reviewed-by: Ali Alsuliman <ali.al.solaiman@gmail.com>
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 f60a99f..ad74d6c 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
@@ -172,6 +172,7 @@
 import org.apache.asterix.lang.common.struct.Identifier;
 import org.apache.asterix.lang.common.struct.VarIdentifier;
 import org.apache.asterix.lang.common.util.FunctionUtil;
+import org.apache.asterix.lang.common.util.LangDatasetUtil;
 import org.apache.asterix.lang.common.util.ViewUtil;
 import org.apache.asterix.lang.sqlpp.rewrites.SqlppQueryRewriter;
 import org.apache.asterix.metadata.IDatasetDetails;
@@ -601,10 +602,10 @@
     }
 
     protected LangRewritingContext createLangRewritingContext(MetadataProvider metadataProvider,
-            List<FunctionDecl> declaredFunctions, List<ViewDecl> declaredViews, IWarningCollector warningCollector,
-            int varCounter) {
+            List<FunctionDecl> declaredFunctions, List<ViewDecl> declaredViews, List<DatasetDecl> declaredDatasets,
+            IWarningCollector warningCollector, int varCounter) {
         return new LangRewritingContext(metadataProvider, declaredFunctions, declaredViews, warningCollector,
-                varCounter);
+                declaredDatasets, varCounter);
     }
 
     protected Namespace handleUseDataverseStatement(MetadataProvider metadataProvider, Statement stmt)
@@ -921,6 +922,20 @@
                     throw new CompilationException(ErrorCode.DATASET_EXISTS, sourceLoc, datasetName, dataverseName);
                 }
             }
+            if (dd.getQuery() != null) {
+                IQueryRewriter queryRewriter = rewriterFactory.createQueryRewriter();
+                Query wrappedQuery = queryRewriter.createDatasetAccessorQuery(dd, namespaceResolver, namespace);
+                dd.setNamespace(namespace);
+                LangRewritingContext langRewritingContext =
+                        createLangRewritingContext(metadataProvider, declaredFunctions, null,
+                                Collections.singletonList(dd), warningCollector, wrappedQuery.getVarCounter());
+                apiFramework.reWriteQuery(langRewritingContext, wrappedQuery, sessionOutput, false, false,
+                        Collections.emptyList());
+
+                LangDatasetUtil.getDatasetDependencies(metadataProvider, dd, queryRewriter);
+                appCtx.getReceptionist().ensureAuthorized(requestParameters, metadataProvider);
+            }
+
             List<TypeExpression> partitioningExprTypes = null;
             if (dsType == DatasetType.INTERNAL) {
                 partitioningExprTypes = ((InternalDetailsDecl) dd.getDatasetDetailsDecl()).getPartitioningExprTypes();
@@ -1033,7 +1048,6 @@
 
             if (dsType == DatasetType.INTERNAL) {
                 JobSpecification jobSpec = DatasetUtil.createDatasetJobSpec(dataset, metadataProvider);
-
                 // #. make metadataTxn commit before calling runJob.
                 MetadataManager.INSTANCE.commitTransaction(mdTxnCtx);
                 bActiveTxn = false;
@@ -2932,8 +2946,9 @@
             Query wrappedQuery =
                     queryRewriter.createViewAccessorQuery(viewDecl, metadataProvider.getNamespaceResolver());
             metadataProvider.setDefaultNamespace(ns);
+
             LangRewritingContext langRewritingContext = createLangRewritingContext(metadataProvider, declaredFunctions,
-                    Collections.singletonList(viewDecl), warningCollector, wrappedQuery.getVarCounter());
+                    Collections.singletonList(viewDecl), null, warningCollector, wrappedQuery.getVarCounter());
             apiFramework.reWriteQuery(langRewritingContext, wrappedQuery, sessionOutput, false, false,
                     Collections.emptyList());
 
@@ -3237,7 +3252,7 @@
                 fdList.add(fd);
                 metadataProvider.setDefaultNamespace(ns);
                 LangRewritingContext langRewritingContext = createLangRewritingContext(metadataProvider, fdList, null,
-                        warningCollector, wrappedQuery.getVarCounter());
+                        null, warningCollector, wrappedQuery.getVarCounter());
                 apiFramework.reWriteQuery(langRewritingContext, wrappedQuery, sessionOutput, false, false,
                         Collections.emptyList());
 
@@ -4077,7 +4092,7 @@
                 Map<VarIdentifier, IAObject> externalVars = createExternalVariables(copyTo, stmtParams);
                 // Query Rewriting (happens under the same ongoing metadata transaction)
                 LangRewritingContext langRewritingContext = createLangRewritingContext(metadataProvider,
-                        declaredFunctions, null, warningCollector, copyTo.getVarCounter());
+                        declaredFunctions, null, null, warningCollector, copyTo.getVarCounter());
                 Pair<IReturningStatement, Integer> rewrittenResult = apiFramework.reWriteQuery(langRewritingContext,
                         copyTo, sessionOutput, true, true, externalVars.keySet());
 
@@ -4141,6 +4156,7 @@
                 metadataProvider.setWriteTransaction(true);
                 final JobSpecification jobSpec =
                         rewriteCompileInsertUpsert(hcc, metadataProvider, stmtInsertUpsert, stmtParams);
+                appCtx.getReceptionist().ensureAuthorized(reqParams, metadataProvider);
                 MetadataManager.INSTANCE.commitTransaction(mdTxnCtx);
                 bActiveTxn = false;
                 return isCompileOnly() ? null : jobSpec;
@@ -4298,7 +4314,7 @@
 
         // Query Rewriting (happens under the same ongoing metadata transaction)
         LangRewritingContext langRewritingContext = createLangRewritingContext(metadataProvider, declaredFunctions,
-                null, warningCollector, query.getVarCounter());
+                null, null, warningCollector, query.getVarCounter());
         Pair<IReturningStatement, Integer> rewrittenResult = apiFramework.reWriteQuery(langRewritingContext, query,
                 sessionOutput, true, true, externalVars.keySet());
 
@@ -4317,7 +4333,7 @@
 
         // Insert/upsert statement rewriting (happens under the same ongoing metadata transaction)
         LangRewritingContext langRewritingContext = createLangRewritingContext(metadataProvider, declaredFunctions,
-                null, warningCollector, insertUpsert.getVarCounter());
+                null, null, warningCollector, insertUpsert.getVarCounter());
         Pair<IReturningStatement, Integer> rewrittenResult = apiFramework.reWriteQuery(langRewritingContext,
                 insertUpsert, sessionOutput, true, true, externalVars.keySet());
 
@@ -5226,7 +5242,7 @@
     }
 
     private interface IStatementCompiler {
-        JobSpecification compile() throws AlgebricksException, RemoteException, ACIDException;
+        JobSpecification compile() throws AlgebricksException, RemoteException, ACIDException, HyracksDataException;
     }
 
     protected void handleQuery(MetadataProvider metadataProvider, Query query, IHyracksClientConnection hcc,
diff --git a/asterixdb/asterix-app/src/test/java/org/apache/asterix/test/sqlpp/ParserTestExecutor.java b/asterixdb/asterix-app/src/test/java/org/apache/asterix/test/sqlpp/ParserTestExecutor.java
index ba2381b..7effe9d 100644
--- a/asterixdb/asterix-app/src/test/java/org/apache/asterix/test/sqlpp/ParserTestExecutor.java
+++ b/asterixdb/asterix-app/src/test/java/org/apache/asterix/test/sqlpp/ParserTestExecutor.java
@@ -213,7 +213,7 @@
                     Query query = (Query) st;
                     IQueryRewriter rewriter = sqlppRewriterFactory.createQueryRewriter();
                     LangRewritingContext rwContext = new LangRewritingContext(metadataProvider, functions, null,
-                            TestUtils.NOOP_WARNING_COLLECTOR, query.getVarCounter());
+                            TestUtils.NOOP_WARNING_COLLECTOR, null, query.getVarCounter());
                     rewrite(rewriter, query, rwContext);
 
                     // Tests deep copy and deep equality.
diff --git a/asterixdb/asterix-lang-common/src/main/java/org/apache/asterix/lang/common/base/IQueryRewriter.java b/asterixdb/asterix-lang-common/src/main/java/org/apache/asterix/lang/common/base/IQueryRewriter.java
index 12c3b93..0f8e3e9 100644
--- a/asterixdb/asterix-lang-common/src/main/java/org/apache/asterix/lang/common/base/IQueryRewriter.java
+++ b/asterixdb/asterix-lang-common/src/main/java/org/apache/asterix/lang/common/base/IQueryRewriter.java
@@ -23,9 +23,11 @@
 
 import org.apache.asterix.common.api.INamespaceResolver;
 import org.apache.asterix.common.exceptions.CompilationException;
+import org.apache.asterix.common.metadata.Namespace;
 import org.apache.asterix.lang.common.expression.AbstractCallExpression;
 import org.apache.asterix.lang.common.expression.VariableExpr;
 import org.apache.asterix.lang.common.rewrites.LangRewritingContext;
+import org.apache.asterix.lang.common.statement.DatasetDecl;
 import org.apache.asterix.lang.common.statement.FunctionDecl;
 import org.apache.asterix.lang.common.statement.Query;
 import org.apache.asterix.lang.common.statement.ViewDecl;
@@ -66,4 +68,8 @@
     Query createFunctionAccessorQuery(FunctionDecl functionDecl);
 
     Query createViewAccessorQuery(ViewDecl viewDecl, INamespaceResolver namespaceResolver);
+
+    Query createDatasetAccessorQuery(DatasetDecl datasetDecl, INamespaceResolver namespaceResolver,
+            Namespace namespace);
+
 }
diff --git a/asterixdb/asterix-lang-common/src/main/java/org/apache/asterix/lang/common/rewrites/LangRewritingContext.java b/asterixdb/asterix-lang-common/src/main/java/org/apache/asterix/lang/common/rewrites/LangRewritingContext.java
index 19b3cfa..196e717 100644
--- a/asterixdb/asterix-lang-common/src/main/java/org/apache/asterix/lang/common/rewrites/LangRewritingContext.java
+++ b/asterixdb/asterix-lang-common/src/main/java/org/apache/asterix/lang/common/rewrites/LangRewritingContext.java
@@ -25,6 +25,7 @@
 
 import org.apache.asterix.common.functions.FunctionSignature;
 import org.apache.asterix.common.metadata.DatasetFullyQualifiedName;
+import org.apache.asterix.lang.common.statement.DatasetDecl;
 import org.apache.asterix.lang.common.statement.FunctionDecl;
 import org.apache.asterix.lang.common.statement.ViewDecl;
 import org.apache.asterix.lang.common.struct.VarIdentifier;
@@ -37,16 +38,19 @@
     private final IWarningCollector warningCollector;
     private final Map<FunctionSignature, FunctionDecl> declaredFunctions;
     private final Map<DatasetFullyQualifiedName, ViewDecl> declaredViews;
+    private final Map<DatasetFullyQualifiedName, DatasetDecl> declaredDatasets;
     private final Counter varCounter;
     private int systemVarCounter = 1;
     private final Map<Integer, VarIdentifier> oldVarIdToNewVarId = new HashMap<>();
 
     public LangRewritingContext(MetadataProvider metadataProvider, List<FunctionDecl> declaredFunctions,
-            List<ViewDecl> declaredViews, IWarningCollector warningCollector, int varCounter) {
+            List<ViewDecl> declaredViews, IWarningCollector warningCollector, List<DatasetDecl> declaredDatasets,
+            int varCounter) {
         this.metadataProvider = metadataProvider;
         this.warningCollector = warningCollector;
         this.declaredFunctions = createMap(declaredFunctions, FunctionDecl::getSignature);
         this.declaredViews = createMap(declaredViews, ViewDecl::getViewName);
+        this.declaredDatasets = createMap(declaredDatasets, DatasetDecl::getDatasetName);
         this.varCounter = new Counter(varCounter);
     }
 
@@ -102,6 +106,10 @@
         return declaredViews;
     }
 
+    public Map<DatasetFullyQualifiedName, DatasetDecl> getDeclaredDatasets() {
+        return declaredDatasets;
+    }
+
     private static <K, V> Map<K, V> createMap(List<V> values, java.util.function.Function<V, K> keyMapper) {
         if (values == null || values.isEmpty()) {
             return Collections.emptyMap();
diff --git a/asterixdb/asterix-lang-common/src/main/java/org/apache/asterix/lang/common/statement/DatasetDecl.java b/asterixdb/asterix-lang-common/src/main/java/org/apache/asterix/lang/common/statement/DatasetDecl.java
index ab6097b..210ffc5 100644
--- a/asterixdb/asterix-lang-common/src/main/java/org/apache/asterix/lang/common/statement/DatasetDecl.java
+++ b/asterixdb/asterix-lang-common/src/main/java/org/apache/asterix/lang/common/statement/DatasetDecl.java
@@ -23,6 +23,7 @@
 import org.apache.asterix.common.config.DatasetConfig;
 import org.apache.asterix.common.config.DatasetConfig.DatasetType;
 import org.apache.asterix.common.exceptions.CompilationException;
+import org.apache.asterix.common.metadata.DatasetFullyQualifiedName;
 import org.apache.asterix.common.metadata.DataverseName;
 import org.apache.asterix.common.metadata.Namespace;
 import org.apache.asterix.lang.common.base.AbstractStatement;
@@ -42,7 +43,7 @@
 public class DatasetDecl extends AbstractStatement {
 
     protected final Identifier name;
-    protected final Namespace namespace;
+    protected Namespace namespace;
     protected final TypeExpression itemType;
     protected final TypeExpression metaItemType;
     protected final DatasetType datasetType;
@@ -73,6 +74,11 @@
         this.query = query;
     }
 
+    public DatasetFullyQualifiedName getDatasetName() {
+        return new DatasetFullyQualifiedName(namespace.getDatabaseName(), namespace.getDataverseName(),
+                name.getValue());
+    }
+
     public boolean getIfNotExists() {
         return this.ifNotExists;
     }
@@ -105,6 +111,10 @@
         return query;
     }
 
+    public void setNamespace(Namespace namespace) {
+        this.namespace = namespace;
+    }
+
     public String getNodegroupName() {
         AdmObjectNode nodeGroupObj = (AdmObjectNode) withObjectNode.get(DatasetDeclParametersUtil.NODE_GROUP_NAME);
         if (nodeGroupObj == null) {
diff --git a/asterixdb/asterix-lang-common/src/main/java/org/apache/asterix/lang/common/util/LangDatasetUtil.java b/asterixdb/asterix-lang-common/src/main/java/org/apache/asterix/lang/common/util/LangDatasetUtil.java
new file mode 100644
index 0000000..29737f5
--- /dev/null
+++ b/asterixdb/asterix-lang-common/src/main/java/org/apache/asterix/lang/common/util/LangDatasetUtil.java
@@ -0,0 +1,57 @@
+/*
+ * 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.util;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+
+import org.apache.asterix.common.exceptions.CompilationException;
+import org.apache.asterix.common.exceptions.ErrorCode;
+import org.apache.asterix.common.metadata.DependencyFullyQualifiedName;
+import org.apache.asterix.lang.common.base.Expression;
+import org.apache.asterix.lang.common.base.IQueryRewriter;
+import org.apache.asterix.lang.common.statement.DatasetDecl;
+import org.apache.asterix.metadata.declared.MetadataProvider;
+import org.apache.asterix.metadata.entities.Dataset;
+
+public class LangDatasetUtil {
+    private LangDatasetUtil() {
+    }
+
+    public static List<List<DependencyFullyQualifiedName>> getDatasetDependencies(MetadataProvider metadataProvider,
+            DatasetDecl datasetDecl, IQueryRewriter rewriter) throws CompilationException {
+        Expression normBody = datasetDecl.getQuery().getBody();
+        if (normBody == null) {
+            throw new CompilationException(ErrorCode.COMPILATION_ILLEGAL_STATE, datasetDecl.getSourceLocation(),
+                    datasetDecl.getName().toString());
+        }
+
+        List<DependencyFullyQualifiedName> datasetDependencies = new ArrayList<>();
+        List<DependencyFullyQualifiedName> synonymDependencies = new ArrayList<>();
+        List<DependencyFullyQualifiedName> functionDependencies = new ArrayList<>();
+        ExpressionUtils.collectDependencies(metadataProvider, normBody, rewriter, datasetDependencies,
+                synonymDependencies, functionDependencies);
+
+        List<DependencyFullyQualifiedName> typeDependencies = Collections.emptyList();
+        return Dataset.createDependencies(datasetDependencies, functionDependencies, typeDependencies,
+                synonymDependencies);
+    }
+}
diff --git a/asterixdb/asterix-lang-sqlpp/src/main/java/org/apache/asterix/lang/sqlpp/rewrites/SqlppQueryRewriter.java b/asterixdb/asterix-lang-sqlpp/src/main/java/org/apache/asterix/lang/sqlpp/rewrites/SqlppQueryRewriter.java
index 183b5e0..15865a2 100644
--- a/asterixdb/asterix-lang-sqlpp/src/main/java/org/apache/asterix/lang/sqlpp/rewrites/SqlppQueryRewriter.java
+++ b/asterixdb/asterix-lang-sqlpp/src/main/java/org/apache/asterix/lang/sqlpp/rewrites/SqlppQueryRewriter.java
@@ -48,6 +48,7 @@
 import org.apache.asterix.lang.common.expression.VariableExpr;
 import org.apache.asterix.lang.common.literal.MissingLiteral;
 import org.apache.asterix.lang.common.rewrites.LangRewritingContext;
+import org.apache.asterix.lang.common.statement.DatasetDecl;
 import org.apache.asterix.lang.common.statement.FunctionDecl;
 import org.apache.asterix.lang.common.statement.Query;
 import org.apache.asterix.lang.common.statement.ViewDecl;
@@ -204,6 +205,8 @@
         // Load all the accessed datasets
         loadAccessedDatasets();
 
+        rewriteDatasetQueryExpression();
+
         // Inlines functions and views
         loadAndInlineUdfsAndViews();
 
@@ -345,6 +348,17 @@
         rewriteTopExpr(visitor, null);
     }
 
+    protected void rewriteDatasetQueryExpression() throws CompilationException {
+        Map<DatasetFullyQualifiedName, DatasetDecl> ds = context.getDeclaredDatasets();
+        if (ds != null && ds.size() > 0) {
+            DatasetFullyQualifiedName datasetName = ds.keySet().iterator().next();
+            if (ds.get(datasetName) != null) {
+                Expression normBody = fetchDatasetDecl(ds.get(datasetName));
+                ds.get(datasetName).getQuery().setBody(normBody);
+            }
+        }
+    }
+
     protected void loadAndInlineUdfsAndViews() throws CompilationException {
         Pair<Map<FunctionSignature, FunctionDecl>, Map<DatasetFullyQualifiedName, ViewDecl>> udfAndViewDecls =
                 loadUdfsAndViews(topStatement);
@@ -453,6 +467,7 @@
                                 fd.getNormalizedFuncBody().accept(callVisitor, null);
                             }
                         }
+
                     }
                     break;
                 case WINDOW_EXPRESSION:
@@ -491,6 +506,16 @@
         return fd;
     }
 
+    private Expression fetchDatasetDecl(DatasetDecl ds) throws CompilationException {
+        String databaseName = ds.getNamespace().getDatabaseName();
+        DataverseName dataverseName = ds.getNamespace().getDataverseName();
+        String datasetName = ds.getName().toString();
+        Expression expression = rewriteFunctionOrViewBody(databaseName, dataverseName,
+                new DatasetFullyQualifiedName(databaseName, dataverseName, datasetName), ds.getQuery().getBody(),
+                Collections.emptyList(), false, ds.getSourceLocation());
+        return expression;
+    }
+
     private ViewDecl fetchViewDecl(DatasetFullyQualifiedName viewName, SourceLocation sourceLoc)
             throws CompilationException {
         IAType viewItemType = null;
@@ -617,7 +642,6 @@
     @Override
     public Query createViewAccessorQuery(ViewDecl viewDecl, INamespaceResolver namespaceResolver) {
         boolean usingDatabase = namespaceResolver.isUsingDatabase();
-        // dataverse_name.view_name
         String databaseName = viewDecl.getViewName().getDatabaseName();
         DataverseName dataverseName = viewDecl.getViewName().getDataverseName();
         String viewName = viewDecl.getViewName().getDatasetName();
@@ -626,6 +650,18 @@
         return ExpressionUtils.createWrappedQuery(vAccessExpr, viewDecl.getSourceLocation());
     }
 
+    @Override
+    public Query createDatasetAccessorQuery(DatasetDecl datasetDecl, INamespaceResolver namespaceResolver,
+            Namespace namespace) {
+        boolean usingDatabase = namespaceResolver.isUsingDatabase();
+        String databaseName = namespace.getDatabaseName();
+        DataverseName dataverseName = namespace.getDataverseName();
+        String datasetName = datasetDecl.getName().toString();
+        Expression datasetAccessExpression = createDatasetAccessExpression(databaseName, dataverseName, datasetName,
+                datasetDecl.getSourceLocation(), usingDatabase);
+        return ExpressionUtils.createWrappedQuery(datasetAccessExpression, datasetDecl.getSourceLocation());
+    }
+
     private static Expression createDatasetAccessExpression(String databaseName, DataverseName dataverseName,
             String datasetName, SourceLocation sourceLoc, boolean usingDatabase) {
         AbstractExpression resultExpr;
diff --git a/asterixdb/asterix-lang-sqlpp/src/main/java/org/apache/asterix/lang/sqlpp/rewrites/visitor/SqlppLoadAccessedDataset.java b/asterixdb/asterix-lang-sqlpp/src/main/java/org/apache/asterix/lang/sqlpp/rewrites/visitor/SqlppLoadAccessedDataset.java
index 8b44df3..2f3323f 100644
--- a/asterixdb/asterix-lang-sqlpp/src/main/java/org/apache/asterix/lang/sqlpp/rewrites/visitor/SqlppLoadAccessedDataset.java
+++ b/asterixdb/asterix-lang-sqlpp/src/main/java/org/apache/asterix/lang/sqlpp/rewrites/visitor/SqlppLoadAccessedDataset.java
@@ -30,6 +30,7 @@
 import org.apache.asterix.lang.common.base.ILangExpression;
 import org.apache.asterix.lang.common.expression.CallExpr;
 import org.apache.asterix.lang.common.rewrites.LangRewritingContext;
+import org.apache.asterix.lang.common.statement.DatasetDecl;
 import org.apache.asterix.lang.common.statement.FunctionDecl;
 import org.apache.asterix.lang.common.statement.ViewDecl;
 import org.apache.asterix.lang.common.util.ExpressionUtils;
@@ -66,18 +67,26 @@
             datasetName = ExpressionUtils.getStringLiteral(exprs.get(2));
 
             EntityDetails.EntityType entityType = EntityDetails.EntityType.DATASET;
-            if (exprs.size() > 3 && Boolean.TRUE.equals(ExpressionUtils.getBooleanLiteral(exprs.get(3)))) {
-                DatasetFullyQualifiedName viewDatasetName =
+            if (exprs.size() > 3) {
+                DatasetFullyQualifiedName viewOrDatasetName =
                         new DatasetFullyQualifiedName(databaseName, dataverseName, datasetName);
-                Map<DatasetFullyQualifiedName, ViewDecl> declaredViews = context.getDeclaredViews();
-                if (declaredViews.containsKey(viewDatasetName)) {
-                    return;
+                if (Boolean.TRUE.equals(ExpressionUtils.getBooleanLiteral(exprs.get(3)))) {
+                    Map<DatasetFullyQualifiedName, ViewDecl> declaredViews = context.getDeclaredViews();
+                    if (declaredViews.containsKey(viewOrDatasetName)) {
+                        return;
+                    }
+                    entityType = EntityDetails.EntityType.VIEW;
+                } else if (Boolean.FALSE.equals(ExpressionUtils.getBooleanLiteral(exprs.get(3)))) {
+                    Map<DatasetFullyQualifiedName, DatasetDecl> declaredVDatasets = context.getDeclaredDatasets();
+                    if (declaredVDatasets.containsKey(viewOrDatasetName)) {
+                        return;
+                    }
                 }
-                entityType = EntityDetails.EntityType.VIEW;
             }
 
             context.getMetadataProvider()
                     .addAccessedEntity(new EntityDetails(databaseName, dataverseName, datasetName, entityType));
+
         } else {
             FunctionSignature signature = expression.getFunctionSignature();
             Map<FunctionSignature, FunctionDecl> declaredFunctions = context.getDeclaredFunctions();
diff --git a/asterixdb/asterix-lang-sqlpp/src/main/java/org/apache/asterix/lang/sqlpp/rewrites/visitor/VariableCheckAndRewriteVisitor.java b/asterixdb/asterix-lang-sqlpp/src/main/java/org/apache/asterix/lang/sqlpp/rewrites/visitor/VariableCheckAndRewriteVisitor.java
index 346ad4f..d5c43bb 100644
--- a/asterixdb/asterix-lang-sqlpp/src/main/java/org/apache/asterix/lang/sqlpp/rewrites/visitor/VariableCheckAndRewriteVisitor.java
+++ b/asterixdb/asterix-lang-sqlpp/src/main/java/org/apache/asterix/lang/sqlpp/rewrites/visitor/VariableCheckAndRewriteVisitor.java
@@ -42,6 +42,7 @@
 import org.apache.asterix.lang.common.expression.FieldAccessor;
 import org.apache.asterix.lang.common.expression.VariableExpr;
 import org.apache.asterix.lang.common.rewrites.LangRewritingContext;
+import org.apache.asterix.lang.common.statement.DatasetDecl;
 import org.apache.asterix.lang.common.statement.ViewDecl;
 import org.apache.asterix.lang.common.struct.Identifier;
 import org.apache.asterix.lang.common.struct.VarIdentifier;
@@ -187,12 +188,19 @@
         String resolvedDatasetName;
         boolean viaSynonym, isView;
         ViewDecl viewDecl = findDeclaredView(databaseName, dataverseName, datasetName);
+        DatasetDecl datasetDecl = findDeclaredDataset(databaseName, dataverseName, datasetName);
         if (viewDecl != null) {
             resolvedDatabaseName = viewDecl.getViewName().getDatabaseName();
             resolvedDataverseName = viewDecl.getViewName().getDataverseName();
             resolvedDatasetName = viewDecl.getViewName().getDatasetName();
             viaSynonym = false;
             isView = true;
+        } else if (datasetDecl != null) {
+            resolvedDatabaseName = databaseName;
+            resolvedDataverseName = dataverseName;
+            resolvedDatasetName = datasetName;
+            viaSynonym = false;
+            isView = false;
         } else {
             Pair<Dataset, Boolean> p = findDataset(databaseName, dataverseName, datasetName, true, sourceLoc);
             if (p == null) {
@@ -305,6 +313,12 @@
                 : declaredViews.get(new DatasetFullyQualifiedName(databaseName, dataverseName, viewName));
     }
 
+    private DatasetDecl findDeclaredDataset(String databaseName, DataverseName dataverseName, String datasetName) {
+        Map<DatasetFullyQualifiedName, DatasetDecl> declaredDatasets = context.getDeclaredDatasets();
+        return declaredDatasets.isEmpty() ? null
+                : declaredDatasets.get(new DatasetFullyQualifiedName(databaseName, dataverseName, datasetName));
+    }
+
     @Override
     public Expression visit(CallExpr callExpr, ILangExpression arg) throws CompilationException {
         // skip variables inside SQL-92 aggregates (they will be resolved by SqlppGroupByAggregationSugarVisitor)
diff --git a/asterixdb/asterix-metadata/src/main/java/org/apache/asterix/metadata/entities/Dataset.java b/asterixdb/asterix-metadata/src/main/java/org/apache/asterix/metadata/entities/Dataset.java
index 9d41097..9aa5d84 100644
--- a/asterixdb/asterix-metadata/src/main/java/org/apache/asterix/metadata/entities/Dataset.java
+++ b/asterixdb/asterix-metadata/src/main/java/org/apache/asterix/metadata/entities/Dataset.java
@@ -19,6 +19,8 @@
 
 package org.apache.asterix.metadata.entities;
 
+import java.util.ArrayList;
+import java.util.Arrays;
 import java.util.Collections;
 import java.util.HashMap;
 import java.util.List;
@@ -42,6 +44,7 @@
 import org.apache.asterix.common.ioopcallbacks.LSMIndexPageWriteCallbackFactory;
 import org.apache.asterix.common.metadata.DatasetFullyQualifiedName;
 import org.apache.asterix.common.metadata.DataverseName;
+import org.apache.asterix.common.metadata.DependencyFullyQualifiedName;
 import org.apache.asterix.common.metadata.IDataset;
 import org.apache.asterix.common.metadata.MetadataUtil;
 import org.apache.asterix.common.transactions.IRecoveryManager.ResourceType;
@@ -882,4 +885,23 @@
     public ILSMTupleFilterCallbackFactory getTupleFilterCallbackFactory() {
         return NoOpLSMTupleFilterCallbackFactory.INSTANCE;
     }
+
+    public static List<DependencyKind> DEPENDENCIES_SCHEMA =
+            Arrays.asList(DependencyKind.DATASET, DependencyKind.FUNCTION, DependencyKind.TYPE, DependencyKind.SYNONYM);
+
+    public static List<List<DependencyFullyQualifiedName>> createDependencies(
+            List<DependencyFullyQualifiedName> datasetDependencies,
+            List<DependencyFullyQualifiedName> functionDependencies,
+            List<DependencyFullyQualifiedName> typeDependencies,
+            List<DependencyFullyQualifiedName> synonymDependencies) {
+        List<List<DependencyFullyQualifiedName>> depList = new ArrayList<>(DEPENDENCIES_SCHEMA.size());
+        depList.add(datasetDependencies);
+        depList.add(functionDependencies);
+        depList.add(typeDependencies);
+        if (!synonymDependencies.isEmpty()) {
+            depList.add(synonymDependencies);
+        }
+        return depList;
+    }
+
 }