@Override
  public TableScan appendsBetween(long fromSnapshotId, long toSnapshotId) {
    validateSnapshotIdsRefinement(fromSnapshotId, toSnapshotId);
    return new IncrementalDataTableScan(
        table(),
        schema(),
        context().fromSnapshotIdExclusive(fromSnapshotId).toSnapshotId(toSnapshotId));
  }
@TestTemplate
  public void testIgnoreResiduals() throws IOException {
    add(table.newAppend(), files("A"));
    add(table.newAppend(), files("B"));
    add(table.newAppend(), files("C"));

    TableScan scan1 = table.newScan().filter(Expressions.equal("id", 5)).appendsBetween(1, 3);

    try (CloseableIterable<CombinedScanTask> tasks = scan1.planTasks()) {
      assertThat(tasks).as("Tasks should not be empty").hasSizeGreaterThan(0);
      for (CombinedScanTask combinedScanTask : tasks) {
        for (FileScanTask fileScanTask : combinedScanTask.files()) {
          assertThat(fileScanTask.residual())
              .as("Residuals must be preserved")
              .isNotEqualTo(Expressions.alwaysTrue());
        }
      }
    }

    TableScan scan2 =
        table.newScan().filter(Expressions.equal("id", 5)).appendsBetween(1, 3).ignoreResiduals();

    try (CloseableIterable<CombinedScanTask> tasks = scan2.planTasks()) {
      assertThat(tasks).as("Tasks should not be empty").hasSizeGreaterThan(0);
      for (CombinedScanTask combinedScanTask : tasks) {
        for (FileScanTask fileScanTask : combinedScanTask.files()) {
          assertThat(fileScanTask.residual())
              .as("Residuals must be ignored")
              .isEqualTo(Expressions.alwaysTrue());
        }
      }
    }
  }