Skip to content
Permalink
Browse files

[FIX] expression.py: auto_join no require join

When we search for example:

```
  self.env['account.analytic.account'].search(
    ['|', ('id', '=', 22), ('partner_id.name', 'ilike', 'yo')]
  )
```

with a record with ID 22 that has partner_id unset, this would
unexpectedly return no records: because partner_id field is
`auto_join=True` and so when auto_join'ing we remove any records
that has no partner_id.

This has been reported before, this changeset is an example of it being
fixed (if this was added it would probably be in master).

opw-1816246
opw-1941547
opw-1950010
closes #31908
  • Loading branch information...
nle-odoo committed Mar 18, 2019
1 parent d7ca035 commit 5a6d9a7863dc1cacaa9b9fd9760aab56ebed7132
Showing with 30 additions and 8 deletions.
  1. +3 −2 odoo/models.py
  2. +27 −6 odoo/osv/expression.py
@@ -3870,10 +3870,11 @@ def _where_calc(self, domain, active_test=True):
tables = e.get_tables()
where_clause, where_params = e.to_sql()
where_clause = [where_clause] if where_clause else []
joins = e.get_outer_joins()
else:
where_clause, where_params, tables = [], [], ['"%s"' % self._table]
where_clause, where_params, tables, joins = [], [], ['"%s"' % self._table], None

return Query(tables, where_clause, where_params)
return Query(tables, where_clause, where_params, joins)

def _check_qorder(self, word):
if not regex_order.match(word):
@@ -564,25 +564,38 @@ def generate_alias(self):
alias, alias_statement = generate_table_alias(self._models[0]._table, links)
return alias

def add_join_context(self, model, lhs_col, table_col, link):
def add_join_context(self, model, lhs_col, table_col, link, outer=False):
""" See above comments for more details. A join context is a tuple like:
``(lhs, model, lhs_col, col, link)``
``(lhs, model, lhs_col, col, link, outer)``
After adding the join, the model of the current leaf is updated.
"""
self.join_context.append((self.model, model, lhs_col, table_col, link))
self.join_context.append((self.model, model, lhs_col, table_col, link, outer))
self._models.append(model)
self.model = model

def get_join_conditions(self):
conditions = []
alias = self._models[0]._table
for context in self.join_context:
if context[5]:
continue
previous_alias = alias
alias += '__' + context[4]
conditions.append('"%s"."%s"="%s"."%s"' % (previous_alias, context[2], alias, context[3]))
return conditions

def get_outer_joins(self):
joins = {}
alias = self._models[0]._table
for context in self.join_context:
if not context[5]:
continue
previous_alias = alias
alias += '__' + context[4]
joins.setdefault(previous_alias, []).append((alias, context[2], context[3], context[5]))
return joins

def get_tables(self):
tables = set()
links = []
@@ -684,9 +697,17 @@ def get_tables(self):
tables.append(table)
table_name = _quote(self.root_model._table)
if table_name not in tables:
tables.append(table_name)
tables.insert(0, table_name)
return tables

def get_outer_joins(self):
""" Returns the list of outer join tables """
joins = {}
for leaf in self.result:
for table, join in leaf.get_outer_joins().items():
joins.setdefault(table, []).extend(join)
return joins

# ----------------------------------------
# Parsing
# ----------------------------------------
@@ -883,12 +904,12 @@ def push_result(leaf):

elif len(path) > 1 and field.store and field.type == 'many2one' and field.auto_join:
# res_partner.state_id = res_partner__state_id.id
leaf.add_join_context(comodel, path[0], 'id', path[0])
leaf.add_join_context(comodel, path[0], 'id', path[0], outer='LEFT JOIN')
push(create_substitution_leaf(leaf, (path[1], operator, right), comodel))

elif len(path) > 1 and field.store and field.type == 'one2many' and field.auto_join:
# res_partner.id = res_partner__bank_ids.partner_id
leaf.add_join_context(comodel, 'id', field.inverse_name, path[0])
leaf.add_join_context(comodel, 'id', field.inverse_name, path[0], outer='LEFT JOIN')
domain = field.domain(model) if callable(field.domain) else field.domain
push(create_substitution_leaf(leaf, (path[1], operator, right), comodel))
if domain:

0 comments on commit 5a6d9a7

Please sign in to comment.
You can’t perform that action at this time.