@Override
  public GenericUDAFEvaluator getEvaluator(TypeInfo[] parameters)
      throws SemanticException {
    if (parameters.length != 2 ) {
      throw new UDFArgumentTypeException(parameters.length - 1,
          "Exactly 2 (col + #bitvectors) arguments are expected.");
    }

    if (parameters[0].getCategory() != ObjectInspector.Category.PRIMITIVE) {
      throw new UDFArgumentTypeException(0,
          "Only primitive type arguments are accepted but "
              + parameters[0].getTypeName() + " is passed.");
    }

    ColumnStatsType cst = ColumnStatsType.getColumnStatsType(((PrimitiveTypeInfo) parameters[0]));
    switch (cst) {
      case LONG:
        return new GenericUDAFLongStatsEvaluator();
      case DOUBLE:
        return new GenericUDAFDoubleStatsEvaluator();
      case STRING:
        return new GenericUDAFStringStatsEvaluator();
      case DECIMAL:
        return new GenericUDAFDecimalStatsEvaluator();
      case DATE:
        return new GenericUDAFDateStatsEvaluator();
      case TIMESTAMP:
        return new GenericUDAFTimestampStatsEvaluator();
      default:
        throw new UDFArgumentTypeException(0,
            "Type argument " + parameters[0].getTypeName() + " not valid");
    }
  }
GenericUDAFComputeBitVector. This UDAF will compute a bit vector using
FMSketch algorithm. The ndv_compute_bit_vector function can
be used on top of it to extract an estimate of the ndv from it.
ql/src/java/org/apache/hadoop/hive/ql/udf/generic/GenericUDAFComputeBitVectorFMSketch.java