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