static private ExprNodeDesc removeNonPartCols(ExprNodeDesc expr, List<String> partCols,
      Set<String> referred) {
    if (expr instanceof ExprNodeFieldDesc) {
      // Column is not a partition column for the table,
      // as we do not allow partitions based on complex
      // list or struct fields.
      return new ExprNodeConstantDesc(expr.getTypeInfo(), null);
    }
    else if (expr instanceof ExprNodeColumnDesc) {
      String column = ((ExprNodeColumnDesc) expr).getColumn();
      if (!partCols.contains(column)) {
        // Column doesn't appear to be a partition column for the table.
        return new ExprNodeConstantDesc(expr.getTypeInfo(), null);
      }
      referred.add(column);
    }
    else if (expr instanceof ExprNodeGenericFuncDesc) {
      List<ExprNodeDesc> children = expr.getChildren();
      for (int i = 0; i < children.size(); ++i) {
        ExprNodeDesc other = removeNonPartCols(children.get(i), partCols, referred);
        if (ExprNodeDescUtils.isNullConstant(other)) {
          if (FunctionRegistry.isOpAnd(expr)) {
            // partcol=... AND nonpartcol=...   is replaced with partcol=... AND TRUE
            // which will be folded to partcol=...
            // This cannot be done also for OR
            Preconditions.checkArgument(expr.getTypeInfo().accept(TypeInfoFactory.booleanTypeInfo));
            other = new ExprNodeConstantDesc(expr.getTypeInfo(), true);
          } else {
            // Functions like NVL, COALESCE, CASE can change a
            // NULL introduced by a nonpart column removal into a non-null
            // and cause overaggressive prunning, missing data (incorrect result)
            return new ExprNodeConstantDesc(expr.getTypeInfo(), null);
          }
        }
        children.set(i, other);
      }
    }
    return expr;
  }
See compactExpr. Some things in the expr are replaced with nulls for pruner, however
the virtual columns are not removed (ExprNodeColumnDesc cannot tell them apart from
partition columns), so we do it here.
The expression is only used to prune by partition name, so we have no business with VCs.
@param expr original partition pruning expression.
@param partCols list of partition columns for the table.
@param referred partition columns referred by expr
@return partition pruning expression that only contains partition columns from the list.
ql/src/java/org/apache/hadoop/hive/ql/optimizer/ppr/PartitionPruner.java