Doris-Breakwater commented on issue #67773:
URL: https://github.com/apache/doris/issues/67773#issuecomment-5614088801

   ## Breakwater on-call analysis
   
   **Verdict: confirmed, actionable compatibility/correctness bug.** The 
proposed failure mode is supported by the code, and the cross-version read path 
is reachable. I would prioritize this as a high-severity query-correctness 
issue because it can silently omit qualifying rows; the remaining unknown is 
prevalence, not validity.
   
   ### Verified facts
   
   - `ZoneMapPB` is proto2, and `has_nan` is field 8. `ZoneMap::from_proto` 
currently assigns `zone_map.has_nan()` without consulting `has_has_nan()`, so 
absent and explicitly-false metadata collapse to the same in-memory value.
   - Before #55633, the writer already instantiated zone maps for FLOAT and 
DOUBLE and used the generic `std::minmax_element` path. Reproducing that exact 
path with `{1.0, NaN, 2.0}` yields stored bounds `[1.0, 2.0]`; the old protobuf 
cannot record the hidden NaN.
   - Doris comparison semantics place NaN above finite values. Both the legacy 
column-predicate path and the expression zone-map path consume the result of 
`ZoneMap::from_proto`, so those finite bounds can cause a false-negative page 
or segment prune for a predicate such as `d > 3.0`.
   - The recent reversed-bounds protection from #67431 only detects legacy 
pages whose bounds never moved (for example, NaN-only pages). Mixed finite/NaN 
pages have ordinary-looking ordered bounds, so that protection does not cover 
this case.
   - This is not only hypothetical dead-format compatibility: the 3.1 branch 
has no `has_nan` field, while the 4.0/4.1 readers have the unguarded read. The 
[official 4.x upgrade 
guide](https://doris.apache.org/docs/4.x/admin-manual/cluster-management/upgrade/)
 explicitly covers 3.x-to-4.0 upgrades and states that an upgrade replaces 
FE/BE binaries and libraries, leaving existing data files in place. Legacy 
rowsets can therefore be read by an affected 4.x BE immediately after upgrade.
   - The issue currently has no labels or assignee. It should be triaged under 
the project's BE/storage/zone-map correctness conventions.
   
   ### Recommended fix
   
   Handle the compatibility distinction centrally in `ZoneMap::from_proto`: for 
FLOAT or DOUBLE, an absent field 8 should make range bounds unusable (for 
example, set the deserialized zone map's `pass_all` state, or introduce an 
explicit range-validity state). Preserve `has_null`/`has_not_null` so null-only 
pruning remains available. Do not fail the scan.
   
   Using field presence is preferable to a segment-version gate: fields 6-8 
were introduced together, and the Doris writer explicitly calls 
`set_has_nan(false)` for a known NaN-free zone, so `has_has_nan()` 
distinguishes new known-false metadata from legacy unknown metadata without 
inferring a deployment tag or version.
   
   This needs to remain in the common deserialization/index layer so segment 
pruning, page pruning, predicate elimination, and expression zone-map 
evaluation inherit the conservative behavior. A consumer-only check would leave 
other pruning paths exposed.
   
   ### Tests and next steps
   
   1. Add FLOAT and DOUBLE unit cases that construct a `ZoneMapPB` with valid 
ordered finite bounds and deliberately do not set field 8; after `from_proto`, 
range pruning must be disabled.
   2. Add the control case with `set_has_nan(false)`; its range must remain 
usable. Also verify that an older non-floating zone map without field 8 remains 
usable.
   3. Add a reader-level regression for both page and segment pruning using 
legacy metadata representing `{1.0, NaN, 2.0}` and `d > 3.0`. A segment 
artifact written by a pre-#55633 build would be the strongest cross-version 
regression fixture.
   4. Backport the fix to maintained 4.0 and 4.1 lines, since those are the 
readers that can encounter pre-4.0 rowsets. Coordinate with #67431 coverage: 
the current 4.0 branch also lacks that separate reversed-bounds safeguard.
   
   No logs or runtime profile are required to accept the bug because the 
metadata compatibility failure is deterministic. To quantify exposure and 
release urgency, it would still help to collect the source version(s) of 
upgraded clusters, whether FLOAT/DOUBLE columns can contain NaN, and whether 
all pre-4.0 rowsets have actually been rewritten by compaction. Until that 
inventory exists, affected deployments should not assume compaction has removed 
all legacy segments.
   
   Breakwater-GitHub-Analysis-Slot: slot_2338064ac779
   


-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: [email protected]

For queries about this service, please contact Infrastructure at:
[email protected]


---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to