@SuppressWarnings("unchecked")
    @Override
    public Object process(Node nd, Stack<Node> stack, NodeProcessorCtx procCtx,
        Object... nodeOutputs) throws SemanticException {
      // Assert that there is at least one item in the stack. This should never
      // be called for leafs.
      assert(!stack.isEmpty());

      // LineageCtx
      LineageCtx lCtx = (LineageCtx) procCtx;
      Operator<? extends OperatorDesc> op = (Operator<? extends OperatorDesc>)nd;

      // Get the row schema of the input operator.
      // The row schema of the parent operator
      Operator<? extends OperatorDesc> inpOp = getParent(stack);
      lCtx.getIndex().copyPredicates(inpOp, op);
      RowSchema rs = op.getSchema();
      List<ColumnInfo> inp_cols = inpOp.getSchema().getSignature();

      // check only for input cols
      for(ColumnInfo input : inp_cols) {
        Dependency inp_dep = lCtx.getIndex().getDependency(inpOp, input);
        if (inp_dep != null) {
          //merge it with rs colInfo
          ColumnInfo ci = rs.getColumnInfo(input.getInternalName());
          lCtx.getIndex().mergeDependency(op, ci, inp_dep);
        }
      }
      return null;
    }
Union processor.
In this case we call mergeDependency as opposed to putDependency
in order to account for visits from different parents.
ql/src/java/org/apache/hadoop/hive/ql/optimizer/lineage/OpProcFactory.java