modules/core/dbutils/src/main/java/org/rhq/core/db/PostgresqlDatabaseType.java | 8 + modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/util/CriteriaQueryGenerator.java | 5 - modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/util/QueryUtility.java | 41 ++++------ 3 files changed, 23 insertions(+), 31 deletions(-)
New commits: commit 41074662511d03f3cbced4c631a2433b2583d6e1 Author: Jay Shaughnessy jshaughn@redhat.com Date: Fri Jan 29 22:15:23 2010 -0500
Handle the fact that postgres parses the escape character like any other string literal, treating \ like an escape character and therefore forcing '\' to indicate a backslash as the escape char. Handle escaping of literal % and _ and \ in the LIKE pattern.
diff --git a/modules/core/dbutils/src/main/java/org/rhq/core/db/PostgresqlDatabaseType.java b/modules/core/dbutils/src/main/java/org/rhq/core/db/PostgresqlDatabaseType.java index c7566b9..02d5c73 100644 --- a/modules/core/dbutils/src/main/java/org/rhq/core/db/PostgresqlDatabaseType.java +++ b/modules/core/dbutils/src/main/java/org/rhq/core/db/PostgresqlDatabaseType.java @@ -165,8 +165,12 @@ public abstract class PostgresqlDatabaseType extends DatabaseType {
/** * This is overridden for Postgres because by default (at least in our currently supported versions) - * postgres does not treat the backslash as a string literal, which breaks the sql standard. See - * http://opensource.atlassian.com/projects/hibernate/browse/HHH-2674 for more. + * postgres treats '' as an escape character in a string literal and the ESCAPE character for + * LIKE syntax is specified as a string literal. Therefore, ESCAPE '\' is required to + * specify that the escape character is in fact a single backslash. + * Note 1: The default behavior may change in a future version of postgres given that + * the standard_conforming_strings setting may change from 'off' to 'on' out of the box. + * Note 2: Also related, http://opensource.atlassian.com/projects/hibernate/browse/HHH-2674 for more. * * @see DatabaseType#getEscapeCharacter() */ diff --git a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/util/CriteriaQueryGenerator.java b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/util/CriteriaQueryGenerator.java index 41a5a8c..56602a5 100644 --- a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/util/CriteriaQueryGenerator.java +++ b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/util/CriteriaQueryGenerator.java @@ -365,11 +365,6 @@ public final class CriteriaQueryGenerator { if (wantCaseInsensitiveMatch) { formattedValue = formattedValue.toLowerCase(); } - /* - * Double escape backslashes if they are not treated as string literals by the db vendor - * http://opensource.atlassian.com/projects/hibernate/browse/HHH-2674 - */ - formattedValue = QueryUtility.handleDoubleEscaping(formattedValue);
if (wantsFuzzyMatching) { // append '%' onto edges that don't already have '%' explicitly set from the caller diff --git a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/util/QueryUtility.java b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/util/QueryUtility.java index 7f91e4a..0c890c5 100644 --- a/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/util/QueryUtility.java +++ b/modules/enterprise/server/jar/src/main/java/org/rhq/enterprise/server/util/QueryUtility.java @@ -27,6 +27,8 @@ import org.rhq.core.db.DatabaseTypeFactory; public class QueryUtility {
private static String ESCAPE_CHARACTER = null; + private static String ESCAPE_CLAUSE_CHARACTER = null; + private static String ESCAPED_ESCAPE = null; private static String ESCAPED_PERCENT = null; private static String ESCAPED_UNDERSCORE = null;
@@ -45,6 +47,7 @@ public class QueryUtility {
// Escape LIKE's wildcard characters with escaped characters so that the user's input // will be matched literally + value = value.replace(ESCAPE_CHARACTER, ESCAPED_ESCAPE); value = value.replace("_", ESCAPED_UNDERSCORE); value = value.replace("%", ESCAPED_PERCENT);
@@ -75,44 +78,34 @@ public class QueryUtility { public static String getEscapeClause() { init();
- return " ESCAPE '" + ESCAPE_CHARACTER + "' "; + return " ESCAPE '" + ESCAPE_CLAUSE_CHARACTER + "' "; }
/** - * If the current DatabaseType requires double escaping then ensure it is set correctly. This may be useful - * if the search string has been constructed outside of QueryUtil.formatSearchParameter(String). - * - * @param value single escaped search string value - * @return The double escaped string - */ - public static String handleDoubleEscaping(String value) { - init(); - - if ("\\".equals(ESCAPE_CHARACTER)) { - value = value.replace("\_", ESCAPED_UNDERSCORE); - value = value.replace("\%", ESCAPED_PERCENT); - } - - return value; - } - - /** - * Get the proper escape character for the current DatabaseType. + * Get the proper ESCAPE clause character for the current DatabaseType. * * @return The escape character(s) */ public static String getEscapeCharacter() { init();
- return ESCAPE_CHARACTER; + return ESCAPE_CLAUSE_CHARACTER; }
private static void init() { - if (null == ESCAPE_CHARACTER) { - ESCAPE_CHARACTER = DatabaseTypeFactory.getDefaultDatabaseType().getEscapeCharacter(); + if (null == ESCAPE_CLAUSE_CHARACTER) { + ESCAPE_CLAUSE_CHARACTER = DatabaseTypeFactory.getDefaultDatabaseType().getEscapeCharacter(); + + // The escape character should be a single character. In postgres and possibly other + // db types the character itself may need to be escaped for proper parsing of the ESCAPE value. + // (for example, ESCAPE '\' in postgres because backslash in a string literal is + // escaped by default. In such a case assume the last character is the true escape character. + int len = ESCAPE_CLAUSE_CHARACTER.length(); + ESCAPE_CHARACTER = (len > 1) ? ESCAPE_CLAUSE_CHARACTER.substring(len - 1) : ESCAPE_CLAUSE_CHARACTER; + + ESCAPED_ESCAPE = ESCAPE_CHARACTER + ESCAPE_CHARACTER; ESCAPED_UNDERSCORE = ESCAPE_CHARACTER + "_"; ESCAPED_PERCENT = ESCAPE_CHARACTER + "%"; } } - }
rhq-commits@lists.fedorahosted.org