private OrcRawRecordMerger.KeyInterval findOriginalMinMaxKeys(OrcSplit orcSplit, OrcTail orcTail,
      Reader.Options deleteEventReaderOptions) {

    // This method returns the minimum and maximum synthetic row ids that are present in this split
    // because min and max keys are both inclusive when filtering out the delete delta records.

    if (syntheticProps == null) {
      // syntheticProps containing the synthetic rowid offset is computed if there are delete delta files.
      // If there aren't any delete delta files, then we don't need this anyway.
      return new OrcRawRecordMerger.KeyInterval(null, null);
    }

    long splitStart = orcSplit.getStart();
    long splitEnd = orcSplit.getStart() + orcSplit.getLength();

    long minRowId = syntheticProps.getRowIdOffset();
    long maxRowId = syntheticProps.getRowIdOffset();

    for(StripeInformation stripe: orcTail.getStripes()) {
      if (splitStart > stripe.getOffset()) {
        // This stripe starts before the current split starts. This stripe is not included in this split.
        minRowId += stripe.getNumberOfRows();
      }

      if (splitEnd > stripe.getOffset()) {
        // This stripe starts before the current split ends.
        maxRowId += stripe.getNumberOfRows();
      } else {
        // The split ends before (or exactly where) this stripe starts.
        // Remaining stripes are not included in this split.
        break;
      }
    }

    RecordIdentifier minKey = new RecordIdentifier(syntheticProps.getSyntheticWriteId(),
        syntheticProps.getBucketProperty(), minRowId);

    RecordIdentifier maxKey = new RecordIdentifier(syntheticProps.getSyntheticWriteId(),
        syntheticProps.getBucketProperty(), maxRowId > 0? maxRowId - 1: 0);

    OrcRawRecordMerger.KeyInterval keyIntervalTmp = new OrcRawRecordMerger.KeyInterval(minKey, maxKey);

    if (minRowId >= maxRowId) {
      /**
       * The split lies entirely within a single stripe. In this case, the reader for this split will not read any data.
       * See {@link org.apache.orc.impl.RecordReaderImpl#RecordReaderImpl
       * We can return the min max key interval as is (it will not read any of the delete delta records into mem)
       */

      LOG.info("findOriginalMinMaxKeys(): This split starts and ends in the same stripe.");
    }

    LOG.info("findOriginalMinMaxKeys(): " + keyIntervalTmp);

    // Using min/max ROW__ID from original will work for ppd to the delete deltas because the writeid is the same in
    // the min and the max ROW__ID
    setSARG(keyIntervalTmp, deleteEventReaderOptions, minKey.getBucketProperty(), maxKey.getBucketProperty(),
        minKey.getRowId(), maxKey.getRowId());

    return keyIntervalTmp;
  }
figure out min/max bucket, rowid for push down.  This is different from
min/max ROW__ID because ROW__ID comparison uses dictionary order on two
tuples (a,b,c), but PPD can only do
(a between (x,y) and b between(x1,y1) and c between(x2,y2))
Consider:
(0,536936448,0), (0,536936448,2), (10000001,536936448,0)
1st is min ROW_ID, 3r is max ROW_ID
and Delete events (0,536936448,2),....,(10000001,536936448,1000000)
So PPD based on min/max ROW_ID would have 0<= rowId <=0 which will
miss this delete event.  But we still want PPD to filter out data if
possible.

So use stripe stats to find proper min/max for bucketProp and rowId
writeId is the same in both cases
ql/src/java/org/apache/hadoop/hive/ql/io/orc/VectorizedOrcAcidRowBatchReader.java