Skip to content
Browse files

[FIX] auto_join no require join

When we search for example:

    ['|', ('id', '=', 22), ('', '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).

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/
  2. +27 −6 odoo/osv/
@@ -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()
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.model = model

def get_join_conditions(self):
conditions = []
alias = self._models[0]._table
for context in self.join_context:
if context[5]:
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]:
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):
table_name = _quote(self.root_model._table)
if table_name not in tables:
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 and field.type == 'many2one' and field.auto_join:
# res_partner.state_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 and field.type == 'one2many' and field.auto_join:
# = 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.