From 3e81f4649edabe63e2fbb88754ce9ca4572b80f2 Mon Sep 17 00:00:00 2001 From: Lukas Eder Date: Fri, 22 Aug 2025 14:30:09 +0200 Subject: [PATCH] [jOOQ/jOOQ#18876] Base64 error when using multiset, binary column, and custom converter in MySQL --- .../main/java/org/jooq/impl/JSONReader.java | 19 ++++++++++++++++--- 1 file changed, 16 insertions(+), 3 deletions(-) diff --git a/jOOQ/src/main/java/org/jooq/impl/JSONReader.java b/jOOQ/src/main/java/org/jooq/impl/JSONReader.java index e44ccfa9e2..c1b85abe97 100644 --- a/jOOQ/src/main/java/org/jooq/impl/JSONReader.java +++ b/jOOQ/src/main/java/org/jooq/impl/JSONReader.java @@ -67,6 +67,8 @@ import java.util.List; import java.util.Map; import java.util.Map.Entry; import java.util.Set; +import java.util.regex.Matcher; +import java.util.regex.Pattern; import org.jooq.ContextConverter; import org.jooq.ConverterContext; @@ -78,6 +80,7 @@ import org.jooq.QualifiedRecord; import org.jooq.Record; import org.jooq.Result; import org.jooq.SQLDialect; +import org.jooq.SQLDialectCategory; import org.jooq.Source; /** @@ -232,6 +235,7 @@ final class JSONReader { private static final Set ENCODE_BINARY_AS_HEX = SQLDialect.supportedBy(H2, POSTGRES, SQLITE, TRINO, YUGABYTEDB); private static final Set ENCODE_BINARY_AS_TEXT = SQLDialect.supportedBy(MARIADB); + private static final Pattern P_MYSQL_BINARY_PREFIX = Pattern.compile("^base64:type\\d+:(.*)$"); private static final List patchRecord(DSLContext ctx, boolean multiset, Fields result, List record) { ConverterContext cc = null; @@ -245,6 +249,7 @@ final class JSONReader { // not according to org.jooq.tools.Convert if (t.isBinary() && value instanceof String s) { if (multiset) { + Matcher m; // [#12134] PostgreSQL encodes binary data as hex // TODO [#13427] This doesn't work if bytea_output is set to escape @@ -258,9 +263,17 @@ final class JSONReader { 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))); + // [#12134] [#18876] MySQL encodes binary data as prefixed base64 + // - type15: VARBINARY + // - type16: BIT + // - type249: TINYBLOB + // - type250: MEDIUMBLOB and LONG VARBINARY + // - type251: LONGBLOB + // - type252: BLOB + // - type254: BINARY + else if (ctx.family().category() == SQLDialectCategory.MYSQL + && (m = P_MYSQL_BINARY_PREFIX.matcher(s)).matches()) + record.set(i, Base64.getDecoder().decode(m.replaceFirst("$1"))); else record.set(i, Base64.getDecoder().decode(s)); }