@Override
  public void evaluate(VectorizedRowBatch batch) throws HiveException {
    int n = batch.size;
    if (n <= 0) {
      return;
    }

    VectorExpression childExpr1 = this.childExpressions[0];

    boolean prevSelectInUse = batch.selectedInUse;

    // Save the original selected vector
    int[] sel = batch.selected;
    if (batch.selectedInUse) {
      System.arraycopy(sel, 0, initialSelected, 0, n);
    } else {
      for (int i = 0; i < n; i++) {
        initialSelected[i] = i;
        sel[i] = i;
      }
      batch.selectedInUse = true;
    }

    childExpr1.evaluate(batch);

    // Preserve the selected reference and size values generated
    // after the first child is evaluated.
    int sizeAfterFirstChild = batch.size;
    int[] selectedAfterFirstChild = batch.selected;

    // Calculate unselected ones in last evaluate.
    for (int j = 0; j < n; j++) {
      tmp[initialSelected[j]] = 0;
    }
    for (int j = 0; j < batch.size; j++) {
      tmp[selectedAfterFirstChild[j]] = 1;
    }
    int unselectedSize = 0;
    for (int j = 0; j < n; j++) {
      int i = initialSelected[j];
      if (tmp[i] == 0) {
        unselected[unselectedSize++] = i;
      }
    }

    int newSize = sizeAfterFirstChild;

    batch.selected = unselected;
    batch.size = unselectedSize;

    if (unselectedSize > 0) {

      // Evaluate subsequent child expression over unselected ones only.

      final int childrenCount = this.childExpressions.length;
      int childIndex = 1;
      while (true) {
  
        boolean isLastChild = (childIndex + 1 >= childrenCount);
  
        // When we have yet another child beyond the current one... save unselected.
        if (!isLastChild) {
          System.arraycopy(batch.selected, 0, unselectedCopy, 0, unselectedSize);
        }
  
        VectorExpression childExpr = this.childExpressions[childIndex];
  
        childExpr.evaluate(batch);
  
        // Merge the result of last evaluate to previous evaluate.
        newSize += batch.size;
        for (int i = 0; i < batch.size; i++) {
          tmp[batch.selected[i]] = 1;
        }

        if (isLastChild) {
          break;
        }

        unselectedSize = subtract(unselectedCopy, unselectedSize, batch.selected, batch.size,
            difference);
        if (unselectedSize == 0) {
          break;
        }
        System.arraycopy(difference, 0, batch.selected, 0, unselectedSize);
        batch.size = unselectedSize;

        childIndex++;
      }
    }

    // Important: Restore the batch's selected array.
    batch.selected = selectedAfterFirstChild;

    int k = 0;
    for (int j = 0; j < n; j++) {
      int i = initialSelected[j];
      if (tmp[i] == 1) {
        batch.selected[k++] = i;
      }
    }

    batch.size = newSize;
    if (newSize == n) {
      // Filter didn't do anything
      batch.selectedInUse = prevSelectInUse;
    }
  }
Remove (subtract) members from an array and produce the results into
a difference array.
@param all
         The selected array containing all members.
@param allSize
         The size of all.
@param remove
         The indices to remove.  They must all be present in input selected array.
@param removeSize
         The size of remove.
@param difference
         The resulting difference -- the all array indices not in the
         remove array.
@return
         The resulting size of the difference array.
ql/src/java/org/apache/hadoop/hive/ql/exec/vector/expressions/FilterExprOrExpr.java