subids = ids[i:i+cr.IN_MAX]
cr.execute('SELECT "%s"' \
' FROM "%s"' \
- ' WHERE "%s" in %%s' % (s, f, w),(tuple(subids),))
+ ' WHERE "%s" IN %%s' % (s, f, w),(tuple(subids),))
res.extend([r[0] for r in cr.fetchall()])
else:
cr.execute('SELECT distinct("%s")' \
self.__main_table = None # 'root' table. set by parse()
self.__DUMMY_LEAF = (1, '=', 1) # a dummy leaf that must not be parsed or sql generated
+ @property
+ def exp(self):
+ return self.__exp[:]
def parse(self, cr, uid, table, context):
""" transform the leafs of the expression """
if self._is_operator(e) or e == self.__DUMMY_LEAF:
continue
left, operator, right = e
+ operator = operator.lower()
working_table = table
main_table = table
fargs = left.split('.', 1)
if len(fargs) > 1:
if field._type == 'many2one':
right = field_obj.search(cr, uid, [(fargs[1], operator, right)], context=context)
- self.__exp[i] = (fargs[0], 'in', right)
+ if right == []:
+ self.__exp[i] = ( 'id', '=', 0 )
+ else:
+ self.__exp[i] = (fargs[0], 'in', right)
# Making search easier when there is a left operand as field.o2m or field.m2m
if field._type in ['many2many','one2many']:
right = field_obj.search(cr, uid, [(fargs[1], operator, right)], context=context)
right1 = table.search(cr, uid, [(fargs[0],'in', right)], context=context)
- self.__exp[i] = ('id', 'in', right1)
- continue
+ if right1 == []:
+ self.__exp[i] = ( 'id', '=', 0 )
+ else:
+ self.__exp[i] = ('id', 'in', right1)
+
+ if not isinstance(field,fields.property):
+ continue
- if field._properties and ((not field.store) or field._fnct_search):
- # this is a function field
+ if field._properties and not field.store:
+ # this is a function field that is not stored
if not field._fnct_search:
# the function field doesn't provide a search function and doesn't store
# values in the database, so we must ignore it : we generate a dummy leaf
self.__exp[i] = self.__DUMMY_LEAF
else:
subexp = field.search(cr, uid, table, left, [self.__exp[i]], context=context)
- # we assume that the expression is valid
- # we create a dummy leaf for forcing the parsing of the resulting expression
- self.__exp[i] = '&'
- self.__exp.insert(i + 1, self.__DUMMY_LEAF)
- for j, se in enumerate(subexp):
- self.__exp.insert(i + 2 + j, se)
+ if not subexp:
+ self.__exp[i] = self.__DUMMY_LEAF
+ else:
+ # we assume that the expression is valid
+ # we create a dummy leaf for forcing the parsing of the resulting expression
+ self.__exp[i] = '&'
+ self.__exp.insert(i + 1, self.__DUMMY_LEAF)
+ for j, se in enumerate(subexp):
+ self.__exp.insert(i + 2 + j, se)
# else, the value of the field is store in the database, so we search on it
elif field._type == 'one2many':
else:
call_null = True
- if right:
+ if right is not False:
if isinstance(right, basestring):
ids2 = [x[0] for x in field_obj.name_search(cr, uid, right, [], operator, context=context, limit=None)]
if ids2:
self.__exp[i] = ('id', 'in', _rec_convert(ids2))
else:
call_null_m2m = True
- if right:
+ if right is not False:
if isinstance(right, basestring):
res_ids = [x[0] for x in field_obj.name_search(cr, uid, right, [], operator, context=context)]
if res_ids:
- opeartor = 'in'
+ operator = 'in'
else:
if not isinstance(right, list):
res_ids = [right]
dom = _rec_get(ids2, working_table, parent=left)
self.__exp = self.__exp[:i] + dom + self.__exp[i+1:]
else:
- if isinstance(right, basestring): # and not isinstance(field, fields.related):
+ def _get_expression(field_obj,cr, uid, left, right, operator, context=None):
+ if context is None:
+ context = {}
c = context.copy()
c['active_test'] = False
+ #Special treatment to ill-formed domains
+ operator = ( operator in ['<','>','<=','>='] ) and 'in' or operator
+
+ dict_op = {'not in':'!=','in':'=','=':'in','!=':'not in','<>':'not in'}
+ if isinstance(right,tuple):
+ right = list(right)
+ if (not isinstance(right,list)) and operator in ['not in','in']:
+ operator = dict_op[operator]
+ elif isinstance(right,list) and operator in ['<>','!=','=']: #for domain (FIELD,'=',['value1','value2'])
+ operator = dict_op[operator]
res_ids = field_obj.name_search(cr, uid, right, [], operator, limit=None, context=c)
if not res_ids:
- self.__exp[i] = ('id','=',0)
+ return ('id','=',0)
else:
right = map(lambda x: x[0], res_ids)
- self.__exp[i] = (left, 'in', right)
+ return (left, 'in', right)
+
+ m2o_str = False
+ if right:
+ if isinstance(right, basestring): # and not isinstance(field, fields.related):
+ m2o_str = True
+ elif isinstance(right,(list,tuple)):
+ m2o_str = True
+ for ele in right:
+ if not isinstance(ele, basestring):
+ m2o_str = False
+ break
+ elif right == []:
+ m2o_str = False
+ if operator in ('not in', '!=', '<>'):
+ # (many2one not in []) should return all records
+ self.__exp[i] = self.__DUMMY_LEAF
+ else:
+ self.__exp[i] = ('id','=',0)
+ else:
+ new_op = '='
+ if operator in ['not like','not ilike','not in','<>','!=']:
+ new_op = '!='
+ #Is it ok to put 'left' and not 'id' ?
+ self.__exp[i] = (left,new_op,False)
+
+ if m2o_str:
+ self.__exp[i] = _get_expression(field_obj,cr, uid, left, right, operator, context=context)
else:
# other field type
# add the time part to datetime field when it's not there: