[IMP] core: remove parameter 'extra' from Query.join() and Query.left_join()
Part-of: odoo/odoo#134677
This commit is contained in:
@@ -10,7 +10,7 @@ from collections import defaultdict
|
||||
from odoo import _, api, Command, fields, models, modules, tools
|
||||
from odoo.exceptions import AccessError
|
||||
from odoo.osv import expression
|
||||
from odoo.tools.misc import clean_context, groupby as tools_groupby
|
||||
from odoo.tools import clean_context, groupby as tools_groupby, SQL
|
||||
|
||||
_logger = logging.getLogger(__name__)
|
||||
_image_dataurl = re.compile(r'(data:image/[a-z]+?);base64,([a-z0-9+/\n]{3,}=*)\n*([\'"])(?: data-filename="([^"]*)")?', re.I)
|
||||
@@ -294,23 +294,34 @@ class Message(models.Model):
|
||||
allowed_ids = set()
|
||||
model_ids = defaultdict(lambda: defaultdict(set))
|
||||
|
||||
rel_alias = query.left_join(
|
||||
self._table, 'id', 'mail_message_res_partner_rel', 'mail_message_id', 'partner_ids',
|
||||
'{rhs}.res_partner_id = %s', [pid],
|
||||
)
|
||||
notif_alias = query.left_join(
|
||||
self._table, 'id', 'mail_notification', 'mail_message_id', 'notification_ids',
|
||||
'{rhs}.res_partner_id = %s', [pid],
|
||||
)
|
||||
query_str, params = query.select(
|
||||
f'"{self._table}"."id"',
|
||||
f'"{self._table}"."model"',
|
||||
f'"{self._table}"."res_id"',
|
||||
f'"{self._table}"."author_id"',
|
||||
f'"{self._table}"."message_type"',
|
||||
f'COALESCE("{rel_alias}"."res_partner_id", "{notif_alias}"."res_partner_id")',
|
||||
)
|
||||
self.env.cr.execute(query_str, params)
|
||||
rel_alias = query.make_alias(self._table, 'partner_ids')
|
||||
query.add_join("LEFT JOIN", rel_alias, 'mail_message_res_partner_rel', SQL(
|
||||
"%s = %s AND %s = %s",
|
||||
SQL.identifier(self._table, 'id'),
|
||||
SQL.identifier(rel_alias, 'mail_message_id'),
|
||||
SQL.identifier(rel_alias, 'res_partner_id'),
|
||||
pid,
|
||||
))
|
||||
notif_alias = query.make_alias(self._table, 'notification_ids')
|
||||
query.add_join("LEFT JOIN", notif_alias, 'mail_notification', SQL(
|
||||
"%s = %s AND %s = %s",
|
||||
SQL.identifier(self._table, 'id'),
|
||||
SQL.identifier(notif_alias, 'mail_message_id'),
|
||||
SQL.identifier(notif_alias, 'res_partner_id'),
|
||||
pid,
|
||||
))
|
||||
self.env.cr.execute(query.select(
|
||||
SQL.identifier(self._table, 'id'),
|
||||
SQL.identifier(self._table, 'model'),
|
||||
SQL.identifier(self._table, 'res_id'),
|
||||
SQL.identifier(self._table, 'author_id'),
|
||||
SQL.identifier(self._table, 'message_type'),
|
||||
SQL(
|
||||
"COALESCE(%s, %s)",
|
||||
SQL.identifier(rel_alias, 'res_partner_id'),
|
||||
SQL.identifier(notif_alias, 'res_partner_id'),
|
||||
),
|
||||
))
|
||||
for id_, model, res_id, author_id, message_type, partner_id in self.env.cr.fetchall():
|
||||
ids.append(id_)
|
||||
if author_id == pid:
|
||||
|
||||
+13
-8
@@ -2780,18 +2780,23 @@ class BaseModel(metaclass=MetaModel):
|
||||
comodel = self.env[field.comodel_name]
|
||||
subquery = Query(self.env.cr, comodel._table)
|
||||
comodel._apply_ir_rules(subquery)
|
||||
# add the extra join condition only if there is an actual subquery
|
||||
extra, extra_params = None, ()
|
||||
if subquery.where_clause:
|
||||
subquery_str, extra_params = subquery.select()
|
||||
extra = '"{rhs}"."%s" IN (%s)' % (field.column2, subquery_str)
|
||||
# LEFT JOIN field_relation ON
|
||||
# alias.id = field_relation.field_column1
|
||||
# AND field_relation.field_column2 IN (subquery)
|
||||
rel_alias = query.left_join(
|
||||
alias, 'id', field.relation, field.column1, field.name,
|
||||
extra=extra, extra_params=extra_params,
|
||||
rel_alias = query.make_alias(alias, field.name)
|
||||
condition = SQL(
|
||||
"%s = %s",
|
||||
SQL.identifier(alias, 'id'),
|
||||
SQL.identifier(rel_alias, field.column1),
|
||||
)
|
||||
if subquery.where_clause:
|
||||
condition = SQL(
|
||||
"%s AND %s IN %s",
|
||||
condition,
|
||||
SQL.identifier(rel_alias, field.column2),
|
||||
subquery.subselect(),
|
||||
)
|
||||
query.add_join("LEFT JOIN", rel_alias, field.relation, condition)
|
||||
return '"%s"."%s"' % (rel_alias, field.column2)
|
||||
elif field.translate and not self.env.context.get('prefetch_langs'):
|
||||
lang = self.env.lang or 'en_US'
|
||||
|
||||
+10
-44
@@ -110,10 +110,11 @@ class Query(object):
|
||||
self._where_clauses.append(SQL(where_clause, *where_params))
|
||||
self._ids = None
|
||||
|
||||
def join(self, lhs_alias, lhs_column, rhs_table, rhs_column, link, extra=None, extra_params=()):
|
||||
def join(self, lhs_alias: str, lhs_column: str, rhs_table: str, rhs_column: str, link: str):
|
||||
"""
|
||||
Perform a join between a table already present in the current Query object and
|
||||
another table.
|
||||
another table. This method is essentially a shortcut for methods :meth:`~.make_alias`
|
||||
and :meth:`~.add_join`.
|
||||
|
||||
:param str lhs_alias: alias of a table already defined in the current Query object.
|
||||
:param str lhs_column: column of `lhs_alias` to be used for the join's ON condition.
|
||||
@@ -121,59 +122,24 @@ class Query(object):
|
||||
:param str rhs_column: column of `rhs_alias` to be used for the join's ON condition.
|
||||
:param str link: used to generate the alias for the joined table, this string should
|
||||
represent the relationship (the link) between both tables.
|
||||
:param str extra: an sql string of a predicate or series of predicates to append to the
|
||||
join's ON condition, `lhs_alias` and `rhs_alias` can be injected if the string uses
|
||||
the `lhs` and `rhs` variables with the `str.format` syntax. e.g.::
|
||||
|
||||
query.join(..., extra="{lhs}.name != {rhs}.name OR ...", ...)
|
||||
|
||||
:param tuple extra_params: a tuple of values to be interpolated into `extra`, this is
|
||||
done by psycopg2.
|
||||
|
||||
Full example:
|
||||
|
||||
>>> rhs_alias = query.join(
|
||||
... "res_users",
|
||||
... "partner_id",
|
||||
... "res_partner",
|
||||
... "id",
|
||||
... "partner_id", # partner_id is the "link" from res_users to res_partner
|
||||
... "{lhs}.\"name\" != %s",
|
||||
... ("Mitchell Admin",),
|
||||
... )
|
||||
>>> rhs_alias
|
||||
res_users_res_partner__partner_id
|
||||
|
||||
From the example above, the resulting query would be something like::
|
||||
|
||||
SELECT ...
|
||||
FROM "res_users" AS "res_users"
|
||||
JOIN "res_partner" AS "res_users_res_partner__partner_id"
|
||||
ON "res_users"."partner_id" = "res_users_res_partner__partner_id"."id"
|
||||
AND "res_users"."name" != 'Mitchell Admin'
|
||||
WHERE ...
|
||||
|
||||
"""
|
||||
return self._join('JOIN', lhs_alias, lhs_column, rhs_table, rhs_column, link, extra, extra_params)
|
||||
assert lhs_alias in self._tables or lhs_alias in self._joins, "Alias %r not in %s" % (lhs_alias, str(self))
|
||||
rhs_alias = self.make_alias(lhs_alias, link)
|
||||
condition = SQL("%s = %s", SQL.identifier(lhs_alias, lhs_column), SQL.identifier(rhs_alias, rhs_column))
|
||||
self.add_join('JOIN', rhs_alias, rhs_table, condition)
|
||||
return rhs_alias
|
||||
|
||||
def left_join(self, lhs_alias, lhs_column, rhs_table, rhs_column, link, extra=None, extra_params=()):
|
||||
def left_join(self, lhs_alias: str, lhs_column: str, rhs_table: str, rhs_column: str, link: str):
|
||||
""" Add a LEFT JOIN to the current table (if necessary), and return the
|
||||
alias corresponding to ``rhs_table``.
|
||||
|
||||
See the documentation of :meth:`join` for a better overview of the
|
||||
arguments and what they do.
|
||||
"""
|
||||
return self._join('LEFT JOIN', lhs_alias, lhs_column, rhs_table, rhs_column, link, extra, extra_params)
|
||||
|
||||
def _join(self, kind, lhs_alias, lhs_column, rhs_table, rhs_column, link, extra=None, extra_params=()):
|
||||
assert lhs_alias in self._tables or lhs_alias in self._joins, "Alias %r not in %s" % (lhs_alias, str(self))
|
||||
rhs_alias = self.make_alias(lhs_alias, link)
|
||||
condition = SQL("%s = %s", SQL.identifier(lhs_alias, lhs_column), SQL.identifier(rhs_alias, rhs_column))
|
||||
if extra:
|
||||
extra = SQL(extra, *extra_params)
|
||||
extra = SQL(extra.code.format(lhs=lhs_alias, rhs=rhs_alias), *extra.params)
|
||||
condition = SQL("%s AND %s", condition, extra)
|
||||
self.add_join(kind, rhs_alias, rhs_table, condition)
|
||||
self.add_join('LEFT JOIN', rhs_alias, rhs_table, condition)
|
||||
return rhs_alias
|
||||
|
||||
@property
|
||||
|
||||
Reference in New Issue
Block a user