Doris-Breakwater commented on issue #66030: URL: https://github.com/apache/doris/issues/66030#issuecomment-5076182386
Breakwater-GitHub-Analysis-Slot: slot_4fd365c156f3 ## Preliminary maintainer assessment **Verdict: confirmed FE planner/short-circuit contract bug, with a high-confidence code-level root cause.** The supplied DDL, query, versions, and stack are sufficient for triage. The issue is open with no labels, assignee, milestone, or linked development item; it should be routed as an FE/Nereids point-query bug. ### Root cause The exception is the exact invariant at [`PointQueryExecutor.setScanRangeLocations()` line 120](https://github.com/apache/doris/blob/b10073ad9ca/fe/fe-core/src/main/java/org/apache/doris/qe/PointQueryExecutor.java#L112-L121): after lazy range evaluation, a point query must target exactly one tablet. The invariant is violated because a predicate required by the short-circuit path is removed earlier: 1. `LogicalResultSinkToShortCircuitPointQuery` marks this query as short-circuit while both key equalities (`pk = 'abcd'` and `_id = 1`) are still present. The rewrite order intentionally runs this rule before `PruneOlapScanPartition`. 2. For the singleton LIST partition `VALUES IN ('abcd')`, partition pruning proves `pk = 'abcd'` is always true inside the selected partition. In `b10073ad9ca`, [`PruneOlapScanPartition` calls `PartitionPruner.prunePredicate()`](https://github.com/apache/doris/blob/b10073ad9ca/fe/fe-core/src/main/java/org/apache/doris/nereids/rules/rewrite/PruneOlapScanPartition.java#L77-L98), which removes that conjunct. In `aec169d2025`, removal is deferred but still performed by `PrunePartitionPredicate`. 3. The translated legacy `OlapScanNode` consequently retains only `_id = 1`. During short-circuit execution, [`lazyEvaluateRangeLocations()` recomputes filters and tablet ranges from those remaining conjuncts](https://github.com/apache/doris/blob/b10073ad9ca/fe/fe-core/src/main/java/org/apache/doris/planner/OlapScanNode.java#L966-L983). 4. Because the distribution is `HASH(pk, _id)`, `HashDistributionPruner` cannot compute the hash without the removed `pk` filter and returns every bucket tablet. `BUCKETS AUTO` resolved to more than one tablet in this reproduction, so the `size() == 1` precondition fails. This also fully explains why there is no BE log: the FE throws before selecting a tablet/backend or sending the lookup RPC. It is not a BE storage or row-store failure. The missing predicate is more than a routing problem. `PointQueryExecutor.addKeyTuples()` later builds the primary-key lookup tuple from the same scan conjuncts. Merely weakening the one-tablet assertion or choosing an arbitrary tablet would therefore be incorrect and could expose a null/missing key literal or wrong-result path. ### Recommended fix Keep partition pruning enabled, but do not remove partition predicates for a query already marked as short-circuit. The focused fix is to include: ```java ctx.statementContext.isShortCircuitQuery() ``` in the `skipPrunePredicate` condition in `PruneOlapScanPartition`. This works with both affected implementations: it prevents direct removal in `b10073ad9ca` and prevents recording the predicate for deferred removal in `aec169d2025`/newer code. It also preserves all primary-key literals for both distribution pruning and `addKeyTuples()`. Changing `PointQueryExecutor` to accept multiple tablets is not recommended: the short-circuit request and retry path are designed around one tablet, and that would mask the lost-key-predicate defect rather than repair it. ### Regression coverage - Add a `point_query_p0` case based on the supplied DDL, but use a fixed multi-bucket count such as `BUCKETS 4` so the failure is deterministic. - With default `skip_prune_predicate = false`, verify `EXPLAIN` still reports `SHORT-CIRCUIT` and the query returns `('abcd', 1)`. - Cover both a normal statement and server-side prepare/execute, including repeated execution so cached short-circuit context is exercised. - Add a second LIST-partition case where the partition key is a primary-key column but is not a distribution column. That case guards key-tuple construction even when tablet pruning can succeed without the partition key. - Retain a missing-key lookup case and verify it returns an empty result rather than an FE exception. ### Workaround and missing information A safe session-level workaround on both reported builds is: ```sql SET skip_prune_predicate = true; ``` This preserves the predicate while retaining short-circuit execution. If that setting is undesirable, `SET enable_short_circuit_query = false` avoids the failing path at the cost of point-query performance. No additional FE/BE logs or Doris profile are needed to establish the root cause. Two non-blocking details would help make the regression match the report exactly: the actual bucket count selected by `BUCKETS AUTO`, and whether step 5 was issued through server-side prepare/execute (the stack includes `ExecuteCommand`). Neither affects the diagnosis. -- 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]
