private ExprNodeDesc rewriteBetweenToIn(final ExprNodeDesc comparisonExpression, final ExprNodeDesc leftExpression,
                                            final ExprNodeDesc rightExpression, boolean invert) {
      // difference in BETWEEN values could be millions, since for each value a new ExprNodeConstantDesc is created
      // we should limit the rewrite to avoid taking too much memory
      final int REWRITE_THRESHOLD = 100;

      boolean shouldRewrite = false;
      long startVal = 0, endVal = 0;

      if (ExprNodeDescUtils.isIntegerType(comparisonExpression)
          && leftExpression instanceof ExprNodeConstantDesc
          && rightExpression instanceof ExprNodeConstantDesc) {
        Object leftValue = ((ExprNodeConstantDesc) leftExpression).getValue();
        Object rightValue = ((ExprNodeConstantDesc) rightExpression).getValue();

        startVal = ((Number)leftValue).longValue();
        endVal = ((Number)rightValue).longValue();

        // BETWEEN could be (10,0)
        if(startVal > endVal) {
          Long tmpVal = startVal;
          startVal = endVal;
          endVal = tmpVal;
        }

        if ((endVal - startVal) <= REWRITE_THRESHOLD) {
          shouldRewrite = true;
        }
      }

      if (shouldRewrite) {

        List<ExprNodeDesc> constantExprs = new ArrayList<>();
        constantExprs.add(comparisonExpression);
        //generate list of contiguous integers
        for (long i = startVal; i <= endVal; i++) {
          ExprNodeConstantDesc constExpr = new ExprNodeConstantDesc(comparisonExpression.getTypeInfo(), i);
          constantExprs.add(constExpr);
        }
        ExprNodeDesc newExpression = new ExprNodeGenericFuncDesc(TypeInfoFactory.booleanTypeInfo,
                                                                 new GenericUDFIn(), constantExprs);
        return newExpression;
      } else {
        // We transform the BETWEEN clause to AND clause (with NOT on top in invert is true).
        // This is more straightforward, as the evaluateExpression method will deal with
        // generating the final row count relying on the basic comparator evaluation methods
        final ExprNodeDesc leftComparator = new ExprNodeGenericFuncDesc(TypeInfoFactory.booleanTypeInfo,
                                                        new GenericUDFOPEqualOrGreaterThan(),
                                                        Lists.newArrayList(comparisonExpression, leftExpression));
        final ExprNodeDesc rightComparator = new ExprNodeGenericFuncDesc(TypeInfoFactory.booleanTypeInfo,
                                                        new GenericUDFOPEqualOrLessThan(),
                                                        Lists.newArrayList(comparisonExpression, rightExpression));
        ExprNodeDesc newExpression = new ExprNodeGenericFuncDesc(TypeInfoFactory.booleanTypeInfo,
                                                                 new GenericUDFOPAnd(),
                                                                 Lists.newArrayList(leftComparator, rightComparator));
        if (invert) {
          newExpression = new ExprNodeGenericFuncDesc(TypeInfoFactory.booleanTypeInfo,
                                                      new GenericUDFOPNot(), Lists.newArrayList(newExpression));
        }
        return newExpression;
      }
    }
removes all values which are outside of the scope of the column
ql/src/java/org/apache/hadoop/hive/ql/optimizer/stats/annotation/StatsRulesProcFactory.java