Index: openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/kernel/exps/StringLength.java =================================================================== --- openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/kernel/exps/StringLength.java (revision 566297) +++ openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/kernel/exps/StringLength.java (working copy) @@ -53,6 +53,8 @@ SQLBuffer buf, int index) { DBDictionary dict = ctx.store.getDBDictionary(); String func = dict.stringLengthFunction; + if (getValue() instanceof Lit || getValue() instanceof Param) + func = dict.addCastAsString(func, "{0}", " AS VARCHAR(1000))"); dict.assertSupport(func != null, "StringLengthFunction"); int idx = func.indexOf("{0}"); Index: openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/kernel/exps/ToLowerCase.java =================================================================== --- openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/kernel/exps/ToLowerCase.java (revision 566297) +++ openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/kernel/exps/ToLowerCase.java (working copy) @@ -42,6 +42,8 @@ DBDictionary dict = ctx.store.getDBDictionary(); String func = dict.toLowerCaseFunction; + if (getValue() instanceof Lit || getValue() instanceof Param) + func = dict.addCastAsString(func, "{0}", " AS VARCHAR(1000))"); dict.assertSupport(func != null, "ToLowerCaseFunction"); int idx = func.indexOf("{0}"); Index: openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/kernel/exps/ToUpperCase.java =================================================================== --- openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/kernel/exps/ToUpperCase.java (revision 566297) +++ openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/kernel/exps/ToUpperCase.java (working copy) @@ -42,6 +42,8 @@ DBDictionary dict = ctx.store.getDBDictionary(); String func = dict.toUpperCaseFunction; + if (getValue() instanceof Lit || getValue() instanceof Param) + func = dict.addCastAsString(func, "{0}", " AS VARCHAR(1000))"); dict.assertSupport(func != null, "ToUpperCaseFunction"); int idx = func.indexOf("{0}"); Index: openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/kernel/exps/Trim.java =================================================================== --- openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/kernel/exps/Trim.java (revision 566297) +++ openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/kernel/exps/Trim.java (working copy) @@ -152,6 +152,9 @@ dict.assertSupport(func != null, "TrimTrailingFunction"); } + if (_val instanceof Lit || _val instanceof Param) + func = dict.addCastAsString(func, "{0}", " AS VARCHAR(1000))"); + int fromPart = func.indexOf("{0}"); int charPart = func.indexOf("{1}"); if (charPart == -1) Index: openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/kernel/exps/UnaryOp.java =================================================================== --- openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/kernel/exps/UnaryOp.java (revision 566297) +++ openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/kernel/exps/UnaryOp.java (working copy) @@ -125,6 +125,7 @@ sql.append(getOperator()); sql.append("("); _val.appendTo(sel, ctx, state, sql, 0); + sql.addCastForParam(getOperator(), _val); sql.append(")"); } Index: openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/sql/AbstractDB2Dictionary.java =================================================================== --- openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/sql/AbstractDB2Dictionary.java (revision 566297) +++ openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/sql/AbstractDB2Dictionary.java (working copy) @@ -19,6 +19,8 @@ package org.apache.openjpa.jdbc.sql; import org.apache.openjpa.jdbc.kernel.exps.FilterValue; +import org.apache.openjpa.jdbc.kernel.exps.Val; +import org.apache.openjpa.meta.JavaTypes; /** * Base dictionary for the IBM DB2 family of databases. @@ -36,9 +38,9 @@ // DB2-based databases have restrictions on having uncast parameters // in string functions - toUpperCaseFunction = "UPPER(CAST({0} AS VARCHAR(1000)))"; - toLowerCaseFunction = "LOWER(CAST({0} AS VARCHAR(1000)))"; - stringLengthFunction = "LENGTH(CAST({0} AS VARCHAR(1000)))"; + toUpperCaseFunction = "UPPER({0})"; + toLowerCaseFunction = "LOWER({0})"; + stringLengthFunction = "LENGTH({0})"; concatenateFunction = "(CAST({0} AS VARCHAR(1000)))||" + "(CAST({1} AS VARCHAR(1000)))"; @@ -100,5 +102,33 @@ buf.append(") AS INTEGER)"); } buf.append(")"); + } + + /** + * add CAST for a scalar function where operand is a param + * @param func original string + * @param target string to look for + * @param asString + * @return + */ + public String addCastAsString(String func, String target, String asString) { + String fstring = func; + if (func.indexOf(target) != -1) + fstring = func.replace(target, "CAST(" + target + asString); + return fstring; + } + + /** + * add CAST for a function operator where operand is a param + * @param func function name + * @param val + * @return + */ + public String addCastAsType(String func, Val val) { + String fstring = null; + String type = getTypeName(getJDBCType(JavaTypes.getTypeCode( + val.getType()), false)); + fstring = "CAST(? AS " + type + ")"; + return fstring; } } Index: openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/sql/DBDictionary.java =================================================================== --- openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/sql/DBDictionary.java (revision 566297) +++ openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/sql/DBDictionary.java (working copy) @@ -92,7 +92,6 @@ import org.apache.openjpa.lib.log.Log; import org.apache.openjpa.lib.util.Localizer; import org.apache.openjpa.lib.util.Localizer.Message; -import org.apache.openjpa.meta.FieldMetaData; import org.apache.openjpa.meta.JavaTypes; import org.apache.openjpa.util.GeneralException; import org.apache.openjpa.util.OpenJPAException; @@ -2541,6 +2540,28 @@ protected void appendLength(SQLBuffer buf, int type) { } + /** + * add CAST for a scalar function where operand is a param + * @param func original string + * @param target string to look for + * @param asString + * @return + */ + public String addCastAsString(String func, String target, String asString) { + return func; + } + + /** + * add CAST for a function operator where operand is a param + * @param func function name + * @param val + * @return + */ + public String addCastAsType(String func, Val val) { + return null; + } + + /////////// // DDL SQL /////////// Index: openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/sql/SQLBuffer.java =================================================================== --- openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/sql/SQLBuffer.java (revision 566324) +++ openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/sql/SQLBuffer.java (working copy) @@ -31,6 +31,7 @@ import org.apache.commons.lang.ObjectUtils; import org.apache.openjpa.jdbc.kernel.JDBCFetchConfiguration; +import org.apache.openjpa.jdbc.kernel.exps.Val; import org.apache.openjpa.jdbc.schema.Column; import org.apache.openjpa.jdbc.schema.Sequence; import org.apache.openjpa.jdbc.schema.Table; @@ -593,6 +594,19 @@ } /** + * Replace SQL '?' with CAST string if required by DB platform + * @param oper + * @param val + */ + public void addCastForParam(String oper, Val val) { + if (_sql.charAt(_sql.length()-1) == '?') { + String castString = _dict.addCastAsType(oper, val); + if (castString != null) + _sql.replace(_sql.length()-1, _sql.length(), castString); + } + } + + /** * Represents a subselect. */ private static class Subselect {