This is an automated email from the ASF dual-hosted git repository. arina pushed a commit to branch master in repository https://gitbox.apache.org/repos/asf/drill.git
commit a8c9a0f75477cb49284e337d5ebcda51318f4380 Author: Dobes Vandermeer <dob...@gmail.com> AuthorDate: Tue Mar 10 14:02:27 2020 -0700 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 --- .../org/apache/drill/exec/server/rest/QueryResources.java | 6 ++++-- .../org/apache/drill/exec/server/rest/QueryWrapper.java | 15 +++++++++++++-- exec/java-exec/src/main/resources/rest/query/query.ftl | 2 ++ .../org/apache/drill/exec/server/rest/RestServerTest.java | 4 ++-- .../apache/drill/exec/server/rest/TestQueryWrapper.java | 10 +++++++++- 5 files changed, 30 insertions(+), 7 deletions(-) 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 class QueryResources { 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 @@ package org.apache.drill.exec.server.rest; 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.UserProtos.RunQuery; 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 @@ public class QueryWrapper { 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 @@ public class QueryWrapper { @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 @@ public class QueryWrapper { 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 @@ import org.apache.drill.test.ClusterTest; 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 @@ public class TestQueryWrapper extends RestServerTest { @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); + } + }