protected void evaluateString(ColumnVector columnVector, LongColumnVector output, int i) {
   BytesColumnVector bcv = (BytesColumnVector) columnVector;
   text.set(bcv.vector[i], bcv.start[i], bcv.length[i]);
   try {
     date.setTime(formatter.parse(text.toString()).getTime());
     output.vector[i] = baseDate - DateWritable.dateToDays(date);
   } catch (ParseException e) {
     output.vector[i] = 1;
     output.isNull[i] = true;
   }
 }
  @Override
  public void evaluate(VectorizedRowBatch batch) {

    if (childExpressions != null) {
      super.evaluateChildren(batch);
    }

    LongColumnVector outV = (LongColumnVector) batch.cols[outputColumn];
    ColumnVector inputCol = batch.cols[this.colNum];
    /* every line below this is identical for evaluateLong & evaluateString */
    final int n = inputCol.isRepeating ? 1 : batch.size;
    int[] sel = batch.selected;

    if (batch.size == 0) {
      /* n != batch.size when isRepeating */
      return;
    }

    /* true for all algebraic UDFs with no state */
    outV.isRepeating = inputCol.isRepeating;

    switch (inputTypes[0]) {
      case DATE:
        baseDate = (int) longValue;
        break;

      case TIMESTAMP:
        date.setTime(longValue / 1000000);
        baseDate = DateWritable.dateToDays(date);
        break;

      case STRING:
        try {
          date.setTime(formatter.parse(new String(stringValue, "UTF-8")).getTime());
          baseDate = DateWritable.dateToDays(date);
          break;
        } catch (Exception e) {
          outV.noNulls = false;
          if (batch.selectedInUse) {
            for (int j = 0; j < n; j++) {
              int i = sel[j];
              outV.isNull[i] = true;
            }
          } else {
            for (int i = 0; i < n; i++) {
              outV.isNull[i] = true;
            }
          }
          return;
        }
    }

    switch (inputTypes[1]) {
      case DATE:
        if (inputCol.noNulls) {
          outV.noNulls = true;
          if (batch.selectedInUse) {
            for (int j = 0; j < n; j++) {
              int i = sel[j];
              outV.vector[i] = evaluateDate(inputCol, i);
            }
          } else {
            for (int i = 0; i < n; i++) {
              outV.vector[i] = evaluateDate(inputCol, i);
            }
          }
        } else {
          // Handle case with nulls. Don't do function if the value is null, to save time,
          // because calling the function can be expensive.
          outV.noNulls = false;
          if (batch.selectedInUse) {
            for (int j = 0; j < n; j++) {
              int i = sel[j];
              outV.isNull[i] = inputCol.isNull[i];
              if (!inputCol.isNull[i]) {
                outV.vector[i] = evaluateDate(inputCol, i);
              }
            }
          } else {
            for (int i = 0; i < n; i++) {
              outV.isNull[i] = inputCol.isNull[i];
              if (!inputCol.isNull[i]) {
                outV.vector[i] = evaluateDate(inputCol, i);
              }
            }
          }
        }
        break;

      case TIMESTAMP:
        if (inputCol.noNulls) {
          outV.noNulls = true;
          if (batch.selectedInUse) {
            for (int j = 0; j < n; j++) {
              int i = sel[j];
              outV.vector[i] = evaluateTimestamp(inputCol, i);
            }
          } else {
            for (int i = 0; i < n; i++) {
              outV.vector[i] = evaluateTimestamp(inputCol, i);
            }
          }
        } else {
          // Handle case with nulls. Don't do function if the value is null, to save time,
          // because calling the function can be expensive.
          outV.noNulls = false;
          if (batch.selectedInUse) {
            for (int j = 0; j < n; j++) {
              int i = sel[j];
              outV.isNull[i] = inputCol.isNull[i];
              if (!inputCol.isNull[i]) {
                outV.vector[i] = evaluateTimestamp(inputCol, i);
              }
            }
          } else {
            for (int i = 0; i < n; i++) {
              outV.isNull[i] = inputCol.isNull[i];
              if (!inputCol.isNull[i]) {
                outV.vector[i] = evaluateTimestamp(inputCol, i);
              }
            }
          }
        }
        break;

      case STRING:
        if (inputCol.noNulls) {
          outV.noNulls = true;
          if (batch.selectedInUse) {
            for (int j = 0; j < n; j++) {
              int i = sel[j];
              evaluateString(inputCol, outV, i);
            }
          } else {
            for (int i = 0; i < n; i++) {
              evaluateString(inputCol, outV, i);
            }
          }
        } else {
          // Handle case with nulls. Don't do function if the value is null, to save time,
          // because calling the function can be expensive.
          outV.noNulls = false;
          if (batch.selectedInUse) {
            for (int j = 0; j < n; j++) {
              int i = sel[j];
              outV.isNull[i] = inputCol.isNull[i];
              if (!inputCol.isNull[i]) {
                evaluateString(inputCol, outV, i);
              }
            }
          } else {
            for (int i = 0; i < n; i++) {
              outV.isNull[i] = inputCol.isNull[i];
              if (!inputCol.isNull[i]) {
                evaluateString(inputCol, outV, i);
              }
            }
          }
        }
        break;
    }
  }
 protected int evaluateTimestamp(ColumnVector columnVector, int index) {
   LongColumnVector lcv = (LongColumnVector) columnVector;
   date.setTime(lcv.vector[index] / 1000000);
   return baseDate - DateWritable.dateToDays(date);
 }