private Operator genNotNullFilterForJoinSourcePlan(QB qb, Operator input,
                                                     QBJoinTree joinTree, ExprNodeDesc[] joinKeys, boolean OuternotInCheck) throws SemanticException {

    /*
     * The notInCheck param is used for the purpose of adding an
     *  (outerQueryTable.outerQueryCol is not null ) predicate to the join,
     *  since it is not added naturally because of outer join
     */

    if (qb == null || joinTree == null) {
      return input;
    }

    if (!joinTree.getNoOuterJoin() && !OuternotInCheck) {
      return input;
    }

    if (joinKeys == null || joinKeys.length == 0) {
      return input;
    }
    Multimap<Integer, ExprNodeColumnDesc> hashes = ArrayListMultimap.create();
    if (input instanceof FilterOperator) {
      ExprNodeDescUtils.getExprNodeColumnDesc(Arrays.asList(((FilterDesc)input.getConf()).getPredicate()), hashes);
    }
    ExprNodeDesc filterPred = null;
    List<Boolean> nullSafes = joinTree.getNullSafes();
    for (int i = 0; i < joinKeys.length; i++) {
      if (nullSafes.get(i) || (joinKeys[i] instanceof ExprNodeColumnDesc &&
          ((ExprNodeColumnDesc)joinKeys[i]).getIsPartitionColOrVirtualCol())) {
        // no need to generate is not null predicate for partitioning or
        // virtual column, since those columns can never be null.
        continue;
      }
      boolean skip = false;
      for (ExprNodeColumnDesc node : hashes.get(joinKeys[i].hashCode())) {
        if (node.isSame(joinKeys[i])) {
          skip = true;
          break;
        }
      }
      if (skip) {
        // there is already a predicate on this src.
        continue;
      }
      List<ExprNodeDesc> args = new ArrayList<ExprNodeDesc>();
      args.add(joinKeys[i]);
      ExprNodeDesc nextExpr = ExprNodeGenericFuncDesc.newInstance(
          FunctionRegistry.getFunctionInfo("isnotnull").getGenericUDF(), args);
      filterPred = filterPred == null ? nextExpr : ExprNodeDescUtils
          .mergePredicates(filterPred, nextExpr);
    }

    if (filterPred == null) {
      return input;
    }

    OpParseContext inputCtx = opParseCtx.get(input);
    RowResolver inputRR = inputCtx.getRowResolver();

    if (input instanceof FilterOperator) {
      FilterOperator f = (FilterOperator) input;
      List<ExprNodeDesc> preds = new ArrayList<ExprNodeDesc>();
      preds.add(f.getConf().getPredicate());
      preds.add(filterPred);
      f.getConf().setPredicate(ExprNodeDescUtils.mergePredicates(preds));

      return input;
    }

    FilterDesc filterDesc = new FilterDesc(filterPred, false);
    filterDesc.setGenerated(true);
    Operator output = putOpInsertMap(OperatorFactory.getAndMakeChild(filterDesc,
        new RowSchema(inputRR.getColumnInfos()), input), inputRR);

    LOG.debug("Created Filter Plan for {} row schema: {}", qb.getId(), inputRR);
    return output;
  }
create a filter plan. The condition and the inputs are specified.

@param qb
         current query block
@param condn
         The condition to be resolved
@param input
         the input operator
ql/src/java/org/apache/hadoop/hive/ql/parse/SemanticAnalyzer.java