[FIX] core: make one2many empty search use EXIST

This speeds update the peformance of searching empty one2many fields

closes odoo/odoo#88176

X-original-commit: a7679d246ae43bf81fd8b279008b57dbdc1bba05
Signed-off-by: Raphael Collet <rco@odoo.com>
This commit is contained in:
Michael Tietz
2022-04-07 13:24:13 +02:00
parent 42054bd898
commit 6e96a41cc8
2 changed files with 16 additions and 9 deletions
+8 -6
View File
@@ -1673,9 +1673,10 @@ class TestOne2many(TransactionCase):
with self.assertQueries(['''
SELECT "res_partner".id
FROM "res_partner"
WHERE ("res_partner"."id" IN (
SELECT "partner_id" FROM "res_partner_bank" WHERE "partner_id" IS NOT NULL
))
WHERE EXISTS (
SELECT 1 FROM "res_partner_bank" AS "res_partner__bank_ids"
WHERE "res_partner__bank_ids"."partner_id" = "res_partner".id
)
ORDER BY "res_partner"."id"
''']):
self.Partner.search([('bank_ids', '!=', False)], order='id')
@@ -1683,9 +1684,10 @@ class TestOne2many(TransactionCase):
with self.assertQueries(['''
SELECT "res_partner".id
FROM "res_partner"
WHERE ("res_partner"."id" NOT IN (
SELECT "partner_id" FROM "res_partner_bank" WHERE "partner_id" IS NOT NULL
))
WHERE NOT EXISTS (
SELECT 1 FROM "res_partner_bank" AS "res_partner__bank_ids"
WHERE "res_partner__bank_ids"."partner_id" = "res_partner".id
)
ORDER BY "res_partner"."id"
''']):
self.Partner.search([('bank_ids', '=', False)], order='id')
+8 -3
View File
@@ -809,9 +809,14 @@ class expression(object):
else:
if inverse_field.store and not (inverse_is_int and domain):
# rewrite condition to match records with/without lines
op1 = 'inselect' if operator in NEGATIVE_TERM_OPERATORS else 'not inselect'
subquery = f'SELECT "{inverse_field.name}" FROM "{comodel._table}" WHERE "{inverse_field.name}" IS NOT NULL'
push(('id', op1, (subquery, [])), model, alias, internal=True)
exists = 'EXISTS' if operator in NEGATIVE_TERM_OPERATORS else 'NOT EXISTS'
rel_alias = _generate_table_alias(alias, field.name)
push_result(f"""
{exists} (
SELECT 1 FROM "{comodel._table}" AS "{rel_alias}"
WHERE "{rel_alias}"."{inverse_field.name}" = "{alias}".id
)
""", [])
else:
comodel_domain = [(inverse_field.name, '!=', False)]
if inverse_is_int and domain: