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 2021/09/27 21:09:14 UTC

[asterixdb] branch master updated: [NO ISSUE][API] Add dataverse parameter to Query Service API

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


The following commit(s) were added to refs/heads/master by this push:
     new 801f208  [NO ISSUE][API] Add dataverse parameter to Query Service API
801f208 is described below

commit 801f20866db6c8bcbd91607dff439f8e03c5e052
Author: Dmitry Lychagin <dm...@couchbase.com>
AuthorDate: Fri Sep 24 13:07:57 2021 -0700

    [NO ISSUE][API] Add dataverse parameter to Query Service API
    
    - user model changes: no
    - storage format changes: no
    - interface changes: yes
    
    Details:
    - Add 'dataverse' parameter to /query/service API
    - It specifies default dataverse name for the statement
    - If dataverse does not exist then it is ignored (with a warning)
    - Add testcases and update documentation
    
    Change-Id: I67af8c7652f775cef8ea5273ddd91ff78aac233b
    Reviewed-on: https://asterix-gerrit.ics.uci.edu/c/asterixdb/+/13383
    Tested-by: Jenkins <je...@fulliautomatix.ics.uci.edu>
    Integration-Tests: Jenkins <je...@fulliautomatix.ics.uci.edu>
    Reviewed-by: Dmitry Lychagin <dm...@couchbase.com>
---
 .../asterix/translator/IRequestParameters.java     |  5 +++
 .../apache/asterix/api/http/server/ApiServlet.java |  2 +-
 .../api/http/server/NCQueryServiceServlet.java     |  2 +-
 .../http/server/QueryServiceRequestParameters.java | 12 +++++++
 .../api/http/server/QueryServiceServlet.java       |  4 +--
 .../apache/asterix/api/java/AsterixJavaClient.java |  2 +-
 .../message/AbstractInternalRequestMessage.java    |  2 +-
 .../message/ExecuteStatementRequestMessage.java    | 29 ++++++++-------
 .../asterix/app/translator/QueryTranslator.java    | 42 ++++++++++++++++++----
 .../asterix/app/translator/RequestParameters.java  | 22 ++++++++----
 .../http/servlet/QueryCancellationServletTest.java |  4 +--
 .../request-dataverse.1.ddl.sqlpp                  | 38 ++++++++++++++++++++
 .../request-dataverse.2.query.sqlpp                | 23 ++++++++++++
 .../request-dataverse.3.query.sqlpp                | 23 ++++++++++++
 .../request-dataverse.4.query.sqlpp                | 28 +++++++++++++++
 .../api/request-dataverse/request-dataverse.2.adm  |  1 +
 .../api/request-dataverse/request-dataverse.3.adm  |  1 +
 .../api/request-dataverse/request-dataverse.4.adm  |  1 +
 .../test/resources/runtimets/testsuite_sqlpp.xml   |  7 ++++
 asterixdb/asterix-doc/src/site/markdown/api.md     |  1 +
 .../lang/common/statement/DataverseDecl.java       | 11 ++++++
 21 files changed, 226 insertions(+), 34 deletions(-)

diff --git a/asterixdb/asterix-algebra/src/main/java/org/apache/asterix/translator/IRequestParameters.java b/asterixdb/asterix-algebra/src/main/java/org/apache/asterix/translator/IRequestParameters.java
index 5c743ee..00342b6 100644
--- a/asterixdb/asterix-algebra/src/main/java/org/apache/asterix/translator/IRequestParameters.java
+++ b/asterixdb/asterix-algebra/src/main/java/org/apache/asterix/translator/IRequestParameters.java
@@ -75,4 +75,9 @@ public interface IRequestParameters extends ICommonRequestParameters {
     boolean isForceDropDataset();
 
     boolean isSkipAdmissionPolicy();
+
+    /**
+     * @return canonical name of the default dataverse for this statement
+     */
+    String getDefaultDataverseName();
 }
diff --git a/asterixdb/asterix-app/src/main/java/org/apache/asterix/api/http/server/ApiServlet.java b/asterixdb/asterix-app/src/main/java/org/apache/asterix/api/http/server/ApiServlet.java
index c5eb69d..081c69a 100644
--- a/asterixdb/asterix-app/src/main/java/org/apache/asterix/api/http/server/ApiServlet.java
+++ b/asterixdb/asterix-app/src/main/java/org/apache/asterix/api/http/server/ApiServlet.java
@@ -151,7 +151,7 @@ public class ApiServlet extends AbstractServlet {
             long startTime = System.currentTimeMillis();
             final IRequestParameters requestParameters = new RequestParameters(requestReference, query, resultSet,
                     new ResultProperties(IStatementExecutor.ResultDelivery.IMMEDIATE), new IStatementExecutor.Stats(),
-                    new IStatementExecutor.StatementProperties(), null, null, null, null, true);
+                    new IStatementExecutor.StatementProperties(), null, null, null, null, null, true);
             translator.compileAndExecute(hcc, requestParameters);
             long endTime = System.currentTimeMillis();
             duration = (endTime - startTime) / 1000.00;
diff --git a/asterixdb/asterix-app/src/main/java/org/apache/asterix/api/http/server/NCQueryServiceServlet.java b/asterixdb/asterix-app/src/main/java/org/apache/asterix/api/http/server/NCQueryServiceServlet.java
index 2189c17..68d7b08 100644
--- a/asterixdb/asterix-app/src/main/java/org/apache/asterix/api/http/server/NCQueryServiceServlet.java
+++ b/asterixdb/asterix-app/src/main/java/org/apache/asterix/api/http/server/NCQueryServiceServlet.java
@@ -138,7 +138,7 @@ public class NCQueryServiceServlet extends QueryServiceServlet {
             int stmtCategoryRestrictionMask, boolean forceDropDataset) {
         return new ExecuteStatementRequestMessage(ncCtx.getNodeId(), responseFuture.getFutureId(), queryLanguage,
                 statementsText, sessionOutput.config(), resultProperties.getNcToCcResultProperties(),
-                param.getClientContextID(), handleUrl, optionalParameters, statementParameters,
+                param.getClientContextID(), param.getDataverse(), handleUrl, optionalParameters, statementParameters,
                 param.isMultiStatement(), param.getProfileType(), stmtCategoryRestrictionMask, requestReference,
                 forceDropDataset);
     }
diff --git a/asterixdb/asterix-app/src/main/java/org/apache/asterix/api/http/server/QueryServiceRequestParameters.java b/asterixdb/asterix-app/src/main/java/org/apache/asterix/api/http/server/QueryServiceRequestParameters.java
index 2b0b314..feb48df 100644
--- a/asterixdb/asterix-app/src/main/java/org/apache/asterix/api/http/server/QueryServiceRequestParameters.java
+++ b/asterixdb/asterix-app/src/main/java/org/apache/asterix/api/http/server/QueryServiceRequestParameters.java
@@ -60,6 +60,7 @@ public class QueryServiceRequestParameters {
         STATEMENT("statement"),
         FORMAT("format"),
         CLIENT_ID("client_context_id"),
+        DATAVERSE("dataverse"),
         PRETTY("pretty"),
         MODE("mode"),
         TIMEOUT("timeout"),
@@ -116,6 +117,7 @@ public class QueryServiceRequestParameters {
     private String path;
     private String statement;
     private String clientContextID;
+    private String dataverse;
     private OutputFormat format = OutputFormat.CLEAN_JSON;
     private ResultDelivery mode = ResultDelivery.IMMEDIATE;
     private PlanFormat planFormat = PlanFormat.JSON;
@@ -198,6 +200,14 @@ public class QueryServiceRequestParameters {
         this.clientContextID = clientContextID;
     }
 
+    public String getDataverse() {
+        return dataverse;
+    }
+
+    public void setDataverse(String dataverse) {
+        this.dataverse = dataverse;
+    }
+
     public ResultDelivery getMode() {
         return mode;
     }
@@ -341,6 +351,7 @@ public class QueryServiceRequestParameters {
         object.put("pretty", pretty);
         object.put("mode", mode.getName());
         object.put("clientContextID", clientContextID);
+        object.put("dataverse", dataverse);
         object.put("format", format.toString());
         object.put("timeout", timeout);
         object.put("maxResultReads", maxResultReads);
@@ -414,6 +425,7 @@ public class QueryServiceRequestParameters {
             throws HyracksDataException {
         setStatement(valGetter.apply(req, Parameter.STATEMENT.str()));
         setClientContextID(valGetter.apply(req, Parameter.CLIENT_ID.str()));
+        setDataverse(valGetter.apply(req, Parameter.DATAVERSE.str()));
 
         setFormatIfExists(req, acceptHeader, Parameter.FORMAT.str(), valGetter);
         setMode(parseIfExists(req, Parameter.MODE.str(), valGetter, getMode(), ResultDelivery::fromName));
diff --git a/asterixdb/asterix-app/src/main/java/org/apache/asterix/api/http/server/QueryServiceServlet.java b/asterixdb/asterix-app/src/main/java/org/apache/asterix/api/http/server/QueryServiceServlet.java
index cb26574..f66403d 100644
--- a/asterixdb/asterix-app/src/main/java/org/apache/asterix/api/http/server/QueryServiceServlet.java
+++ b/asterixdb/asterix-app/src/main/java/org/apache/asterix/api/http/server/QueryServiceServlet.java
@@ -512,8 +512,8 @@ public class QueryServiceServlet extends AbstractQueryApiServlet {
             ResultProperties resultProperties, Stats stats, IStatementExecutor.StatementProperties statementProperties,
             Map<String, String> optionalParameters, Map<String, IAObject> stmtParams, int stmtCategoryRestriction) {
         return new RequestParameters(requestReference, statementsText, resultSet, resultProperties, stats,
-                statementProperties, null, param.getClientContextID(), optionalParameters, stmtParams,
-                param.isMultiStatement(), stmtCategoryRestriction);
+                statementProperties, null, param.getClientContextID(), param.getDataverse(), optionalParameters,
+                stmtParams, param.isMultiStatement(), stmtCategoryRestriction);
     }
 
     protected static boolean isPrintingProfile(IStatementExecutor.Stats stats) {
diff --git a/asterixdb/asterix-app/src/main/java/org/apache/asterix/api/java/AsterixJavaClient.java b/asterixdb/asterix-app/src/main/java/org/apache/asterix/api/java/AsterixJavaClient.java
index 4fe6582..4b70f95 100644
--- a/asterixdb/asterix-app/src/main/java/org/apache/asterix/api/java/AsterixJavaClient.java
+++ b/asterixdb/asterix-app/src/main/java/org/apache/asterix/api/java/AsterixJavaClient.java
@@ -137,7 +137,7 @@ public class AsterixJavaClient {
                 RequestReference.of(UUID.randomUUID().toString(), "CC", System.currentTimeMillis());
         final IRequestParameters requestParameters = new RequestParameters(requestReference, statement, null,
                 new ResultProperties(IStatementExecutor.ResultDelivery.IMMEDIATE), new IStatementExecutor.Stats(),
-                new IStatementExecutor.StatementProperties(), null, null, null, statementParams, true);
+                new IStatementExecutor.StatementProperties(), null, null, null, null, statementParams, true);
         translator.compileAndExecute(hcc, requestParameters);
         executionPlans = translator.getExecutionPlans();
         writer.flush();
diff --git a/asterixdb/asterix-app/src/main/java/org/apache/asterix/app/message/AbstractInternalRequestMessage.java b/asterixdb/asterix-app/src/main/java/org/apache/asterix/app/message/AbstractInternalRequestMessage.java
index 26aac63..ce95f5b 100644
--- a/asterixdb/asterix-app/src/main/java/org/apache/asterix/app/message/AbstractInternalRequestMessage.java
+++ b/asterixdb/asterix-app/src/main/java/org/apache/asterix/app/message/AbstractInternalRequestMessage.java
@@ -94,7 +94,7 @@ public abstract class AbstractInternalRequestMessage implements ICcAddressedMess
         ResponsePrinter printer = new ResponsePrinter(sessionOutput);
         ResultProperties resultProperties = new ResultProperties(IStatementExecutor.ResultDelivery.IMMEDIATE, 1);
         IRequestParameters requestParams = new RequestParameters(requestReference, "", null, resultProperties,
-                new IStatementExecutor.Stats(), new IStatementExecutor.StatementProperties(), null, null,
+                new IStatementExecutor.Stats(), new IStatementExecutor.StatementProperties(), null, null, null,
                 additionalParams, Collections.emptyMap(), false);
         MetadataManager.INSTANCE.init();
         IStatementExecutor translator =
diff --git a/asterixdb/asterix-app/src/main/java/org/apache/asterix/app/message/ExecuteStatementRequestMessage.java b/asterixdb/asterix-app/src/main/java/org/apache/asterix/app/message/ExecuteStatementRequestMessage.java
index 30b98ec..fa05870 100644
--- a/asterixdb/asterix-app/src/main/java/org/apache/asterix/app/message/ExecuteStatementRequestMessage.java
+++ b/asterixdb/asterix-app/src/main/java/org/apache/asterix/app/message/ExecuteStatementRequestMessage.java
@@ -66,7 +66,7 @@ import org.apache.logging.log4j.LogManager;
 import org.apache.logging.log4j.Logger;
 
 public class ExecuteStatementRequestMessage implements ICcAddressedMessage {
-    private static final long serialVersionUID = 2L;
+    private static final long serialVersionUID = 3L;
     private static final Logger LOGGER = LogManager.getLogger();
     //TODO: Make configurable: https://issues.apache.org/jira/browse/ASTERIXDB-2062
     public static final long DEFAULT_NC_TIMEOUT_MILLIS = TimeUnit.MILLISECONDS.toMillis(Long.MAX_VALUE);
@@ -79,6 +79,7 @@ public class ExecuteStatementRequestMessage implements ICcAddressedMessage {
     private final SessionConfig sessionConfig;
     private final ResultProperties resultProperties;
     private final String clientContextID;
+    private final String defaultDataverseName;
     private final String handleUrl;
     private final Map<String, String> optionalParameters;
     private final Map<String, byte[]> statementParameters;
@@ -91,20 +92,21 @@ public class ExecuteStatementRequestMessage implements ICcAddressedMessage {
 
     public ExecuteStatementRequestMessage(String requestNodeId, long requestMessageId, ILangExtension.Language lang,
             String statementsText, SessionConfig sessionConfig, ResultProperties resultProperties,
-            String clientContextID, String handleUrl, Map<String, String> optionalParameters,
-            Map<String, byte[]> statementParameters, boolean multiStatement, ProfileType profileType,
-            int statementCategoryRestrictionMask, IRequestReference requestReference, boolean forceDropDataset) {
+            String clientContextID, String defaultDataverseName, String handleUrl,
+            Map<String, String> optionalParameters, Map<String, byte[]> statementParameters, boolean multiStatement,
+            ProfileType profileType, int statementCategoryRestrictionMask, IRequestReference requestReference,
+            boolean forceDropDataset) {
         this(requestNodeId, requestMessageId, lang, statementsText, sessionConfig, resultProperties, clientContextID,
-                handleUrl, optionalParameters, statementParameters, multiStatement, profileType,
+                defaultDataverseName, handleUrl, optionalParameters, statementParameters, multiStatement, profileType,
                 statementCategoryRestrictionMask, requestReference, forceDropDataset, false);
     }
 
     protected ExecuteStatementRequestMessage(String requestNodeId, long requestMessageId, ILangExtension.Language lang,
             String statementsText, SessionConfig sessionConfig, ResultProperties resultProperties,
-            String clientContextID, String handleUrl, Map<String, String> optionalParameters,
-            Map<String, byte[]> statementParameters, boolean multiStatement, ProfileType profileType,
-            int statementCategoryRestrictionMask, IRequestReference requestReference, boolean forceDropDataset,
-            boolean skipAdmissionPolicy) {
+            String clientContextID, String defaultDataverseName, String handleUrl,
+            Map<String, String> optionalParameters, Map<String, byte[]> statementParameters, boolean multiStatement,
+            ProfileType profileType, int statementCategoryRestrictionMask, IRequestReference requestReference,
+            boolean forceDropDataset, boolean skipAdmissionPolicy) {
         this.requestNodeId = requestNodeId;
         this.requestMessageId = requestMessageId;
         this.lang = lang;
@@ -121,6 +123,7 @@ public class ExecuteStatementRequestMessage implements ICcAddressedMessage {
         this.requestReference = requestReference;
         this.forceDropDataset = forceDropDataset;
         this.skipAdmissionPolicy = skipAdmissionPolicy;
+        this.defaultDataverseName = defaultDataverseName;
     }
 
     @Override
@@ -163,10 +166,10 @@ public class ExecuteStatementRequestMessage implements ICcAddressedMessage {
             final IStatementExecutor.Stats stats = new IStatementExecutor.Stats();
             stats.setProfileType(profileType);
             Map<String, IAObject> stmtParams = RequestParameters.deserializeParameterValues(statementParameters);
-            final IRequestParameters requestParameters =
-                    new RequestParameters(requestReference, statementsText, null, resultProperties, stats,
-                            statementProperties, outMetadata, clientContextID, optionalParameters, stmtParams,
-                            multiStatement, statementCategoryRestrictionMask, forceDropDataset, skipAdmissionPolicy);
+            final IRequestParameters requestParameters = new RequestParameters(requestReference, statementsText, null,
+                    resultProperties, stats, statementProperties, outMetadata, clientContextID, defaultDataverseName,
+                    optionalParameters, stmtParams, multiStatement, statementCategoryRestrictionMask, forceDropDataset,
+                    skipAdmissionPolicy);
             translator.compileAndExecute(ccApp.getHcc(), requestParameters);
             translator.getWarnings(warnings, maxWarnings - warnings.size());
             stats.updateTotalWarningsCount(parserTotalWarningsCount);
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 740454b..2fa4c7b 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
@@ -346,10 +346,8 @@ public class QueryTranslator extends AbstractLangTranslator implements IStatemen
                 }
                 validateOperation(appCtx, activeDataverse, stmt);
                 MetadataProvider metadataProvider = MetadataProvider.create(appCtx, activeDataverse);
-                metadataProvider.getConfig().putAll(config);
-                metadataProvider.setWriterFactory(writerFactory);
-                metadataProvider.setResultSerializerFactoryProvider(resultSerializerFactoryProvider);
-                metadataProvider.setOutputFile(outputFile);
+                configureMetadataProvider(metadataProvider, config, resultSerializerFactoryProvider, writerFactory,
+                        outputFile);
                 IStatementRewriter stmtRewriter = rewriterFactory.createStatementRewriter();
                 rewriteStatement(stmt, stmtRewriter, metadataProvider); // Rewrite the statement's AST.
                 Statement.Kind kind = stmt.getKind();
@@ -516,6 +514,24 @@ public class QueryTranslator extends AbstractLangTranslator implements IStatemen
         }
     }
 
+    protected void configureMetadataProvider(MetadataProvider metadataProvider, Map<String, String> config,
+            IResultSerializerFactoryProvider resultSerializerFactoryProvider, IAWriterFactory writerFactory,
+            FileSplit outputFile) {
+        metadataProvider.getConfig().putAll(config);
+        metadataProvider.setWriterFactory(writerFactory);
+        metadataProvider.setResultSerializerFactoryProvider(resultSerializerFactoryProvider);
+        metadataProvider.setOutputFile(outputFile);
+    }
+
+    protected DataverseDecl getRequestDataverseDecl(IRequestParameters requestParameters) throws AlgebricksException {
+        String requestDataverseName = requestParameters.getDefaultDataverseName();
+        if (requestDataverseName == null) {
+            return null;
+        }
+        DataverseName dvName = DataverseName.createFromCanonicalForm(requestDataverseName);
+        return new DataverseDecl(dvName, true);
+    }
+
     protected void handleSetStatement(Statement stmt, Map<String, String> config) throws CompilationException {
         SetStatement ss = (SetStatement) stmt;
         String pname = ss.getPropName();
@@ -559,7 +575,17 @@ public class QueryTranslator extends AbstractLangTranslator implements IStatemen
             DataverseName dvName = stmtUseDataverse.getDataverseName();
             Dataverse dv = MetadataManager.INSTANCE.getDataverse(metadataProvider.getMetadataTxnContext(), dvName);
             if (dv == null) {
-                throw new MetadataException(ErrorCode.UNKNOWN_DATAVERSE, stmtUseDataverse.getSourceLocation(), dvName);
+                if (stmtUseDataverse.getIfExists()) {
+                    if (warningCollector.shouldWarn()) {
+                        warningCollector.warn(
+                                Warning.of(stmtUseDataverse.getSourceLocation(), ErrorCode.UNKNOWN_DATAVERSE, dvName));
+                    }
+                    MetadataManager.INSTANCE.commitTransaction(mdTxnCtx);
+                    return activeDataverse;
+                } else {
+                    throw new MetadataException(ErrorCode.UNKNOWN_DATAVERSE, stmtUseDataverse.getSourceLocation(),
+                            dvName);
+                }
             }
             MetadataManager.INSTANCE.commitTransaction(mdTxnCtx);
             return dv;
@@ -4539,9 +4565,13 @@ public class QueryTranslator extends AbstractLangTranslator implements IStatemen
     }
 
     protected void validateStatements(IRequestParameters requestParameters)
-            throws CompilationException, HyracksDataException {
+            throws AlgebricksException, HyracksDataException {
         validateStatements(statements, requestParameters.isMultiStatement(),
                 requestParameters.getStatementCategoryRestrictionMask());
+        DataverseDecl requestDataverseDecl = getRequestDataverseDecl(requestParameters);
+        if (requestDataverseDecl != null) {
+            statements.add(0, requestDataverseDecl);
+        }
     }
 
     public static void validateStatements(List<Statement> statements, boolean allowMultiStatement,
diff --git a/asterixdb/asterix-app/src/main/java/org/apache/asterix/app/translator/RequestParameters.java b/asterixdb/asterix-app/src/main/java/org/apache/asterix/app/translator/RequestParameters.java
index 6c8f21c..e7af36b 100644
--- a/asterixdb/asterix-app/src/main/java/org/apache/asterix/app/translator/RequestParameters.java
+++ b/asterixdb/asterix-app/src/main/java/org/apache/asterix/app/translator/RequestParameters.java
@@ -58,40 +58,42 @@ public class RequestParameters implements IRequestParameters {
     private final boolean multiStatement;
     private final int statementCategoryRestrictionMask;
     private final String statement;
+    private final String defaultDataverseName;
     private final boolean forceDropDataset;
     private final boolean skipAdmissionPolicy;
 
     public RequestParameters(IRequestReference requestReference, String statement, IResultSet resultSet,
             ResultProperties resultProperties, Stats stats, StatementProperties statementProperties,
-            IStatementExecutor.ResultMetadata outMetadata, String clientContextId,
+            IStatementExecutor.ResultMetadata outMetadata, String clientContextId, String defaultDataverseName,
             Map<String, String> optionalParameters, Map<String, IAObject> statementParameters, boolean multiStatement) {
         this(requestReference, statement, resultSet, resultProperties, stats, statementProperties, outMetadata,
-                clientContextId, optionalParameters, statementParameters, multiStatement, NO_CATEGORY_RESTRICTION_MASK);
+                clientContextId, defaultDataverseName, optionalParameters, statementParameters, multiStatement,
+                NO_CATEGORY_RESTRICTION_MASK);
     }
 
     public RequestParameters(IRequestReference requestReference, String statement, IResultSet resultSet,
             ResultProperties resultProperties, Stats stats, StatementProperties statementProperties,
-            IStatementExecutor.ResultMetadata outMetadata, String clientContextId,
+            IStatementExecutor.ResultMetadata outMetadata, String clientContextId, String defaultDataverseName,
             Map<String, String> optionalParameters, Map<String, IAObject> statementParameters, boolean multiStatement,
             int statementCategoryRestrictionMask) {
         this(requestReference, statement, resultSet, resultProperties, stats, statementProperties, outMetadata,
-                clientContextId, optionalParameters, statementParameters, multiStatement,
+                clientContextId, defaultDataverseName, optionalParameters, statementParameters, multiStatement,
                 statementCategoryRestrictionMask, false);
     }
 
     public RequestParameters(IRequestReference requestReference, String statement, IResultSet resultSet,
             ResultProperties resultProperties, Stats stats, StatementProperties statementProperties,
-            IStatementExecutor.ResultMetadata outMetadata, String clientContextId,
+            IStatementExecutor.ResultMetadata outMetadata, String clientContextId, String defaultDataverseName,
             Map<String, String> optionalParameters, Map<String, IAObject> statementParameters, boolean multiStatement,
             int statementCategoryRestrictionMask, boolean forceDropDataset) {
         this(requestReference, statement, resultSet, resultProperties, stats, statementProperties, outMetadata,
-                clientContextId, optionalParameters, statementParameters, multiStatement,
+                clientContextId, defaultDataverseName, optionalParameters, statementParameters, multiStatement,
                 statementCategoryRestrictionMask, forceDropDataset, false);
     }
 
     public RequestParameters(IRequestReference requestReference, String statement, IResultSet resultSet,
             ResultProperties resultProperties, Stats stats, StatementProperties statementProperties,
-            IStatementExecutor.ResultMetadata outMetadata, String clientContextId,
+            IStatementExecutor.ResultMetadata outMetadata, String clientContextId, String defaultDataverseName,
             Map<String, String> optionalParameters, Map<String, IAObject> statementParameters, boolean multiStatement,
             int statementCategoryRestrictionMask, boolean forceDropDataset, boolean skipAdmissionPolicy) {
         this.requestReference = requestReference;
@@ -107,6 +109,7 @@ public class RequestParameters implements IRequestParameters {
         this.multiStatement = multiStatement;
         this.statementCategoryRestrictionMask = statementCategoryRestrictionMask;
         this.forceDropDataset = forceDropDataset;
+        this.defaultDataverseName = defaultDataverseName;
         this.skipAdmissionPolicy = skipAdmissionPolicy;
     }
 
@@ -180,6 +183,11 @@ public class RequestParameters implements IRequestParameters {
         return requestReference;
     }
 
+    @Override
+    public String getDefaultDataverseName() {
+        return defaultDataverseName;
+    }
+
     public static Map<String, byte[]> serializeParameterValues(Map<String, JsonNode> inParams)
             throws HyracksDataException {
         if (inParams == null || inParams.isEmpty()) {
diff --git a/asterixdb/asterix-app/src/test/java/org/apache/asterix/api/http/servlet/QueryCancellationServletTest.java b/asterixdb/asterix-app/src/test/java/org/apache/asterix/api/http/servlet/QueryCancellationServletTest.java
index 50e1155..68fb9a8 100644
--- a/asterixdb/asterix-app/src/test/java/org/apache/asterix/api/http/servlet/QueryCancellationServletTest.java
+++ b/asterixdb/asterix-app/src/test/java/org/apache/asterix/api/http/servlet/QueryCancellationServletTest.java
@@ -71,7 +71,7 @@ public class QueryCancellationServletTest {
 
         final RequestReference requestReference = RequestReference.of("1", "node1", System.currentTimeMillis());
         RequestParameters requestParameters = new RequestParameters(requestReference, "select 1", null, null, null,
-                null, null, "1", null, null, true);
+                null, null, "1", null, null, null, true);
         ClientRequest request = new ClientRequest(requestParameters);
         request.setJobId(new JobId(1));
         request.markCancellable();
@@ -88,7 +88,7 @@ public class QueryCancellationServletTest {
         // Tests the case that the job cancellation hit some exception from Hyracks.
         final RequestReference requestReference2 = RequestReference.of("2", "node1", System.currentTimeMillis());
         requestParameters = new RequestParameters(requestReference2, "select 1", null, null, null, null, null, "2",
-                null, null, true);
+                null, null, null, true);
         ClientRequest request2 = new ClientRequest(requestParameters);
         request2.setJobId(new JobId(2));
         request2.markCancellable();
diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/api/request-dataverse/request-dataverse.1.ddl.sqlpp b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/api/request-dataverse/request-dataverse.1.ddl.sqlpp
new file mode 100644
index 0000000..cb28d2f
--- /dev/null
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/api/request-dataverse/request-dataverse.1.ddl.sqlpp
@@ -0,0 +1,38 @@
+/*
+ * 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 test1 if exists;
+create dataverse test1;
+
+drop dataverse test2.test3 if exists;
+create dataverse test2.test3;
+
+use test1;
+
+create function f1() {
+  select value r
+  from range(0, 9) r
+};
+
+use test2.test3;
+
+create function f23() {
+  select value r
+  from range(10, 19) r
+};
diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/api/request-dataverse/request-dataverse.2.query.sqlpp b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/api/request-dataverse/request-dataverse.2.query.sqlpp
new file mode 100644
index 0000000..765f51b
--- /dev/null
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/api/request-dataverse/request-dataverse.2.query.sqlpp
@@ -0,0 +1,23 @@
+/*
+ * 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.
+ */
+
+// requesttype=application/x-www-form-urlencoded
+// param dataverse:string=test1
+
+array_sum(f1());
diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/api/request-dataverse/request-dataverse.3.query.sqlpp b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/api/request-dataverse/request-dataverse.3.query.sqlpp
new file mode 100644
index 0000000..c6e311c
--- /dev/null
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/api/request-dataverse/request-dataverse.3.query.sqlpp
@@ -0,0 +1,23 @@
+/*
+ * 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.
+ */
+
+// requesttype=application/json
+// param dataverse:json="test2/test3"
+
+array_sum(f23());
diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/api/request-dataverse/request-dataverse.4.query.sqlpp b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/api/request-dataverse/request-dataverse.4.query.sqlpp
new file mode 100644
index 0000000..252ccb0
--- /dev/null
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/api/request-dataverse/request-dataverse.4.query.sqlpp
@@ -0,0 +1,28 @@
+/*
+ * 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.
+ */
+
+/*
+ * Warn if specified dataverse name is unknown
+ */
+
+// requesttype=application/json
+// param dataverse:json="testUnknown"
+// param max-warnings:json=10
+
+array_max(test1.f1());
diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/results/api/request-dataverse/request-dataverse.2.adm b/asterixdb/asterix-app/src/test/resources/runtimets/results/api/request-dataverse/request-dataverse.2.adm
new file mode 100644
index 0000000..7d37386
--- /dev/null
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/results/api/request-dataverse/request-dataverse.2.adm
@@ -0,0 +1 @@
+45
\ No newline at end of file
diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/results/api/request-dataverse/request-dataverse.3.adm b/asterixdb/asterix-app/src/test/resources/runtimets/results/api/request-dataverse/request-dataverse.3.adm
new file mode 100644
index 0000000..aca544d
--- /dev/null
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/results/api/request-dataverse/request-dataverse.3.adm
@@ -0,0 +1 @@
+145
\ No newline at end of file
diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/results/api/request-dataverse/request-dataverse.4.adm b/asterixdb/asterix-app/src/test/resources/runtimets/results/api/request-dataverse/request-dataverse.4.adm
new file mode 100644
index 0000000..f11c82a
--- /dev/null
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/results/api/request-dataverse/request-dataverse.4.adm
@@ -0,0 +1 @@
+9
\ No newline at end of file
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 e82b94a..3871f40 100644
--- a/asterixdb/asterix-app/src/test/resources/runtimets/testsuite_sqlpp.xml
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/testsuite_sqlpp.xml
@@ -47,6 +47,13 @@
         <expected-error>ASX0044: DELETE statement is not supported in read-only mode</expected-error>
       </compilation-unit>
     </test-case>
+    <test-case FilePath="api" check-warnings="true">
+      <compilation-unit name="request-dataverse">
+        <output-dir compare="Text">request-dataverse</output-dir>
+        <expected-warn>ASX1063: Cannot find dataverse with name testUnknown</expected-warn>
+        <source-location>false</source-location>
+      </compilation-unit>
+    </test-case>
     <test-case FilePath="api">
       <compilation-unit name="request-param-validation">
         <output-dir compare="Text">request-param-validation</output-dir>
diff --git a/asterixdb/asterix-doc/src/site/markdown/api.md b/asterixdb/asterix-doc/src/site/markdown/api.md
index d39919f..81f0e3b 100644
--- a/asterixdb/asterix-doc/src/site/markdown/api.md
+++ b/asterixdb/asterix-doc/src/site/markdown/api.md
@@ -39,6 +39,7 @@ __Parameters__
   used e.g. to match individual requests, jobs, and responses. Another option could be to use it for groups of requests
   if an application decides to put e.g. an group identifier into that field to route groups of responses to a
   particular response processor.
+* `dataverse` - Default dataverse for this statement (Optional). If the specified dataverse does not exist then this setting is ignored.
 * `mode` - Result delivery mode. Possible values are `immediate`, `deferred`, `async` (default: `immediate`).
   If the delivery mode is `immediate` the query result is returned with the response.
   If the delivery mode is `deferred` the response contains a handle to the <a href="#queryresult">result</a>.
diff --git a/asterixdb/asterix-lang-common/src/main/java/org/apache/asterix/lang/common/statement/DataverseDecl.java b/asterixdb/asterix-lang-common/src/main/java/org/apache/asterix/lang/common/statement/DataverseDecl.java
index 829c407..b901819 100644
--- a/asterixdb/asterix-lang-common/src/main/java/org/apache/asterix/lang/common/statement/DataverseDecl.java
+++ b/asterixdb/asterix-lang-common/src/main/java/org/apache/asterix/lang/common/statement/DataverseDecl.java
@@ -28,14 +28,25 @@ public class DataverseDecl extends AbstractStatement {
 
     private DataverseName dataverseName;
 
+    private boolean ifExists;
+
     public DataverseDecl(DataverseName dataverseName) {
+        this(dataverseName, false);
+    }
+
+    public DataverseDecl(DataverseName dataverseName, boolean ifExists) {
         this.dataverseName = dataverseName;
+        this.ifExists = ifExists;
     }
 
     public DataverseName getDataverseName() {
         return dataverseName;
     }
 
+    public boolean getIfExists() {
+        return ifExists;
+    }
+
     @Override
     public Kind getKind() {
         return Statement.Kind.DATAVERSE_DECL;