[#1154] Bad inlining of byte[] in most dialects
This commit is contained in:
parent
0071b65f4b
commit
30f44b809a
@ -313,17 +313,14 @@ extends BaseTest<A, B, S, B2S, BS, L, X, D, T, U, I, IPK, T658, T725, T639, T785
|
||||
|
||||
Object[] array1 = create.select(vals(s1, s2, s3, s4)).fetchOneArray();
|
||||
Object[] array2 = create.select(vals(b1, b2, sh1, sh2, i1, i2, l1, l2, bi1, bi2, bd1, bd2, db1, db2, f1, f2)).fetchOneArray();
|
||||
Object[] array3 = create.select(vals(d1, d2, t1, t2, ts1, ts2)).fetchOneArray();
|
||||
Object[] array4 = create.select(vals(by1, by2, bool1, bool2, bool3)).fetchOneArray();
|
||||
|
||||
assertEquals(4, array1.length);
|
||||
assertEquals(16, array2.length);
|
||||
assertEquals(6, array3.length);
|
||||
assertEquals(5, array4.length);
|
||||
|
||||
assertEquals(asList(s1, s2, s3, s4), asList(array1));
|
||||
assertEquals(asList((Number) b1, b2, sh1, sh2, i1, i2, l1, l2, bi1, bi2, bd1, bd2, db1, db2, f1, f2), asList(array2));
|
||||
assertEquals(asList(d1, d2, t1, t2, ts1, ts2), asList(array3));
|
||||
|
||||
array4[0] = new String((byte[]) array4[0]);
|
||||
assertEquals(asList(new String(by1), by2, bool1, bool2, bool3), asList(array4));
|
||||
|
||||
@ -35,7 +35,9 @@
|
||||
*/
|
||||
package org.jooq.impl;
|
||||
|
||||
import static java.lang.Integer.toOctalString;
|
||||
import static org.jooq.impl.Factory.getDataType;
|
||||
import static org.jooq.tools.StringUtils.leftPad;
|
||||
|
||||
import java.lang.reflect.Constructor;
|
||||
import java.lang.reflect.Method;
|
||||
@ -840,4 +842,53 @@ final class Util {
|
||||
|
||||
return StatementType.PREPARED_STATEMENT;
|
||||
}
|
||||
|
||||
|
||||
// ------------------------------------------------------------------------
|
||||
// XXX This section is taken from the H2 Database
|
||||
// ------------------------------------------------------------------------
|
||||
|
||||
private static final char[] HEX = "0123456789abcdef".toCharArray();
|
||||
|
||||
/**
|
||||
* Convert a byte array to a hex encoded string.
|
||||
*
|
||||
* @param value the byte array
|
||||
* @return the hex encoded string
|
||||
*/
|
||||
static String convertBytesToHex(byte[] value) {
|
||||
return convertBytesToHex(value, value.length);
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert a byte array to a hex encoded string.
|
||||
*
|
||||
* @param value the byte array
|
||||
* @param len the number of bytes to encode
|
||||
* @return the hex encoded string
|
||||
*/
|
||||
static String convertBytesToHex(byte[] value, int len) {
|
||||
char[] buff = new char[len + len];
|
||||
char[] hex = HEX;
|
||||
for (int i = 0; i < len; i++) {
|
||||
int c = value[i] & 0xff;
|
||||
buff[i + i] = hex[c >> 4];
|
||||
buff[i + i + 1] = hex[c & 0xf];
|
||||
}
|
||||
return new String(buff);
|
||||
}
|
||||
|
||||
/**
|
||||
* Postgres uses octals instead of hex encoding
|
||||
*/
|
||||
static String convertBytesToPostgresOctal(byte[] binary) {
|
||||
StringBuilder sb = new StringBuilder();
|
||||
|
||||
for (byte b : binary) {
|
||||
sb.append("\\\\");
|
||||
sb.append(leftPad(toOctalString(b), 3, '0'));
|
||||
}
|
||||
|
||||
return sb.toString();
|
||||
}
|
||||
}
|
||||
@ -42,12 +42,12 @@ import static org.jooq.SQLDialect.DERBY;
|
||||
import static org.jooq.SQLDialect.H2;
|
||||
import static org.jooq.SQLDialect.HSQLDB;
|
||||
import static org.jooq.SQLDialect.INGRES;
|
||||
import static org.jooq.SQLDialect.MYSQL;
|
||||
import static org.jooq.SQLDialect.ORACLE;
|
||||
import static org.jooq.SQLDialect.POSTGRES;
|
||||
import static org.jooq.SQLDialect.SQLITE;
|
||||
import static org.jooq.SQLDialect.SQLSERVER;
|
||||
import static org.jooq.SQLDialect.SYBASE;
|
||||
import static org.jooq.conf.StatementType.STATEMENT;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
import java.util.Arrays;
|
||||
@ -64,8 +64,6 @@ import org.jooq.Param;
|
||||
import org.jooq.RenderContext;
|
||||
import org.jooq.SQLDialect;
|
||||
import org.jooq.UDTRecord;
|
||||
import org.jooq.exception.DataAccessException;
|
||||
import org.jooq.tools.JooqLogger;
|
||||
import org.jooq.tools.StringUtils;
|
||||
|
||||
/**
|
||||
@ -270,24 +268,41 @@ class Val<T> extends AbstractField<T> implements Param<T>, BindingProvider {
|
||||
context.sql(val.toString());
|
||||
}
|
||||
}
|
||||
|
||||
// [#1154] Binary data cannot always be inlined
|
||||
else if (type == byte[].class) {
|
||||
byte[] binary = (byte[]) val;
|
||||
|
||||
// [#1154] Binary data cannot always be inlined
|
||||
if (dialect == H2) {
|
||||
if (asList(ASE, SQLSERVER, SYBASE).contains(dialect)) {
|
||||
context.sql("0x")
|
||||
.sql(Util.convertBytesToHex(binary));
|
||||
}
|
||||
else if (dialect == DB2) {
|
||||
context.sql("blob(X'")
|
||||
.sql(Util.convertBytesToHex(binary))
|
||||
.sql("')");
|
||||
}
|
||||
else if (asList(DERBY, H2, HSQLDB, INGRES, MYSQL, SQLITE).contains(dialect)) {
|
||||
context.sql("X'")
|
||||
.sql(StringUtils.convertBytesToHex(binary))
|
||||
.sql(Util.convertBytesToHex(binary))
|
||||
.sql("'");
|
||||
}
|
||||
else if (Util.getStatementType(context.getSettings()) == STATEMENT) {
|
||||
throw new DataAccessException("Cannot inline binary data in dialect " + dialect + ". Use StatementType.PREPARED_STATEMENT instead");
|
||||
else if (asList(ORACLE).contains(dialect)) {
|
||||
context.sql("hextoraw('")
|
||||
.sql(Util.convertBytesToHex(binary))
|
||||
.sql("')");
|
||||
}
|
||||
else if (dialect == POSTGRES) {
|
||||
context.sql("E'")
|
||||
.sql(Util.convertBytesToPostgresOctal(binary))
|
||||
.sql("'::bytea");
|
||||
}
|
||||
|
||||
// This default behaviour is used in debug logging for dialects
|
||||
// that do not support inlining binary data
|
||||
else {
|
||||
context.sql("'")
|
||||
.sql(Arrays.toString(binary).replace("'", "''"))
|
||||
context.sql("X'")
|
||||
.sql(Util.convertBytesToHex(binary))
|
||||
.sql("'");
|
||||
}
|
||||
}
|
||||
|
||||
@ -936,38 +936,4 @@ public final class StringUtils {
|
||||
String cc = toCamelCase(string);
|
||||
return cc.substring(0, 1).toLowerCase() + cc.substring(1);
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------
|
||||
// XXX This section is taken from the H2 Database
|
||||
// ------------------------------------------------------------------------
|
||||
|
||||
private static final char[] HEX = "0123456789abcdef".toCharArray();
|
||||
|
||||
/**
|
||||
* Convert a byte array to a hex encoded string.
|
||||
*
|
||||
* @param value the byte array
|
||||
* @return the hex encoded string
|
||||
*/
|
||||
public static String convertBytesToHex(byte[] value) {
|
||||
return convertBytesToHex(value, value.length);
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert a byte array to a hex encoded string.
|
||||
*
|
||||
* @param value the byte array
|
||||
* @param len the number of bytes to encode
|
||||
* @return the hex encoded string
|
||||
*/
|
||||
public static String convertBytesToHex(byte[] value, int len) {
|
||||
char[] buff = new char[len + len];
|
||||
char[] hex = HEX;
|
||||
for (int i = 0; i < len; i++) {
|
||||
int c = value[i] & 0xff;
|
||||
buff[i + i] = hex[c >> 4];
|
||||
buff[i + i + 1] = hex[c & 0xf];
|
||||
}
|
||||
return new String(buff);
|
||||
}
|
||||
}
|
||||
|
||||
Loading…
Reference in New Issue
Block a user