From 4849513ddbe5a50def74bbe08468dbb2e61bccac Mon Sep 17 00:00:00 2001 From: Lukas Eder Date: Thu, 31 Mar 2022 17:22:01 +0200 Subject: [PATCH] [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. --- .../java/org/jooq/impl/DefaultBinding.java | 2 +- .../java/org/jooq/impl/DefaultDSLContext.java | 2 +- .../main/java/org/jooq/impl/JSONReader.java | 35 +++++++++++-------- .../main/java/org/jooq/impl/LoaderImpl.java | 2 +- 4 files changed, 24 insertions(+), 17 deletions(-) diff --git a/jOOQ/src/main/java/org/jooq/impl/DefaultBinding.java b/jOOQ/src/main/java/org/jooq/impl/DefaultBinding.java index 082a204157..683999762b 100644 --- a/jOOQ/src/main/java/org/jooq/impl/DefaultBinding.java +++ b/jOOQ/src/main/java/org/jooq/impl/DefaultBinding.java @@ -4087,7 +4087,7 @@ public class DefaultBinding implements Binding { static Result readMultisetJSON(Scope ctx, AbstractRow row, Class 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); } diff --git a/jOOQ/src/main/java/org/jooq/impl/DefaultDSLContext.java b/jOOQ/src/main/java/org/jooq/impl/DefaultDSLContext.java index 5c2c925a11..d1901db477 100644 --- a/jOOQ/src/main/java/org/jooq/impl/DefaultDSLContext.java +++ b/jOOQ/src/main/java/org/jooq/impl/DefaultDSLContext.java @@ -1426,7 +1426,7 @@ public class DefaultDSLContext extends AbstractScope implements DSLContext, Seri @Override public Result fetchFromJSON(String string) { - return new JSONReader(this, null, null).read(string); + return new JSONReader(this, null, null, false).read(string); } @Override diff --git a/jOOQ/src/main/java/org/jooq/impl/JSONReader.java b/jOOQ/src/main/java/org/jooq/impl/JSONReader.java index 14856af949..4bbf79d3e4 100644 --- a/jOOQ/src/main/java/org/jooq/impl/JSONReader.java +++ b/jOOQ/src/main/java/org/jooq/impl/JSONReader.java @@ -88,11 +88,13 @@ final class JSONReader { private final DSLContext ctx; private final AbstractRow row; private final Class recordType; + private final boolean multiset; - JSONReader(DSLContext ctx, AbstractRow row, Class recordType) { + JSONReader(DSLContext ctx, AbstractRow row, Class recordType, boolean multiset) { this.ctx = ctx; this.row = row; this.recordType = recordType != null ? recordType : (Class) Record.class; + this.multiset = multiset; } final Result read(String string) { @@ -249,20 +251,25 @@ final class JSONReader { 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)); } diff --git a/jOOQ/src/main/java/org/jooq/impl/LoaderImpl.java b/jOOQ/src/main/java/org/jooq/impl/LoaderImpl.java index 87106f7b2d..10cfb61062 100644 --- a/jOOQ/src/main/java/org/jooq/impl/LoaderImpl.java +++ b/jOOQ/src/main/java/org/jooq/impl/LoaderImpl.java @@ -685,7 +685,7 @@ final class LoaderImpl implements try { reader = input.reader(); - Result r = new JSONReader<>(configuration.dsl(), null, null).read(reader); + Result r = new JSONReader<>(configuration.dsl(), null, null, false).read(reader); source = r.fields(); // The current json format is not designed for streaming. Thats why