private void pushJoinFilters(QB qb, QBJoinTree joinTree,
                               Map<String, Operator> map,
                               boolean recursively) throws SemanticException {
    if ( recursively ) {
      if (joinTree.getJoinSrc() != null) {
        pushJoinFilters(qb, joinTree.getJoinSrc(), map);
      }
    }
    List<List<ASTNode>> filters = joinTree.getFiltersForPushing();
    int pos = 0;
    for (String src : joinTree.getBaseSrc()) {
      if (src != null) {
        Operator srcOp = map.get(src);
        List<ASTNode> filter = filters.get(pos);
        for (ASTNode cond : filter) {
          srcOp = genFilterPlan(qb, cond, srcOp, false);
        }
        map.put(src, srcOp);
      }
      pos++;
    }
  }
Extract the filters from the join condition and push them on top of the
source operators. This procedure traverses the query tree recursively,
ql/src/java/org/apache/hadoop/hive/ql/parse/SemanticAnalyzer.java