@Override
  public void evaluateGroupBatch(VectorizedRowBatch batch)
      throws HiveException {

    evaluateInputExpr(batch);

    // First row determines isGroupResultNull and double firstValue; stream fill result as repeated.

    // We do not filter when PTF is in reducer.
    Preconditions.checkState(!batch.selectedInUse);

    if (!haveFirstValue) {
      final int size = batch.size;
      if (size == 0) {
        return;
      }
      DoubleColumnVector doubleColVector = ((DoubleColumnVector) batch.cols[inputColumnNum]);
      if (doubleColVector.isRepeating) {

        if (doubleColVector.noNulls || !doubleColVector.isNull[0]) {
          firstValue = doubleColVector.vector[0];
          isGroupResultNull = false;
        }
      } else if (doubleColVector.noNulls) {
        firstValue = doubleColVector.vector[0];
        isGroupResultNull = false;
      } else {
        if (!doubleColVector.isNull[0]) {
          firstValue = doubleColVector.vector[0];
          isGroupResultNull = false;
        }
      }
      haveFirstValue = true;
    }

    /*
     * Do careful maintenance of the outputColVector.noNulls flag.
     */

    // First value is repeated for all batches.
    DoubleColumnVector outputColVector = (DoubleColumnVector) batch.cols[outputColumnNum];
    outputColVector.isRepeating = true;
    if (isGroupResultNull) {
      outputColVector.noNulls = false;
      outputColVector.isNull[0] = true;
    } else {
      outputColVector.isNull[0] = false;
      outputColVector.vector[0] = firstValue;
    }
  }
This class evaluates double first_value() for a PTF group.

We capture the first value from the first batch.  It can be NULL.
We then set (stream) the output column with that value as repeated in each batch.
ql/src/java/org/apache/hadoop/hive/ql/exec/vector/ptf/VectorPTFEvaluatorDoubleFirstValue.java