From b191254d8aceca10b40dd5957f3ddf9147a4c534 Mon Sep 17 00:00:00 2001 From: Ants Aasma Date: Tue, 26 Jun 2007 16:37:30 +0000 Subject: [PATCH] fix #624, modulo operator escaping on mysql and postgres someone should test this with oracle, firebird and sql server also --- CHANGES | 3 +++ lib/sqlalchemy/databases/mysql.py | 6 ++++++ lib/sqlalchemy/databases/postgres.py | 2 ++ test/sql/query.py | 24 ++++++++++++++++++++++++ 4 files changed, 35 insertions(+) diff --git a/CHANGES b/CHANGES index 1b5af7a51c..be73b34fea 100644 --- a/CHANGES +++ b/CHANGES @@ -46,6 +46,7 @@ up ORM decision making [ticket:593] - added Interval type to types.py [ticket:595] - mysql + - fixed escaping of the modulo operator [ticket:624] - added 'fields' to reserved words [ticket:590] - oracle - datetime fixes: got subsecond TIMESTAMP to work [ticket:604], @@ -54,6 +55,8 @@ LOB objects detected in a result set to be forced into OracleBinary so that the LOB is read() automatically, if no typemap was present (i.e., if a textual execute() was issued). +- postgres + - fixed escaping of the modulo operator [ticket:624] - sqlite - sqlite better handles datetime/date/time objects mixed and matched with various Date/Time/DateTime columns diff --git a/lib/sqlalchemy/databases/mysql.py b/lib/sqlalchemy/databases/mysql.py index 91d59f1e23..6e4e0a660d 100644 --- a/lib/sqlalchemy/databases/mysql.py +++ b/lib/sqlalchemy/databases/mysql.py @@ -1205,6 +1205,12 @@ class MySQLCompiler(ansisql.ANSICompiler): text += " \n LIMIT 18446744073709551615" text += " OFFSET " + str(select.offset) return text + + def binary_operator_string(self, binary): + if binary.operator == '%': + return '%%' + else: + return ansisql.ANSICompiler.binary_operator_string(self, binary) class MySQLSchemaGenerator(ansisql.ANSISchemaGenerator): def get_column_specification(self, column, override_pk=False, first_pk=False): diff --git a/lib/sqlalchemy/databases/postgres.py b/lib/sqlalchemy/databases/postgres.py index 0eca18be38..a514b9de02 100644 --- a/lib/sqlalchemy/databases/postgres.py +++ b/lib/sqlalchemy/databases/postgres.py @@ -532,6 +532,8 @@ class PGCompiler(ansisql.ANSICompiler): def binary_operator_string(self, binary): if isinstance(binary.type, sqltypes.String) and binary.operator == '+': return '||' + elif binary.operator == '%': + return '%%' else: return ansisql.ANSICompiler.binary_operator_string(self, binary) diff --git a/test/sql/query.py b/test/sql/query.py index 593b392e83..f7c38eb87d 100644 --- a/test/sql/query.py +++ b/test/sql/query.py @@ -637,6 +637,30 @@ class CompoundTest(PersistTest): assert u.execute().fetchall() == [('aaa', 'bbb'), ('bbb', 'ccc'), ('ccc', 'aaa')] assert u.alias('foo').select().execute().fetchall() == [('aaa', 'bbb'), ('bbb', 'ccc'), ('ccc', 'aaa')] +class OperatorTest(PersistTest): + def setUpAll(self): + global metadata, flds + metadata = BoundMetaData(testbase.db) + flds = Table('flds', metadata, + Column('idcol', Integer, Sequence('t1pkseq'), primary_key=True), + Column('intcol', Integer), + Column('strcol', String(50)), + ) + metadata.create_all() + + flds.insert().execute([ + dict(intcol=5, strcol='foo'), + dict(intcol=13, strcol='bar') + ]) + + def tearDownAll(self): + metadata.drop_all() + + def test_modulo(self): + self.assertEquals( + select([flds.c.intcol % 3], order_by=flds.c.idcol).execute().fetchall(), + [(2,),(1,)] + ) if __name__ == "__main__": testbase.main() -- 2.47.2