HappenLee opened a new issue, #68240:
URL: https://github.com/apache/doris/issues/68240

   ### Search before asking
   
   Related issues #67994 and #67995 describe reader-cache and ZoneMap failures. 
This report tracks the broader consistency problem across hidden-column 
pruning, statistics, and direct reads, including short-circuit point queries 
and two-phase row-ID fetches that do not use the normal scan materialization 
path.
   
   ### Version
   
   Apache Doris master. The existing reader/cache and pruning reports describe 
baseline `846d9b2ebfc595ddfd77579447db16a674c901f7`.
   
   Related proposed implementation: #68125, inspected at 
`0022410d4b3cddbb48c548c47bc22b4a7e99d5d8`. Its regression scenarios are 
referenced below. No new cluster reproduction or test execution was performed 
when filing this report.
   
   ### What's Wrong?
   
   Some hidden columns store placeholders in segment files and obtain their 
logical values from the owning rowset during a read:
   
   - `__DORIS_VERSION_COL__`: a single-version rowset can supply its version 
instead of the physical `0`.
   - `__DORIS_COMMIT_TSO_COL__`: a published single-version rowset can supply 
its assigned commit TSO instead of the physical `0`.
   - `__DORIS_BINLOG_TSO__`: the row-binlog read path can materialize a TSO 
instead of its physical placeholder, subject to the row-binlog read context.
   
   These semantics are not interchangeable with reading the physical column or 
its indexes. Several paths can bypass or precede normal hidden-column 
materialization:
   
   1. **Pruning:** physical segment/page ZoneMaps, Bloom filters, or inverted 
indexes can reject rows based on placeholders rather than the logical values 
that row evaluation will see.
   2. **Statistics:** a pushed-down MIN/MAX path can consume placeholder 
statistics rather than the logical hidden-column values.
   3. **Reader reuse:** a reader cache keyed only by column identity can return 
a physical reader when a logical constant is required, or reuse a 
context-dependent constant where a physical read is intended.
   4. **Direct reads:** short-circuit point queries and lazy two-phase row-ID 
fetches can read physical column values or deserialize a JSONB row-store 
payload without performing the replacement used by a normal `SegmentIterator` 
scan. A JSONB row cache also lacks the owning rowset context needed to derive 
the logical value.
   
   As a result, the returned hidden value or matching row set can depend on the 
execution path, cache warmup order, or whether row storage is enabled.
   
   ### What You Expected?
   
   Logical projection, predicate evaluation, index pruning, and pushed-down 
statistics must agree on the hidden-column values derived from the exact owning 
rowset.
   
   Point queries and two-phase reads must return the same logical 
VERSION/COMMIT_TSO values as normal scans. Multi-version rowsets, unpublished 
internal reads, deliberately physical accesses, and row-binlog-specific 
BINLOG_TSO handling must retain their respective semantics; they must not 
receive an unconditional constant replacement.
   
   ### How to Reproduce?
   
   The following point-query scenario is adapted from the public regression 
case in #68125. It is a proposed comparison for an affected build; it has not 
been rerun for this report.
   
   ```sql
   CREATE TABLE hidden_column_point_read (
       k INT,
       v INT
   ) UNIQUE KEY(k)
   DISTRIBUTED BY HASH(k) BUCKETS 1
   PROPERTIES (
       "replication_num" = "1",
       "enable_unique_key_merge_on_write" = "true",
       "light_schema_change" = "true",
       "store_row_column" = "true",
       "disable_auto_compaction" = "true"
   );
   
   INSERT INTO hidden_column_point_read VALUES (1, 10);
   SET show_hidden_columns = true;
   
   SELECT __DORIS_VERSION_COL__
   FROM hidden_column_point_read WHERE k = 1;
   
   SELECT /*+ SET_VAR(enable_short_circuit_query=false) */
          __DORIS_VERSION_COL__
   FROM hidden_column_point_read WHERE k = 1;
   ```
   
   Verify that the first query actually uses the short-circuit path. Both 
queries should return the same positive published version, rather than one path 
returning the physical `0`. Repeat with partial row storage and with an 
ordinary-column point query first to warm the row cache.
   
   Additional validation should cover:
   
   - Two singleton rowsets whose sort keys interleave in a lazy TopN result. 
Assert that the plan contains `PhysicalLazyMaterialize`, and compare each 
fetched row's hidden version with its source rowset. Exercise both column 
storage and full row storage; replacement must apply only to the newly appended 
rows.
   - COMMIT_TSO projection and predicates on a ROW-binlog-enabled base table, 
using source rowset metadata as an independent oracle.
   - Ordinary predicates and common expressions at both segment and page 
levels, with reader caches initially cold and warm.
   - MIN/MAX with execution-plan assertions proving that the statistics 
pushdown path is active. A query that silently falls back to a normal scan does 
not validate that optimization.
   - BINLOG_TSO through the actual row-binlog scan context, plus controls for 
physical/internal and multi-version reads.
   
   ### Anything Else?
   
   The proposed direction in #68125 is to centralize hidden-column 
identification and read-time value resolution, use logical summaries where 
available, and avoid pruning from physical indexes that do not describe those 
values. Context-dependent logical constants should not pollute the shared 
physical reader cache. Direct reads must retain the exact owning rowset and 
resolve VERSION/COMMIT_TSO accordingly; BINLOG_TSO materialization needs the 
row-binlog scan context.
   
   Statistics fast paths should be used only when the reader can supply the 
correct logical result; otherwise they should fall back to normal iteration.
   
   Public implementation and test references:
   
   - [Hidden-column value 
resolution](https://github.com/apache/doris/blob/0022410d4b3cddbb48c548c47bc22b4a7e99d5d8/be/src/storage/read_time_hidden_column.cpp).
   - [Point-query and interleaved lazy-fetch regression 
scenarios](https://github.com/apache/doris/blob/0022410d4b3cddbb48c548c47bc22b4a7e99d5d8/regression-test/suites/point_query_p0/test_point_query_read_time_hidden_columns.groovy).
   - #68125 addresses the broader hidden-column read contract.
   - #68097 addresses the COMMIT_TSO reader-entry-point and direct-read subset.
   - #67994 and #67995 contain the earlier cache and ZoneMap analyses.
   


-- 
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