odoo/odoo#73523

Created by fw-bot
Merged at 75697934b34df882ec03595b876a8a6dadcef4c5

Statuses:

label
odoo-dev:14.0-13.0-fix-crm-uninstall-adt-8vf--fw
head
b78fa7cca68d56271a833746359afcf4b9df0180
merged
4 years ago by Adrian Torres (adt)
odoo/odoo
13.0 #72802
14.0 #73523
saas-14.3 #73665
saas-14.4 #73666
15.0
16.0
17.0
18.0
saas-18.2
saas-18.3
saas-18.4
master #73668

[FW][FIX] base: perform sanity check on undeletable ir.model.data

This commit adds a sanity check to the part of the ORM that uninstalls
module data, as a recap, here's how module uninstallation works:

  • We fetch all data (ir.model.data) that corresponds to the module being
    uninstalled (WHERE module='my_module')
  • We divide this data according to its type (ir.model, ir.model.field,
    constraints, etc.)
  • We fetch the corresponding records to each type, we delete them in a
    certain order (e.g. ir.model.field before ir.model) and then finally we
    delete the ir.model.data as a last step

The data is deleted in batch for maximum performance, if one of the data
cannot be deleted however, we perform a binary search until we find the
culprit(s) and we store these culprits in a list of undeletable_ids.

At the end of the process, we delete all ir.model.data except for
the ones that are undeletable, however, it is possible that because of
the multiple-step procedure, an undeletable ir.model.data could have
become deletable.

Imagine that an ir.model.field cannot be deleted, its module data id is
added to the list of undeletable_ids, however if later on its ir.model
is deleted successfully, the ir.model.field is dropped because its table
is dropped, in this case the ir.model.data becomes deletable, but since
we simply ignore it at the end of the process, we potentially end up
with orphaned xmlids.

This can be problematic when we reinstall the module and uninstall it
again, as the system does not expect an orphaned xmlid, will completely
crash and prevent the 2nd uninstallation of the module.

This is the case with CRM and its
crm.lead.scoring.frequency.field.field_id field, its ir.model.field
cannot be deleted because the name field (and display_name) of the same
model depend on it, so it is left as is, then further down the process
the entire model is deleted and as a result so is all of its remaining
fields, however the ir.module.data for the field that could not be
deleted remains.

opw-2575592

Forward-Port-Of: #72802