Repository: drill
Updated Branches:
refs/heads/master 6796006f2 -> 453f6f7a8
DRILL-3196: Disable multiple partitions in a SELECT-CLAUSE
Project: http://git-wip-us.apache.org/repos/asf/drill/repo
Commit: http://git-wip-us.apache.org/repos/asf/drill/commit/453f6f7a
Tree: http://git-wip-us.apache.org/repos/asf/drill/tree/453f6f7a
Diff: http://git-wip-us.apache.org/repos/asf/drill/diff/453f6f7a
Branch: refs/heads/master
Commit: 453f6f7a8328658563b7704d1400a882857d104b
Parents: 6796006
Author: Hsuan-Yi Chu <hsuanyi@usc.edu>
Authored: Mon Jun 1 11:09:16 2015 -0700
Committer: Aman Sinha <asinha@maprtech.com>
Committed: Thu Jun 11 09:52:54 2015 -0700
----------------------------------------------------------------------
.../sql/parser/UnsupportedOperatorsVisitor.java | 65 ++++++++++---
.../apache/drill/exec/TestWindowFunctions.java | 98 ++++++++++++++++++++
2 files changed, 152 insertions(+), 11 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/drill/blob/453f6f7a/exec/java-exec/src/main/java/org/apache/drill/exec/planner/sql/parser/UnsupportedOperatorsVisitor.java
----------------------------------------------------------------------
diff --git a/exec/java-exec/src/main/java/org/apache/drill/exec/planner/sql/parser/UnsupportedOperatorsVisitor.java
b/exec/java-exec/src/main/java/org/apache/drill/exec/planner/sql/parser/UnsupportedOperatorsVisitor.java
index f1ec851..b92de3b 100644
--- a/exec/java-exec/src/main/java/org/apache/drill/exec/planner/sql/parser/UnsupportedOperatorsVisitor.java
+++ b/exec/java-exec/src/main/java/org/apache/drill/exec/planner/sql/parser/UnsupportedOperatorsVisitor.java
@@ -17,12 +17,15 @@
*/
package org.apache.drill.exec.planner.sql.parser;
-import org.apache.calcite.sql.SqlSelect;
-import org.apache.calcite.sql.fun.SqlCountAggFunction;
import org.apache.drill.exec.ExecConstants;
import org.apache.drill.exec.exception.UnsupportedOperatorCollector;
import org.apache.drill.exec.ops.QueryContext;
import org.apache.drill.exec.work.foreman.SqlUnsupportedException;
+
+import org.apache.calcite.sql.SqlIdentifier;
+import org.apache.calcite.sql.SqlSelect;
+import org.apache.calcite.sql.SqlWindow;
+import org.apache.calcite.sql.fun.SqlCountAggFunction;
import org.apache.calcite.sql.SqlCall;
import org.apache.calcite.sql.SqlKind;
import org.apache.calcite.sql.SqlJoin;
@@ -32,7 +35,9 @@ import org.apache.calcite.sql.type.SqlTypeName;
import org.apache.calcite.sql.util.SqlShuttle;
import org.apache.calcite.sql.SqlDataTypeSpec;
import org.apache.calcite.sql.SqlSetOperator;
+
import java.util.List;
+
import com.google.common.collect.Lists;
public class UnsupportedOperatorsVisitor extends SqlShuttle {
@@ -78,6 +83,53 @@ public class UnsupportedOperatorsVisitor extends SqlShuttle {
@Override
public SqlNode visit(SqlCall sqlCall) {
+ // Inspect the window functions
+ if(sqlCall instanceof SqlSelect) {
+ SqlSelect sqlSelect = (SqlSelect) sqlCall;
+
+ // This is used to keep track of the window function which has been defined
+ SqlNode definedWindow = null;
+ for(SqlNode nodeInSelectList : sqlSelect.getSelectList()) {
+ if(nodeInSelectList.getKind() == SqlKind.OVER) {
+ // Throw exceptions if window functions are disabled
+ if(!context.getOptions().getOption(ExecConstants.ENABLE_WINDOW_FUNCTIONS).bool_val)
{
+ unsupportedOperatorCollector.setException(SqlUnsupportedException.ExceptionType.FUNCTION,
+ "Window functions are disabled\n" +
+ "See Apache Drill JIRA: DRILL-2559");
+ throw new UnsupportedOperationException();
+ }
+
+ SqlNode window = ((SqlCall) nodeInSelectList).operand(1);
+
+ // Partition window is referenced as a SqlIdentifier,
+ // which is defined in the window list
+ if(window instanceof SqlIdentifier) {
+ // Expand the SqlIdentifier as the expression defined in the window list
+ for(SqlNode sqlNode : sqlSelect.getWindowList()) {
+ if(((SqlWindow) sqlNode).getDeclName().equalsDeep(window, false)) {
+ window = sqlNode;
+ break;
+ }
+ }
+
+ assert !(window instanceof SqlIdentifier) : "Identifier should have been expanded
as a window defined in the window list";
+ }
+
+ // In a SELECT-SCOPE, only a partition can be defined
+ if(definedWindow == null) {
+ definedWindow = window;
+ } else {
+ if(!definedWindow.equalsDeep(window, false)) {
+ unsupportedOperatorCollector.setException(SqlUnsupportedException.ExceptionType.FUNCTION,
+ "Multiple window definitions in a single SELECT list is not currently supported
\n" +
+ "See Apache Drill JIRA: DRILL-3196");
+ throw new UnsupportedOperationException();
+ }
+ }
+ }
+ }
+ }
+
// Disable unsupported Intersect, Except
if(sqlCall.getKind() == SqlKind.INTERSECT || sqlCall.getKind() == SqlKind.EXCEPT) {
unsupportedOperatorCollector.setException(SqlUnsupportedException.ExceptionType.RELATIONAL,
@@ -118,15 +170,6 @@ public class UnsupportedOperatorsVisitor extends SqlShuttle {
}
}
- // Throw exceptions if window functions are disabled
- if(sqlCall.getOperator().getKind().equals(SqlKind.OVER)
- && !context.getOptions().getOption(ExecConstants.ENABLE_WINDOW_FUNCTIONS).bool_val)
{
- unsupportedOperatorCollector.setException(SqlUnsupportedException.ExceptionType.FUNCTION,
- "Window functions are disabled\n" +
- "See Apache Drill JIRA: DRILL-2559");
- throw new UnsupportedOperationException();
- }
-
// Disable Function
for(String strOperator : disabledOperators) {
if(sqlCall.getOperator().isName(strOperator)) {
http://git-wip-us.apache.org/repos/asf/drill/blob/453f6f7a/exec/java-exec/src/test/java/org/apache/drill/exec/TestWindowFunctions.java
----------------------------------------------------------------------
diff --git a/exec/java-exec/src/test/java/org/apache/drill/exec/TestWindowFunctions.java b/exec/java-exec/src/test/java/org/apache/drill/exec/TestWindowFunctions.java
new file mode 100644
index 0000000..fc75d73
--- /dev/null
+++ b/exec/java-exec/src/test/java/org/apache/drill/exec/TestWindowFunctions.java
@@ -0,0 +1,98 @@
+/**
+ * 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.drill.exec;
+
+import org.apache.drill.BaseTestQuery;
+import org.apache.drill.common.exceptions.UserException;
+import org.apache.drill.exec.work.foreman.SqlUnsupportedException;
+import org.apache.drill.exec.work.foreman.UnsupportedFunctionException;
+import org.junit.Test;
+
+public class TestWindowFunctions extends BaseTestQuery {
+ private static void throwAsUnsupportedException(UserException ex) throws Exception {
+ SqlUnsupportedException.errorClassNameToException(ex.getOrCreatePBError(false).getException().getExceptionClass());
+ throw ex;
+ }
+
+ @Test // DRILL-3196
+ public void testSinglePartition() throws Exception {
+ final String query = "explain plan for select sum(a2) over(partition by a2), count(*)
over(partition by a2) \n" +
+ "from cp.`tpch/nation.parquet`";
+
+ test("alter session set `window.enable` = true");
+ test(query);
+ test("alter session set `window.enable` = false");
+ }
+
+ @Test // DRILL-3196
+ public void testSinglePartitionDefinedInWindowList() throws Exception {
+ final String query = "explain plan for select sum(a2) over w \n" +
+ "from cp.`tpch/nation.parquet` \n" +
+ "window w as (partition by a2 order by a2)";
+
+ test("alter session set `window.enable` = true");
+ test(query);
+ test("alter session set `window.enable` = false");
+ }
+
+ @Test(expected = UnsupportedFunctionException.class) // DRILL-3196
+ public void testMultiplePartitions() throws Exception {
+ try {
+ final String query = "explain plan for select sum(a2) over(partition by a2), count(*)
over(partition by a2,b2,c2) \n" +
+ "from cp.`tpch/nation.parquet`";
+
+ test("alter session set `window.enable` = true");
+ test(query);
+ test("alter session set `window.enable` = false");
+ } catch(UserException ex) {
+ throwAsUnsupportedException(ex);
+ throw ex;
+ }
+ }
+
+ @Test(expected = UnsupportedFunctionException.class) // DRILL-3196
+ public void testSinglePartitionMultipleOrderBy() throws Exception {
+ try {
+ final String query = "explain plan for select sum(a2) over(partition by a2 order by
a2), count(*) over(partition by a2 order by b2) \n" +
+ "from cp.`tpch/nation.parquet`";
+
+ test("alter session set `window.enable` = true");
+ test(query);
+ test("alter session set `window.enable` = false");
+ } catch(UserException ex) {
+ throwAsUnsupportedException(ex);
+ throw ex;
+ }
+ }
+
+ @Test(expected = UnsupportedFunctionException.class) // DRILL-3196
+ public void testMultiplePartitionsDefinedInWindowList() throws Exception {
+ try {
+ final String query = "explain plan for select sum(a2) over(partition by a2), count(*)
over w \n" +
+ "from cp.`tpch/nation.parquet` \n" +
+ "window w as (partition by a2, b2, c2)";
+
+ test("alter session set `window.enable` = true");
+ test(query);
+ test("alter session set `window.enable` = false");
+ } catch(UserException ex) {
+ throwAsUnsupportedException(ex);
+ throw ex;
+ }
+ }
+}
|