From c8d2b997dc3d11e86de6f5005a77860a5b02aeff Mon Sep 17 00:00:00 2001 From: Lukas Eder Date: Thu, 23 Aug 2012 19:27:24 +0200 Subject: [PATCH] [#1727] Cast VARCHAR bind values to their actual string length in Firebird --- jOOQ/src/main/java/org/jooq/impl/Val.java | 32 ++++++++++++++++++----- 1 file changed, 26 insertions(+), 6 deletions(-) diff --git a/jOOQ/src/main/java/org/jooq/impl/Val.java b/jOOQ/src/main/java/org/jooq/impl/Val.java index eca510e127..8c30514016 100644 --- a/jOOQ/src/main/java/org/jooq/impl/Val.java +++ b/jOOQ/src/main/java/org/jooq/impl/Val.java @@ -233,12 +233,10 @@ class Val extends AbstractField implements Param { toSQL(context, getValue(), getType()); } - // [#1727] VARCHAR types should be cast to their actual lengths - else if (getValue() != null && type == SQLDataType.VARCHAR) { - - // Multiply by 4 to be sure that even UTF-32 collations will fit - // But don't use larger numbers than Derby's upper limit 32672 - toSQLCast(context, getDataType(context), Math.min(32672, 4 * ((String) getValue()).length())); + // [#1727] VARCHAR types should be cast to their actual lengths in some + // dialects + else if (getValue() != null && type == SQLDataType.VARCHAR && asList(FIREBIRD).contains(context.getDialect())) { + toSQLCast(context, getDataType(context), getValueLength()); } // In all other cases, the bind variable can be cast normally @@ -247,6 +245,28 @@ class Val extends AbstractField implements Param { } } + private int getValueLength() { + String string = (String) getValue(); + 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 void toSQLCast(RenderContext context, DataType type, int length) { context.keyword("cast("); toSQL(context, getValue(), getType());