From 8f53fb2fd8a8b8a753837a365f20d4e04a63cc05 Mon Sep 17 00:00:00 2001 From: Heath Thomann Date: Mon, 21 Jan 2013 02:32:24 +0000 Subject: [PATCH] OPENJPA-2324: Option to express literal in query string directly into generate SQL - applied Albert's patch to 1.0.x git-svn-id: https://svn.apache.org/repos/asf/openjpa/branches/1.0.x@1436118 13f79535-47bb-0310-9956-ffa450edef68 --- .../apache/openjpa/jdbc/kernel/exps/Lit.java | 10 ++- .../apache/openjpa/jdbc/sql/SQLBuffer.java | 61 +++++++++++++++---- .../org/apache/openjpa/kernel/Filters.java | 2 + .../org/apache/openjpa/kernel/QueryHints.java | 6 ++ 4 files changed, 64 insertions(+), 15 deletions(-) diff --git a/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/kernel/exps/Lit.java b/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/kernel/exps/Lit.java index 5b45fab39..49db397f0 100644 --- a/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/kernel/exps/Lit.java +++ b/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/kernel/exps/Lit.java @@ -21,6 +21,7 @@ package org.apache.openjpa.jdbc.kernel.exps; import org.apache.openjpa.jdbc.sql.SQLBuffer; import org.apache.openjpa.jdbc.sql.Select; import org.apache.openjpa.kernel.Filters; +import org.apache.openjpa.kernel.QueryHints; import org.apache.openjpa.kernel.exps.Literal; /** @@ -98,7 +99,12 @@ public class Lit if (lstate.otherLength > 1) sql.appendValue(((Object[]) lstate.sqlValue)[index], lstate.getColumn(index)); - else - sql.appendValue(lstate.sqlValue, lstate.getColumn(index)); + else { + Object useLiteral = ctx.fetch.getHint(QueryHints.HINT_USE_LITERAL_IN_SQL); + useLiteral = Filters.convert(useLiteral, Boolean.class); +// useLiteral = true; + boolean useParamToken = useLiteral != null ? !(((Boolean)useLiteral).booleanValue()) : true; + sql.appendValue(lstate.sqlValue, lstate.getColumn(index), useParamToken); + } } } diff --git a/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/sql/SQLBuffer.java b/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/sql/SQLBuffer.java index 4a96a7a42..668830657 100644 --- a/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/sql/SQLBuffer.java +++ b/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/sql/SQLBuffer.java @@ -35,6 +35,8 @@ 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; +import org.apache.openjpa.kernel.Filters; + import serp.util.Numbers; /** @@ -229,30 +231,63 @@ public final class SQLBuffer * Append a parameter value for a specific column. */ public SQLBuffer appendValue(Object o, Column col) { + return appendValue(o, col, true); + } + + public SQLBuffer appendValue(Object o, Column col, boolean useParamToken) { if (o == null) _sql.append("NULL"); else if (o instanceof Raw) _sql.append(o.toString()); else { - _sql.append(PARAMETER_TOKEN); + Class type = Filters.wrap(o.getClass()); +// System.out.println("======1> o="+o+", cls="+o.getClass()); + if (useParamToken || !validParamLiteralType(type)) { + _sql.append(PARAMETER_TOKEN); - // initialize param and col lists; we hold off on col list until - // we get the first non-null col - if (_params == null) - _params = new ArrayList(); - if (col != null && _cols == null) { - _cols = new ArrayList(); - while (_cols.size() < _params.size()) - _cols.add(null); + // initialize param and col lists; we hold off on col list until + // we get the first non-null col + if (_params == null) + _params = new ArrayList(); + if (col != null && _cols == null) { + _cols = new ArrayList(); + while (_cols.size() < _params.size()) + _cols.add(null); + } + + _params.add(o); + if (_cols != null) + _cols.add(col); + } else { + if (type == String.class) { + _sql.append("'" + o.toString().replace("'", "''") + "'"); + } else if ( type == Character.class ) { + if (_dict.storeCharsAsNumbers) { + _sql.append(Integer.toString(((Character)o).charValue())); + } else { + _sql.append("'" + o.toString().replace("'", "''") + "'"); + } + } else { + _sql.append(o.toString()); + } +// System.out.println("======3> _sql="+_sql.toString()); } - - _params.add(o); - if (_cols != null) - _cols.add(col); } return this; } + private boolean validParamLiteralType(Class type) { + boolean ret = type == String.class + || type == Integer.class + || type == Character.class + || type == Boolean.class + || type == Short.class + || type == Long.class + || type == Byte.class; +// System.out.println("======2> type="+type+", ret="+ret); + return ret; + } + /** * Append a parameter value. */ diff --git a/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/Filters.java b/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/Filters.java index e05693415..edf5094f7 100644 --- a/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/Filters.java +++ b/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/Filters.java @@ -253,6 +253,8 @@ public class Filters { if (!num) { if (type == String.class) return o.toString(); + else if (type == Boolean.class && o instanceof String) + return Boolean.valueOf(o.toString()); else if (type == Character.class) { String str = o.toString(); if (str != null && str.length() == 1) diff --git a/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/QueryHints.java b/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/QueryHints.java index 43e1e0f7a..6c829742f 100644 --- a/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/QueryHints.java +++ b/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/QueryHints.java @@ -28,4 +28,10 @@ public interface QueryHints { */ public static final String HINT_RESULT_COUNT = "openjpa.hint.OptimizeResultCount"; + + /** + * A boolean directive to generate literal directly into the SQL statement instead of using position parameter, + * if possible. + */ + public static final String HINT_USE_LITERAL_IN_SQL = "openjpa.hint.UseLiteralInSQL"; }