This is an automated email from the ASF dual-hosted git repository.

xiangfu0 pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/pinot.git


The following commit(s) were added to refs/heads/master by this push:
     new aa58c74490d [Vector Upsert 2/5] Harden vector search metric recording 
and backend param cleanup (#19298)
aa58c74490d is described below

commit aa58c74490de4020d4a7f0168e616e16afc879e6
Author: Xiang Fu <[email protected]>
AuthorDate: Wed Aug 26 14:27:20 2026 -0700

    [Vector Upsert 2/5] Harden vector search metric recording and backend param 
cleanup (#19298)
    
    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.
---
 .../filter/VectorSimilarityFilterOperator.java     | 21 +++++++++++++----
 .../filter/VectorSimilarityFilterOperatorTest.java | 27 ++++++++++++++++++++++
 2 files changed, 43 insertions(+), 5 deletions(-)

diff --git 
a/pinot-core/src/main/java/org/apache/pinot/core/operator/filter/VectorSimilarityFilterOperator.java
 
b/pinot-core/src/main/java/org/apache/pinot/core/operator/filter/VectorSimilarityFilterOperator.java
index 4e45a547990..62e814d243c 100644
--- 
a/pinot-core/src/main/java/org/apache/pinot/core/operator/filter/VectorSimilarityFilterOperator.java
+++ 
b/pinot-core/src/main/java/org/apache/pinot/core/operator/filter/VectorSimilarityFilterOperator.java
@@ -305,8 +305,12 @@ public class VectorSimilarityFilterOperator extends 
BaseFilterOperator {
     String column = _predicate.getLhs().getIdentifier();
     float[] queryVector = _predicate.getValue();
     VectorExplainContext explainContext = _vectorExplainContext;
+    boolean backendParamsNeedCleanup = false;
+    boolean searchExecuted = false;
     try {
       // 1. Configure backend-specific parameters via interfaces
+      // Claim cleanup before the first setter because configuration can fail 
after partially updating reader state.
+      backendParamsNeedCleanup = true;
       configureBackendParams(column);
       refreshExplainContext(null);
       explainContext = _vectorExplainContext;
@@ -317,6 +321,7 @@ public class VectorSimilarityFilterOperator extends 
BaseFilterOperator {
       // 3. Execute ANN search (with pre-filter if available)
       ImmutableRoaringBitmap preFilter = _preFilterBitmap;
       ImmutableRoaringBitmap annResults;
+      searchExecuted = true;
       if (preFilter != null && _vectorIndexReader instanceof 
FilterAwareVectorIndexReader) {
         FilterAwareVectorIndexReader filterAwareReader = 
(FilterAwareVectorIndexReader) _vectorIndexReader;
         if (filterAwareReader.supportsPreFilter()) {
@@ -381,11 +386,17 @@ public class VectorSimilarityFilterOperator extends 
BaseFilterOperator {
 
       return annResults;
     } finally {
-      // Record search metrics for observability — always, regardless of which 
path was taken
-      VectorSearchMetrics.getInstance().recordSearch(_vectorSearchMode, 
_backendType);
-      // Refresh explain context with the final search mode decided during 
execution
-      refreshExplainContext(null);
-      clearBackendParams(column);
+      try {
+        if (searchExecuted) {
+          VectorSearchMetrics.getInstance().recordSearch(_vectorSearchMode, 
_backendType);
+        }
+        // Refresh explain context with the final search mode decided during 
execution
+        refreshExplainContext(null);
+      } finally {
+        if (backendParamsNeedCleanup) {
+          clearBackendParams(column);
+        }
+      }
     }
   }
 
diff --git 
a/pinot-core/src/test/java/org/apache/pinot/core/operator/filter/VectorSimilarityFilterOperatorTest.java
 
b/pinot-core/src/test/java/org/apache/pinot/core/operator/filter/VectorSimilarityFilterOperatorTest.java
index feacc198187..357d7d4a764 100644
--- 
a/pinot-core/src/test/java/org/apache/pinot/core/operator/filter/VectorSimilarityFilterOperatorTest.java
+++ 
b/pinot-core/src/test/java/org/apache/pinot/core/operator/filter/VectorSimilarityFilterOperatorTest.java
@@ -571,6 +571,30 @@ public class VectorSimilarityFilterOperatorTest {
     Assert.assertTrue(explain.contains("effectiveHnswUseBoundedQueue:false"), 
explain);
   }
 
+  @Test
+  public void testBackendParamsAreClearedWhenConfigurationFailsPartway() {
+    ConfigurableVectorReader mockReader = mock(ConfigurableVectorReader.class);
+    Mockito.doThrow(new IllegalStateException("efSearch configuration failed"))
+        .when(mockReader).setEfSearch(20);
+
+    VectorSimilarityPredicate predicate = new VectorSimilarityPredicate(
+        ExpressionContext.forIdentifier("embedding"), new float[]{1.0f, 2.0f}, 
1);
+    VectorSearchParams params = new VectorSearchParams(8, false, null, null, 
20, null, null);
+    VectorSimilarityFilterOperator operator = new 
VectorSimilarityFilterOperator(mockReader, predicate,
+        100, params, null,
+        createVectorIndexConfig("HNSW", 
VectorIndexConfig.VectorDistanceFunction.EUCLIDEAN));
+
+    IllegalStateException exception = 
Assert.expectThrows(IllegalStateException.class, operator::getBitmaps);
+    Assert.assertEquals(exception.getMessage(), "efSearch configuration 
failed");
+    verify(mockReader).setNprobe(8);
+    verify(mockReader).setEfSearch(20);
+    verify(mockReader).clearNprobe();
+    verify(mockReader).clearEfSearch();
+    verify(mockReader).clearUseRelativeDistance();
+    verify(mockReader).clearUseBoundedQueue();
+    verify(mockReader, never()).getDocIds(Mockito.any(float[].class), 
Mockito.anyInt());
+  }
+
   /// Interface combining VectorIndexReader and NprobeAware for mocking 
IVF_FLAT readers.
   interface NprobeAwareVectorReader extends VectorIndexReader, NprobeAware {
   }
@@ -578,6 +602,9 @@ public class VectorSimilarityFilterOperatorTest {
   interface EfSearchAwareVectorReader extends VectorIndexReader, EfSearchAware 
{
   }
 
+  interface ConfigurableVectorReader extends VectorIndexReader, NprobeAware, 
EfSearchAware {
+  }
+
   @SuppressWarnings({"unchecked", "rawtypes"})
   private ForwardIndexReader<?> createMockForwardIndexReader(float[][] 
vectors) {
     ForwardIndexReader mockReader = mock(ForwardIndexReader.class);


---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to