|
@@ -390,34 +390,58 @@ public class InternalComposite
|
|
|
* Format <code>obj</code> using the provided {@link DocValueFormat}.
|
|
|
* If the format is equals to {@link DocValueFormat#RAW}, the object is returned as is
|
|
|
* for numbers and a string for {@link BytesRef}s.
|
|
|
+ *
|
|
|
+ * This method will then attempt to parse the formatted value using the specified format,
|
|
|
+ * and throw an IllegalArgumentException if parsing fails. This in turn prevents us from
|
|
|
+ * returning an after_key which we can't subsequently parse into the original value.
|
|
|
*/
|
|
|
static Object formatObject(Object obj, DocValueFormat format) {
|
|
|
if (obj == null) {
|
|
|
return null;
|
|
|
}
|
|
|
+ Object formatted = obj;
|
|
|
+ Object parsed;
|
|
|
if (obj.getClass() == BytesRef.class) {
|
|
|
BytesRef value = (BytesRef) obj;
|
|
|
if (format == DocValueFormat.RAW) {
|
|
|
- return value.utf8ToString();
|
|
|
+ formatted = value.utf8ToString();
|
|
|
} else {
|
|
|
- return format.format(value);
|
|
|
+ formatted = format.format(value);
|
|
|
+ }
|
|
|
+ parsed = format.parseBytesRef(formatted.toString());
|
|
|
+ if (parsed.equals(obj) == false) {
|
|
|
+ throw new IllegalArgumentException("Format [" + format + "] created output it couldn't parse for value [" + obj +"] "
|
|
|
+ + "of type [" + obj.getClass() + "]. parsed value: [" + parsed + "(" + parsed.getClass() + ")]");
|
|
|
}
|
|
|
} else if (obj.getClass() == Long.class) {
|
|
|
long value = (long) obj;
|
|
|
if (format == DocValueFormat.RAW) {
|
|
|
- return value;
|
|
|
+ formatted = value;
|
|
|
} else {
|
|
|
- return format.format(value);
|
|
|
+ formatted = format.format(value);
|
|
|
+ }
|
|
|
+ parsed = format.parseLong(formatted.toString(), false, () -> {
|
|
|
+ throw new UnsupportedOperationException("Using now() is not supported in after keys");
|
|
|
+ });
|
|
|
+ if (parsed.equals(((Number) obj).longValue()) == false) {
|
|
|
+ throw new IllegalArgumentException("Format [" + format + "] created output it couldn't parse for value [" + obj +"] "
|
|
|
+ + "of type [" + obj.getClass() + "]. parsed value: [" + parsed + "(" + parsed.getClass() + ")]");
|
|
|
}
|
|
|
} else if (obj.getClass() == Double.class) {
|
|
|
double value = (double) obj;
|
|
|
if (format == DocValueFormat.RAW) {
|
|
|
- return value;
|
|
|
+ formatted = value;
|
|
|
} else {
|
|
|
- return format.format(value);
|
|
|
+ formatted = format.format(value);
|
|
|
+ }
|
|
|
+ parsed = format.parseDouble(formatted.toString(), false,
|
|
|
+ () -> {throw new UnsupportedOperationException("Using now() is not supported in after keys");});
|
|
|
+ if (parsed.equals(((Number) obj).doubleValue()) == false) {
|
|
|
+ throw new IllegalArgumentException("Format [" + format + "] created output it couldn't parse for value [" + obj +"] "
|
|
|
+ + "of type [" + obj.getClass() + "]. parsed value: [" + parsed + "(" + parsed.getClass() + ")]");
|
|
|
}
|
|
|
}
|
|
|
- return obj;
|
|
|
+ return formatted;
|
|
|
}
|
|
|
|
|
|
static class ArrayMap extends AbstractMap<String, Object> implements Comparable<ArrayMap> {
|