[jOOQ/jOOQ#12134] Let JSONReader distinguish between multiset and other

Only the MULTISET usage of JSONReader should parse different binary formats depending on dialects (e.g. base64, hex, text, etc.). Ordinary usage should continue parsing base64 irrespective of the used dialect, as that's what had been used by the Loader, for example.
This commit is contained in:
Lukas Eder 2022-03-31 17:22:01 +02:00
parent ce4115dac9
commit 4849513ddb
4 changed files with 24 additions and 17 deletions

View File

@ -4087,7 +4087,7 @@ public class DefaultBinding<T, U> implements Binding<T, U> {
static <R extends Record> Result<R> readMultisetJSON(Scope ctx, AbstractRow<R> row, Class<R> recordType, String s) {
if (s.startsWith("{") || s.startsWith("["))
return new JSONReader<>(ctx.dsl(), row, recordType).read(new StringReader(s), true);
return new JSONReader<>(ctx.dsl(), row, recordType, true).read(new StringReader(s), true);
else
return readMultisetScalar(ctx, row, recordType, s);
}

View File

@ -1426,7 +1426,7 @@ public class DefaultDSLContext extends AbstractScope implements DSLContext, Seri
@Override
public Result<Record> fetchFromJSON(String string) {
return new JSONReader<Record>(this, null, null).read(string);
return new JSONReader<Record>(this, null, null, false).read(string);
}
@Override

View File

@ -88,11 +88,13 @@ final class JSONReader<R extends Record> {
private final DSLContext ctx;
private final AbstractRow<R> row;
private final Class<? extends R> recordType;
private final boolean multiset;
JSONReader(DSLContext ctx, AbstractRow<R> row, Class<? extends R> recordType) {
JSONReader(DSLContext ctx, AbstractRow<R> row, Class<? extends R> recordType, boolean multiset) {
this.ctx = ctx;
this.row = row;
this.recordType = recordType != null ? recordType : (Class<? extends R>) Record.class;
this.multiset = multiset;
}
final Result<R> read(String string) {
@ -249,20 +251,25 @@ final class JSONReader<R extends Record> {
if (field.getType() == byte[].class && record.get(i) instanceof String) {
String s = (String) record.get(i);
// [#12134] PostgreSQL encodes binary data as hex
if (ENCODE_BINARY_AS_HEX.contains(ctx.dialect()))
if (s.startsWith("\\x"))
record.set(i, convertHexToBytes(s, 1, Integer.MAX_VALUE));
if (multiset) {
// [#12134] PostgreSQL encodes binary data as hex
if (ENCODE_BINARY_AS_HEX.contains(ctx.dialect()))
if (s.startsWith("\\x"))
record.set(i, convertHexToBytes(s, 1, Integer.MAX_VALUE));
else
record.set(i, convertHexToBytes(s));
// [#12134] MariaDB encodes binary data as text (?)
else if (ENCODE_BINARY_AS_TEXT.contains(ctx.dialect()))
record.set(i, s);
// [#12134] MySQL encodes binary data as prefixed base64
else if (s.startsWith("base64:type15:"))
record.set(i, Base64.getDecoder().decode(s.substring(14)));
else
record.set(i, convertHexToBytes(s));
// [#12134] MariaDB encodes binary data as text (?)
else if (ENCODE_BINARY_AS_TEXT.contains(ctx.dialect()))
record.set(i, s);
// [#12134] MySQL encodes binary data as prefixed base64
else if (s.startsWith("base64:type15:"))
record.set(i, Base64.getDecoder().decode(s.substring(14)));
record.set(i, Base64.getDecoder().decode(s));
}
else
record.set(i, Base64.getDecoder().decode(s));
}

View File

@ -685,7 +685,7 @@ final class LoaderImpl<R extends Record> implements
try {
reader = input.reader();
Result<Record> r = new JSONReader<>(configuration.dsl(), null, null).read(reader);
Result<Record> r = new JSONReader<>(configuration.dsl(), null, null, false).read(reader);
source = r.fields();
// The current json format is not designed for streaming. Thats why