]> git.ipfire.org Git - thirdparty/sqlalchemy/sqlalchemy.git/commitdiff
- added "ilike()" operator to column operations.
authorMike Bayer <mike_mp@zzzcomputing.com>
Fri, 11 Jan 2008 21:24:01 +0000 (21:24 +0000)
committerMike Bayer <mike_mp@zzzcomputing.com>
Fri, 11 Jan 2008 21:24:01 +0000 (21:24 +0000)
compiles to ILIKE on postgres, lower(x) LIKE lower(y)
on all others [ticket:727]

CHANGES
lib/sqlalchemy/databases/postgres.py
lib/sqlalchemy/sql/compiler.py
lib/sqlalchemy/sql/expression.py
test/sql/query.py
test/sql/select.py

diff --git a/CHANGES b/CHANGES
index 01fa8d2714b827e7e0a993c71f750edbca6ca6f3..e68d8f11959be67c3409fd52d07bd901d1e7a7fd 100644 (file)
--- a/CHANGES
+++ b/CHANGES
@@ -4,6 +4,11 @@ CHANGES
 
 0.4.2p4
 ------
+- sql
+    - added "ilike()" operator to column operations. 
+      compiles to ILIKE on postgres, lower(x) LIKE lower(y)
+      on all others [ticket:727]
+      
 - orm
     - proper error message is raised when trying to access
       expired instance attributes with no session present
index 19db8b6b792388a03e1b692bae5bab66cdd62a5d..bab998d6978b39a3db2d9f81c180b4a1b888d18e 100644 (file)
@@ -625,7 +625,8 @@ class PGCompiler(compiler.DefaultCompiler):
     operators = compiler.DefaultCompiler.operators.copy()
     operators.update(
         {
-            sql_operators.mod : '%%'
+            sql_operators.mod : '%%',
+            sql_operators.ilike_op: 'ILIKE'
         }
     )
 
index 35a12efe393071af82dd72c531046baf283ba923..545c0a1b4270d74e2378a4428ed73bdf7a543c47 100644 (file)
@@ -79,7 +79,7 @@ OPERATORS =  {
     operators.concat_op : '||',
     operators.like_op : 'LIKE',
     operators.notlike_op : 'NOT LIKE',
-    operators.ilike_op : 'ILIKE',
+    operators.ilike_op : lambda x, y: "lower(%s) LIKE lower(%s)" % (x, y),
     operators.notilike_op : 'NOT ILIKE',
     operators.between_op : 'BETWEEN',
     operators.in_op : 'IN',
index 0bf9bea10620377abc027d272123d3d167f1d7d5..187b38a2c11eceede7f7f3c4712467f43a3a5c14 100644 (file)
@@ -1113,6 +1113,9 @@ class ColumnOperators(Operators):
     def like(self, other):
         return self.operate(operators.like_op, other)
 
+    def ilike(self, other):
+        return self.operate(operators.ilike_op, other)
+
     def in_(self, *other):
         return self.operate(operators.in_op, other)
 
@@ -1205,6 +1208,7 @@ class _CompareMixin(ColumnOperators):
         operators.ge : (__compare, operators.lt),
         operators.eq : (__compare, operators.ne),
         operators.like_op : (__compare, operators.notlike_op),
+        operators.ilike_op : (__compare, operators.notilike_op),
     }
 
     def operate(self, op, *other):
index 2d5076b9aef3de3fe96273dfbcedce46c3ed996b..d1583dc578d91e2779a24058fcc5ad186e94aa1e 100644 (file)
@@ -28,7 +28,7 @@ class QueryTest(PersistTest):
     def tearDownAll(self):
         metadata.drop_all()
 
-    def testinsert(self):
+    def test_insert(self):
         users.insert().execute(user_id = 7, user_name = 'jack')
         assert users.count().scalar() == 1
 
@@ -40,7 +40,7 @@ class QueryTest(PersistTest):
         )
         assert users.select().execute().fetchall() == [(7, 'jack'), (8, 'ed'), (9, None)]
 
-    def testupdate(self):
+    def test_update(self):
         users.insert().execute(user_id = 7, user_name = 'jack')
         assert users.count().scalar() == 1
 
@@ -128,7 +128,7 @@ class QueryTest(PersistTest):
             finally:
                 table.drop()
 
-    def testrowiteration(self):
+    def test_row_iteration(self):
         users.insert().execute(user_id = 7, user_name = 'jack')
         users.insert().execute(user_id = 8, user_name = 'ed')
         users.insert().execute(user_id = 9, user_name = 'fred')
@@ -148,6 +148,23 @@ class QueryTest(PersistTest):
             l.append(row)
         self.assert_(len(l) == 2, "fetchmany(size=2) got %s rows" % len(l))
 
+    def test_ilike(self):
+        users.insert().execute(
+            {'user_id':1, 'user_name':'one'},
+            {'user_id':2, 'user_name':'TwO'},
+            {'user_id':3, 'user_name':'ONE'},
+            {'user_id':4, 'user_name':'OnE'},
+        )
+
+        self.assertEquals(select([users.c.user_id]).where(users.c.user_name.ilike('one')).execute().fetchall(), [(1, ), (3, ), (4, )])
+
+        self.assertEquals(select([users.c.user_id]).where(users.c.user_name.ilike('TWO')).execute().fetchall(), [(2, )])
+
+        if testing.against('postgres'):
+            self.assertEquals(select([users.c.user_id]).where(users.c.user_name.like('one')).execute().fetchall(), [(1, )])
+            self.assertEquals(select([users.c.user_id]).where(users.c.user_name.like('TWO')).execute().fetchall(), [])
+
+
     def test_compiled_execute(self):
         users.insert().execute(user_id = 7, user_name = 'jack')
         s = select([users], users.c.user_id==bindparam('id')).compile()
@@ -229,7 +246,7 @@ class QueryTest(PersistTest):
         a_eq(prep(r"(\:that$other)"), "(:that$other)")
         a_eq(prep(r".\:that$ :other."), ".:that$ ?.")
 
-    def testdelete(self):
+    def test_delete(self):
         users.insert().execute(user_id = 7, user_name = 'jack')
         users.insert().execute(user_id = 8, user_name = 'fred')
         print repr(users.select().execute().fetchall())
@@ -238,7 +255,7 @@ class QueryTest(PersistTest):
 
         print repr(users.select().execute().fetchall())
 
-    def testselectlimit(self):
+    def test_select_limit(self):
         users.insert().execute(user_id=1, user_name='john')
         users.insert().execute(user_id=2, user_name='jack')
         users.insert().execute(user_id=3, user_name='ed')
@@ -251,7 +268,7 @@ class QueryTest(PersistTest):
 
     @testing.unsupported('mssql')
     @testing.fails_on('maxdb')
-    def testselectlimitoffset(self):
+    def test_select_limit_offset(self):
         users.insert().execute(user_id=1, user_name='john')
         users.insert().execute(user_id=2, user_name='jack')
         users.insert().execute(user_id=3, user_name='ed')
@@ -769,7 +786,9 @@ class JoinTest(PersistTest):
     def assertRows(self, statement, expected):
         """Execute a statement and assert that rows returned equal expected."""
 
-        found = exec_sorted(statement)
+        found = sorted([tuple(row)
+                       for row in statement.execute().fetchall()])
+                       
         self.assertEquals(found, sorted(expected))
 
     def test_join_x1(self):
@@ -1020,12 +1039,6 @@ class OperatorTest(PersistTest):
         )
 
 
-def exec_sorted(statement, *args, **kw):
-    """Executes a statement and returns a sorted list plain tuple rows."""
-
-    return sorted([tuple(row)
-                   for row in statement.execute(*args, **kw).fetchall()])
-
 
 if __name__ == "__main__":
     testbase.main()
index 70bf704ceb282563923878dbe9d16462722685e6..b922c5c22ca8cac8d57b5740ed2c60a2f9dadea0 100644 (file)
@@ -451,6 +451,8 @@ sq.myothertable_othername AS sq_myothertable_othername FROM (" + sqstring + ") A
         clause = (table1.c.myid == 12) & table1.c.myid.between(15, 20) & table1.c.myid.like('hoho')
         assert str(clause) == str(util.pickle.loads(util.pickle.dumps(clause)))
 
+        
+
     def testextracomparisonoperators(self):
         self.assert_compile(
             table1.select(table1.c.name.contains('jo')),
@@ -523,6 +525,11 @@ sq.myothertable_othername AS sq_myothertable_othername FROM (" + sqstring + ") A
             "SELECT myothertable.othername, count(myothertable.otherid) AS count_1 FROM myothertable GROUP BY myothertable.othername ORDER BY myothertable.othername"
         )
 
+    def testilike(self):
+        stmt = table1.select(table1.c.name.ilike('%something%'))
+        self.assert_compile(stmt, "SELECT mytable.myid, mytable.name, mytable.description FROM mytable WHERE lower(mytable.name) LIKE :mytable_name_1")
+        self.assert_compile(stmt, "SELECT mytable.myid, mytable.name, mytable.description FROM mytable WHERE mytable.name ILIKE %(mytable_name_1)s", dialect=postgres.PGDialect())
+
     def testforupdate(self):
         self.assert_compile(table1.select(table1.c.myid==7, for_update=True), "SELECT mytable.myid, mytable.name, mytable.description FROM mytable WHERE mytable.myid = :mytable_myid_1 FOR UPDATE")