You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@drill.apache.org by ja...@apache.org on 2014/04/20 03:18:55 UTC
[47/51] [abbrv] git commit: Add support for non-equijoins in the
presence of other equijoins between the same tables.
Add support for non-equijoins in the presence of other equijoins between the same tables.
Project: http://git-wip-us.apache.org/repos/asf/incubator-drill/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-drill/commit/63287658
Tree: http://git-wip-us.apache.org/repos/asf/incubator-drill/tree/63287658
Diff: http://git-wip-us.apache.org/repos/asf/incubator-drill/diff/63287658
Branch: refs/heads/master
Commit: 63287658c0628ecfbc56d0d33618ad2219fef438
Parents: 4cfdb3b
Author: Aman Sinha <as...@maprtech.com>
Authored: Fri Apr 4 10:08:24 2014 -0700
Committer: Jacques Nadeau <ja...@apache.org>
Committed: Sat Apr 19 18:07:12 2014 -0700
----------------------------------------------------------------------
.../exec/planner/common/DrillJoinRelBase.java | 4 +-
.../exec/planner/logical/DrillJoinRel.java | 27 ++++++++-
.../exec/planner/logical/DrillJoinRule.java | 63 +++++++++++++++++++-
.../exec/planner/logical/DrillRuleSets.java | 4 +-
.../exec/planner/physical/MergeJoinPrel.java | 2 +-
5 files changed, 91 insertions(+), 9 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/incubator-drill/blob/63287658/exec/java-exec/src/main/java/org/apache/drill/exec/planner/common/DrillJoinRelBase.java
----------------------------------------------------------------------
diff --git a/exec/java-exec/src/main/java/org/apache/drill/exec/planner/common/DrillJoinRelBase.java b/exec/java-exec/src/main/java/org/apache/drill/exec/planner/common/DrillJoinRelBase.java
index e88faf9..b9c112d 100644
--- a/exec/java-exec/src/main/java/org/apache/drill/exec/planner/common/DrillJoinRelBase.java
+++ b/exec/java-exec/src/main/java/org/apache/drill/exec/planner/common/DrillJoinRelBase.java
@@ -45,8 +45,8 @@ import com.google.common.collect.Lists;
* Base class for logical and physical Joins implemented in Drill.
*/
public abstract class DrillJoinRelBase extends JoinRelBase implements DrillRelNode {
- protected final List<Integer> leftKeys = new ArrayList<>();
- protected final List<Integer> rightKeys = new ArrayList<>();
+ protected List<Integer> leftKeys = Lists.newArrayList();
+ protected List<Integer> rightKeys = Lists.newArrayList() ;
public DrillJoinRelBase(RelOptCluster cluster, RelTraitSet traits, RelNode left, RelNode right, RexNode condition,
JoinRelType joinType) throws InvalidRelException {
http://git-wip-us.apache.org/repos/asf/incubator-drill/blob/63287658/exec/java-exec/src/main/java/org/apache/drill/exec/planner/logical/DrillJoinRel.java
----------------------------------------------------------------------
diff --git a/exec/java-exec/src/main/java/org/apache/drill/exec/planner/logical/DrillJoinRel.java b/exec/java-exec/src/main/java/org/apache/drill/exec/planner/logical/DrillJoinRel.java
index 31a8e6e..a3a4ac9 100644
--- a/exec/java-exec/src/main/java/org/apache/drill/exec/planner/logical/DrillJoinRel.java
+++ b/exec/java-exec/src/main/java/org/apache/drill/exec/planner/logical/DrillJoinRel.java
@@ -42,20 +42,41 @@ import org.eigenbase.rex.RexUtil;
import org.eigenbase.sql.fun.SqlStdOperatorTable;
import org.eigenbase.util.Pair;
+import com.google.hive12.common.collect.Lists;
+
/**
* Join implemented in Drill.
*/
public class DrillJoinRel extends DrillJoinRelBase implements DrillRel {
+
/** Creates a DrillJoinRel. */
public DrillJoinRel(RelOptCluster cluster, RelTraitSet traits, RelNode left, RelNode right, RexNode condition,
JoinRelType joinType) throws InvalidRelException {
super(cluster, traits, left, right, condition, joinType);
RexNode remaining = RelOptUtil.splitJoinCondition(left, right, condition, leftKeys, rightKeys);
- if (!remaining.isAlwaysTrue()) {
+ if (!remaining.isAlwaysTrue() && (leftKeys.size() == 0 || rightKeys.size() == 0)) {
throw new InvalidRelException("DrillJoinRel only supports equi-join");
}
}
+
+ public DrillJoinRel(RelOptCluster cluster, RelTraitSet traits, RelNode left, RelNode right, RexNode condition,
+ JoinRelType joinType, List<Integer> leftKeys, List<Integer> rightKeys, boolean checkCartesian) throws InvalidRelException {
+ super(cluster, traits, left, right, condition, joinType);
+
+ assert (leftKeys != null && rightKeys != null);
+
+ if (checkCartesian) {
+ List<Integer> tmpLeftKeys = Lists.newArrayList();
+ List<Integer> tmpRightKeys = Lists.newArrayList();
+ RexNode remaining = RelOptUtil.splitJoinCondition(left, right, condition, tmpLeftKeys, tmpRightKeys);
+ if (!remaining.isAlwaysTrue() && (tmpLeftKeys.size() == 0 || tmpRightKeys.size() == 0)) {
+ throw new InvalidRelException("DrillJoinRel only supports equi-join");
+ }
+ }
+ this.leftKeys = leftKeys;
+ this.rightKeys = rightKeys;
+ }
@Override
public DrillJoinRel copy(RelTraitSet traitSet, RexNode condition, RelNode left, RelNode right, JoinRelType joinType) {
@@ -141,7 +162,9 @@ public class DrillJoinRel extends DrillJoinRelBase implements DrillRel {
);
}
RexNode rexCondition = RexUtil.composeConjunction(context.getRexBuilder(), joinConditions, false);
- return new DrillJoinRel(context.getCluster(), context.getLogicalTraits(), left, right, rexCondition, join.getJoinType());
+ DrillJoinRel joinRel = new DrillJoinRel(context.getCluster(), context.getLogicalTraits(), left, right, rexCondition, join.getJoinType());
+
+ return joinRel;
}
}
http://git-wip-us.apache.org/repos/asf/incubator-drill/blob/63287658/exec/java-exec/src/main/java/org/apache/drill/exec/planner/logical/DrillJoinRule.java
----------------------------------------------------------------------
diff --git a/exec/java-exec/src/main/java/org/apache/drill/exec/planner/logical/DrillJoinRule.java b/exec/java-exec/src/main/java/org/apache/drill/exec/planner/logical/DrillJoinRule.java
index 2a895a5..60c4ae0 100644
--- a/exec/java-exec/src/main/java/org/apache/drill/exec/planner/logical/DrillJoinRule.java
+++ b/exec/java-exec/src/main/java/org/apache/drill/exec/planner/logical/DrillJoinRule.java
@@ -21,8 +21,17 @@ import org.eigenbase.rel.InvalidRelException;
import org.eigenbase.rel.JoinRel;
import org.eigenbase.rel.RelNode;
import org.eigenbase.relopt.*;
+import org.eigenbase.reltype.RelDataTypeField;
+import org.eigenbase.rex.RexBuilder;
+import org.eigenbase.rex.RexNode;
+import org.eigenbase.rex.RexUtil;
+import org.eigenbase.sql.fun.SqlStdOperatorTable;
import org.eigenbase.trace.EigenbaseTrace;
+import com.beust.jcommander.internal.Lists;
+
+import java.util.ArrayList;
+import java.util.List;
import java.util.logging.Logger;
/**
@@ -47,9 +56,59 @@ public class DrillJoinRule extends RelOptRule {
final RelNode convertedLeft = convert(left, traits);
final RelNode convertedRight = convert(right, traits);
+
+ List<Integer> leftKeys = Lists.newArrayList();
+ List<Integer> rightKeys = Lists.newArrayList();
+ int numLeftFields = convertedLeft.getRowType().getFieldCount();
+
+ boolean addFilter = false;
+ RexNode origJoinCondition = join.getCondition();
+ RexNode newJoinCondition = origJoinCondition;
+
+ RexNode remaining = RelOptUtil.splitJoinCondition(convertedLeft, convertedRight, origJoinCondition, leftKeys, rightKeys);
+ boolean hasEquijoins = (leftKeys.size() == rightKeys.size() && leftKeys.size() > 0) ? true : false;
+
+ // If the join involves equijoins and non-equijoins, then we can process the non-equijoins through
+ // a filter right after the join
+ if (! remaining.isAlwaysTrue()) {
+ if (hasEquijoins) {
+ addFilter = true;
+ List<RexNode> equijoinList = Lists.newArrayList();
+ List<RelDataTypeField> leftTypes = convertedLeft.getRowType().getFieldList();
+ List<RelDataTypeField> rightTypes = convertedRight.getRowType().getFieldList();
+ RexBuilder builder = join.getCluster().getRexBuilder();
+
+ for (int i=0; i < leftKeys.size(); i++) {
+ int leftKeyOrdinal = leftKeys.get(i).intValue();
+ int rightKeyOrdinal = rightKeys.get(i).intValue();
+
+ equijoinList.add(builder.makeCall(
+ SqlStdOperatorTable.EQUALS,
+ builder.makeInputRef(leftTypes.get(leftKeyOrdinal).getType(), leftKeyOrdinal),
+ builder.makeInputRef(rightTypes.get(rightKeyOrdinal).getType(), rightKeyOrdinal + numLeftFields)
+ ) );
+ }
+ newJoinCondition = RexUtil.composeConjunction(builder, equijoinList, false);
+ } else {
+ tracer.warning("Non-equijoins are only supported in the presence of an equijoin.");
+ return;
+ }
+ }
+ //else {
+ //
+ // return;
+ // }
+
try {
- call.transformTo(new DrillJoinRel(join.getCluster(), traits, convertedLeft, convertedRight, join.getCondition(),
- join.getJoinType()));
+ if (!addFilter) {
+ RelNode joinRel = new DrillJoinRel(join.getCluster(), traits, convertedLeft, convertedRight, origJoinCondition,
+ join.getJoinType(), leftKeys, rightKeys, false);
+ call.transformTo(joinRel);
+ } else {
+ RelNode joinRel = new DrillJoinRel(join.getCluster(), traits, convertedLeft, convertedRight, newJoinCondition,
+ join.getJoinType(), leftKeys, rightKeys, false);
+ call.transformTo(new DrillFilterRel(join.getCluster(), traits, joinRel, remaining));
+ }
} catch (InvalidRelException e) {
tracer.warning(e.toString());
}
http://git-wip-us.apache.org/repos/asf/incubator-drill/blob/63287658/exec/java-exec/src/main/java/org/apache/drill/exec/planner/logical/DrillRuleSets.java
----------------------------------------------------------------------
diff --git a/exec/java-exec/src/main/java/org/apache/drill/exec/planner/logical/DrillRuleSets.java b/exec/java-exec/src/main/java/org/apache/drill/exec/planner/logical/DrillRuleSets.java
index 2a1d3ff..e249af3 100644
--- a/exec/java-exec/src/main/java/org/apache/drill/exec/planner/logical/DrillRuleSets.java
+++ b/exec/java-exec/src/main/java/org/apache/drill/exec/planner/logical/DrillRuleSets.java
@@ -90,8 +90,8 @@ public class DrillRuleSets {
DrillLimitRule.INSTANCE,
DrillSortRule.INSTANCE,
DrillJoinRule.INSTANCE,
- DrillUnionRule.INSTANCE
-
+ DrillUnionRule.INSTANCE,
+ MergeProjectRule.INSTANCE
));
public static final RuleSet DRILL_PHYSICAL_MEM = new DrillRuleSet(ImmutableSet.of( //
http://git-wip-us.apache.org/repos/asf/incubator-drill/blob/63287658/exec/java-exec/src/main/java/org/apache/drill/exec/planner/physical/MergeJoinPrel.java
----------------------------------------------------------------------
diff --git a/exec/java-exec/src/main/java/org/apache/drill/exec/planner/physical/MergeJoinPrel.java b/exec/java-exec/src/main/java/org/apache/drill/exec/planner/physical/MergeJoinPrel.java
index bfb2192..0ced205 100644
--- a/exec/java-exec/src/main/java/org/apache/drill/exec/planner/physical/MergeJoinPrel.java
+++ b/exec/java-exec/src/main/java/org/apache/drill/exec/planner/physical/MergeJoinPrel.java
@@ -55,7 +55,7 @@ public class MergeJoinPrel extends DrillJoinRelBase implements Prel {
}
RexNode remaining = RelOptUtil.splitJoinCondition(left, right, condition, leftKeys, rightKeys);
- if (!remaining.isAlwaysTrue()) {
+ if (!remaining.isAlwaysTrue() && (leftKeys.size() == 0 || rightKeys.size() == 0)) {
throw new InvalidRelException("MergeJoinPrel only supports equi-join");
}
}