Skip to content

[Vector Upsert 3/5] Never materialize nested vector subtrees as metadata filters - #19299

Open
xiangfu0 wants to merge 3 commits into
apache:masterfrom
xiangfu0:xiangfu0/upsert-vector-3-nested-vector-guard
Open

[Vector Upsert 3/5] Never materialize nested vector subtrees as metadata filters#19299
xiangfu0 wants to merge 3 commits into
apache:masterfrom
xiangfu0:xiangfu0/upsert-vector-3-nested-vector-guard

Conversation

@xiangfu0

@xiangfu0 xiangfu0 commented Aug 19, 2026

Copy link
Copy Markdown
Contributor

Part 3/5 of the split of #19287 (Fix FULL-upsert vector candidate generation).

Summary

FilterPlanNode treated any non-leaf AND sibling as a metadata filter when wiring
pre-filter bitmaps for filter-aware ANN. A nested subtree containing a
VECTOR_SIMILARITY predicate — e.g. AND(vector, AND(vector2, metadata)) or
AND(vector, NOT(vector2)) — was eagerly materialized into a bitmap, executing top-K
candidate generation out of its boolean context and pushing its results into the sibling
vector search as a pre-filter.

  • Track retained child FilterContexts alongside their operators so
    wirePreFilterForVectorOperators can pair them.
  • Only treat subtrees with no vector predicate as metadata
    (containsVectorPredicate / hasSafeMetadataSibling).
  • Adaptive pre-filter selection for plain metadata siblings is unchanged.

Validation

  • FilterPlanNodeTest: 13 tests passed. The new
    testNestedVectorSimilaritySubtreeIsNeverMaterializedAsMetadata fails all 3 boolean
    shapes against master's planner and passes with this change.

Stacked on #19298 — this PR shows the earlier stack commits until predecessors merge; review only the last commit here.

Stack

  1. [Vector Upsert 1/5] Support allowed-document filtering in exact vector scan #19297 — exact-scan allowed-document filtering
  2. [Vector Upsert 2/5] Harden vector search metric recording and backend param cleanup #19298 — backend param cleanup hardening
  3. [Vector Upsert 3/5] Never materialize nested vector subtrees as metadata filters #19299 — nested vector metadata guard
  4. [Vector Upsert 4/5] Apply the query's visible-document set before vector candidate generation #19300 — apply the visible-document set before candidate generation (core fix)
  5. [Vector Upsert 5/5] Add FULL-upsert vector integration coverage #19301 — integration coverage

@codecov-commenter

codecov-commenter commented Aug 19, 2026

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 84.21053% with 15 lines in your changes missing coverage. Please review.
✅ Project coverage is 67.23%. Comparing base (e4888b0) to head (8abc05f).

Files with missing lines Patch % Lines
...operator/filter/ExactVectorScanFilterOperator.java 83.05% 6 Missing and 4 partials ⚠️
...not/core/operator/filter/VectorCandidateScope.java 75.00% 2 Missing ⚠️
...ava/org/apache/pinot/core/plan/FilterPlanNode.java 89.47% 0 Missing and 2 partials ⚠️
...perator/filter/VectorSimilarityFilterOperator.java 88.88% 0 Missing and 1 partial ⚠️
Additional details and impacted files
@@             Coverage Diff              @@
##             master   #19299      +/-   ##
============================================
+ Coverage     67.20%   67.23%   +0.03%     
  Complexity     1424     1424              
============================================
  Files          3462     3463       +1     
  Lines        220361   220407      +46     
  Branches      35147    35164      +17     
============================================
+ Hits         148087   148187     +100     
+ Misses        60467    60386      -81     
- Partials      11807    11834      +27     
Flag Coverage Δ
integration 100.00% <ø> (ø)
integration1 100.00% <ø> (ø)
integration2 0.00% <ø> (ø)
java-25 67.23% <84.21%> (+0.03%) ⬆️
lane-a 100.00% <ø> (ø)
lane-b 0.00% <ø> (ø)
temurin 67.23% <84.21%> (+0.03%) ⬆️
unittests 67.23% <84.21%> (+0.03%) ⬆️
unittests1 57.86% <84.21%> (+0.02%) ⬆️
unittests2 39.22% <0.00%> (+<0.01%) ⬆️

Flags with carried forward coverage won't be shown. Click here to find out more.

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

…r scan

Extract a shared computeExactMatches helper that unifies the exact top-K and
threshold scan paths and can restrict scoring to an allowed-document bitmap.

Introduce VectorCandidateScope, an immutable set of document IDs a vector
predicate is allowed to consider as candidates. Vector top-K is not monotonic,
so unlike an ordinary predicate -- which is correct to intersect with the result
afterwards -- a document set that defines what the query may see has to be
applied before candidate generation. The type carries that contract and says
nothing about where the restriction came from; callers decide that.
ExactVectorScanFilterOperator accepts one via a new constructor overload, and no
production caller passes one yet.

Also let the operator record its own exact-scan search and fallback metrics,
which were previously invisible to VectorSearchMetrics, and report the applied
candidate-filter cardinality in explain output.

Add filtered-reader coverage for HnswVectorIndexReader.
… param cleanup

Only record a vector search metric when a search actually executed, and
guarantee backend search parameters are cleared even when configuration fails
partway or the explain-context refresh throws. Previously a failure inside
configureBackendParams still recorded a search that never ran, and an exception
from refreshExplainContext could skip clearBackendParams entirely.
…ata filters

FilterPlanNode treated any non-leaf AND sibling as a metadata filter when
wiring pre-filter bitmaps for filter-aware ANN. A nested subtree containing a
VECTOR_SIMILARITY predicate (e.g. AND(vector, AND(vector2, metadata)) or
AND(vector, NOT(vector2))) was eagerly materialized into a bitmap, executing
top-K candidate generation out of its boolean context and pushing its results
into the sibling vector search as a pre-filter.

Track the retained child FilterContexts alongside their operators so
wirePreFilterForVectorOperators can pair them, and only treat subtrees with no
vector predicate as metadata. Adaptive pre-filter selection for plain metadata
siblings is unchanged.
@xiangfu0
xiangfu0 force-pushed the xiangfu0/upsert-vector-3-nested-vector-guard branch from aa7de76 to 8abc05f Compare August 19, 2026 01:38
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants