You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@drill.apache.org by am...@apache.org on 2015/02/26 06:35:54 UTC
drill git commit: DRILL-1325: Throw UnsupportedRelOperatorException
for unequal joins, implicit cross joins
Repository: drill
Updated Branches:
refs/heads/master 471013836 -> d72d6030e
DRILL-1325: Throw UnsupportedRelOperatorException for unequal joins, implicit cross joins
Project: http://git-wip-us.apache.org/repos/asf/drill/repo
Commit: http://git-wip-us.apache.org/repos/asf/drill/commit/d72d6030
Tree: http://git-wip-us.apache.org/repos/asf/drill/tree/d72d6030
Diff: http://git-wip-us.apache.org/repos/asf/drill/diff/d72d6030
Branch: refs/heads/master
Commit: d72d6030ed3961a5e4fa8839b4be5ec1065f4059
Parents: 4710138
Author: Hsuan-Yi Chu <hs...@usc.edu>
Authored: Tue Feb 24 19:08:40 2015 -0800
Committer: Hsuan-Yi Chu <hs...@usc.edu>
Committed: Wed Feb 25 17:49:26 2015 -0800
----------------------------------------------------------------------
.../exec/physical/impl/join/JoinUtils.java | 42 +++++++++
.../planner/sql/handlers/DefaultSqlHandler.java | 30 ++++--
.../work/foreman/SqlUnsupportedException.java | 4 +
.../foreman/UnsupportedDataTypeException.java | 4 +
.../foreman/UnsupportedFunctionException.java | 6 +-
.../UnsupportedRelOperatorException.java | 4 +
.../apache/drill/TestDisabledFunctionality.java | 97 ++++++++++++++++++++
7 files changed, 177 insertions(+), 10 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/drill/blob/d72d6030/exec/java-exec/src/main/java/org/apache/drill/exec/physical/impl/join/JoinUtils.java
----------------------------------------------------------------------
diff --git a/exec/java-exec/src/main/java/org/apache/drill/exec/physical/impl/join/JoinUtils.java b/exec/java-exec/src/main/java/org/apache/drill/exec/physical/impl/join/JoinUtils.java
index 04f3bbe..b94289c 100644
--- a/exec/java-exec/src/main/java/org/apache/drill/exec/physical/impl/join/JoinUtils.java
+++ b/exec/java-exec/src/main/java/org/apache/drill/exec/physical/impl/join/JoinUtils.java
@@ -19,6 +19,11 @@
package org.apache.drill.exec.physical.impl.join;
import org.apache.drill.common.logical.data.JoinCondition;
+import org.eigenbase.rel.JoinRelBase;
+import org.eigenbase.rel.RelNode;
+import org.eigenbase.relopt.RelOptUtil;
+
+import java.util.List;
public class JoinUtils {
public static enum JoinComparator {
@@ -51,4 +56,41 @@ public class JoinUtils {
throw new IllegalArgumentException("Invalid comparator supplied to this join.");
}
+ /**
+ * Check if the given RelNode contains any Cartesian join.
+ * Return true if find one. Otherwise, return false.
+ *
+ * @param relNode the RelNode to be inspected.
+ * @param leftKeys a list used for the left input into the join which has
+ * equi-join keys. It can be empty or not (but not null),
+ * this method will clear this list before using it.
+ * @param rightKeys a list used for the right input into the join which has
+ * equi-join keys. It can be empty or not (but not null),
+ * this method will clear this list before using it.
+ * @return Return true if the given relNode contains Cartesian join.
+ * Otherwise, return false
+ */
+ public static boolean checkCartesianJoin(RelNode relNode, List<Integer> leftKeys, List<Integer> rightKeys) {
+ if (relNode instanceof JoinRelBase) {
+ leftKeys.clear();
+ rightKeys.clear();
+
+ JoinRelBase joinRel = (JoinRelBase) relNode;
+ RelNode left = joinRel.getLeft();
+ RelNode right = joinRel.getRight();
+
+ RelOptUtil.splitJoinCondition(left, right, joinRel.getCondition(), leftKeys, rightKeys);
+ if(leftKeys.isEmpty() || rightKeys.isEmpty()) {
+ return true;
+ }
+ }
+
+ for (RelNode child : relNode.getInputs()) {
+ if(checkCartesianJoin(child, leftKeys, rightKeys)) {
+ return true;
+ }
+ }
+
+ return false;
+ }
}
http://git-wip-us.apache.org/repos/asf/drill/blob/d72d6030/exec/java-exec/src/main/java/org/apache/drill/exec/planner/sql/handlers/DefaultSqlHandler.java
----------------------------------------------------------------------
diff --git a/exec/java-exec/src/main/java/org/apache/drill/exec/planner/sql/handlers/DefaultSqlHandler.java b/exec/java-exec/src/main/java/org/apache/drill/exec/planner/sql/handlers/DefaultSqlHandler.java
index 0ac7c97..35e7f5c 100644
--- a/exec/java-exec/src/main/java/org/apache/drill/exec/planner/sql/handlers/DefaultSqlHandler.java
+++ b/exec/java-exec/src/main/java/org/apache/drill/exec/planner/sql/handlers/DefaultSqlHandler.java
@@ -18,6 +18,7 @@
package org.apache.drill.exec.planner.sql.handlers;
import java.io.IOException;
+import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
@@ -35,6 +36,7 @@ import org.apache.drill.exec.ops.QueryContext;
import org.apache.drill.exec.physical.PhysicalPlan;
import org.apache.drill.exec.physical.base.AbstractPhysicalVisitor;
import org.apache.drill.exec.physical.base.PhysicalOperator;
+import org.apache.drill.exec.physical.impl.join.JoinUtils;
import org.apache.drill.exec.planner.logical.DrillRel;
import org.apache.drill.exec.planner.logical.DrillScreenRel;
import org.apache.drill.exec.planner.logical.DrillStoreRel;
@@ -61,7 +63,9 @@ import org.apache.drill.exec.server.options.OptionValue;
import org.apache.drill.exec.util.Pointer;
import org.apache.drill.exec.work.foreman.ForemanSetupException;
import org.apache.drill.exec.work.foreman.SqlUnsupportedException;
+import org.apache.drill.exec.work.foreman.UnsupportedRelOperatorException;
import org.eigenbase.rel.RelNode;
+import org.eigenbase.relopt.RelOptPlanner;
import org.eigenbase.relopt.RelOptUtil;
import org.eigenbase.relopt.RelTraitSet;
import org.eigenbase.relopt.hep.HepPlanner;
@@ -103,7 +107,7 @@ public class DefaultSqlHandler extends AbstractSqlHandler {
}
protected void log(String name, Prel node) {
- String plan = PrelSequencer.printWithIds(node, SqlExplainLevel.ALL_ATTRIBUTES);;
+ String plan = PrelSequencer.printWithIds(node, SqlExplainLevel.ALL_ATTRIBUTES);
if(textPlan != null){
textPlan.value = plan;
}
@@ -186,13 +190,23 @@ public class DefaultSqlHandler extends AbstractSqlHandler {
return rel;
}
- protected DrillRel convertToDrel(RelNode relNode) throws RelConversionException {
- RelNode convertedRelNode = planner.transform(DrillSqlWorker.LOGICAL_RULES,
- relNode.getTraitSet().plus(DrillRel.DRILL_LOGICAL), relNode);
- if (convertedRelNode instanceof DrillStoreRel) {
- throw new UnsupportedOperationException();
- } else {
- return new DrillScreenRel(convertedRelNode.getCluster(), convertedRelNode.getTraitSet(), convertedRelNode);
+ protected DrillRel convertToDrel(RelNode relNode) throws RelConversionException, SqlUnsupportedException {
+ try {
+ RelNode convertedRelNode = planner.transform(DrillSqlWorker.LOGICAL_RULES,
+ relNode.getTraitSet().plus(DrillRel.DRILL_LOGICAL), relNode);
+ if (convertedRelNode instanceof DrillStoreRel) {
+ throw new UnsupportedOperationException();
+ } else {
+ return new DrillScreenRel(convertedRelNode.getCluster(), convertedRelNode.getTraitSet(), convertedRelNode);
+ }
+ } catch (RelOptPlanner.CannotPlanException ex) {
+ logger.error(ex.getMessage());
+
+ if(JoinUtils.checkCartesianJoin(relNode, new ArrayList<Integer>(), new ArrayList<Integer>())) {
+ throw new UnsupportedRelOperatorException("This query cannot be planned possibly due to either a cartesian join or an inequality join");
+ } else {
+ throw ex;
+ }
}
}
http://git-wip-us.apache.org/repos/asf/drill/blob/d72d6030/exec/java-exec/src/main/java/org/apache/drill/exec/work/foreman/SqlUnsupportedException.java
----------------------------------------------------------------------
diff --git a/exec/java-exec/src/main/java/org/apache/drill/exec/work/foreman/SqlUnsupportedException.java b/exec/java-exec/src/main/java/org/apache/drill/exec/work/foreman/SqlUnsupportedException.java
index 65e9d2d..2299afa 100644
--- a/exec/java-exec/src/main/java/org/apache/drill/exec/work/foreman/SqlUnsupportedException.java
+++ b/exec/java-exec/src/main/java/org/apache/drill/exec/work/foreman/SqlUnsupportedException.java
@@ -43,6 +43,10 @@ public abstract class SqlUnsupportedException extends ForemanSetupException {
"See Apache Drill JIRA: DRILL-" + jiraNumber);
}
+ public SqlUnsupportedException(String errorMessage) {
+ super(errorMessage);
+ }
+
public static void errorMessageToException(String errorMessage) throws SqlUnsupportedException {
UnsupportedOperatorCollector collector = new UnsupportedOperatorCollector();
for(ExceptionType ex : ExceptionType.values()) {
http://git-wip-us.apache.org/repos/asf/drill/blob/d72d6030/exec/java-exec/src/main/java/org/apache/drill/exec/work/foreman/UnsupportedDataTypeException.java
----------------------------------------------------------------------
diff --git a/exec/java-exec/src/main/java/org/apache/drill/exec/work/foreman/UnsupportedDataTypeException.java b/exec/java-exec/src/main/java/org/apache/drill/exec/work/foreman/UnsupportedDataTypeException.java
index cac753b..305e6d3 100644
--- a/exec/java-exec/src/main/java/org/apache/drill/exec/work/foreman/UnsupportedDataTypeException.java
+++ b/exec/java-exec/src/main/java/org/apache/drill/exec/work/foreman/UnsupportedDataTypeException.java
@@ -23,4 +23,8 @@ public class UnsupportedDataTypeException extends SqlUnsupportedException {
public UnsupportedDataTypeException(String drillJiraNumber, String message) {
super(drillJiraNumber, message);
}
+
+ public UnsupportedDataTypeException(String errorMessage) {
+ super(errorMessage);
+ }
}
http://git-wip-us.apache.org/repos/asf/drill/blob/d72d6030/exec/java-exec/src/main/java/org/apache/drill/exec/work/foreman/UnsupportedFunctionException.java
----------------------------------------------------------------------
diff --git a/exec/java-exec/src/main/java/org/apache/drill/exec/work/foreman/UnsupportedFunctionException.java b/exec/java-exec/src/main/java/org/apache/drill/exec/work/foreman/UnsupportedFunctionException.java
index 216a75a..797713e 100644
--- a/exec/java-exec/src/main/java/org/apache/drill/exec/work/foreman/UnsupportedFunctionException.java
+++ b/exec/java-exec/src/main/java/org/apache/drill/exec/work/foreman/UnsupportedFunctionException.java
@@ -17,10 +17,12 @@
*/
package org.apache.drill.exec.work.foreman;
-import org.eigenbase.sql.SqlOperator;
-
public class UnsupportedFunctionException extends SqlUnsupportedException {
public UnsupportedFunctionException(String drillJiraNumber, String message) {
super(drillJiraNumber, message);
}
+
+ public UnsupportedFunctionException(String errorMessage) {
+ super(errorMessage);
+ }
}
http://git-wip-us.apache.org/repos/asf/drill/blob/d72d6030/exec/java-exec/src/main/java/org/apache/drill/exec/work/foreman/UnsupportedRelOperatorException.java
----------------------------------------------------------------------
diff --git a/exec/java-exec/src/main/java/org/apache/drill/exec/work/foreman/UnsupportedRelOperatorException.java b/exec/java-exec/src/main/java/org/apache/drill/exec/work/foreman/UnsupportedRelOperatorException.java
index 2dbae4c..b86c2de 100644
--- a/exec/java-exec/src/main/java/org/apache/drill/exec/work/foreman/UnsupportedRelOperatorException.java
+++ b/exec/java-exec/src/main/java/org/apache/drill/exec/work/foreman/UnsupportedRelOperatorException.java
@@ -21,4 +21,8 @@ public class UnsupportedRelOperatorException extends SqlUnsupportedException {
public UnsupportedRelOperatorException(String drillJiraNumber, String message) {
super(drillJiraNumber, message);
}
+
+ public UnsupportedRelOperatorException(String errorMessage) {
+ super(errorMessage);
+ }
}
http://git-wip-us.apache.org/repos/asf/drill/blob/d72d6030/exec/java-exec/src/test/java/org/apache/drill/TestDisabledFunctionality.java
----------------------------------------------------------------------
diff --git a/exec/java-exec/src/test/java/org/apache/drill/TestDisabledFunctionality.java b/exec/java-exec/src/test/java/org/apache/drill/TestDisabledFunctionality.java
index b1437c1..bc680b6 100644
--- a/exec/java-exec/src/test/java/org/apache/drill/TestDisabledFunctionality.java
+++ b/exec/java-exec/src/test/java/org/apache/drill/TestDisabledFunctionality.java
@@ -191,4 +191,101 @@ public class TestDisabledFunctionality extends BaseTestQuery{
throw ex;
}
}
+
+ @Test(expected = UnsupportedRelOperatorException.class) // DRILL-2068
+ public void testImplicitCartesianJoin() throws Exception {
+ try {
+ test("select a.*, b.user_port " +
+ "from cp.`employee.json` a, sys.drillbits b;");
+ } catch(Exception ex) {
+ SqlUnsupportedException.errorMessageToException(ex.getMessage());
+ throw ex;
+ }
+ }
+
+ @Test(expected = UnsupportedRelOperatorException.class) // see DRILL-2068, DRILL-1325
+ public void testNonEqualJoin() throws Exception {
+ try {
+ test("select a.*, b.user_port " +
+ "from cp.`employee.json` a, sys.drillbits b " +
+ "where a.position_id <> b.user_port;");
+ } catch(Exception ex) {
+ SqlUnsupportedException.errorMessageToException(ex.getMessage());
+ throw ex;
+ }
+ }
+
+ @Test(expected = UnsupportedRelOperatorException.class) // see DRILL-2068, DRILL-1325
+ public void testMultipleJoinsWithOneNonEqualJoin() throws Exception {
+ try {
+ test("select a.last_name, b.n_name, c.r_name " +
+ "from cp.`employee.json` a, cp.`tpch/nation.parquet` b, cp.`tpch/region.parquet` c " +
+ "where a.position_id > b.n_nationKey and b.n_nationKey = c.r_regionkey;");
+ } catch(Exception ex) {
+ SqlUnsupportedException.errorMessageToException(ex.getMessage());
+ throw ex;
+ }
+ }
+
+ @Test(expected = UnsupportedRelOperatorException.class) // see DRILL-2068, DRILL-1325
+ public void testLeftOuterJoin() throws Exception {
+ try {
+ test("select a.lastname, b.n_name " +
+ "from cp.`employee.json` a LEFT JOIN cp.`tpch/nation.parquet` b " +
+ "ON a.position_id > b.n_nationKey;");
+ } catch(Exception ex) {
+ SqlUnsupportedException.errorMessageToException(ex.getMessage());
+ throw ex;
+ }
+ }
+
+ @Test(expected = UnsupportedRelOperatorException.class) // see DRILL-2068, DRILL-1325
+ public void testInnerJoin() throws Exception {
+ try {
+ test("select a.lastname, b.n_name " +
+ "from cp.`employee.json` a INNER JOIN cp.`tpch/nation.parquet` b " +
+ "ON a.position_id > b.n_nationKey;");
+ } catch(Exception ex) {
+ SqlUnsupportedException.errorMessageToException(ex.getMessage());
+ throw ex;
+ }
+ }
+
+ @Test(expected = UnsupportedFunctionException.class) // see DRILL-1325, DRILL-2155, see DRILL-1937
+ public void testMultipleUnsupportedOperatorations() throws Exception {
+ try {
+ test("select a.lastname, b.n_name " +
+ "from cp.`employee.json` a, cp.`tpch/nation.parquet` b " +
+ "where b.n_nationkey = " +
+ "(select r_regionkey from cp.`tpch/region.parquet` " +
+ "where r_regionkey = 1)");
+ } catch(Exception ex) {
+ SqlUnsupportedException.errorMessageToException(ex.getMessage());
+ throw ex;
+ }
+ }
+
+ @Test(expected = UnsupportedRelOperatorException.class) // see DRILL-1325,
+ public void testSubqueryWithoutCorrelatedJoinCondition() throws Exception {
+ try {
+ test("select a.lastname " +
+ "from cp.`employee.json` a " +
+ "where exists (select n_name from cp.`tpch/nation.parquet` b) AND a.position_id = 10");
+ } catch(Exception ex) {
+ SqlUnsupportedException.errorMessageToException(ex.getMessage());
+ throw ex;
+ }
+ }
+
+ @Test(expected = UnsupportedRelOperatorException.class) // see DRILL-2068, DRILL-1325
+ public void testExplainPlanForCartesianJoin() throws Exception {
+ try {
+ test("explain plan for (select a.lastname, b.n_name " +
+ "from cp.`employee.json` a INNER JOIN cp.`tpch/nation.parquet` b " +
+ "ON a.position_id > b.n_nationKey);");
+ } catch(Exception ex) {
+ SqlUnsupportedException.errorMessageToException(ex.getMessage());
+ throw ex;
+ }
+ }
}
\ No newline at end of file