Index: openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/kernel/exps/Lit.java =================================================================== --- openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/kernel/exps/Lit.java (revision 567749) +++ openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/kernel/exps/Lit.java (working copy) @@ -28,7 +28,7 @@ * * @author Abe White */ -class Lit +public class Lit extends Const implements Literal { Index: openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/kernel/exps/Param.java =================================================================== --- openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/kernel/exps/Param.java (revision 567749) +++ openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/kernel/exps/Param.java (working copy) @@ -33,7 +33,7 @@ * * @author Abe White */ -class Param +public class Param extends Const implements Parameter { 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 567749) +++ openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/kernel/exps/StringLength.java (working copy) @@ -53,8 +53,8 @@ SQLBuffer buf, int index) { DBDictionary dict = ctx.store.getDBDictionary(); String func = dict.stringLengthFunction; + func = dict.getCastFunction(getValue(), func); dict.assertSupport(func != null, "StringLengthFunction"); - int idx = func.indexOf("{0}"); buf.append(func.substring(0, idx)); getValue().appendTo(sel, ctx, state, buf, index); 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 567749) +++ openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/kernel/exps/ToLowerCase.java (working copy) @@ -42,6 +42,7 @@ DBDictionary dict = ctx.store.getDBDictionary(); String func = dict.toLowerCaseFunction; + func=dict.getCastFunction(getValue(), func); 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 567749) +++ openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/kernel/exps/ToUpperCase.java (working copy) @@ -42,6 +42,7 @@ DBDictionary dict = ctx.store.getDBDictionary(); String func = dict.toUpperCaseFunction; + func = dict.getCastFunction(getValue(), func); 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 567749) +++ openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/kernel/exps/Trim.java (working copy) @@ -150,8 +150,8 @@ } else { func = dict.trimTrailingFunction; dict.assertSupport(func != null, "TrimTrailingFunction"); - } - + } + func = dict.getCastFunction(_val, func); 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 567749) +++ 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 567838) +++ openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/sql/AbstractDB2Dictionary.java (working copy) @@ -38,7 +38,7 @@ // in string functions toUpperCaseFunction = "UPPER(CAST({0} AS VARCHAR(1000)))"; toLowerCaseFunction = "LOWER(CAST({0} AS VARCHAR(1000)))"; - stringLengthFunction = "LENGTH(CAST({0} AS VARCHAR(1000)))"; + stringLengthFunction = "LENGTH({0})"; concatenateFunction = "(CAST({0} AS VARCHAR(1000)))||" + "(CAST({1} AS VARCHAR(1000)))"; Index: openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/sql/DB2Dictionary.java =================================================================== --- openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/sql/DB2Dictionary.java (revision 567749) +++ openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/sql/DB2Dictionary.java (working copy) @@ -33,6 +33,11 @@ import org.apache.openjpa.util.UnsupportedException; import org.apache.openjpa.kernel.Filters; import org.apache.openjpa.jdbc.kernel.exps.FilterValue; +import org.apache.openjpa.jdbc.kernel.exps.Val; +import org.apache.openjpa.jdbc.kernel.exps.Lit; +import org.apache.openjpa.jdbc.kernel.exps.Param; + + /** * Dictionary for IBM DB2 database. @@ -613,4 +618,77 @@ append("/*["); val.appendTo(buf); } + + /** + * add CAST for a scalar function where operand is a param + * @param func original string + * @param target string to look for + * @param asString + * @return + */ + private 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; + } + + /** + * Return the correct CAST function syntax + * @param + * @return a String with the correct CAST function syntax + */ + public String getCastFunction(Val val, String func){ + if (val instanceof Lit || val instanceof Param) + if (func.indexOf("VARCHAR") == -1) + func = addCastAsString(func,"{0}"," AS VARCHAR(1000))"); + return func; + } + + public void indexOf(SQLBuffer buf, FilterValue str, FilterValue find, + FilterValue start) { + if (find.getValue() != null) { // non constants + buf.append("(LOCATE(CAST(("); + find.appendTo(buf); + buf.append(") AS VARCHAR(1000)), "); + } else { + // this is a constant + buf.append("(LOCATE("); + find.appendTo(buf); + buf.append(", "); + } + if (str.getValue() != null){ + buf.append("CAST(("); + str.appendTo(buf); + buf.append(") AS VARCHAR(1000))"); + } else { + str.appendTo(buf); + } + if (start != null) { + + if (start.getValue() == null) { + buf.append(", CAST(("); + start.appendTo(buf); + buf.append(") AS INTEGER) + 1"); + } else { + buf.append(", "); + start.appendTo(buf); + } + } + buf.append(") - 1)"); + } } 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 567749) +++ openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/sql/DBDictionary.java (working copy) @@ -68,6 +68,8 @@ import org.apache.openjpa.jdbc.kernel.exps.ExpContext; import org.apache.openjpa.jdbc.kernel.exps.ExpState; import org.apache.openjpa.jdbc.kernel.exps.FilterValue; +import org.apache.openjpa.jdbc.kernel.exps.Lit; +import org.apache.openjpa.jdbc.kernel.exps.Param; import org.apache.openjpa.jdbc.kernel.exps.Val; import org.apache.openjpa.jdbc.meta.ClassMapping; import org.apache.openjpa.jdbc.meta.FieldMapping; @@ -92,7 +94,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 +2542,18 @@ protected void appendLength(SQLBuffer buf, int type) { } + + /** + * 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 /////////// @@ -3869,4 +3882,17 @@ public String getVersionColumn(Column column, String tableAlias) { return column.toString(); } + + /** + * Attach CAST to the current function if necessary + * @param String the sql function statement + * @return a String with the correct CAST function syntax + */ + public String getCastFunction(Val val, String func){ + return func; + } + } + + + 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 567749) +++ 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 {