diff options
author | Tor Brede Vekterli <vekterli@verizonmedia.com> | 2019-12-04 15:42:50 +0100 |
---|---|---|
committer | Tor Brede Vekterli <vekterli@verizonmedia.com> | 2019-12-04 15:42:50 +0100 |
commit | 92856cba3fe5f8a5f0d00db3bfbb2cb4ce3d209e (patch) | |
tree | f1a9c751d75179ebae26c1fbb828df1e01bd7d92 /indexinglanguage/src/test | |
parent | fec2553bc3dc96382e4cb4cd9e7da9e567a1023f (diff) |
Preserve array updates with element index matching in indexing docproc
The resulting `MapValueUpdate` would previously be constructed with the
wrong type for the index, causing an exception to be thrown and for the
update to fail entirely.
Diffstat (limited to 'indexinglanguage/src/test')
2 files changed, 90 insertions, 3 deletions
diff --git a/indexinglanguage/src/test/java/com/yahoo/vespa/indexinglanguage/DocumentUpdateTestCase.java b/indexinglanguage/src/test/java/com/yahoo/vespa/indexinglanguage/DocumentUpdateTestCase.java index beed3053692..a6362e71594 100644 --- a/indexinglanguage/src/test/java/com/yahoo/vespa/indexinglanguage/DocumentUpdateTestCase.java +++ b/indexinglanguage/src/test/java/com/yahoo/vespa/indexinglanguage/DocumentUpdateTestCase.java @@ -9,6 +9,7 @@ import com.yahoo.document.update.AddValueUpdate; import com.yahoo.document.update.AssignValueUpdate; import com.yahoo.document.update.FieldUpdate; import com.yahoo.document.update.ValueUpdate; +import com.yahoo.document.update.MapValueUpdate; import com.yahoo.vespa.indexinglanguage.expressions.Expression; import com.yahoo.vespa.indexinglanguage.parser.ParseException; import org.junit.Test; @@ -66,14 +67,19 @@ public class DocumentUpdateTestCase { assertTrue(upd.getCreateIfNonExistent()); } - @Test - public void assign_updates_to_structs_are_preserved() throws ParseException { - var docType = new DocumentType("my_input"); + private static StructDataType makeStructType() { var structType = new StructDataType("foobarstruct"); var fooField = new Field("foo", DataType.STRING); var barField = new Field("bar", DataType.STRING); structType.addField(fooField); structType.addField(barField); + return structType; + } + + @Test + public void assign_updates_to_structs_are_preserved() throws ParseException { + var docType = new DocumentType("my_input"); + var structType = makeStructType(); docType.addField(new Field("mystruct", structType)); var upd = new DocumentUpdate(docType, "id:scheme:my_input::"); @@ -91,4 +97,59 @@ public class DocumentUpdateTestCase { var av = (AssignValueUpdate)valueUpdate; assertEquals(av.getValue(), updatedStruct); } + + @Test + public void assign_matched_array_of_structs_element_update_is_preserved() throws ParseException { + var docType = new DocumentType("my_input"); + var structType = makeStructType(); + var arrayType = ArrayDataType.getArray(structType); + docType.addField(new Field("my_array", arrayType)); + + var updatedStruct = new Struct(structType); + updatedStruct.setFieldValue("foo", new StringFieldValue("new groovy value")); + updatedStruct.setFieldValue("bar", new StringFieldValue("totally tubular!")); + + var upd = new DocumentUpdate(docType, "id:scheme:my_input::"); + var assignUpdate = ValueUpdate.createAssign(updatedStruct); + upd.addFieldUpdate(FieldUpdate.createMap(docType.getField("my_array"), + new IntegerFieldValue(2), assignUpdate)); + + upd = Expression.execute(Expression.fromString("input my_array | passthrough my_array"), upd); + + assertEquals(upd.fieldUpdates().size(), 1); + var fieldUpdate = upd.getFieldUpdate("my_array"); + assertNotNull(fieldUpdate); + var valueUpdate = fieldUpdate.getValueUpdate(0); + assertTrue(valueUpdate instanceof MapValueUpdate); + var mvu = (MapValueUpdate)valueUpdate; + assertEquals(mvu.getValue(), new IntegerFieldValue(2)); + assertEquals(mvu.getUpdate(), assignUpdate); + } + + @Test + public void assign_matched_array_of_primitives_element_update_is_preserved() throws ParseException { + var docType = new DocumentType("my_input"); + var arrayType = ArrayDataType.getArray(DataType.INT); + docType.addField(new Field("my_array", arrayType)); + + var upd = new DocumentUpdate(docType, "id:scheme:my_input::"); + // Use an unreasonably large array index to ensure nothing creates an implicit array under the + // hood when processing the update itself. "Ensure" here means "the test will most likely OOM + // and we'll notice it pretty quickly". + var arrayIndex = new IntegerFieldValue(2_000_000_000); + var assignUpdate = ValueUpdate.createAssign(new IntegerFieldValue(12345)); + upd.addFieldUpdate(FieldUpdate.createMap(docType.getField("my_array"), arrayIndex, assignUpdate)); + + upd = Expression.execute(Expression.fromString("input my_array | passthrough my_array"), upd); + + assertEquals(upd.fieldUpdates().size(), 1); + var fieldUpdate = upd.getFieldUpdate("my_array"); + assertNotNull(fieldUpdate); + var valueUpdate = fieldUpdate.getValueUpdate(0); + assertTrue(valueUpdate instanceof MapValueUpdate); + var mvu = (MapValueUpdate)valueUpdate; + assertEquals(mvu.getValue(), arrayIndex); + assertEquals(mvu.getUpdate(), assignUpdate); + } + } diff --git a/indexinglanguage/src/test/java/com/yahoo/vespa/indexinglanguage/ValueUpdateToDocumentTestCase.java b/indexinglanguage/src/test/java/com/yahoo/vespa/indexinglanguage/ValueUpdateToDocumentTestCase.java index b9be7ddbe50..2468dbe5003 100644 --- a/indexinglanguage/src/test/java/com/yahoo/vespa/indexinglanguage/ValueUpdateToDocumentTestCase.java +++ b/indexinglanguage/src/test/java/com/yahoo/vespa/indexinglanguage/ValueUpdateToDocumentTestCase.java @@ -138,6 +138,32 @@ public class ValueUpdateToDocumentTestCase { } @Test + public void array_of_struct_assign_is_converted() { + DocumentType docType = new DocumentType("my_type"); + StructDataType structType = new StructDataType("my_struct"); + structType.addField(new Field("a", DataType.INT)); + ArrayDataType arrType = DataType.getArray(structType); + Field field = new Field("my_arr", arrType); + docType.addField(field); + + var updatedStruct = new Struct(structType); + updatedStruct.setFieldValue("a", new IntegerFieldValue(42)); + ValueUpdate update = ValueUpdate.createMap(new IntegerFieldValue(2), ValueUpdate.createAssign(updatedStruct)); + + Document doc = FieldUpdateHelper.newPartialDocument(docType, new DocumentId("id:foo:my_type::1"), field, update); + assertNotNull(doc); + // Due to how the roller coaster ride of the partial documents appear to work, we end up creating + // a document with an array that only contains the to-be-updated element, but always at the first + // index rather than the arbitrary updated index (which is good because otherwise it'd have to + // be pre-allocated). + FieldValue obj = doc.getFieldValue("my_arr"); + assertTrue(obj instanceof Array); + Array arr = (Array)obj; + assertEquals(1, arr.size()); + assertEquals(updatedStruct, arr.get(0)); + } + + @Test public void requireThatRemoveIsConverted() { DocumentType docType = new DocumentType("my_type"); ArrayDataType arrType = DataType.getArray(DataType.INT); |