diff --git a/ql/src/java/org/apache/hadoop/hive/ql/optimizer/ConvertJoinMapJoin.java b/ql/src/java/org/apache/hadoop/hive/ql/optimizer/ConvertJoinMapJoin.java index 0f9e86b..d334664 100644 --- a/ql/src/java/org/apache/hadoop/hive/ql/optimizer/ConvertJoinMapJoin.java +++ b/ql/src/java/org/apache/hadoop/hive/ql/optimizer/ConvertJoinMapJoin.java @@ -780,9 +780,8 @@ public MapJoinOperator convertJoinMapJoin(JoinOperator joinOp, OptimizeTezProcCo private void removeCycleCreatingSemiJoinOps(MapJoinOperator mapjoinOp, Operator parentSelectOpOfBigTable, ParseContext parseContext) throws SemanticException { - boolean semiJoinCycle = false; - ReduceSinkOperator rs = null; - TableScanOperator ts = null; + Map semiJoinMap = + new HashMap(); for (Operator op : parentSelectOpOfBigTable.getChildOperators()) { if (!(op instanceof SelectOperator)) { continue; @@ -793,8 +792,8 @@ private void removeCycleCreatingSemiJoinOps(MapJoinOperator mapjoinOp, if (!(op instanceof ReduceSinkOperator)) { continue; } - rs = (ReduceSinkOperator) op; - ts = parseContext.getRsOpToTsOpMap().get(rs); + ReduceSinkOperator rs = (ReduceSinkOperator) op; + TableScanOperator ts = parseContext.getRsOpToTsOpMap().get(rs); if (ts == null) { continue; } @@ -808,18 +807,23 @@ private void removeCycleCreatingSemiJoinOps(MapJoinOperator mapjoinOp, for (TableScanOperator parentTS : tsOps) { // If the parent is same as the ts, then we have a cycle. if (ts == parentTS) { - semiJoinCycle = true; + semiJoinMap.put(rs, ts); break; } } } } } - - // By design there can be atmost 1 such cycle. - if (semiJoinCycle) { - GenTezUtils.removeBranch(rs); - GenTezUtils.removeSemiJoinOperator(parseContext, rs, ts); + if (semiJoinMap.size() > 0) { + Set rsOps = OperatorUtils.findOperatorsUpstream( + parentSelectOpOfBigTable, ReduceSinkOperator.class); + if (rsOps.size() > 0) { + for (ReduceSinkOperator rs : semiJoinMap.keySet()) { + GenTezUtils.removeBranch(rs); + GenTezUtils.removeSemiJoinOperator(parseContext, rs, + semiJoinMap.get(rs)); + } + } } } diff --git a/ql/src/java/org/apache/hadoop/hive/ql/parse/GenTezUtils.java b/ql/src/java/org/apache/hadoop/hive/ql/parse/GenTezUtils.java index aee74ad..fe2dea5 100644 --- a/ql/src/java/org/apache/hadoop/hive/ql/parse/GenTezUtils.java +++ b/ql/src/java/org/apache/hadoop/hive/ql/parse/GenTezUtils.java @@ -569,7 +569,8 @@ public static void removeSemiJoinOperator(ParseContext context, TypeInfoFactory.booleanTypeInfo, Boolean.TRUE); DynamicValuePredicateContext filterDynamicValuePredicatesCollection = new DynamicValuePredicateContext(); - collectDynamicValuePredicates(((FilterOperator)(ts.getChildOperators().get(0))).getConf().getPredicate(), + FilterDesc filterDesc = ((FilterOperator)(ts.getChildOperators().get(0))).getConf(); + collectDynamicValuePredicates(filterDesc.getPredicate(), filterDynamicValuePredicatesCollection); for (ExprNodeDesc nodeToRemove : filterDynamicValuePredicatesCollection .childParentMapping.keySet()) { @@ -594,8 +595,8 @@ public static void removeSemiJoinOperator(ParseContext context, ExprNodeDesc nodeParent = filterDynamicValuePredicatesCollection .childParentMapping.get(nodeToRemove); if (nodeParent == null) { - // This was the only predicate, set filter expression to null - ts.getConf().setFilterExpr(null); + // This was the only predicate, set filter expression to const + filterDesc.setPredicate(constNode); } else { int i = nodeParent.getChildren().indexOf(nodeToRemove); nodeParent.getChildren().remove(i);