Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 4 additions & 5 deletions be/src/format/table/iceberg_reader_mixin.h
Original file line number Diff line number Diff line change
Expand Up @@ -534,11 +534,10 @@ class IcebergReaderMixin : public BaseReader, public TableSchemaChangeHelper {

template <typename BaseReader>
Status IcebergReaderMixin<BaseReader>::_init_row_filters() {
// COUNT(*) short-circuit. A table-level row count of 0 (e.g. an all-deleted table read with
// ignore_iceberg_dangling_delete, where total-records == total-position-deletes) is still a
// valid pushed-down count, so accept >= 0 -- matching FileScanner and the Paimon readers. FE
// sends -1 when there is no table-level count; using > 0 here would drop a genuine 0 into the
// delete-applying path below and never produce the intended CountReader(0).
// COUNT(*) short-circuit. A table-level row count of 0 (an empty current snapshot) is still a
// valid pushed-down count, so accept >= 0 -- matching FileScanner and the Paimon readers. FE sends
// -1 when there is no table-level count; using > 0 here would drop a genuine 0 into the normal read
// path below and never produce the intended CountReader(0).
if (this->_push_down_agg_type == TPushAggOp::type::COUNT &&
this->get_scan_range().table_format_params.__isset.table_level_row_count &&
this->get_scan_range().table_format_params.table_level_row_count >= 0) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -127,10 +127,9 @@ public class IcebergConnectorMetadata implements ConnectorMetadata {
private static final int ICEBERG_ROW_LINEAGE_MIN_VERSION = 3;

// Snapshot-summary keys for table-level row count (getTableStatistics). Local literal copies of the
// spec-stable iceberg strings — byte-identical to legacy IcebergUtils.TOTAL_* and to the COUNT(*)
// pushdown copies in IcebergScanPlanProvider (themselves deliberately NOT org.apache.iceberg
// .SnapshotSummary.* per that file's note). Duplicated rather than shared so this fix does not touch
// the unrelated scan provider. All THREE keys are read: legacy getIcebergRowCount (via
// spec-stable iceberg strings — byte-identical to legacy IcebergUtils.TOTAL_*. These remain optimizer
// estimates only; exact COUNT(*) pushdown deliberately derives its result from live manifest-list counters.
// All THREE keys are read: legacy getIcebergRowCount (via
// getCountFromSummary, upstream 32a2651f66b / #64648) nets out position deletes AND gates the count to
// UNKNOWN on any equality delete — see computeRowCount.
private static final String TOTAL_RECORDS = "total-records";
Expand Down Expand Up @@ -823,9 +822,8 @@ public Optional<ConnectorTableStatistics> getTableStatistics(
* .getIcebergRowCount} (which calls {@code getCountFromSummary(summary, true)}, upstream 32a2651f66b /
* #64648): any equality delete ({@code total-equality-deletes} absent or {@code != "0"}) -> -1 (UNKNOWN),
* since equality deletes re-project at read time and the summary cannot net them out; otherwise
* {@code total-records - total-position-deletes}. Shares the equality-delete gate with the COUNT(*)
* pushdown {@code IcebergScanPlanProvider.getCountFromSummary}, differing only in dangling-delete handling
* (table statistics always net out position deletes; the pushdown honors the dangling-delete session var).
* {@code total-records - total-position-deletes}. This best-effort optimizer estimate is not used as an
* exact query result; COUNT(*) pushdown independently sums live-row counters from the manifest list.
* Empty table (no current snapshot) -> -1, which the caller maps to UNKNOWN.
*/
private static long computeRowCount(Table table) {
Expand All @@ -842,8 +840,7 @@ private static long computeRowCount(Snapshot snapshot) {
// summary, true) (upstream 32a2651f66b, #64648): an absent total-* counter (compaction / replace /
// overwrite snapshots may omit one — the pre-fix Long.parseLong(null) NPE-d), or any equality delete
// (total-equality-deletes != "0"), makes the summary row count unsafe -> -1 (caller maps to UNKNOWN),
// because equality deletes re-project at read time and the summary cannot net them out. Same gate as
// the COUNT(*) pushdown IcebergScanPlanProvider.getCountFromSummary.
// because equality deletes re-project at read time and the summary cannot net them out.
String equalityDeletes = summary.get(TOTAL_EQUALITY_DELETES);
String totalRecords = summary.get(TOTAL_RECORDS);
String positionDeletes = summary.get(TOTAL_POSITION_DELETES);
Expand Down
Loading
Loading