DRILL-7603: Allow default schema to be set for HTTP queries
This allows REST API requests and Web UI requests to specify a
default
schema. Otherwise this is not possible for HTTP clients because the
"USE" command requires a session, which HTTP clients do not have.
closes #1996
diff --git a/exec/java-exec/src/main/java/org/apache/drill/exec/server/rest/QueryResources.java b/exec/java-exec/src/main/java/org/apache/drill/exec/server/rest/QueryResources.java
index bf07fae..ec2a400 100644
--- a/exec/java-exec/src/main/java/org/apache/drill/exec/server/rest/QueryResources.java
+++ b/exec/java-exec/src/main/java/org/apache/drill/exec/server/rest/QueryResources.java
@@ -96,10 +96,12 @@
public Viewable submitQuery(@FormParam("query") String query,
@FormParam("queryType") String queryType,
@FormParam("autoLimit") String autoLimit,
- @FormParam("userName") String userName) throws Exception {
+ @FormParam("userName") String userName,
+ @FormParam("defaultSchema") String defaultSchema) throws Exception {
try {
+ // Apply options from the form fields, if provided
final String trimmedQueryString = CharMatcher.is(';').trimTrailingFrom(query.trim());
- final QueryResult result = submitQueryJSON(new QueryWrapper(trimmedQueryString, queryType, autoLimit, userName));
+ final QueryResult result = submitQueryJSON(new QueryWrapper(trimmedQueryString, queryType, autoLimit, userName, defaultSchema));
List<Integer> rowsPerPageValues = work.getContext().getConfig().getIntList(ExecConstants.HTTP_WEB_CLIENT_RESULTSET_ROWS_PER_PAGE_VALUES);
Collections.sort(rowsPerPageValues);
final String rowsPerPageValuesAsStr = Joiner.on(",").join(rowsPerPageValues);
diff --git a/exec/java-exec/src/main/java/org/apache/drill/exec/server/rest/QueryWrapper.java b/exec/java-exec/src/main/java/org/apache/drill/exec/server/rest/QueryWrapper.java
index 3b99491..0a7bcd7 100644
--- a/exec/java-exec/src/main/java/org/apache/drill/exec/server/rest/QueryWrapper.java
+++ b/exec/java-exec/src/main/java/org/apache/drill/exec/server/rest/QueryWrapper.java
@@ -19,6 +19,7 @@
import com.fasterxml.jackson.annotation.JsonCreator;
import com.fasterxml.jackson.annotation.JsonProperty;
+import org.apache.calcite.schema.SchemaPlus;
import org.apache.drill.common.config.DrillConfig;
import org.apache.drill.common.exceptions.UserException;
import org.apache.drill.common.exceptions.UserRemoteException;
@@ -32,6 +33,7 @@
import org.apache.drill.exec.proto.helper.QueryIdHelper;
import org.apache.drill.exec.rpc.user.InboundImpersonationManager;
import org.apache.drill.exec.server.options.SessionOptionManager;
+import org.apache.drill.exec.store.SchemaTreeProvider;
import org.apache.drill.exec.util.ImpersonationUtil;
import org.apache.drill.exec.work.WorkManager;
import org.apache.parquet.Strings;
@@ -51,8 +53,8 @@
private final String query;
private final String queryType;
private final int autoLimitRowCount;
-
private final String userName;
+ private final String defaultSchema;
private static MemoryMXBean memMXBean = ManagementFactory.getMemoryMXBean();
@@ -61,11 +63,13 @@
@JsonProperty("query") String query,
@JsonProperty("queryType") String queryType,
@JsonProperty("autoLimit") String autoLimit,
- @JsonProperty("userName") String userName) {
+ @JsonProperty("userName") String userName,
+ @JsonProperty("defaultSchema") String defaultSchema) {
this.query = query;
this.queryType = queryType.toUpperCase();
this.autoLimitRowCount = autoLimit != null && autoLimit.matches("[0-9]+") ? Integer.valueOf(autoLimit) : 0;
this.userName = userName;
+ this.defaultSchema = defaultSchema;
}
public String getQuery() {
@@ -90,6 +94,13 @@
applyUserName(workManager, webUserConnection);
int defaultMaxRows = webUserConnection.getSession().getOptions().getOption(ExecConstants.QUERY_MAX_ROWS).num_val.intValue();
+ if (!Strings.isNullOrEmpty(defaultSchema)) {
+ SessionOptionManager options = webUserConnection.getSession().getOptions();
+ SchemaTreeProvider schemaTreeProvider = new SchemaTreeProvider(workManager.getContext());
+ SchemaPlus rootSchema = schemaTreeProvider.createRootSchema(options);
+ webUserConnection.getSession().setDefaultSchemaPath(defaultSchema, rootSchema);
+ }
+
int maxRows;
if (autoLimitRowCount > 0 && defaultMaxRows > 0) {
maxRows = Math.min(autoLimitRowCount, defaultMaxRows);
diff --git a/exec/java-exec/src/main/resources/rest/query/query.ftl b/exec/java-exec/src/main/resources/rest/query/query.ftl
index 520a93b..e7bbed2 100644
--- a/exec/java-exec/src/main/resources/rest/query/query.ftl
+++ b/exec/java-exec/src/main/resources/rest/query/query.ftl
@@ -82,6 +82,8 @@
Submit
</button>
<input type="checkbox" name="forceLimit" value="limit" <#if model.isAutoLimitEnabled()>checked</#if>> Limit results to <input type="text" id="autoLimit" name="autoLimit" min="0" value="${model.getDefaultRowsAutoLimited()?c}" size="6" pattern="[0-9]*"> rows <span class="glyphicon glyphicon-info-sign" title="Limits the number of records retrieved in the query. Ignored if query has a limit already" style="cursor:pointer"></span>
+ <label> Default Schema <input type="text" size="10" name="defaultSchema" id="defaultSchema"> </label>
+ <span class="glyphicon glyphicon-info-sign" title="Set the default schema used to find table names, and for SHOW FILES and SHOW TABLES" style="cursor:pointer"></span>
<input type="hidden" name="csrfToken" value="${model.getCsrfToken()}">
</form>
diff --git a/exec/java-exec/src/test/java/org/apache/drill/exec/server/rest/RestServerTest.java b/exec/java-exec/src/test/java/org/apache/drill/exec/server/rest/RestServerTest.java
index 7136a7d..2915d28 100644
--- a/exec/java-exec/src/test/java/org/apache/drill/exec/server/rest/RestServerTest.java
+++ b/exec/java-exec/src/test/java/org/apache/drill/exec/server/rest/RestServerTest.java
@@ -30,11 +30,11 @@
public class RestServerTest extends ClusterTest {
protected QueryWrapper.QueryResult runQuery(String sql) throws Exception {
- return runQuery(new QueryWrapper(sql, "SQL", null, null));
+ return runQuery(new QueryWrapper(sql, "SQL", null, null, null));
}
protected QueryWrapper.QueryResult runQueryWithUsername(String sql, String userName) throws Exception {
- return runQuery(new QueryWrapper(sql, "SQL", null, userName));
+ return runQuery(new QueryWrapper(sql, "SQL", null, userName, null));
}
protected QueryWrapper.QueryResult runQuery(QueryWrapper q) throws Exception {
diff --git a/exec/java-exec/src/test/java/org/apache/drill/exec/server/rest/TestQueryWrapper.java b/exec/java-exec/src/test/java/org/apache/drill/exec/server/rest/TestQueryWrapper.java
index ed8ac2d..aaa7931 100644
--- a/exec/java-exec/src/test/java/org/apache/drill/exec/server/rest/TestQueryWrapper.java
+++ b/exec/java-exec/src/test/java/org/apache/drill/exec/server/rest/TestQueryWrapper.java
@@ -50,11 +50,19 @@
@Test
public void testImpersonationDisabled() throws Exception {
try {
- QueryWrapper q = new QueryWrapper("SHOW SCHEMAS", "SQL", null, "alfred");
+ QueryWrapper q = new QueryWrapper("SHOW SCHEMAS", "SQL", null, "alfred", null);
runQuery(q);
fail("Should have thrown exception");
} catch (UserException e) {
assertThat(e.getMessage(), containsString("User impersonation is not enabled"));
}
}
+
+ @Test
+ public void testSpecifyDefaultSchema() throws Exception {
+ QueryWrapper.QueryResult result = runQuery(new QueryWrapper("SHOW FILES", "SQL", null, null, "dfs.tmp"));
+ // SHOW FILES will fail if default schema is not provided
+ assertEquals("COMPLETED", result.queryState);
+ }
+
}