Skip to content

Commit bd59ab3

Browse files
committed
[FIX] util/orm: don't mark inherited field manual for custom
Fields created from [studio] have their state set to `manual`, while inherited fields have their state set to `base`. [studio]: https://github.com/odoo/odoo/blob/d58f4ed332af35f6de26a93f07adf05368731e20/odoo/orm/model_classes.py#L493-L508 During the process, inherited fields were being marked as `manual`, even when they should retain their original state. The goal is to preserve the existing state(base) and avoid overriding the state of inherited fields to `manual`. So, this fix can apply odoo/odoo#239400 ``` ('account.product_product_menu_sellable', 122, 'Accounting > Customers > Products', 254): Traceback (most recent call last): File "/tmp/tmpqgivh7_j/migrations/base/tests/test_mock_crawl.py", line 335, in crawl_menu self.mock_action(action_vals) File "/tmp/tmpqgivh7_j/migrations/base/tests/test_mock_crawl.py", line 348, in mock_action return self.mock_act_window(action) File "/tmp/tmpqgivh7_j/migrations/base/tests/test_mock_crawl.py", line 432, in mock_act_window views = get_views( File "/home/odoo/src/odoo/19.0/addons/mail/models/mail_thread.py", line 471, in get_views res = super().get_views(views, options) File "/home/odoo/src/enterprise/19.0/web_studio/models/models.py", line 10, in get_views result = super().get_views(views, options=options) File "/home/odoo/src/enterprise/19.0/web_studio/models/ir_ui_view.py", line 52, in get_views return super().get_views(views, options) File "/home/odoo/src/odoo/19.0/odoo/addons/base/models/ir_ui_view.py", line 2946, in get_views result['models'][model] = {"fields": self.env[model].fields_get( File "/home/odoo/src/enterprise/19.0/web_studio/models/ir_model.py", line 76, in fields_get return super().fields_get(allfields, attributes=attributes) File "/home/odoo/src/enterprise/19.0/ai_fields/models/models.py", line 47, in fields_get res = super().fields_get(allfields, attributes) File "/home/odoo/src/odoo/19.0/odoo/orm/models.py", line 3361, in fields_get description = field.get_description(self.env, attributes=attributes) File "/home/odoo/src/odoo/19.0/odoo/orm/fields.py", line 884, in get_description value = value(env) File "/home/odoo/src/odoo/19.0/odoo/orm/fields.py", line 937, in _description_groupable model._read_group_groupby(model._table, groupby, query) File "/home/odoo/src/odoo/19.0/addons/mail/models/mail_activity_mixin.py", line 257, in _read_group_groupby return super()._read_group_groupby(alias, groupby_spec, query) File "/home/odoo/src/odoo/19.0/odoo/orm/models.py", line 2064, in _read_group_groupby coquery = comodel._search(codomain, bypass_access=field.bypass_search_access) File "/home/odoo/src/odoo/19.0/odoo/addons/base/models/ir_attachment.py", line 677, in _search records = self.sudo().with_context(active_test=False).search_fetch( File "/home/odoo/src/odoo/19.0/odoo/orm/models.py", line 1418, in search_fetch return self._fetch_query(query, fields_to_fetch) File "/home/odoo/src/odoo/19.0/odoo/orm/models.py", line 3917, in _fetch_query rows = self.env.execute_query(query.select(*sql_terms)) File "/home/odoo/src/odoo/19.0/odoo/orm/environments.py", line 534, in execute_query self.cr.execute(query) File "/home/odoo/src/odoo/19.0/odoo/tests/test_cursor.py", line 79, in execute return self._cursor.execute(*args, **kwargs) File "/home/odoo/src/odoo/19.0/odoo/sql_db.py", line 433, in execute self._obj.execute(query, params) psycopg2.DatabaseError: out of memory for query result ``` upg-4179716 opw-6101425
1 parent ff34144 commit bd59ab3

1 file changed

Lines changed: 58 additions & 22 deletions

File tree

src/util/orm.py

Lines changed: 58 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,8 @@
1616
from itertools import chain
1717
from textwrap import dedent
1818

19+
from psycopg2 import sql
20+
1921
try:
2022
from unittest.mock import patch
2123
except ImportError:
@@ -602,34 +604,68 @@ def custom_module_field_as_manual(env, rollback=True, do_flush=False):
602604
# if the field was not correctly removed from the database during past upgrades, the field remains in the database.
603605
reserved_words = ["env"]
604606
ignores = {"ir.actions.server": ["condition"], "ir.ui.view": ["page"]}
607+
608+
cte = ""
609+
include = ""
610+
if version_gte("17.0"):
611+
cte = """
612+
WITH delegated_fields AS (
613+
SELECT array_agg(f.id) AS ids
614+
FROM ir_model_fields f
615+
JOIN ir_model m
616+
ON m.id = f.model_id
617+
AND m.model = %s
618+
JOIN ir_model_inherit i
619+
ON i.model_id = m.id
620+
AND i.parent_field_id IS NOT NULL
621+
JOIN ir_model_fields lf
622+
ON lf.id = i.parent_field_id
623+
WHERE f.related = lf.name || '.' || f.name
624+
)
625+
"""
626+
include = "AND id NOT IN (SELECT unnest(ids) FROM delegated_fields)"
627+
628+
query = format_query(
629+
env.cr,
630+
"""
631+
{cte}
632+
UPDATE ir_model_fields
633+
SET state = 'manual'
634+
WHERE state = 'base'
635+
AND model = %s
636+
AND name NOT IN %s
637+
{include}
638+
RETURNING id
639+
""",
640+
cte=sql.SQL(cte),
641+
include=sql.SQL(include),
642+
)
605643
for model in models:
606644
model_fields = tuple(list(env.registry[model]._fields) + reserved_words + ignores.get(model, []))
607-
env.cr.execute(
608-
"""
609-
UPDATE ir_model_fields
610-
SET state = 'manual'
611-
WHERE state = 'base'
612-
AND model = %s
613-
AND name not in %s
614-
RETURNING id
615-
""",
616-
[model, model_fields],
617-
)
645+
if not cte:
646+
env.cr.execute(
647+
query,
648+
[model, model_fields],
649+
)
650+
else:
651+
env.cr.execute(
652+
query,
653+
[model, model, model_fields],
654+
)
618655
updated_field_ids += [r[0] for r in env.cr.fetchall()]
619656

620657
# 2.2 Convert fields of custom models, models that were just converted to `manual` models in the previous step.
621658
for model in custom_models:
622-
env.cr.execute(
623-
"""
624-
UPDATE ir_model_fields
625-
SET state = 'manual'
626-
WHERE state = 'base'
627-
AND model = %s
628-
AND name not in %s
629-
RETURNING id
630-
""",
631-
(model, tuple(reserved_words)),
632-
)
659+
if not cte:
660+
env.cr.execute(
661+
query,
662+
[model, tuple(reserved_words)],
663+
)
664+
else:
665+
env.cr.execute(
666+
query,
667+
[model, model, tuple(reserved_words)],
668+
)
633669
updated_field_ids += [r[0] for r in env.cr.fetchall()]
634670

635671
# 2.3 Temporarily disable rules that come from custom modules

0 commit comments

Comments
 (0)