X-Git-Url: http://git.inspyration.org/?a=blobdiff_plain;f=openerp%2Fosv%2Fexpression.py;h=648a8447292e4f1714ee6b30de313ac2fb349e48;hb=7119170b09718ccf5898ee079860cc07de38ef45;hp=18a1e9508f59fcbbeeb5224b3fffdf257fded18d;hpb=fbd0758cb5c986f35543e3f64e4274dcb4fc7b18;p=odoo%2Fodoo.git diff --git a/openerp/osv/expression.py b/openerp/osv/expression.py index 18a1e95..648a844 100644 --- a/openerp/osv/expression.py +++ b/openerp/osv/expression.py @@ -152,8 +152,8 @@ DOMAIN_OPERATORS = (NOT_OPERATOR, OR_OPERATOR, AND_OPERATOR) # for consistency. This list doesn't contain '<>' as it is simpified to '!=' # by the normalize_operator() function (so later part of the code deals with # only one representation). -# An internal (i.e. not available to the user) 'inselect' operator is also -# used. In this case its right operand has the form (subselect, params). +# Internals (i.e. not available to the user) 'inselect' and 'not inselect' +# operators are also used. In this case its right operand has the form (subselect, params). TERM_OPERATORS = ('=', '!=', '<=', '<', '>', '>=', '=?', '=like', '=ilike', 'like', 'not like', 'ilike', 'not ilike', 'in', 'not in', 'child_of') @@ -395,7 +395,7 @@ def is_leaf(element, internal=False): """ INTERNAL_OPS = TERM_OPERATORS + ('<>',) if internal: - INTERNAL_OPS += ('inselect',) + INTERNAL_OPS += ('inselect', 'not inselect') return (isinstance(element, tuple) or isinstance(element, list)) \ and len(element) == 3 \ and element[1] in INTERNAL_OPS \ @@ -1012,18 +1012,24 @@ class expression(object): else: if field._type == 'datetime' and right and len(right) == 10: - if operator in ('>', '>='): + if operator in ('>', '>=', '='): right += ' 00:00:00' elif operator in ('<', '<='): right += ' 23:59:59' push(create_substitution_leaf(leaf, (left, operator, right), working_model)) - elif field.translate: + elif field.translate and right: need_wildcard = operator in ('like', 'ilike', 'not like', 'not ilike') sql_operator = {'=like': 'like', '=ilike': 'ilike'}.get(operator, operator) if need_wildcard: right = '%%%s%%' % right + inselect_operator = 'inselect' + if sql_operator in NEGATIVE_TERM_OPERATORS: + # negate operator (fix lp:1071710) + sql_operator = sql_operator[4:] if sql_operator[:3] == 'not' else '=' + inselect_operator = 'not inselect' + subselect = '( SELECT res_id' \ ' FROM ir_translation' \ ' WHERE name = %s' \ @@ -1031,7 +1037,7 @@ class expression(object): ' AND type = %s' instr = ' %s' #Covering in,not in operators with operands (%s,%s) ,etc. - if sql_operator in ['in', 'not in']: + if sql_operator == 'in': instr = ','.join(['%s'] * len(right)) subselect += ' AND value ' + sql_operator + ' ' + " (" + instr + ")" \ ') UNION (' \ @@ -1051,7 +1057,7 @@ class expression(object): right, right, ] - push(create_substitution_leaf(leaf, ('id', 'inselect', (subselect, params)), working_model)) + push(create_substitution_leaf(leaf, ('id', inselect_operator, (subselect, params)), working_model)) else: push_result(leaf) @@ -1072,7 +1078,7 @@ class expression(object): left, operator, right = leaf # final sanity checks - should never fail - assert operator in (TERM_OPERATORS + ('inselect',)), \ + assert operator in (TERM_OPERATORS + ('inselect', 'not inselect')), \ "Invalid operator %r in domain term %r" % (operator, leaf) assert leaf in (TRUE_LEAF, FALSE_LEAF) or left in model._all_columns \ or left in MAGIC_COLUMNS, "Invalid field %r in domain term %r" % (left, leaf) @@ -1091,6 +1097,10 @@ class expression(object): query = '(%s."%s" in (%s))' % (table_alias, left, right[0]) params = right[1] + elif operator == 'not inselect': + query = '(%s."%s" not in (%s))' % (table_alias, left, right[0]) + params = right[1] + elif operator in ['in', 'not in']: # Two cases: right is a boolean or a list. The boolean case is an # abuse and handled for backward compatibility. @@ -1114,7 +1124,9 @@ class expression(object): if left == 'id': instr = ','.join(['%s'] * len(params)) else: - instr = ','.join([model._columns[left]._symbol_set[0]] * len(params)) + ss = model._columns[left]._symbol_set + instr = ','.join([ss[0]] * len(params)) + params = map(ss[1], params) query = '(%s."%s" %s (%s))' % (table_alias, left, operator, instr) else: # The case for (left, 'in', []) or (left, 'not in', []).