while i + 1<len(self.__exp):
i += 1
e = self.__exp[i]
- if self._is_operator(e) or e == self.__DUMMY_LEAF:
+ if is_operator(e) or e == TRUE_LEAF or e == FALSE_LEAF:
continue
+
+ # check if the expression is valid
+ if not is_leaf(e):
+ raise ValueError('Bad domain expression: %r, %r is not a valid term.' % (exp, e))
+
+ # normalize the leaf's operator
+ e = normalize_leaf(*e)
+ self.__exp[i] = e
left, operator, right = e
- operator = operator.lower()
- working_table = table
- main_table = table
+
+ working_table = table # The table containing the field (the name provided in the left operand)
fargs = left.split('.', 1)
+
+ # If the field is _inherits'd, search for the working_table,
+ # and extract the field.
if fargs[0] in table._inherit_fields:
while True:
- field = main_table._columns.get(fargs[0], False)
+ field = working_table._columns.get(fargs[0])
if field:
- working_table = main_table
self.__field_tables[i] = working_table
break
- working_table = main_table.pool.get(main_table._inherit_fields[fargs[0]][0])
- if working_table not in self.__all_tables:
- self.__joins.append('%s."%s"=%s."%s"' % (working_table._table, 'id', main_table._table, main_table._inherits[working_table._name]))
- self.__all_tables.add(working_table)
- main_table = working_table
+ next_table = working_table.pool.get(working_table._inherit_fields[fargs[0]][0])
+ if next_table not in self.__all_tables:
- self.__joins.append('%s.%s=%s.%s' % (next_table._table, 'id', working_table._table, working_table._inherits[next_table._name]))
++ self.__joins.append('%s."%s"=%s."%s"' % (next_table._table, 'id', working_table._table, working_table._inherits[next_table._name]))
+ self.__all_tables.add(next_table)
+ working_table = next_table
+ # Or (try to) directly extract the field.
+ else:
+ field = working_table._columns.get(fargs[0])
- field = working_table._columns.get(fargs[0], False)
if not field:
if left == 'id' and operator == 'child_of':
- ids2 = child_of_right_to_ids(right)
- dom = _rec_get(ids2, working_table)
+ ids2 = child_of_right_to_ids(right, table)
+ dom = child_of_domain(left, ids2, working_table)
self.__exp = self.__exp[:i] + dom + self.__exp[i+1:]
continue
self.__exp[i] = tuple(self.__exp[i])
if field.translate:
+ operator = {'=like':'like','=ilike':'ilike'}.get(operator,operator)
if operator in ('like', 'ilike', 'not like', 'not ilike'):
right = '%%%s%%' % right
-
- query1 = '( SELECT res_id' \
+
- operator = operator == '=like' and 'like' or operator
-
+ subselect = '( SELECT res_id' \
' FROM ir_translation' \
' WHERE name = %s' \
' AND lang = %s' \
right,
]
- self.__exp[i] = ('id', 'inselect', (query1, query2))
- return self
+ self.__exp[i] = ('id', 'inselect', (subselect, params))
def __leaf_to_sql(self, leaf, table):
- if leaf == self.__DUMMY_LEAF:
- return ('(1=1)', [])
left, operator, right = leaf
- if operator == 'inselect':
+ if leaf == TRUE_LEAF:
+ query = 'TRUE'
+ params = []
+
+ elif leaf == FALSE_LEAF:
+ query = 'FALSE'
+ params = []
+
+ elif operator == 'inselect':
- query = '(%s.%s in (%s))' % (table._table, left, right[0])
+ query = '(%s."%s" in (%s))' % (table._table, left, right[0])
params = right[1]
+
elif operator in ['in', 'not in']:
- params = right and right[:] or []
- len_before = len(params)
- for i in range(len_before)[::-1]:
- if params[i] == False:
- del params[i]
-
- len_after = len(params)
- check_nulls = len_after != len_before
- query = '(1=0)'
-
- if len_after:
- if left == 'id':
- instr = ','.join(['%s'] * len_after)
- else:
- instr = ','.join([table._columns[left]._symbol_set[0]] * len_after)
- query = '(%s."%s" %s (%s))' % (table._table, left, operator, instr)
- else:
- # the case for [field, 'in', []] or [left, 'not in', []]
+ # Two cases: right is a boolean or a list. The boolean case is an
+ # abuse and handled for backward compatibility.
+ if isinstance(right, bool):
+ _logger.warning("The domain term '%s' should use the '=' or '!=' operator." % (leaf,))
if operator == 'in':
- query = '(%s."%s" IS NULL)' % (table._table, left)
+ r = 'NOT NULL' if right else 'NULL'
else:
- query = '(%s."%s" IS NOT NULL)' % (table._table, left)
- if check_nulls:
- query = '(%s OR %s."%s" IS NULL)' % (query, table._table, left)
- else:
+ r = 'NULL' if right else 'NOT NULL'
- query = '(%s.%s IS %s)' % (table._table, left, r)
++ query = '(%s."%s" IS %s)' % (table._table, left, r)
+ params = []
+ elif isinstance(right, (list, tuple)):
+ params = right[:]
+ check_nulls = False
+ for i in range(len(params))[::-1]:
+ if params[i] == False:
+ check_nulls = True
+ del params[i]
+
+ if params:
+ if left == 'id':
+ instr = ','.join(['%s'] * len(params))
+ else:
+ instr = ','.join([table._columns[left]._symbol_set[0]] * len(params))
- query = '(%s.%s %s (%s))' % (table._table, left, operator, instr)
++ query = '(%s."%s" %s (%s))' % (table._table, left, operator, instr)
+ else:
+ # The case for (left, 'in', []) or (left, 'not in', []).
+ query = 'FALSE' if operator == 'in' else 'TRUE'
+
+ if check_nulls and operator == 'in':
- query = '(%s OR %s.%s IS NULL)' % (query, table._table, left)
++ query = '(%s OR %s."%s" IS NULL)' % (query, table._table, left)
+ elif not check_nulls and operator == 'not in':
- query = '(%s OR %s.%s IS NULL)' % (query, table._table, left)
++ query = '(%s OR %s."%s" IS NULL)' % (query, table._table, left)
+ elif check_nulls and operator == 'not in':
- query = '(%s AND %s.%s IS NOT NULL)' % (query, table._table, left) # needed only for TRUE.
++ query = '(%s AND %s."%s" IS NOT NULL)' % (query, table._table, left) # needed only for TRUE.
+ else: # Must not happen.
+ pass
+
+ elif right == False and (left in table._columns) and table._columns[left]._type=="boolean" and (operator == '='):
- query = '(%s.%s IS NULL or %s.%s = false )' % (table._table, left, table._table, left)
++ query = '(%s."%s" IS NULL or %s."%s" = false )' % (table._table, left, table._table, left)
params = []
- if right == False and (leaf[0] in table._columns) and table._columns[leaf[0]]._type=="boolean" and (operator == '='):
- query = '(%s."%s" IS NULL or %s."%s" = false )' % (table._table, left,table._table, left)
- elif (((right == False) and (type(right)==bool)) or (right is None)) and (operator == '='):
- query = '%s."%s" IS NULL ' % (table._table, left)
- elif right == False and (leaf[0] in table._columns) and table._columns[leaf[0]]._type=="boolean" and (operator in ['<>', '!=']):
- query = '(%s."%s" IS NOT NULL and %s."%s" != false)' % (table._table, left,table._table, left)
- elif (((right == False) and (type(right)==bool)) or right is None) and (operator in ['<>', '!=']):
- query = '%s."%s" IS NOT NULL' % (table._table, left)
- elif (operator == '=?'):
- op = '='
- if (right is False or right is None):
- return ( 'TRUE',[])
- if left in table._columns:
- format = table._columns[left]._symbol_set[0]
- query = '(%s."%s" %s %s)' % (table._table, left, op, format)
- params = table._columns[left]._symbol_set[1](right)
- else:
- query = "(%s.\"%s\" %s '%%s')" % (table._table, left, op)
- params = right
+ elif (right is False or right is None) and (operator == '='):
- query = '%s.%s IS NULL ' % (table._table, left)
++ query = '%s."%s" IS NULL ' % (table._table, left)
+ params = []
+
+ elif right == False and (left in table._columns) and table._columns[left]._type=="boolean" and (operator == '!='):
- query = '(%s.%s IS NOT NULL and %s.%s != false)' % (table._table, left, table._table, left)
++ query = '(%s."%s" IS NOT NULL and %s."%s" != false)' % (table._table, left, table._table, left)
+ params = []
+
+ elif (right is False or right is None) and (operator == '!='):
- query = '%s.%s IS NOT NULL' % (table._table, left)
++ query = '%s."%s" IS NOT NULL' % (table._table, left)
+ params = []
+ elif (operator == '=?'):
+ if (right is False or right is None):
+ query = 'TRUE'
+ params = []
+ elif left in table._columns:
+ format = table._columns[left]._symbol_set[0]
- query = '(%s.%s = %s)' % (table._table, left, format)
++ query = '(%s."%s" = %s)' % (table._table, left, format)
+ params = table._columns[left]._symbol_set[1](right)
else:
- query = "(%s.%s = '%%s')" % (table._table, left)
- if left == 'id':
- query = '%s.id %s %%s' % (table._table, operator)
- params = right
++ query = "(%s.\"%s\" = '%%s')" % (table._table, left)
+ params = right
+
+ elif left == 'id':
+ query = '%s.id %s %%s' % (table._table, operator)
+ params = right
+
+ else:
+ like = operator in ('like', 'ilike', 'not like', 'not ilike')
+
+ op = {'=like':'like','=ilike':'ilike'}.get(operator, operator)
+ if left in table._columns:
+ format = like and '%s' or table._columns[left]._symbol_set[0]
+ if self.has_unaccent and op in ('ilike', 'not ilike'):
- query = '(unaccent(%s.%s) %s unaccent(%s))' % (table._table, left, op, format)
++ query = '(unaccent(%s."%s") %s unaccent(%s))' % (table._table, left, op, format)
else:
- query = '(%s.%s %s %s)' % (table._table, left, op, format)
- operator = {'=like':'like','=ilike':'ilike'}.get(operator,operator)
- like = operator in ('like', 'ilike', 'not like', 'not ilike')
-
- op = {'=like':'like','=ilike':'ilike'}.get(operator,operator)
- if left in table._columns:
- format = like and '%s' or table._columns[left]._symbol_set[0]
- query = '(%s."%s" %s %s)' % (table._table, left, op, format)
- else:
- query = "(%s.\"%s\" %s '%s')" % (table._table, left, op, right)
-
- add_null = False
- if like:
- if isinstance(right, str):
- str_utf8 = right
- elif isinstance(right, unicode):
- str_utf8 = right.encode('utf-8')
- else:
- str_utf8 = str(right)
- params = '%%%s%%' % str_utf8
- add_null = not str_utf8
- elif left in table._columns:
- params = table._columns[left]._symbol_set[1](right)
++ query = '(%s."%s" %s %s)' % (table._table, left, op, format)
+ else:
+ if self.has_unaccent and op in ('ilike', 'not ilike'):
- query = "(unaccent(%s.%s) %s unaccent('%s'))" % (table._table, left, op, right)
++ query = "(unaccent(%s.\"%s\") %s unaccent('%s'))" % (table._table, left, op, right)
+ else:
- query = "(%s.%s %s '%s')" % (table._table, left, op, right)
++ query = "(%s.\"%s\" %s '%s')" % (table._table, left, op, right)
+
+ add_null = False
+ if like:
+ if isinstance(right, str):
+ str_utf8 = right
+ elif isinstance(right, unicode):
+ str_utf8 = right.encode('utf-8')
+ else:
+ str_utf8 = str(right)
+ params = '%%%s%%' % str_utf8
+ add_null = not str_utf8
+ elif left in table._columns:
+ params = table._columns[left]._symbol_set[1](right)
- if add_null:
- query = '(%s OR \"%s\" IS NULL)' % (query, left)
+ if add_null:
- query = '(%s OR %s.%s IS NULL)' % (query, table._table, left)
++ query = '(%s OR %s."%s" IS NULL)' % (query, table._table, left)
if isinstance(params, basestring):
params = [params]