morrySnow opened a new pull request, #67891:
URL: https://github.com/apache/doris/pull/67891

   ## Problem
   
   Foreign-key join elimination could produce incorrect results for a 
self-referencing table when LIMIT or TopN invalidated the primary-key side. The 
optimizer could remove the join and return rows that had no match in the 
limited primary input.
   
   ## Root cause
   
   `ForeignKeyContext` represented both catalog-declared primary keys and the 
validity of a particular relation instance with the same set of qualified 
catalog columns. When a limited scan expired its proof, visiting another scan 
of the same physical table registered the catalog primary key again. Because 
both scans shared the same catalog identity, this revived the expired proof for 
the first scan even though their output slots had different ExprIds.
   
   ## Reproduction
   
   Create a self-referencing table containing `(id, parent_id) = (1, 1), (2, 
2)`, declare `id` as its primary key and `parent_id` as a foreign key to `id`, 
then join the table to `(select id from the same table order by id limit 1)`. 
The valid join returns only `1`. Before this change, join elimination removed 
the limited primary side and incorrectly returned `1, 2`.
   
   ## Fix
   
   - Keep catalog primary-key declarations in `declaredPrimaryKeys`.
   - Track usable primary-key proofs by exact output Slot/ExprId in 
`activePrimaryKeySlots`.
   - Activate a slot only when its catalog column is a declared primary key.
   - Expire only the slots output by the invalidating plan node.
   - Propagate an alias proof only when its origin slot is still active.
   - Keep existing foreign-key and predicate-compatibility semantics unchanged.
   
   ## Tests
   
   - `./run-fe-ut.sh --run 
org.apache.doris.nereids.rules.rewrite.EliminateJoinByFkTest` — 17 tests, 0 
failures, 0 errors.
   - `DISABLE_BUILD_UI=ON ./build.sh --fe` — full FE reactor build passed; FE 
checkstyle reported 0 violations.
   - Generated the new regression output with `-forceGenOut` — 1 suite passed.
   - Ran the new regression normally against the rebuilt sandbox — 1 suite 
passed, 0 failed/fatal/skipped.
   - Manually verified that limited, reversed, aliased-over-TopN, and 
incompatible-filter plans retain the join, while plain and safely aliased plans 
remain eliminable.
   


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