From ba55bed00820e12f0d55898ee1a9917644cb4b73 Mon Sep 17 00:00:00 2001 From: Miroslav Stampar Date: Thu, 25 Oct 2012 10:41:16 +0200 Subject: [PATCH] More general approach for PostgreSQL concatenation operator precedence problem (Issue #219) --- plugins/dbms/postgresql/syntax.py | 9 +++++++-- plugins/generic/databases.py | 2 +- 2 files changed, 8 insertions(+), 3 deletions(-) diff --git a/plugins/dbms/postgresql/syntax.py b/plugins/dbms/postgresql/syntax.py index 47cf95b52..de0580ae9 100644 --- a/plugins/dbms/postgresql/syntax.py +++ b/plugins/dbms/postgresql/syntax.py @@ -14,6 +14,11 @@ class Syntax(GenericSyntax): @staticmethod def unescape(expression, quote=True): + """ + Note: PostgreSQL has a general problem with concenation operator (||) precedence (hence the parentheses enclosing) + e.g. SELECT 1 WHERE 'a'!='a'||'b' will trigger error ("argument of WHERE must be type boolean, not type text") + """ + if quote: while True: index = expression.find("'") @@ -28,11 +33,11 @@ class Syntax(GenericSyntax): lastIndex = firstIndex + index old = "'%s'" % expression[firstIndex:lastIndex] - unescaped = "||".join("CHR(%d)" % (ord(expression[i])) for i in xrange(firstIndex, lastIndex)) # Postgres CHR() function already accepts Unicode code point of character(s) + unescaped = "(%s)" % "||".join("CHR(%d)" % (ord(expression[i])) for i in xrange(firstIndex, lastIndex)) # Postgres CHR() function already accepts Unicode code point of character(s) expression = expression.replace(old, unescaped) else: - expression = "||".join("CHR(%d)" % ord(c) for c in expression) + expression = "(%s)" % "||".join("CHR(%d)" % ord(c) for c in expression) return expression diff --git a/plugins/generic/databases.py b/plugins/generic/databases.py index 890c19cb6..f874f2f51 100644 --- a/plugins/generic/databases.py +++ b/plugins/generic/databases.py @@ -256,7 +256,7 @@ class Databases: if condition: if conf.excludeSysDbs: query += " WHERE " - query += " AND ".join("%s != ('%s')" % (condition, unsafeSQLIdentificatorNaming(db)) for db in self.excludeDbsList) + query += " AND ".join("%s != '%s'" % (condition, unsafeSQLIdentificatorNaming(db)) for db in self.excludeDbsList) infoMsg = "skipping system database%s '%s'" % ("s" if len(self.excludeDbsList) > 1 else "", ", ".join(db for db in self.excludeDbsList)) logger.info(infoMsg) elif not Backend.isDbms(DBMS.SQLITE):