Skip to content

Commit 0e02488

Browse files
committed
Add compound predicate and radial+WHERE test coverage
- Unit test: compound AND predicate survives pushdown into bool.filter - Integration test: compound WHERE (term + range) produces bool query - Integration test: radial max_distance with WHERE produces bool query Signed-off-by: Eric Wei <mengwei.eric@gmail.com>
1 parent 534b5f4 commit 0e02488

2 files changed

Lines changed: 68 additions & 0 deletions

File tree

integ-test/src/test/java/org/opensearch/sql/sql/VectorSearchIT.java

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -256,6 +256,50 @@ public void testOrderByScoreAscRejects() throws IOException {
256256
assertThat(ex.getMessage(), containsString("_score ASC is not supported"));
257257
}
258258

259+
// ── Compound predicate and radial + WHERE ───────────────────────────────
260+
261+
@Test
262+
public void testExplainCompoundPredicateProducesBoolQuery() throws IOException {
263+
String explain =
264+
explainQuery(
265+
"SELECT v._id, v._score "
266+
+ "FROM vectorSearch(table='"
267+
+ TEST_INDEX
268+
+ "', field='embedding', "
269+
+ "vector='[1.0, 2.0, 3.0]', option='k=10') AS v "
270+
+ "WHERE v.state = 'TX' AND v.age > 30 "
271+
+ "LIMIT 10");
272+
273+
assertTrue("Explain should contain bool query:\n" + explain, explain.contains("bool"));
274+
assertTrue(
275+
"Explain should contain must clause (knn in scoring context):\n" + explain,
276+
explain.contains("must"));
277+
assertTrue(
278+
"Explain should contain filter clause (compound WHERE in non-scoring context):\n" + explain,
279+
explain.contains("filter"));
280+
}
281+
282+
@Test
283+
public void testExplainRadialWithWhereProducesBoolQuery() throws IOException {
284+
String explain =
285+
explainQuery(
286+
"SELECT v._id, v._score "
287+
+ "FROM vectorSearch(table='"
288+
+ TEST_INDEX
289+
+ "', field='embedding', "
290+
+ "vector='[1.0, 2.0]', option='max_distance=10.5') AS v "
291+
+ "WHERE v.state = 'TX' "
292+
+ "LIMIT 100");
293+
294+
assertTrue("Explain should contain bool query:\n" + explain, explain.contains("bool"));
295+
assertTrue(
296+
"Explain should contain must clause (knn in scoring context):\n" + explain,
297+
explain.contains("must"));
298+
assertTrue(
299+
"Explain should contain filter clause (WHERE in non-scoring context):\n" + explain,
300+
explain.contains("filter"));
301+
}
302+
259303
// ── LIMIT validation ───────────────────────────────────────────────────
260304

261305
@Test

opensearch/src/test/java/org/opensearch/sql/opensearch/storage/scan/VectorSearchQueryBuilderTest.java

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -243,6 +243,30 @@ void pushDownSortScoreAscRejected() {
243243
assertTrue(ex.getMessage().contains("_score ASC is not supported"));
244244
}
245245

246+
@Test
247+
void pushDownFilterCompoundPredicateSurvives() {
248+
var requestBuilder = createRequestBuilder();
249+
var knnQuery = new WrapperQueryBuilder("{\"knn\":{}}");
250+
var builder = new VectorSearchQueryBuilder(requestBuilder, knnQuery, Map.of("k", "5"));
251+
252+
// Simulate WHERE name = 'John' AND age > 30
253+
var condition =
254+
DSL.and(
255+
DSL.equal(new ReferenceExpression("name", STRING), DSL.literal("John")),
256+
DSL.greater(new ReferenceExpression("age", ExprCoreType.INTEGER), DSL.literal(30)));
257+
var dummyChild = new LogicalValues(Collections.emptyList());
258+
var filter = new LogicalFilter(dummyChild, condition);
259+
260+
boolean pushed = builder.pushDownFilter(filter);
261+
262+
assertTrue(pushed, "pushDownFilter with compound predicate should succeed");
263+
QueryBuilder resultQuery = requestBuilder.getSourceBuilder().query();
264+
assertTrue(resultQuery instanceof BoolQueryBuilder, "Result should be a BoolQuery");
265+
BoolQueryBuilder boolQuery = (BoolQueryBuilder) resultQuery;
266+
assertEquals(1, boolQuery.must().size(), "knn query should be in must (scoring context)");
267+
assertEquals(1, boolQuery.filter().size(), "compound WHERE should be in filter (non-scoring)");
268+
}
269+
246270
private OpenSearchRequestBuilder createRequestBuilder() {
247271
return new OpenSearchRequestBuilder(
248272
mock(OpenSearchExprValueFactory.class), 10000, mock(Settings.class));

0 commit comments

Comments
 (0)