niwibe/django-orm — Issue #8: fix in postgresql query lookup
Author: white-bear
Created: 2012-02-19 14:26:07+00:00
State: open

please, fix postgresql lookup 'contains'
in current realisation its compiles wrong sql
wrong:
'contains': lambda field, param, is_list: ('%s @> %%s' % field, [param]) \
if not is_list else (u'%%s = ANY(%s)' % field, [param]),
correct:
'contains': lambda field, param, is_list: ('%s @> %%s' % field, [param]) \
if is_list else (u'%%s = ANY(%s)' % field, [param]),
file where to fix: django_orm/postgresql/query.py line 79

and next bug in file django_orm/postgresql/fields/arrays.py line 39
you set for all values is_list to True. Correct way is to set it to False, and validate type of value.
wrong:

def get_db_prep_lookup(self, lookup_type, value, connection, prepared=False):
value = self.get_prep_lookup(lookup_type, value)

if lookup_type == 'indexexact':
return value, False

is_list = True
if isinstance(value, (list, tuple)):
if isinstance(value[0], basestring):
value = u"{%s}" % (",".join(['"%s"' % x for x in value]))
elif isinstance(value[0], (float, int, long)):
value = u"{%s}" % (",".join(map(str, value)))
else:
raise ValueError('invalid value')

return value, is_list

correct:

def get_db_prep_lookup(self, lookup_type, value, connection, prepared=False):
value = self.get_prep_lookup(lookup_type, value)

if lookup_type == 'indexexact':
return value, False

is_list = False
if isinstance(value, (list, tuple)):
if len(value) == 1:
return value[0], False
is_list = True
if isinstance(value[0], basestring):
value = u"{%s}" % (",".join(['"%s"' % x for x in value]))
elif isinstance(value[0], (float, int, long)):
value = u"{%s}" % (",".join(map(str, value)))
else:
raise ValueError('invalid value')

return value, is_list