Skip to content

Commit c855b61

Browse files
authored
Subdoc SET Operator for Flat Collections (#267)
1 parent a45e01d commit c855b61

File tree

7 files changed

+1055
-24
lines changed

7 files changed

+1055
-24
lines changed

document-store/src/integrationTest/java/org/hypertrace/core/documentstore/DocStoreQueryV1Test.java

Lines changed: 30 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -201,7 +201,7 @@ private static void createFlatCollectionSchema(
201201
String createTableSQL =
202202
String.format(
203203
"CREATE TABLE \"%s\" ("
204-
+ "\"_id\" INTEGER PRIMARY KEY,"
204+
+ "\"id\" TEXT PRIMARY KEY,"
205205
+ "\"item\" TEXT,"
206206
+ "\"price\" INTEGER,"
207207
+ "\"quantity\" INTEGER,"
@@ -3540,7 +3540,7 @@ void testFlatPostgresCollectionUnnestWithOnlyMainFilter(String dataStoreName)
35403540
void testFlatPostgresCollectionArrayRelationalFilter(String dataStoreName) throws IOException {
35413541
Collection flatCollection = getFlatCollection(dataStoreName);
35423542

3543-
// Filter: ANY tag in tags equals "hygiene" AND _id <= 8
3543+
// Filter: ANY tag in tags equals "hygiene" AND id IN (1-8)
35443544
// Exclude docs 9-10 (NULL/empty arrays) to avoid ARRAY[] type error
35453545
Query arrayRelationalQuery =
35463546
Query.builder()
@@ -3560,7 +3560,10 @@ void testFlatPostgresCollectionArrayRelationalFilter(String dataStoreName) throw
35603560
.build())
35613561
.operand(
35623562
RelationalExpression.of(
3563-
IdentifierExpression.of("_id"), LTE, ConstantExpression.of(8)))
3563+
IdentifierExpression.of("id"),
3564+
IN,
3565+
ConstantExpression.ofStrings(
3566+
List.of("1", "2", "3", "4", "5", "6", "7", "8"))))
35643567
.build())
35653568
.build();
35663569

@@ -3617,7 +3620,10 @@ void testFlatVsNestedCollectionNestedFieldSelections(String dataStoreName) throw
36173620
.addSort(IdentifierExpression.of("item"), ASC)
36183621
.setFilter(
36193622
RelationalExpression.of(
3620-
IdentifierExpression.of("_id"), LTE, ConstantExpression.of(8)))
3623+
IdentifierExpression.of("id"),
3624+
IN,
3625+
ConstantExpression.ofStrings(
3626+
List.of("1", "2", "3", "4", "5", "6", "7", "8"))))
36213627
.build();
36223628

36233629
// Assert both match the expected response
@@ -3643,7 +3649,10 @@ void testFlatVsNestedCollectionNestedFieldSelections(String dataStoreName) throw
36433649
.addSort(IdentifierExpression.of("item"), ASC)
36443650
.setFilter(
36453651
RelationalExpression.of(
3646-
IdentifierExpression.of("_id"), LTE, ConstantExpression.of(8)))
3652+
IdentifierExpression.of("id"),
3653+
IN,
3654+
ConstantExpression.ofStrings(
3655+
List.of("1", "2", "3", "4", "5", "6", "7", "8"))))
36473656
.build();
36483657

36493658
// Assert both match the expected response
@@ -3669,7 +3678,10 @@ void testFlatVsNestedCollectionNestedFieldSelections(String dataStoreName) throw
36693678
.addSort(IdentifierExpression.of("item"), ASC)
36703679
.setFilter(
36713680
RelationalExpression.of(
3672-
IdentifierExpression.of("_id"), LTE, ConstantExpression.of(8)))
3681+
IdentifierExpression.of("id"),
3682+
IN,
3683+
ConstantExpression.ofStrings(
3684+
List.of("1", "2", "3", "4", "5", "6", "7", "8"))))
36733685
.build();
36743686

36753687
// Assert both match the expected response with nested structure
@@ -5242,7 +5254,7 @@ void testRelOpArrayContains(String dataStoreName) {
52425254
// @> ('["Green"]')::jsonb) p(countWithParser)
52435255
assertEquals(1, containsCount);
52445256

5245-
// Test 2: NOT_CONTAINS - props.colors NOT_CONTAINS "Green" AND _id <= 8
5257+
// Test 2: NOT_CONTAINS - props.colors NOT_CONTAINS "Green" AND id IN (1-8)
52465258
// Expected: 7 documents (all except id=1 which has Green, limited to first 8)
52475259
Query notContainsQuery =
52485260
Query.builder()
@@ -5257,13 +5269,16 @@ void testRelOpArrayContains(String dataStoreName) {
52575269
ConstantExpression.of("Green")))
52585270
.operand(
52595271
RelationalExpression.of(
5260-
IdentifierExpression.of("_id"), LTE, ConstantExpression.of(8)))
5272+
IdentifierExpression.of("id"),
5273+
IN,
5274+
ConstantExpression.ofStrings(
5275+
List.of("1", "2", "3", "4", "5", "6", "7", "8"))))
52615276
.build())
52625277
.build();
52635278

52645279
long notContainsCount = flatCollection.count(notContainsQuery);
52655280
// Generated query: SELECT COUNT(*) FROM (SELECT * FROM "myTestFlat" WHERE ("props"->'colors'
5266-
// IS NULL OR NOT "props"->'colors' @> ('["Green"]')::jsonb) AND ("_id" <= ('8'::int4)))
5281+
// IS NULL OR NOT "props"->'colors' @> ('["Green"]')::jsonb) AND ("id" IN ('1', '2', ...)))
52675282
// p(countWithParser)
52685283
assertEquals(7, notContainsCount);
52695284
}
@@ -5287,7 +5302,7 @@ void testRelOpArrayIN(String dataStoreName) {
52875302
long inCount = flatCollection.count(inQuery);
52885303
assertEquals(2, inCount);
52895304

5290-
// Test 2: NOT_IN - props.brand NOT_IN ["Dettol"] AND _id <= 8
5305+
// Test 2: NOT_IN - props.brand NOT_IN ["Dettol"] AND id IN (1-8)
52915306
// Expected: 7 documents (all except id=1 which is Dettol, limited to first 8)
52925307
Query notInQuery =
52935308
Query.builder()
@@ -5301,7 +5316,10 @@ void testRelOpArrayIN(String dataStoreName) {
53015316
ConstantExpression.ofStrings(List.of("Dettol"))))
53025317
.operand(
53035318
RelationalExpression.of(
5304-
IdentifierExpression.of("_id"), LTE, ConstantExpression.of(8)))
5319+
IdentifierExpression.of("id"),
5320+
IN,
5321+
ConstantExpression.ofStrings(
5322+
List.of("1", "2", "3", "4", "5", "6", "7", "8"))))
53055323
.build())
53065324
.build();
53075325

@@ -5607,7 +5625,7 @@ public void testUnnestNestedArrayWithNullValue(String dataStoreName) throws IOEx
56075625
UnnestExpression.of(JsonIdentifierExpression.of("props", "source-loc"), true))
56085626
.setFilter(
56095627
RelationalExpression.of(
5610-
IdentifierExpression.of("_id"), EQ, ConstantExpression.of(1)))
5628+
IdentifierExpression.of("id"), EQ, ConstantExpression.of("1")))
56115629
.build();
56125630

56135631
Iterator<Document> iterator = collection.aggregate(query);

0 commit comments

Comments
 (0)