fix(server): skip unsafe count optm for nested predicates#3100
Conversation
imbajin
left a comment
There was a problem hiding this comment.
Blocking: yes. Summary: Flat connective count predicates remain semantically unsafe and can return incorrect results after the destructive NotStep rewrite. Evidence: exact-head control-flow review and two independent TinkerPop 3.5.1 reproductions.
| } | ||
|
|
||
| final P<?> predicate = ((IsStep<?>) step.getNextStep()).getPredicate(); | ||
| if (this.hasNestedConnectivePredicate(predicate)) { |
There was a problem hiding this comment.
This guard only rejects a ConnectiveP whose child is another ConnectiveP, so flat expressions such as P.eq(0L).and(P.gt(0L)) and P.lte(0L).or(P.gte(1L)) still enter the optimization. The loop then derives useNotStep from only the first range-driving child and removes the complete count().is(...); on an empty adjacency the contradiction can return true, and on a non-empty adjacency the tautology can return false. Both shapes were reproduced against the current strategy on TinkerPop 3.5.1. Please disable the destructive rewrite for every ConnectiveP unless equivalence is derived from the complete boolean expression; the conservative fix is to skip all ConnectiveP values here. Add flat AND/OR regressions for both zero and nonzero counts.
|
This ci failure is not from this PR.HugeCountStrategy only fires on Gremlin traversals with count().is(...), but KoutTraverser uses HugeGraph's own BFS framework (no Gremlin traversal at all). The change only skips more cases,. |
imbajin
left a comment
There was a problem hiding this comment.
Blocking: yes. Summary: The blanket ConnectiveP guard fixes the incorrect-result cases, but it also removes safe range limiting for common flat count predicates and can turn bounded counts into full scans. Evidence: exact-head control-flow inspection, confirmed independently by two review lanes.
| } | ||
|
|
||
| final P<?> predicate = ((IsStep<?>) step.getNextStep()).getPredicate(); | ||
| if (predicate instanceof ConnectiveP) { |
There was a problem hiding this comment.
Returning here for every ConnectiveP bypasses the entire strategy, including the safe RangeGlobalStep insertion. Common predicates such as between(1, 18) are connective predicates, so a high-degree count().is(...) traversal now counts the complete input instead of stopping at the upper threshold. The new result assertions do not detect this plan regression. Please keep disabling the destructive NotStep/dismissCountIs rewrites unless full-expression equivalence is proven, while retaining a proven-safe range cap for analyzable flat connectives (and continue skipping nested cases as needed). Add a traversal-plan regression that asserts a representative flat connective still receives the range bound.
imbajin
left a comment
There was a problem hiding this comment.
Blocking: no. Summary: The current head preserves safe range limiting for flat connective predicates while bypassing unsafe nested predicate rewrites; no actionable issues were found. Evidence: CountStrategyCoreTest passed 35/35 on the exact head, and all 15 visible latest-head checks succeeded.
Purpose of the PR
Main Changes
HugeCountStrategytocount().is(...)traversalscontaining nested connective predicates.
CountGlobalStep + IsSteptraversal for nestedpredicates, so that TinkerPop evaluates the complete predicate tree.
connective predicates.
into
RangeGlobalSteporNotStep, which can change or invert thefiltering semantics.
negated form.
Verifying these changes
Does this PR potentially affect the following parts?
Documentation Status
Doc - TODODoc - DoneDoc - No Need