Search in sources :

Example 1 with CommonMergeJoinOperator

use of org.apache.hadoop.hive.ql.exec.CommonMergeJoinOperator in project hive by apache.

the class GenTezWork method process.

@Override
public Object process(Node nd, Stack<Node> stack, NodeProcessorCtx procContext, Object... nodeOutputs) throws SemanticException {
    GenTezProcContext context = (GenTezProcContext) procContext;
    assert context != null && context.currentTask != null && context.currentRootOperator != null;
    // Operator is a file sink or reduce sink. Something that forces
    // a new vertex.
    Operator<?> operator = (Operator<?>) nd;
    // root is the start of the operator pipeline we're currently
    // packing into a vertex, typically a table scan, union or join
    Operator<?> root = context.currentRootOperator;
    LOG.debug("Root operator: " + root);
    LOG.debug("Leaf operator: " + operator);
    if (context.clonedReduceSinks.contains(operator)) {
        // just skip and keep going
        return null;
    }
    TezWork tezWork = context.currentTask.getWork();
    // Right now the work graph is pretty simple. If there is no
    // Preceding work we have a root and will generate a map
    // vertex. If there is a preceding work we will generate
    // a reduce vertex
    BaseWork work;
    if (context.rootToWorkMap.containsKey(root)) {
        // will result into a vertex with multiple FS or RS operators.
        if (context.childToWorkMap.containsKey(operator)) {
            // if we've seen both root and child, we can bail.
            // clear out the mapjoin set. we don't need it anymore.
            context.currentMapJoinOperators.clear();
            // clear out the union set. we don't need it anymore.
            context.currentUnionOperators.clear();
            return null;
        } else {
            // At this point we don't have to do anything special. Just
            // run through the regular paces w/o creating a new task.
            work = context.rootToWorkMap.get(root);
        }
    } else {
        // create a new vertex
        if (context.preceedingWork == null) {
            work = utils.createMapWork(context, root, tezWork, null);
        } else {
            work = GenTezUtils.createReduceWork(context, root, tezWork);
        }
        context.rootToWorkMap.put(root, work);
    }
    // this is where we set the sort columns that we will be using for KeyValueInputMerge
    if (operator instanceof DummyStoreOperator) {
        work.addSortCols(root.getOpTraits().getSortCols().get(0));
    }
    if (!context.childToWorkMap.containsKey(operator)) {
        List<BaseWork> workItems = new LinkedList<BaseWork>();
        workItems.add(work);
        context.childToWorkMap.put(operator, workItems);
    } else {
        context.childToWorkMap.get(operator).add(work);
    }
    // which can affect the working of all downstream transformations.
    if (context.currentMergeJoinOperator != null) {
        // we are currently walking the big table side of the merge join. we need to create or hook up
        // merge join work.
        MergeJoinWork mergeJoinWork = null;
        if (context.opMergeJoinWorkMap.containsKey(context.currentMergeJoinOperator)) {
            // we have found a merge work corresponding to this closing operator. Hook up this work.
            mergeJoinWork = context.opMergeJoinWorkMap.get(context.currentMergeJoinOperator);
        } else {
            // we need to create the merge join work
            mergeJoinWork = new MergeJoinWork();
            mergeJoinWork.setMergeJoinOperator(context.currentMergeJoinOperator);
            tezWork.add(mergeJoinWork);
            context.opMergeJoinWorkMap.put(context.currentMergeJoinOperator, mergeJoinWork);
        }
        // connect the work correctly.
        work.addSortCols(root.getOpTraits().getSortCols().get(0));
        mergeJoinWork.addMergedWork(work, null, context.leafOperatorToFollowingWork);
        Operator<? extends OperatorDesc> parentOp = getParentFromStack(context.currentMergeJoinOperator, stack);
        // Set the big table position. Both the reduce work and merge join operator
        // should be set with the same value.
        //      int pos = context.currentMergeJoinOperator.getTagForOperator(parentOp);
        int pos = context.currentMergeJoinOperator.getConf().getBigTablePosition();
        work.setTag(pos);
        context.currentMergeJoinOperator.getConf().setBigTablePosition(pos);
        tezWork.setVertexType(work, VertexType.MULTI_INPUT_UNINITIALIZED_EDGES);
        for (BaseWork parentWork : tezWork.getParents(work)) {
            TezEdgeProperty edgeProp = tezWork.getEdgeProperty(parentWork, work);
            tezWork.disconnect(parentWork, work);
            tezWork.connect(parentWork, mergeJoinWork, edgeProp);
        }
        for (BaseWork childWork : tezWork.getChildren(work)) {
            TezEdgeProperty edgeProp = tezWork.getEdgeProperty(work, childWork);
            tezWork.disconnect(work, childWork);
            tezWork.connect(mergeJoinWork, childWork, edgeProp);
        }
        tezWork.remove(work);
        context.rootToWorkMap.put(root, mergeJoinWork);
        context.childToWorkMap.get(operator).remove(work);
        context.childToWorkMap.get(operator).add(mergeJoinWork);
        work = mergeJoinWork;
        context.currentMergeJoinOperator = null;
    }
    // remember which mapjoin operator links with which work
    if (!context.currentMapJoinOperators.isEmpty()) {
        for (MapJoinOperator mj : context.currentMapJoinOperators) {
            // so we can later run the same logic that is run in ReduceSinkMapJoinProc.
            if (mj.getConf().isDynamicPartitionHashJoin()) {
                // Since this is a dynamic partitioned hash join, the work for this join should be a ReduceWork
                ReduceWork reduceWork = (ReduceWork) work;
                int bigTablePosition = mj.getConf().getPosBigTable();
                reduceWork.setTag(bigTablePosition);
                // Use context.mapJoinParentMap to get the original RS parents, because
                // the MapJoin's parents may have been replaced by dummy operator.
                List<Operator<?>> mapJoinOriginalParents = context.mapJoinParentMap.get(mj);
                if (mapJoinOriginalParents == null) {
                    throw new SemanticException("Unexpected error - context.mapJoinParentMap did not have an entry for " + mj);
                }
                for (int pos = 0; pos < mapJoinOriginalParents.size(); ++pos) {
                    // This processing only needs to happen for the small tables
                    if (pos == bigTablePosition) {
                        continue;
                    }
                    Operator<?> parentOp = mapJoinOriginalParents.get(pos);
                    context.smallTableParentToMapJoinMap.put(parentOp, mj);
                    ReduceSinkOperator parentRS = (ReduceSinkOperator) parentOp;
                    // TableDesc needed for dynamic partitioned hash join
                    GenMapRedUtils.setKeyAndValueDesc(reduceWork, parentRS);
                    // has its ReduceSink parent removed.
                    if (!context.mapJoinToUnprocessedSmallTableReduceSinks.get(mj).contains(parentRS)) {
                        // This reduce sink has been processed already, so the work for the parentRS exists
                        BaseWork parentWork = ReduceSinkMapJoinProc.getMapJoinParentWork(context, parentRS);
                        int tag = parentRS.getConf().getTag();
                        tag = (tag == -1 ? 0 : tag);
                        reduceWork.getTagToInput().put(tag, parentWork.getName());
                    }
                }
            }
            LOG.debug("Processing map join: " + mj);
            // mapjoin later
            if (!context.mapJoinWorkMap.containsKey(mj)) {
                List<BaseWork> workItems = new LinkedList<BaseWork>();
                workItems.add(work);
                context.mapJoinWorkMap.put(mj, workItems);
            } else {
                context.mapJoinWorkMap.get(mj).add(work);
            }
            /*
         * this happens in case of map join operations.
         * The tree looks like this:
         *
         *        RS <--- we are here perhaps
         *        |
         *     MapJoin
         *     /     \
         *   RS       TS
         *  /
         * TS
         *
         * If we are at the RS pointed above, and we may have already visited the
         * RS following the TS, we have already generated work for the TS-RS.
         * We need to hook the current work to this generated work.
         */
            if (context.linkOpWithWorkMap.containsKey(mj)) {
                Map<BaseWork, TezEdgeProperty> linkWorkMap = context.linkOpWithWorkMap.get(mj);
                if (linkWorkMap != null) {
                    // Note: it's not quite clear why this is done inside this if. Seems like it should be on the top level.
                    if (context.linkChildOpWithDummyOp.containsKey(mj)) {
                        if (LOG.isDebugEnabled()) {
                            LOG.debug("Adding dummy ops to work: " + work.getName() + ": " + context.linkChildOpWithDummyOp.get(mj));
                        }
                        for (Operator<?> dummy : context.linkChildOpWithDummyOp.get(mj)) {
                            work.addDummyOp((HashTableDummyOperator) dummy);
                        }
                    }
                    for (Entry<BaseWork, TezEdgeProperty> parentWorkMap : linkWorkMap.entrySet()) {
                        BaseWork parentWork = parentWorkMap.getKey();
                        LOG.debug("connecting " + parentWork.getName() + " with " + work.getName());
                        TezEdgeProperty edgeProp = parentWorkMap.getValue();
                        tezWork.connect(parentWork, work, edgeProp);
                        if (edgeProp.getEdgeType() == EdgeType.CUSTOM_EDGE) {
                            tezWork.setVertexType(work, VertexType.INITIALIZED_EDGES);
                        }
                        // of the downstream work
                        for (ReduceSinkOperator r : context.linkWorkWithReduceSinkMap.get(parentWork)) {
                            if (r.getConf().getOutputName() != null) {
                                LOG.debug("Cloning reduce sink for multi-child broadcast edge");
                                // we've already set this one up. Need to clone for the next work.
                                r = (ReduceSinkOperator) OperatorFactory.getAndMakeChild(r.getCompilationOpContext(), (ReduceSinkDesc) r.getConf().clone(), new RowSchema(r.getSchema()), r.getParentOperators());
                                context.clonedReduceSinks.add(r);
                            }
                            r.getConf().setOutputName(work.getName());
                            context.connectedReduceSinks.add(r);
                        }
                    }
                }
            }
        }
        // clear out the set. we don't need it anymore.
        context.currentMapJoinOperators.clear();
    }
    // we might have to connect parent work with this work later.
    for (Operator<?> parent : new ArrayList<Operator<?>>(root.getParentOperators())) {
        if (LOG.isDebugEnabled()) {
            LOG.debug("Removing " + parent + " as parent from " + root);
        }
        context.leafOperatorToFollowingWork.remove(parent);
        context.leafOperatorToFollowingWork.put(parent, work);
        root.removeParent(parent);
    }
    if (!context.currentUnionOperators.isEmpty()) {
        // if there are union all operators, it means that the walking context contains union all operators.
        // please see more details of context.currentUnionOperator in GenTezWorkWalker
        UnionWork unionWork;
        if (context.unionWorkMap.containsKey(operator)) {
            // since we've passed this operator before.
            assert operator.getChildOperators().isEmpty();
            unionWork = (UnionWork) context.unionWorkMap.get(operator);
            // finally connect the union work with work
            connectUnionWorkWithWork(unionWork, work, tezWork, context);
        } else {
            // we've not seen this terminal before. we need to check
            // rootUnionWorkMap which contains the information of mapping the root
            // operator of a union work to a union work
            unionWork = context.rootUnionWorkMap.get(root);
            if (unionWork == null) {
                // if unionWork is null, it means it is the first time. we need to
                // create a union work object and add this work to it. Subsequent
                // work should reference the union and not the actual work.
                unionWork = GenTezUtils.createUnionWork(context, root, operator, tezWork);
                // finally connect the union work with work
                connectUnionWorkWithWork(unionWork, work, tezWork, context);
            }
        }
        context.currentUnionOperators.clear();
        work = unionWork;
    }
    // reasons. Roots are data sources, leaves are data sinks. I know.
    if (context.leafOperatorToFollowingWork.containsKey(operator)) {
        BaseWork followingWork = context.leafOperatorToFollowingWork.get(operator);
        long bytesPerReducer = context.conf.getLongVar(HiveConf.ConfVars.BYTESPERREDUCER);
        LOG.debug("Second pass. Leaf operator: " + operator + " has common downstream work:" + followingWork);
        if (operator instanceof DummyStoreOperator) {
            // this is the small table side.
            assert (followingWork instanceof MergeJoinWork);
            MergeJoinWork mergeJoinWork = (MergeJoinWork) followingWork;
            CommonMergeJoinOperator mergeJoinOp = mergeJoinWork.getMergeJoinOperator();
            work.setTag(mergeJoinOp.getTagForOperator(operator));
            mergeJoinWork.addMergedWork(null, work, context.leafOperatorToFollowingWork);
            tezWork.setVertexType(mergeJoinWork, VertexType.MULTI_INPUT_UNINITIALIZED_EDGES);
            for (BaseWork parentWork : tezWork.getParents(work)) {
                TezEdgeProperty edgeProp = tezWork.getEdgeProperty(parentWork, work);
                tezWork.disconnect(parentWork, work);
                tezWork.connect(parentWork, mergeJoinWork, edgeProp);
            }
            work = mergeJoinWork;
        } else {
            // need to add this branch to the key + value info
            assert operator instanceof ReduceSinkOperator && ((followingWork instanceof ReduceWork) || (followingWork instanceof MergeJoinWork) || followingWork instanceof UnionWork);
            ReduceSinkOperator rs = (ReduceSinkOperator) operator;
            ReduceWork rWork = null;
            if (followingWork instanceof MergeJoinWork) {
                MergeJoinWork mergeJoinWork = (MergeJoinWork) followingWork;
                rWork = (ReduceWork) mergeJoinWork.getMainWork();
            } else if (followingWork instanceof UnionWork) {
                // this can only be possible if there is merge work followed by the union
                UnionWork unionWork = (UnionWork) followingWork;
                int index = getFollowingWorkIndex(tezWork, unionWork, rs);
                BaseWork baseWork = tezWork.getChildren(unionWork).get(index);
                if (baseWork instanceof MergeJoinWork) {
                    MergeJoinWork mergeJoinWork = (MergeJoinWork) baseWork;
                    // disconnect the connection to union work and connect to merge work
                    followingWork = mergeJoinWork;
                    rWork = (ReduceWork) mergeJoinWork.getMainWork();
                } else {
                    rWork = (ReduceWork) baseWork;
                }
            } else {
                rWork = (ReduceWork) followingWork;
            }
            GenMapRedUtils.setKeyAndValueDesc(rWork, rs);
            // remember which parent belongs to which tag
            int tag = rs.getConf().getTag();
            rWork.getTagToInput().put(tag == -1 ? 0 : tag, work.getName());
            // remember the output name of the reduce sink
            rs.getConf().setOutputName(rWork.getName());
            // For dynamic partitioned hash join, run the ReduceSinkMapJoinProc logic for any
            // ReduceSink parents that we missed.
            MapJoinOperator mj = context.smallTableParentToMapJoinMap.get(rs);
            if (mj != null) {
                // Only need to run the logic for tables we missed
                if (context.mapJoinToUnprocessedSmallTableReduceSinks.get(mj).contains(rs)) {
                    // ReduceSinkMapJoinProc logic does not work unless the ReduceSink is connected as
                    // a parent of the MapJoin, but at this point we have already removed all of the
                    // parents from the MapJoin.
                    // Try temporarily adding the RS as a parent
                    ArrayList<Operator<?>> tempMJParents = new ArrayList<Operator<?>>();
                    tempMJParents.add(rs);
                    mj.setParentOperators(tempMJParents);
                    // ReduceSink also needs MapJoin as child
                    List<Operator<?>> rsChildren = rs.getChildOperators();
                    rsChildren.add(mj);
                    // Since the MapJoin has had all of its other parents removed at this point,
                    // it would be bad here if processReduceSinkToHashJoin() tries to do anything
                    // with the RS parent based on its position in the list of parents.
                    ReduceSinkMapJoinProc.processReduceSinkToHashJoin(rs, mj, context);
                    // Remove any parents from MapJoin again
                    mj.removeParents();
                // TODO: do we also need to remove the MapJoin from the list of RS's children?
                }
            }
            if (!context.connectedReduceSinks.contains(rs)) {
                // add dependency between the two work items
                TezEdgeProperty edgeProp;
                EdgeType edgeType = GenTezUtils.determineEdgeType(work, followingWork, rs);
                if (rWork.isAutoReduceParallelism()) {
                    edgeProp = new TezEdgeProperty(context.conf, edgeType, true, rWork.getMinReduceTasks(), rWork.getMaxReduceTasks(), bytesPerReducer);
                } else {
                    edgeProp = new TezEdgeProperty(edgeType);
                }
                tezWork.connect(work, followingWork, edgeProp);
                context.connectedReduceSinks.add(rs);
            }
        }
    } else {
        LOG.debug("First pass. Leaf operator: " + operator);
    }
    // the next item will be a new root.
    if (!operator.getChildOperators().isEmpty()) {
        assert operator.getChildOperators().size() == 1;
        context.parentOfRoot = operator;
        context.currentRootOperator = operator.getChildOperators().get(0);
        context.preceedingWork = work;
    }
    return null;
}
Also used : CommonMergeJoinOperator(org.apache.hadoop.hive.ql.exec.CommonMergeJoinOperator) ReduceSinkOperator(org.apache.hadoop.hive.ql.exec.ReduceSinkOperator) MapJoinOperator(org.apache.hadoop.hive.ql.exec.MapJoinOperator) Operator(org.apache.hadoop.hive.ql.exec.Operator) DummyStoreOperator(org.apache.hadoop.hive.ql.exec.DummyStoreOperator) HashTableDummyOperator(org.apache.hadoop.hive.ql.exec.HashTableDummyOperator) TezEdgeProperty(org.apache.hadoop.hive.ql.plan.TezEdgeProperty) ArrayList(java.util.ArrayList) BaseWork(org.apache.hadoop.hive.ql.plan.BaseWork) CommonMergeJoinOperator(org.apache.hadoop.hive.ql.exec.CommonMergeJoinOperator) MapJoinOperator(org.apache.hadoop.hive.ql.exec.MapJoinOperator) MergeJoinWork(org.apache.hadoop.hive.ql.plan.MergeJoinWork) RowSchema(org.apache.hadoop.hive.ql.exec.RowSchema) DummyStoreOperator(org.apache.hadoop.hive.ql.exec.DummyStoreOperator) UnionWork(org.apache.hadoop.hive.ql.plan.UnionWork) ReduceWork(org.apache.hadoop.hive.ql.plan.ReduceWork) EdgeType(org.apache.hadoop.hive.ql.plan.TezEdgeProperty.EdgeType) LinkedList(java.util.LinkedList) ReduceSinkOperator(org.apache.hadoop.hive.ql.exec.ReduceSinkOperator) TezWork(org.apache.hadoop.hive.ql.plan.TezWork)

Example 2 with CommonMergeJoinOperator

use of org.apache.hadoop.hive.ql.exec.CommonMergeJoinOperator in project hive by apache.

the class CrossProductCheck method checkMRReducer.

private void checkMRReducer(String taskName, MapredWork mrWrk) throws SemanticException {
    ReduceWork rWrk = mrWrk.getReduceWork();
    if (rWrk == null) {
        return;
    }
    Operator<? extends OperatorDesc> reducer = rWrk.getReducer();
    if (reducer instanceof JoinOperator || reducer instanceof CommonMergeJoinOperator) {
        BaseWork prntWork = mrWrk.getMapWork();
        checkForCrossProduct(taskName, reducer, new ExtractReduceSinkInfo(null).analyze(prntWork));
    }
}
Also used : CommonMergeJoinOperator(org.apache.hadoop.hive.ql.exec.CommonMergeJoinOperator) MapJoinOperator(org.apache.hadoop.hive.ql.exec.MapJoinOperator) AbstractMapJoinOperator(org.apache.hadoop.hive.ql.exec.AbstractMapJoinOperator) JoinOperator(org.apache.hadoop.hive.ql.exec.JoinOperator) ReduceWork(org.apache.hadoop.hive.ql.plan.ReduceWork) BaseWork(org.apache.hadoop.hive.ql.plan.BaseWork) CommonMergeJoinOperator(org.apache.hadoop.hive.ql.exec.CommonMergeJoinOperator)

Example 3 with CommonMergeJoinOperator

use of org.apache.hadoop.hive.ql.exec.CommonMergeJoinOperator in project hive by apache.

the class CrossProductCheck method checkTezReducer.

private void checkTezReducer(TezWork tzWrk) throws SemanticException {
    for (BaseWork wrk : tzWrk.getAllWork()) {
        if (wrk instanceof MergeJoinWork) {
            wrk = ((MergeJoinWork) wrk).getMainWork();
        }
        if (!(wrk instanceof ReduceWork)) {
            continue;
        }
        ReduceWork rWork = (ReduceWork) wrk;
        Operator<? extends OperatorDesc> reducer = ((ReduceWork) wrk).getReducer();
        if (reducer instanceof JoinOperator || reducer instanceof CommonMergeJoinOperator) {
            Map<Integer, ExtractReduceSinkInfo.Info> rsInfo = new HashMap<Integer, ExtractReduceSinkInfo.Info>();
            for (Map.Entry<Integer, String> e : rWork.getTagToInput().entrySet()) {
                rsInfo.putAll(getReducerInfo(tzWrk, rWork.getName(), e.getValue()));
            }
            checkForCrossProduct(rWork.getName(), reducer, rsInfo);
        }
    }
}
Also used : CommonMergeJoinOperator(org.apache.hadoop.hive.ql.exec.CommonMergeJoinOperator) MapJoinOperator(org.apache.hadoop.hive.ql.exec.MapJoinOperator) AbstractMapJoinOperator(org.apache.hadoop.hive.ql.exec.AbstractMapJoinOperator) JoinOperator(org.apache.hadoop.hive.ql.exec.JoinOperator) MergeJoinWork(org.apache.hadoop.hive.ql.plan.MergeJoinWork) HashMap(java.util.HashMap) LinkedHashMap(java.util.LinkedHashMap) ReduceWork(org.apache.hadoop.hive.ql.plan.ReduceWork) BaseWork(org.apache.hadoop.hive.ql.plan.BaseWork) HashMap(java.util.HashMap) LinkedHashMap(java.util.LinkedHashMap) Map(java.util.Map) CommonMergeJoinOperator(org.apache.hadoop.hive.ql.exec.CommonMergeJoinOperator)

Example 4 with CommonMergeJoinOperator

use of org.apache.hadoop.hive.ql.exec.CommonMergeJoinOperator in project hive by apache.

the class ConvertJoinMapJoin method convertJoinSMBJoin.

// replaces the join operator with a new CommonJoinOperator, removes the
// parent reduce sinks
private void convertJoinSMBJoin(JoinOperator joinOp, OptimizeTezProcContext context, int mapJoinConversionPos, int numBuckets, boolean adjustParentsChildren) throws SemanticException {
    MapJoinDesc mapJoinDesc = null;
    if (adjustParentsChildren) {
        mapJoinDesc = MapJoinProcessor.getMapJoinDesc(context.conf, joinOp, joinOp.getConf().isLeftInputJoin(), joinOp.getConf().getBaseSrc(), joinOp.getConf().getMapAliases(), mapJoinConversionPos, true);
    } else {
        JoinDesc joinDesc = joinOp.getConf();
        // retain the original join desc in the map join.
        mapJoinDesc = new MapJoinDesc(MapJoinProcessor.getKeys(joinOp.getConf().isLeftInputJoin(), joinOp.getConf().getBaseSrc(), joinOp).getSecond(), null, joinDesc.getExprs(), null, null, joinDesc.getOutputColumnNames(), mapJoinConversionPos, joinDesc.getConds(), joinDesc.getFilters(), joinDesc.getNoOuterJoin(), null);
        mapJoinDesc.setNullSafes(joinDesc.getNullSafes());
        mapJoinDesc.setFilterMap(joinDesc.getFilterMap());
        mapJoinDesc.setResidualFilterExprs(joinDesc.getResidualFilterExprs());
        mapJoinDesc.resetOrder();
    }
    CommonMergeJoinOperator mergeJoinOp = (CommonMergeJoinOperator) OperatorFactory.get(joinOp.getCompilationOpContext(), new CommonMergeJoinDesc(numBuckets, mapJoinConversionPos, mapJoinDesc), joinOp.getSchema());
    int numReduceSinks = joinOp.getOpTraits().getNumReduceSinks();
    OpTraits opTraits = new OpTraits(joinOp.getOpTraits().getBucketColNames(), numBuckets, joinOp.getOpTraits().getSortCols(), numReduceSinks);
    mergeJoinOp.setOpTraits(opTraits);
    mergeJoinOp.setStatistics(joinOp.getStatistics());
    for (Operator<? extends OperatorDesc> parentOp : joinOp.getParentOperators()) {
        int pos = parentOp.getChildOperators().indexOf(joinOp);
        parentOp.getChildOperators().remove(pos);
        parentOp.getChildOperators().add(pos, mergeJoinOp);
    }
    for (Operator<? extends OperatorDesc> childOp : joinOp.getChildOperators()) {
        int pos = childOp.getParentOperators().indexOf(joinOp);
        childOp.getParentOperators().remove(pos);
        childOp.getParentOperators().add(pos, mergeJoinOp);
    }
    List<Operator<? extends OperatorDesc>> childOperators = mergeJoinOp.getChildOperators();
    List<Operator<? extends OperatorDesc>> parentOperators = mergeJoinOp.getParentOperators();
    childOperators.clear();
    parentOperators.clear();
    childOperators.addAll(joinOp.getChildOperators());
    parentOperators.addAll(joinOp.getParentOperators());
    mergeJoinOp.getConf().setGenJoinKeys(false);
    if (adjustParentsChildren) {
        mergeJoinOp.getConf().setGenJoinKeys(true);
        List<Operator<? extends OperatorDesc>> newParentOpList = new ArrayList<Operator<? extends OperatorDesc>>();
        for (Operator<? extends OperatorDesc> parentOp : mergeJoinOp.getParentOperators()) {
            for (Operator<? extends OperatorDesc> grandParentOp : parentOp.getParentOperators()) {
                grandParentOp.getChildOperators().remove(parentOp);
                grandParentOp.getChildOperators().add(mergeJoinOp);
                newParentOpList.add(grandParentOp);
            }
        }
        mergeJoinOp.getParentOperators().clear();
        mergeJoinOp.getParentOperators().addAll(newParentOpList);
        List<Operator<? extends OperatorDesc>> parentOps = new ArrayList<Operator<? extends OperatorDesc>>(mergeJoinOp.getParentOperators());
        for (Operator<? extends OperatorDesc> parentOp : parentOps) {
            int parentIndex = mergeJoinOp.getParentOperators().indexOf(parentOp);
            if (parentIndex == mapJoinConversionPos) {
                continue;
            }
            // insert the dummy store operator here
            DummyStoreOperator dummyStoreOp = new TezDummyStoreOperator(mergeJoinOp.getCompilationOpContext());
            dummyStoreOp.setParentOperators(new ArrayList<Operator<? extends OperatorDesc>>());
            dummyStoreOp.setChildOperators(new ArrayList<Operator<? extends OperatorDesc>>());
            dummyStoreOp.getChildOperators().add(mergeJoinOp);
            int index = parentOp.getChildOperators().indexOf(mergeJoinOp);
            parentOp.getChildOperators().remove(index);
            parentOp.getChildOperators().add(index, dummyStoreOp);
            dummyStoreOp.getParentOperators().add(parentOp);
            mergeJoinOp.getParentOperators().remove(parentIndex);
            mergeJoinOp.getParentOperators().add(parentIndex, dummyStoreOp);
        }
    }
    mergeJoinOp.cloneOriginalParentsList(mergeJoinOp.getParentOperators());
}
Also used : CommonMergeJoinOperator(org.apache.hadoop.hive.ql.exec.CommonMergeJoinOperator) MuxOperator(org.apache.hadoop.hive.ql.exec.MuxOperator) ReduceSinkOperator(org.apache.hadoop.hive.ql.exec.ReduceSinkOperator) CommonJoinOperator(org.apache.hadoop.hive.ql.exec.CommonJoinOperator) MapJoinOperator(org.apache.hadoop.hive.ql.exec.MapJoinOperator) GroupByOperator(org.apache.hadoop.hive.ql.exec.GroupByOperator) FileSinkOperator(org.apache.hadoop.hive.ql.exec.FileSinkOperator) TezDummyStoreOperator(org.apache.hadoop.hive.ql.exec.TezDummyStoreOperator) AppMasterEventOperator(org.apache.hadoop.hive.ql.exec.AppMasterEventOperator) JoinOperator(org.apache.hadoop.hive.ql.exec.JoinOperator) TableScanOperator(org.apache.hadoop.hive.ql.exec.TableScanOperator) Operator(org.apache.hadoop.hive.ql.exec.Operator) DummyStoreOperator(org.apache.hadoop.hive.ql.exec.DummyStoreOperator) SelectOperator(org.apache.hadoop.hive.ql.exec.SelectOperator) MapJoinDesc(org.apache.hadoop.hive.ql.plan.MapJoinDesc) OpTraits(org.apache.hadoop.hive.ql.plan.OpTraits) TezDummyStoreOperator(org.apache.hadoop.hive.ql.exec.TezDummyStoreOperator) DummyStoreOperator(org.apache.hadoop.hive.ql.exec.DummyStoreOperator) CommonMergeJoinDesc(org.apache.hadoop.hive.ql.plan.CommonMergeJoinDesc) ArrayList(java.util.ArrayList) TezDummyStoreOperator(org.apache.hadoop.hive.ql.exec.TezDummyStoreOperator) CommonMergeJoinDesc(org.apache.hadoop.hive.ql.plan.CommonMergeJoinDesc) MapJoinDesc(org.apache.hadoop.hive.ql.plan.MapJoinDesc) JoinDesc(org.apache.hadoop.hive.ql.plan.JoinDesc) OperatorDesc(org.apache.hadoop.hive.ql.plan.OperatorDesc) CommonMergeJoinOperator(org.apache.hadoop.hive.ql.exec.CommonMergeJoinOperator)

Example 5 with CommonMergeJoinOperator

use of org.apache.hadoop.hive.ql.exec.CommonMergeJoinOperator in project hive by apache.

the class MergeJoinProc method process.

@Override
public Object process(Node nd, Stack<Node> stack, NodeProcessorCtx procCtx, Object... nodeOutputs) throws SemanticException {
    GenTezProcContext context = (GenTezProcContext) procCtx;
    CommonMergeJoinOperator mergeJoinOp = (CommonMergeJoinOperator) nd;
    if (stack.size() < 2 || !(stack.get(stack.size() - 2) instanceof DummyStoreOperator)) {
        context.currentMergeJoinOperator = mergeJoinOp;
        return null;
    }
    TezWork tezWork = context.currentTask.getWork();
    @SuppressWarnings("unchecked") Operator<? extends OperatorDesc> parentOp = (Operator<? extends OperatorDesc>) ((stack.get(stack.size() - 2)));
    // Guaranteed to be just 1 because each DummyStoreOperator can be part of only one work.
    BaseWork parentWork = context.childToWorkMap.get(parentOp).get(0);
    // we need to set the merge work that has been created as part of the dummy store walk. If a
    // merge work already exists for this merge join operator, add the dummy store work to the
    // merge work. Else create a merge work, add above work to the merge work
    MergeJoinWork mergeWork = null;
    if (context.opMergeJoinWorkMap.containsKey(mergeJoinOp)) {
        // we already have the merge work corresponding to this merge join operator
        mergeWork = context.opMergeJoinWorkMap.get(mergeJoinOp);
    } else {
        mergeWork = new MergeJoinWork();
        tezWork.add(mergeWork);
        context.opMergeJoinWorkMap.put(mergeJoinOp, mergeWork);
    }
    mergeWork.addMergedWork(null, parentWork, context.leafOperatorToFollowingWork);
    mergeWork.setMergeJoinOperator(mergeJoinOp);
    tezWork.setVertexType(mergeWork, VertexType.MULTI_INPUT_UNINITIALIZED_EDGES);
    for (BaseWork grandParentWork : tezWork.getParents(parentWork)) {
        TezEdgeProperty edgeProp = tezWork.getEdgeProperty(grandParentWork, parentWork);
        tezWork.disconnect(grandParentWork, parentWork);
        tezWork.connect(grandParentWork, mergeWork, edgeProp);
    }
    for (BaseWork childWork : tezWork.getChildren(parentWork)) {
        TezEdgeProperty edgeProp = tezWork.getEdgeProperty(parentWork, childWork);
        tezWork.disconnect(parentWork, childWork);
        tezWork.connect(mergeWork, childWork, edgeProp);
    }
    tezWork.remove(parentWork);
    DummyStoreOperator dummyOp = (DummyStoreOperator) (stack.get(stack.size() - 2));
    parentWork.setTag(mergeJoinOp.getTagForOperator(dummyOp));
    mergeJoinOp.getParentOperators().remove(dummyOp);
    dummyOp.getChildOperators().clear();
    return true;
}
Also used : CommonMergeJoinOperator(org.apache.hadoop.hive.ql.exec.CommonMergeJoinOperator) ReduceSinkOperator(org.apache.hadoop.hive.ql.exec.ReduceSinkOperator) FileSinkOperator(org.apache.hadoop.hive.ql.exec.FileSinkOperator) Operator(org.apache.hadoop.hive.ql.exec.Operator) DummyStoreOperator(org.apache.hadoop.hive.ql.exec.DummyStoreOperator) MergeJoinWork(org.apache.hadoop.hive.ql.plan.MergeJoinWork) DummyStoreOperator(org.apache.hadoop.hive.ql.exec.DummyStoreOperator) TezEdgeProperty(org.apache.hadoop.hive.ql.plan.TezEdgeProperty) GenTezProcContext(org.apache.hadoop.hive.ql.parse.GenTezProcContext) OperatorDesc(org.apache.hadoop.hive.ql.plan.OperatorDesc) BaseWork(org.apache.hadoop.hive.ql.plan.BaseWork) CommonMergeJoinOperator(org.apache.hadoop.hive.ql.exec.CommonMergeJoinOperator) TezWork(org.apache.hadoop.hive.ql.plan.TezWork)

Aggregations

CommonMergeJoinOperator (org.apache.hadoop.hive.ql.exec.CommonMergeJoinOperator)6 BaseWork (org.apache.hadoop.hive.ql.plan.BaseWork)5 JoinOperator (org.apache.hadoop.hive.ql.exec.JoinOperator)4 MapJoinOperator (org.apache.hadoop.hive.ql.exec.MapJoinOperator)4 ReduceWork (org.apache.hadoop.hive.ql.plan.ReduceWork)4 DummyStoreOperator (org.apache.hadoop.hive.ql.exec.DummyStoreOperator)3 Operator (org.apache.hadoop.hive.ql.exec.Operator)3 ReduceSinkOperator (org.apache.hadoop.hive.ql.exec.ReduceSinkOperator)3 MergeJoinWork (org.apache.hadoop.hive.ql.plan.MergeJoinWork)3 ArrayList (java.util.ArrayList)2 HashMap (java.util.HashMap)2 AbstractMapJoinOperator (org.apache.hadoop.hive.ql.exec.AbstractMapJoinOperator)2 FileSinkOperator (org.apache.hadoop.hive.ql.exec.FileSinkOperator)2 OperatorDesc (org.apache.hadoop.hive.ql.plan.OperatorDesc)2 TezEdgeProperty (org.apache.hadoop.hive.ql.plan.TezEdgeProperty)2 TezWork (org.apache.hadoop.hive.ql.plan.TezWork)2 LinkedHashMap (java.util.LinkedHashMap)1 LinkedList (java.util.LinkedList)1 Map (java.util.Map)1 AppMasterEventOperator (org.apache.hadoop.hive.ql.exec.AppMasterEventOperator)1