Merge pull request #458 from niphlod/fix/like_ansi_behaviour
fix like behaviour as ANSI-SQL LIKE
This commit is contained in:
+8
-7
@@ -1399,12 +1399,13 @@ class BaseAdapter(ConnectionPool):
|
||||
|
||||
def LIKE(self, first, second):
|
||||
"""Case sensitive like operator"""
|
||||
raise NotImplementedError
|
||||
return '(%s LIKE %s)' % (self.expand(first),
|
||||
self.expand(second, 'string'))
|
||||
|
||||
def ILIKE(self, first, second):
|
||||
"""Case insensitive like operator"""
|
||||
return '(%s LIKE %s)' % (self.expand(first),
|
||||
self.expand(second, 'string'))
|
||||
return '(LOWER(%s) LIKE %s)' % (self.expand(first),
|
||||
self.expand(second, 'string').lower())
|
||||
|
||||
def STARTSWITH(self, first, second):
|
||||
return '(%s LIKE %s)' % (self.expand(first),
|
||||
@@ -1414,7 +1415,7 @@ class BaseAdapter(ConnectionPool):
|
||||
return '(%s LIKE %s)' % (self.expand(first),
|
||||
self.expand('%'+second, 'string'))
|
||||
|
||||
def CONTAINS(self, first, second, case_sensitive=False):
|
||||
def CONTAINS(self, first, second, case_sensitive=True):
|
||||
if first.type in ('string', 'text', 'json'):
|
||||
if isinstance(second, Expression):
|
||||
second = Expression(None, self.CONCAT('%', Expression(
|
||||
@@ -2920,11 +2921,11 @@ class PostgreSQLAdapter(BaseAdapter):
|
||||
self.expand(second, 'string'))
|
||||
|
||||
def STARTSWITH(self, first, second):
|
||||
return '(%s ILIKE %s)' % (self.expand(first),
|
||||
return '(%s LIKE %s)' % (self.expand(first),
|
||||
self.expand(second+'%', 'string'))
|
||||
|
||||
def ENDSWITH(self, first, second):
|
||||
return '(%s ILIKE %s)' % (self.expand(first),
|
||||
return '(%s LIKE %s)' % (self.expand(first),
|
||||
self.expand('%'+second, 'string'))
|
||||
|
||||
# GIS functions
|
||||
@@ -9735,7 +9736,7 @@ class Expression(object):
|
||||
db = self.db
|
||||
return Query(db, db._adapter.GE, self, value)
|
||||
|
||||
def like(self, value, case_sensitive=False):
|
||||
def like(self, value, case_sensitive=True):
|
||||
db = self.db
|
||||
op = case_sensitive and db._adapter.LIKE or db._adapter.ILIKE
|
||||
return Query(db, op, self, value)
|
||||
|
||||
+29
-8
@@ -381,14 +381,35 @@ class TestLike(unittest.TestCase):
|
||||
self.assertEqual(db(db.tt.aa.like('%b%')).count(), 1)
|
||||
self.assertEqual(db(db.tt.aa.like('%c')).count(), 1)
|
||||
self.assertEqual(db(db.tt.aa.like('%d%')).count(), 0)
|
||||
self.assertEqual(db(db.tt.aa.lower().like('A%')).count(), 1)
|
||||
self.assertEqual(db(db.tt.aa.lower().like('%B%')).count(),
|
||||
1)
|
||||
self.assertEqual(db(db.tt.aa.lower().like('%C')).count(), 1)
|
||||
self.assertEqual(db(db.tt.aa.upper().like('A%')).count(), 1)
|
||||
self.assertEqual(db(db.tt.aa.upper().like('%B%')).count(),
|
||||
1)
|
||||
self.assertEqual(db(db.tt.aa.upper().like('%C')).count(), 1)
|
||||
#DAL maps like() (and contains(), startswith(), endswith())
|
||||
#to the LIKE operator, that in ANSI-SQL is case-sensitive
|
||||
#There are backends supporting case-sensitivity by default
|
||||
#and backends that needs additional care to turn
|
||||
#case-sensitivity on. To discern among those, let's run
|
||||
#this query comparing previously inserted 'abc' with 'ABC':
|
||||
#if the result is 0, then the backend recognizes
|
||||
#case-sensitivity, if 1 it isn't
|
||||
is_case_insensitive = db(db.tt.aa.like('%ABC%')).count()
|
||||
if is_case_insensitive:
|
||||
self.assertEqual(db(db.tt.aa.like('A%')).count(), 1)
|
||||
self.assertEqual(db(db.tt.aa.like('%B%')).count(), 1)
|
||||
self.assertEqual(db(db.tt.aa.like('%C')).count(), 1)
|
||||
self.assertEqual(db(db.tt.aa.like('A%', case_sensitive=False)).count(), 1)
|
||||
self.assertEqual(db(db.tt.aa.like('%B%', case_sensitive=False)).count(), 1)
|
||||
self.assertEqual(db(db.tt.aa.like('%C', case_sensitive=False)).count(), 1)
|
||||
self.assertEqual(db(db.tt.aa.upper().like('A%')).count(), 1)
|
||||
self.assertEqual(db(db.tt.aa.upper().like('%B%')).count(),1)
|
||||
self.assertEqual(db(db.tt.aa.upper().like('%C')).count(), 1)
|
||||
else:
|
||||
self.assertEqual(db(db.tt.aa.like('A%')).count(), 0)
|
||||
self.assertEqual(db(db.tt.aa.like('%B%')).count(), 0)
|
||||
self.assertEqual(db(db.tt.aa.like('%C')).count(), 0)
|
||||
self.assertEqual(db(db.tt.aa.like('A%', case_sensitive=False)).count(), 1)
|
||||
self.assertEqual(db(db.tt.aa.like('%B%', case_sensitive=False)).count(), 1)
|
||||
self.assertEqual(db(db.tt.aa.like('%C', case_sensitive=False)).count(), 1)
|
||||
self.assertEqual(db(db.tt.aa.upper().like('A%')).count(), 1)
|
||||
self.assertEqual(db(db.tt.aa.upper().like('%B%')).count(),1)
|
||||
self.assertEqual(db(db.tt.aa.upper().like('%C')).count(), 1)
|
||||
db.tt.drop()
|
||||
db.define_table('tt', Field('aa', 'integer'))
|
||||
self.assertEqual(db.tt.insert(aa=1111111111), 1)
|
||||
|
||||
Reference in New Issue
Block a user