private static ExprNodeDesc foldNegative(ExprNodeDesc desc) throws UDFArgumentException {
    if (desc instanceof ExprNodeGenericFuncDesc) {
      ExprNodeGenericFuncDesc funcDesc = (ExprNodeGenericFuncDesc) desc;

      GenericUDF udf = funcDesc.getGenericUDF();
      if (udf instanceof GenericUDFOPNot) {
        ExprNodeDesc child = funcDesc.getChildren().get(0);
        if (child instanceof ExprNodeGenericFuncDesc) {
          ExprNodeGenericFuncDesc childDesc = (ExprNodeGenericFuncDesc)child;
          GenericUDF childUDF = childDesc.getGenericUDF();
          List<ExprNodeDesc> grandChildren = child.getChildren();

          if (childUDF instanceof GenericUDFBaseCompare ||
              childUDF instanceof GenericUDFOPNull ||
              childUDF instanceof GenericUDFOPNotNull) {
            List<ExprNodeDesc> newGrandChildren = new ArrayList<ExprNodeDesc>();
            for(ExprNodeDesc grandChild : grandChildren) {
              newGrandChildren.add(foldNegative(grandChild));
            }

            return ExprNodeGenericFuncDesc.newInstance(
                childUDF.negative(),
                newGrandChildren);
          } else if (childUDF instanceof GenericUDFOPAnd ||
              childUDF instanceof GenericUDFOPOr) {
            List<ExprNodeDesc> newGrandChildren = new ArrayList<ExprNodeDesc>();
            for(ExprNodeDesc grandChild : grandChildren) {
              newGrandChildren.add(foldNegative(
                  ExprNodeGenericFuncDesc.newInstance(new GenericUDFOPNot(),
                      Arrays.asList(grandChild))));
            }

            return ExprNodeGenericFuncDesc.newInstance(
                childUDF.negative(),
                newGrandChildren);
          }else if (childUDF instanceof GenericUDFOPNot) {
            return foldNegative(child.getChildren().get(0));
          } else {
            // For operator like if() that cannot be handled, leave not() as it
            // is and continue processing the children
            List<ExprNodeDesc> newGrandChildren = new ArrayList<ExprNodeDesc>();
            for(ExprNodeDesc grandChild : grandChildren) {
              newGrandChildren.add(foldNegative(grandChild));
            }
            childDesc.setChildren(newGrandChildren);
            return funcDesc;
          }
        }
      }
    }
    return desc;
  }
Combines the logical not() operator with the child operator if possible.
@param desc the expression to be evaluated
@return  the new expression to be replaced
@throws UDFArgumentException
ql/src/java/org/apache/hadoop/hive/ql/optimizer/ConstantPropagateProcFactory.java