aboutsummaryrefslogtreecommitdiffstats
path: root/document/src/main/java/com/yahoo/document/json
diff options
context:
space:
mode:
authorjonmv <venstad@gmail.com>2024-01-23 11:17:45 +0100
committerjonmv <venstad@gmail.com>2024-01-23 11:17:45 +0100
commit06bf40f368802b8b64105b434afd7e26f758f3e6 (patch)
tree3b5344c53b5e0f71594c73912e91c3cd1c2d6b36 /document/src/main/java/com/yahoo/document/json
parent8ead2603e1b5233736aadbc6ef7df26507b873df (diff)
Fix parsing of recursive "match" update syntax
Diffstat (limited to 'document/src/main/java/com/yahoo/document/json')
-rw-r--r--document/src/main/java/com/yahoo/document/json/TokenBuffer.java28
-rw-r--r--document/src/main/java/com/yahoo/document/json/readers/MapReader.java59
2 files changed, 26 insertions, 61 deletions
diff --git a/document/src/main/java/com/yahoo/document/json/TokenBuffer.java b/document/src/main/java/com/yahoo/document/json/TokenBuffer.java
index c1ac239d5f0..dec84e46b77 100644
--- a/document/src/main/java/com/yahoo/document/json/TokenBuffer.java
+++ b/document/src/main/java/com/yahoo/document/json/TokenBuffer.java
@@ -150,34 +150,6 @@ public class TokenBuffer {
return nesting;
}
- public Token prefetchScalar(String name) {
- int localNesting = nesting();
- int nestingBarrier = localNesting;
- Token toReturn = null;
- Iterator<Token> i;
-
- if (name.equals(currentName()) && current().isScalarValue()) {
- toReturn = tokens.get(position);
- } else {
- i = rest().iterator();
- i.next(); // just ignore the first value, as we know it's not what
- // we're looking for, and it's nesting effect is already
- // included
- while (i.hasNext()) {
- Token t = i.next();
- if (localNesting == nestingBarrier && name.equals(t.name) && t.token.isScalarValue()) {
- toReturn = t;
- break;
- }
- localNesting += nestingOffset(t.token);
- if (localNesting < nestingBarrier) {
- break;
- }
- }
- }
- return toReturn;
- }
-
public void skipToRelativeNesting(int relativeNesting) {
int initialNesting = nesting();
do {
diff --git a/document/src/main/java/com/yahoo/document/json/readers/MapReader.java b/document/src/main/java/com/yahoo/document/json/readers/MapReader.java
index a373fa56fd9..c81d296db39 100644
--- a/document/src/main/java/com/yahoo/document/json/readers/MapReader.java
+++ b/document/src/main/java/com/yahoo/document/json/readers/MapReader.java
@@ -90,44 +90,37 @@ public class MapReader {
@SuppressWarnings({ "rawtypes", "unchecked" })
public static ValueUpdate createMapUpdate(TokenBuffer buffer,
DataType currentLevel,
- FieldValue keyParent,
- FieldValue topLevelKey,
boolean ignoreUndefinedFields) {
- TokenBuffer.Token element = buffer.prefetchScalar(UPDATE_ELEMENT);
- if (UPDATE_ELEMENT.equals(buffer.currentName())) {
+ if ( ! JsonToken.START_OBJECT.equals(buffer.current()))
+ throw new IllegalArgumentException("Expected object for match update, got " + buffer.current());
+ buffer.next();
+
+ FieldValue key = null;
+ ValueUpdate update;
+ boolean elementFirst = UPDATE_ELEMENT.equals(buffer.currentName());
+ if (elementFirst) {
+ key = keyTypeForMapUpdate(buffer.currentText(), currentLevel);
buffer.next();
}
- FieldValue key = keyTypeForMapUpdate(element, currentLevel);
- if (keyParent != null) {
- ((CollectionFieldValue) keyParent).add(key);
- }
- // structure is: [(match + element)*, (element + action)]
- // match will always have element, and either match or action
- if (!UPDATE_MATCH.equals(buffer.currentName())) {
- // we have reached an action...
- if (topLevelKey == null) {
- return ValueUpdate.createMap(key, readSingleUpdate(buffer, valueTypeForMapUpdate(currentLevel), buffer.currentName(), ignoreUndefinedFields));
- } else {
- return ValueUpdate.createMap(topLevelKey, readSingleUpdate(buffer, valueTypeForMapUpdate(currentLevel), buffer.currentName(), ignoreUndefinedFields));
- }
- } else {
- // next level of matching
- if (topLevelKey == null) {
- return createMapUpdate(buffer, valueTypeForMapUpdate(currentLevel), key, key, ignoreUndefinedFields);
- } else {
- return createMapUpdate(buffer, valueTypeForMapUpdate(currentLevel), key, topLevelKey, ignoreUndefinedFields);
- }
+ update = UPDATE_MATCH.equals(buffer.currentName()) ? createMapUpdate(buffer, valueTypeForMapUpdate(currentLevel), ignoreUndefinedFields)
+ : readSingleUpdate(buffer, valueTypeForMapUpdate(currentLevel), buffer.currentName(), ignoreUndefinedFields);
+ buffer.next();
+
+ if ( ! elementFirst) {
+ key = keyTypeForMapUpdate(buffer.currentText(), currentLevel);
+ buffer.next();
}
+
+ if ( ! JsonToken.END_OBJECT.equals(buffer.current()))
+ throw new IllegalArgumentException("Expected object end for match update, got " + buffer.current());
+
+ return ValueUpdate.createMap(key, update);
}
@SuppressWarnings("rawtypes")
public static ValueUpdate createMapUpdate(TokenBuffer buffer, Field field, boolean ignoreUndefinedFields) {
- buffer.next();
- MapValueUpdate m = (MapValueUpdate) MapReader.createMapUpdate(buffer, field.getDataType(), null, null, ignoreUndefinedFields);
- buffer.next();
- // must generate the field value in parallel with the actual
- return m;
+ return MapReader.createMapUpdate(buffer, field.getDataType(), ignoreUndefinedFields);
}
private static DataType valueTypeForMapUpdate(DataType parentType) {
@@ -142,14 +135,14 @@ public class MapReader {
}
}
- private static FieldValue keyTypeForMapUpdate(TokenBuffer.Token element, DataType expectedType) {
+ private static FieldValue keyTypeForMapUpdate(String elementText, DataType expectedType) {
FieldValue v;
if (expectedType instanceof ArrayDataType) {
- v = new IntegerFieldValue(Integer.valueOf(element.text));
+ v = new IntegerFieldValue(Integer.valueOf(elementText));
} else if (expectedType instanceof WeightedSetDataType) {
- v = ((WeightedSetDataType) expectedType).getNestedType().createFieldValue(element.text);
+ v = ((WeightedSetDataType) expectedType).getNestedType().createFieldValue(elementText);
} else if (expectedType instanceof MapDataType) {
- v = ((MapDataType) expectedType).getKeyType().createFieldValue(element.text);
+ v = ((MapDataType) expectedType).getKeyType().createFieldValue(elementText);
} else {
throw new IllegalArgumentException("Container type " + expectedType + " not supported for match update.");
}