Skip to content

Commit ee06fc7

Browse files
committed
WIP
1 parent 3d69e41 commit ee06fc7

2 files changed

Lines changed: 109 additions & 2 deletions

File tree

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

Lines changed: 108 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -456,7 +456,7 @@ void testCreateOrReplaceAndReturn(String storeName) throws Exception {
456456
}
457457

458458
@Nested
459-
class SubDocCompatibilityTest {
459+
class SubdocUpdateConsistencyTests {
460460

461461
@Nested
462462
@DisplayName("SET Operator Tests")
@@ -523,6 +523,29 @@ void testSetTopLevelArray(String storeName) throws Exception {
523523
assertEquals("tag6", tagsNode.get(2).asText());
524524
}
525525

526+
@ParameterizedTest(name = "{0}: SET top-level array")
527+
@ArgumentsSource(AllStoresProvider.class)
528+
void testSetTopLevelEmptyArray(String storeName) throws Exception {
529+
String docId = generateDocId("set-array");
530+
insertTestDocument(docId);
531+
532+
Collection collection = getCollection(storeName);
533+
Query query = buildQueryById(docId);
534+
535+
List<SubDocumentUpdate> updates = List.of(SubDocumentUpdate.of("tags", new String[] {}));
536+
537+
UpdateOptions options =
538+
UpdateOptions.builder().returnDocumentType(ReturnDocumentType.AFTER_UPDATE).build();
539+
540+
Optional<Document> result = collection.update(query, updates, options);
541+
542+
assertTrue(result.isPresent());
543+
JsonNode resultJson = OBJECT_MAPPER.readTree(result.get().toJson());
544+
JsonNode tagsNode = resultJson.get("tags");
545+
assertTrue(tagsNode.isArray());
546+
assertEquals(0, tagsNode.size(), storeName);
547+
}
548+
526549
@ParameterizedTest(name = "{0}: SET nested JSONB primitive")
527550
@ArgumentsSource(AllStoresProvider.class)
528551
void testSetNestedJsonbPrimitive(String storeName) throws Exception {
@@ -931,6 +954,90 @@ void testAddToListIfAbsentOnNonArrayField(String storeName) throws Exception {
931954
}
932955
}
933956

957+
@Nested
958+
class AllOperatorTests {
959+
960+
@ParameterizedTest
961+
@ArgumentsSource(AllStoresProvider.class)
962+
void testMultipleUpdatesOnSameFieldThrowsException(String storeName) throws IOException {
963+
String docId = generateDocId("multiple-updates-on-same-field");
964+
insertTestDocument(docId);
965+
966+
Collection collection = getCollection(storeName);
967+
Query query = buildQueryById(docId);
968+
969+
// top-level primitives
970+
List<SubDocumentUpdate> topLevelPrimitiveUpdates =
971+
List.of(
972+
SubDocumentUpdate.builder()
973+
.subDocument("price")
974+
.operator(UpdateOperator.ADD)
975+
.subDocumentValue(SubDocumentValue.of(5))
976+
.build(),
977+
SubDocumentUpdate.builder()
978+
.subDocument("price")
979+
.operator(UpdateOperator.ADD)
980+
.subDocumentValue(SubDocumentValue.of(-15))
981+
.build());
982+
983+
UpdateOptions options =
984+
UpdateOptions.builder().returnDocumentType(ReturnDocumentType.AFTER_UPDATE).build();
985+
986+
// Since there are multiple updates on the same field, it should throw an exception
987+
assertThrows(
988+
Exception.class, () -> collection.update(query, topLevelPrimitiveUpdates, options));
989+
990+
// top-level arrays
991+
List<SubDocumentUpdate> topLevelArrayUpdates =
992+
List.of(
993+
SubDocumentUpdate.builder()
994+
.subDocument("tags")
995+
.operator(UpdateOperator.APPEND_TO_LIST)
996+
.subDocumentValue(SubDocumentValue.of(new String[] {"tag1", "tag2"}))
997+
.build(),
998+
SubDocumentUpdate.builder()
999+
.subDocument("tags")
1000+
.operator(UpdateOperator.REMOVE_ALL_FROM_LIST)
1001+
.subDocumentValue(SubDocumentValue.of(new String[] {"tag2"}))
1002+
.build());
1003+
1004+
assertThrows(
1005+
Exception.class, () -> collection.update(query, topLevelArrayUpdates, options));
1006+
1007+
// nested array updates
1008+
List<SubDocumentUpdate> nestedArrayUpdates =
1009+
List.of(
1010+
SubDocumentUpdate.builder()
1011+
.subDocument("sales.regions")
1012+
.operator(UpdateOperator.SET)
1013+
.subDocumentValue(SubDocumentValue.of(new String[] {"US", "EU", "APAC"}))
1014+
.build(),
1015+
SubDocumentUpdate.builder()
1016+
.subDocument("sales.regions")
1017+
.operator(UpdateOperator.ADD_TO_LIST_IF_ABSENT)
1018+
.subDocumentValue(SubDocumentValue.of(new String[] {"EMEA"}))
1019+
.build());
1020+
1021+
assertThrows(Exception.class, () -> collection.update(query, nestedArrayUpdates, options));
1022+
1023+
// nested primitives
1024+
List<SubDocumentUpdate> nestedPrimitiveUpdates =
1025+
List.of(
1026+
SubDocumentUpdate.builder()
1027+
.subDocument("props.brand")
1028+
.operator(UpdateOperator.SET)
1029+
.subDocumentValue(SubDocumentValue.of("NewBrand"))
1030+
.build(),
1031+
SubDocumentUpdate.builder()
1032+
.subDocument("props.brand")
1033+
.operator(UpdateOperator.ADD_TO_LIST_IF_ABSENT)
1034+
.subDocumentValue(SubDocumentValue.of("NewBrand2"))
1035+
.build());
1036+
1037+
assertThrows(Exception.class, () -> collection.update(query, nestedArrayUpdates, options));
1038+
}
1039+
}
1040+
9341041
@Nested
9351042
@DisplayName("REMOVE_ALL_FROM_LIST Operator Tests")
9361043
class RemoveAllFromListOperatorTests {

document-store/src/main/java/org/hypertrace/core/documentstore/postgres/FlatPostgresCollection.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -680,7 +680,7 @@ private Map<String, String> resolvePathsToColumns(
680680
UpdateOperator operator = update.getOperator();
681681

682682
Preconditions.checkArgument(
683-
SUB_DOC_UPDATE_PARSERS.containsKey(operator), "Unsupported UPDATE operator: " + operator);
683+
UPDATE_PARSER_MAP.containsKey(operator), "Unsupported UPDATE operator: " + operator);
684684

685685
String path = update.getSubDocument().getPath();
686686
Optional<String> columnName = resolveColumnName(path, tableName);

0 commit comments

Comments
 (0)