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]