@Override
  public Page getNextPage() {
    try {
      Page dataPage = delegate.getNextPage();
      if (projectionsAdapter.isPresent()) {
        dataPage = projectionsAdapter.get().adaptPage(dataPage);
      }
      if (dataPage == null) {
        return null;
      }

      if (deleteFilter.isPresent()) {
        int positionCount = dataPage.getPositionCount();
        int[] positionsToKeep = new int[positionCount];
        try (CloseableIterable<TrinoRow> filteredRows =
            deleteFilter
                .get()
                .filter(
                    CloseableIterable.withNoopClose(
                        TrinoRow.fromPage(columnTypes, dataPage, positionCount)))) {
          int positionsToKeepCount = 0;
          for (TrinoRow rowToKeep : filteredRows) {
            positionsToKeep[positionsToKeepCount] = rowToKeep.getPosition();
            positionsToKeepCount++;
          }
          dataPage =
              dataPage
                  .getPositions(positionsToKeep, 0, positionsToKeepCount)
                  .getColumns(expectedColumnIndexes);
        } catch (IOException e) {
          throw new TrinoException(
              ICEBERG_BAD_DATA, "Failed to filter rows during merge-on-read operation", e);
        }
      }

      return dataPage;
    } catch (RuntimeException e) {
      closeWithSuppression(e);
      throwIfInstanceOf(e, TrinoException.class);
      throw new TrinoException(ICEBERG_BAD_DATA, e);
    }
  }
Iceberg original IcebergPageSource has some problems for mixed-format table, such as iceberg
version, table type.
amoro-format-mixed/amoro-mixed-trino/src/main/java/org/apache/amoro/trino/unkeyed/IcebergPageSource.java