From 638ecca308d4323f4345af03be1f349ab23ea9ef Mon Sep 17 00:00:00 2001 From: Eric Antones Date: Sat, 23 Jun 2018 16:53:24 +0200 Subject: [PATCH 1/4] [FIX] Hugely degraded performance for the translation subquery injection in _generate_translated_field #18679 It solves issue #18679 (https://github.com/odoo/odoo/issues/18679) on Odoo v10 Only works on PostgreSQL 9.5 or above --- odoo/addons/base/ir/ir_translation.py | 7 ++++--- odoo/models.py | 8 +++----- 2 files changed, 7 insertions(+), 8 deletions(-) diff --git a/odoo/addons/base/ir/ir_translation.py b/odoo/addons/base/ir/ir_translation.py index ec193543d3d36..d8aa818a93f15 100644 --- a/odoo/addons/base/ir/ir_translation.py +++ b/odoo/addons/base/ir/ir_translation.py @@ -163,7 +163,8 @@ def finish(self): cr.execute(""" INSERT INTO %s(name, lang, res_id, src, type, value, module, state, comments) SELECT name, lang, res_id, src, type, value, module, state, comments FROM %s AS ti - WHERE NOT EXISTS(SELECT 1 FROM ONLY %s AS irt WHERE %s); + WHERE NOT EXISTS(SELECT 1 FROM ONLY %s AS irt WHERE %s) + ON CONFLICT DO NOTHING; """ % (self._model_table, self._table, self._model_table, find_expr), (tuple(src_relevant_fields), tuple(src_relevant_fields))) @@ -281,8 +282,8 @@ def _auto_init(self): cr.execute('CREATE INDEX ir_translation_src_md5 ON ir_translation (md5(src))') cr.commit() - if 'ir_translation_ltn' not in indexes: - cr.execute('CREATE INDEX ir_translation_ltn ON ir_translation (name, lang, type)') + if 'ir_translation_unique' not in indexes: + cr.execute('CREATE INDEX ir_translation_unique ON ir_translation (type, name, lang, res_id, md5(src))') cr.commit() return res diff --git a/odoo/models.py b/odoo/models.py index 3c9daa02ce9cd..664a09cb5eca6 100644 --- a/odoo/models.py +++ b/odoo/models.py @@ -4151,16 +4151,14 @@ def _generate_translated_field(self, table_alias, field, query): # The parenthesis surrounding the select are important, as this is a sub-select. # The quotes surrounding `ir_translation` are important as well. unique_translation_subselect = """ - (SELECT DISTINCT ON (res_id) res_id, value - FROM "ir_translation" - WHERE name=%s AND lang=%s AND value!=%s - ORDER BY res_id, id DESC) + (SELECT res_id, value FROM "ir_translation" + WHERE name=%s AND lang=%s AND value!='') """ alias, alias_statement = query.add_join( (table_alias, unique_translation_subselect, 'id', 'res_id', field), implicit=False, outer=True, - extra_params=["%s,%s" % (self._name, field), self.env.lang, ""], + extra_params=["%s,%s" % (self._name, field), self.env.lang], ) return 'COALESCE("%s"."%s", "%s"."%s")' % (alias, 'value', table_alias, field) else: From 4e19dd0fe0e37802dc185c3d7e074ed5ada66413 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Francisco=20Fern=C3=A1ndez=20=40PlanetaTIC?= Date: Fri, 20 Dec 2019 12:32:37 +0100 Subject: [PATCH 2/4] [FIX] base: create index as unique and remove duplicates before --- odoo/addons/base/ir/ir_translation.py | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/odoo/addons/base/ir/ir_translation.py b/odoo/addons/base/ir/ir_translation.py index d8aa818a93f15..b47e7346c33c7 100644 --- a/odoo/addons/base/ir/ir_translation.py +++ b/odoo/addons/base/ir/ir_translation.py @@ -283,7 +283,17 @@ def _auto_init(self): cr.commit() if 'ir_translation_unique' not in indexes: - cr.execute('CREATE INDEX ir_translation_unique ON ir_translation (type, name, lang, res_id, md5(src))') + # remove duplicated translations before unique index creation + cr.execute(''' + DELETE FROM ir_translation t + USING (SELECT type, name, lang, res_id, md5(src) AS md5_src, max(id) AS max_id + FROM ir_translation + GROUP BY type, name, lang, res_id, md5(src) + HAVING COUNT(id) > 1) dup + WHERE (t.type, t.name, t.lang, t.res_id, md5(t.src)) = (dup.type, dup.name, dup.lang, dup.res_id, dup.md5_src) + AND t.id <> dup.max_id + ''') + cr.execute('CREATE UNIQUE INDEX ir_translation_unique ON ir_translation (type, name, lang, res_id, md5(src))') cr.commit() return res From 791aae0b9a206b8d5ab23f5866bad25bfa043684 Mon Sep 17 00:00:00 2001 From: Eric Antones Date: Wed, 15 Jan 2020 21:14:08 +0100 Subject: [PATCH 3/4] [FIX] base: Make it compatible with all versions of PostgreSQL supported by Odoo 10.0 --- odoo/addons/base/ir/ir_translation.py | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/odoo/addons/base/ir/ir_translation.py b/odoo/addons/base/ir/ir_translation.py index b47e7346c33c7..407888eab2358 100644 --- a/odoo/addons/base/ir/ir_translation.py +++ b/odoo/addons/base/ir/ir_translation.py @@ -160,12 +160,14 @@ def finish(self): (tuple(src_relevant_fields), tuple(src_relevant_fields))) # Step 3: insert new translations - cr.execute(""" INSERT INTO %s(name, lang, res_id, src, type, value, module, state, comments) + cr.execute(""" INSERT INTO %(_model_table)s(name, lang, res_id, src, type, value, module, state, comments) SELECT name, lang, res_id, src, type, value, module, state, comments - FROM %s AS ti - WHERE NOT EXISTS(SELECT 1 FROM ONLY %s AS irt WHERE %s) - ON CONFLICT DO NOTHING; - """ % (self._model_table, self._table, self._model_table, find_expr), + FROM %(_table)s AS ti + WHERE NOT EXISTS(SELECT 1 FROM ONLY %(_model_table)s AS irt WHERE %(find_expr)s) AND + NOT EXISTS(SELECT 1 FROM %(_model_table)s AS tj + WHERE (ti.type, ti.name, ti.lang, ti.res_id, md5(ti.src)) = + (tj.type, tj.name, tj.lang, tj.res_id, md5(tj.src))); + """ % dict(_model_table=self._model_table, _table=self._table, find_expr=find_expr), (tuple(src_relevant_fields), tuple(src_relevant_fields))) if self._debug: From c6f68543443bd5680ff45cd64e8b0f2c3c1930bb Mon Sep 17 00:00:00 2001 From: Eric Antones Date: Thu, 16 Jan 2020 16:02:24 +0100 Subject: [PATCH 4/4] [FIX] base: Fix issues importing translations Based on https://github.com/PlanetaTIC/odoo/commit/3b3c9c687d013200db49484d2fbb4a8b45f7a52d correction. - Previous commit breaks import (from ONLY needed in where not exists) - Avoid duplicates in import (a slightly clearer and cleaner approach) --- odoo/addons/base/ir/ir_translation.py | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/odoo/addons/base/ir/ir_translation.py b/odoo/addons/base/ir/ir_translation.py index 407888eab2358..b58ce388977a1 100644 --- a/odoo/addons/base/ir/ir_translation.py +++ b/odoo/addons/base/ir/ir_translation.py @@ -164,9 +164,13 @@ def finish(self): SELECT name, lang, res_id, src, type, value, module, state, comments FROM %(_table)s AS ti WHERE NOT EXISTS(SELECT 1 FROM ONLY %(_model_table)s AS irt WHERE %(find_expr)s) AND - NOT EXISTS(SELECT 1 FROM %(_model_table)s AS tj - WHERE (ti.type, ti.name, ti.lang, ti.res_id, md5(ti.src)) = - (tj.type, tj.name, tj.lang, tj.res_id, md5(tj.src))); + NOT EXISTS(SELECT 1 FROM ONLY %(_model_table)s AS irt + WHERE (irt.type, irt.name, irt.lang, irt.res_id, md5(irt.src)) = + (ti.type, ti.name, ti.lang, ti.res_id, md5(ti.src))) AND + NOT EXISTS(SELECT 1 FROM %(_table)s AS tj + WHERE (tj.type, tj.name, tj.lang, tj.res_id, md5(tj.src)) = + (ti.type, ti.name, ti.lang, ti.res_id, md5(ti.src)) AND + tj.id > ti.id); """ % dict(_model_table=self._model_table, _table=self._table, find_expr=find_expr), (tuple(src_relevant_fields), tuple(src_relevant_fields)))