Skip to content

[api][spark] Treat an unreported partition statistic as unknown, not as zero - #9379

Merged
JingsongLi merged 2 commits into
apache:masterfrom
sundapeng:fix/rest-partition-absent-statistics
Aug 25, 2026
Merged

[api][spark] Treat an unreported partition statistic as unknown, not as zero#9379
JingsongLi merged 2 commits into
apache:masterfrom
sundapeng:fix/rest-partition-absent-statistics

Conversation

@sundapeng

@sundapeng sundapeng commented Aug 24, 2026

Copy link
Copy Markdown
Member

Purpose

An unreported partition statistic can reach the Spark planner as an exact zero, and a scan over real files then looks free to read.

paimon-api. The statistics are optional in the REST contract, but Partition declares them as primitive long in its @JsonCreator, so Jackson decodes an absent field to 0 and PartitionStatistics.isKnown calls it a measurement. A static @JsonCreator factory now takes them as Long and maps null to UNKNOWN. The public constructor is unchanged, so this is source and binary compatible. totalBuckets and PartitionStatistics stay as they are; the latter travels the other way as a commit delta, where a negative value is a decrement rather than an unmeasured field.

paimon-spark. A catalog that cannot tell "never measured" from "measured, and empty" reports a well formed 0. Since #9351 that becomes the scan row count, and sizeInBytes follows it to zero because the row estimate branch runs whenever numRows is present, leaving the file size fallback unreachable. canBroadcastBySize then passes at any threshold. A reported zero over real bytes is now left unknown and the size is weighed from the files. Only that case changes: zero rows over zero bytes is still an empty scan, and split row counts come from Paimon's own manifests where zero means zero.

Tests

  • PartitionTest: absent statistics decode to UNKNOWN, an explicit zero stays exact, a full partition round trips
  • CatalogManagedPartitionScanTest: partitions parsed from statistics free JSON keep the plan row count empty
  • CatalogManagedPartitionAnalyzeTest: statistics rewritten to zero while the files stay untouched, then the row count comes back unknown and the size above zero. Reverting PaimonStatistics.scala fails that case and no other.
  • paimon-api 150 tests, paimon-core 687 tests, CatalogManagedPartitionAnalyzeTest on Spark 3.5 22 tests
  • Spotless and checkstyle

@sundapeng
sundapeng force-pushed the fix/rest-partition-absent-statistics branch from f7babbe to 7824d56 Compare August 24, 2026 15:52
@sundapeng sundapeng changed the title [api] Decode absent partition statistics as unknown instead of zero [api][spark] Treat an unreported partition statistic as unknown, not as zero Aug 24, 2026
@sundapeng
sundapeng force-pushed the fix/rest-partition-absent-statistics branch from d2701ca to cf0efa0 Compare August 24, 2026 16:41
A listPartitions response may omit the statistics, since the REST contract
does not mark them required. The primitive JsonCreator parameters decoded
that absence to 0, which PartitionStatistics.isKnown reads as an exact
measurement. Since apache#9351 the zero reaches Spark as a 0 row and 0 byte scan,
and a large format table can then be picked as a broadcast build side.
A catalog that cannot tell "never measured" from "measured, and empty"
reports a well formed zero. Since apache#9351 that becomes the scan row count,
and sizeInBytes follows it down because the row estimate branch is taken
whenever numRows is present, leaving the file size fallback unreachable.
The scan then enters the optimizer at 0 bytes and can be picked as a
broadcast build side.
@sundapeng
sundapeng force-pushed the fix/rest-partition-absent-statistics branch from cf0efa0 to cac4e99 Compare August 24, 2026 16:42

@JingsongLi JingsongLi left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

+1

@JingsongLi
JingsongLi merged commit 53f0a24 into apache:master Aug 25, 2026
14 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants