diff --git a/jOOQ/src/main/java/org/jooq/impl/Val.java b/jOOQ/src/main/java/org/jooq/impl/Val.java index 40fc577773..0821af4305 100644 --- a/jOOQ/src/main/java/org/jooq/impl/Val.java +++ b/jOOQ/src/main/java/org/jooq/impl/Val.java @@ -257,6 +257,12 @@ class Val extends AbstractParam { toSQL(context, value, getConverter()); } + // [#1727] VARCHAR types should be cast to their actual lengths in some + // dialects + else if ((type == SQLDataType.VARCHAR || type == SQLDataType.CHAR) && asList(FIREBIRD).contains(family)) { + toSQLCast(context, dataType, getValueLength(), 0, 0); + } + /* [pro] xx xx xxxxxxx xxxx xxxx xxxxx xxxxxx xxx xx xxxx xx xxx xxxxxx xx xxxx xxxxxxxx xxxx xx xxxxx xx xxxxxxxxxxxxxxxxxxxxxxx xx xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx x @@ -270,6 +276,28 @@ class Val extends AbstractParam { } } + private final int getValueLength() { + String string = (String) value; + if (string == null) { + return 1; + } + + else { + int length = string.length(); + + // If non 7-bit ASCII characters are present, multiply the length by + // 4 to be sure that even UTF-32 collations will fit. But don't use + // larger numbers than Derby's upper limit 32672 + for (int i = 0; i < length; i++) { + if (string.charAt(i) > 127) { + return Math.min(32672, 4 * length); + } + } + + return Math.min(32672, length); + } + } + private final void toSQLCast(RenderContext context, DataType type, int length, int precision, int scale) { context.keyword("cast").sql("("); toSQL(context, value, getConverter());