Improve unaccent handling#76436
Conversation
94438b8 to
72d39de
Compare
rco-odoo
left a comment
There was a problem hiding this comment.
Have you been able to confirm the issue, i.e., the index on parent_path not being used when unaccent is enabled?
`website` added its own sql-compatible version of `get_unaccent_wrapper` in order to use `psycopg2.sql` for safety. That is very sad. Add a condition in the "standard" unaccent wrapper which checks whether the input type is a `Composable`, and in that case return an `SQL`. This increases the cost of the wrapper a tad but probably not to a really sensible amount. Task 2634851
For searches, Odoo uses `unaccent` if it's available. On some technical fields this is completely unnecessary and precludes the use of indexes. This PR provides: * an opt-out (`unaccent = False`) on `String` and `Text` fields * a warning if `unaccent` is enabled on *parent_path* fields as their performance can be rather critical and not using the index is quite an issue (note: the check that `parent_path` fields have been moved outside of the check for their existence as we want to check that the field is declared and correctly configured in all cases, probably) Task 2627454
I'd kinda assumed it had been checked, but after duplicating Fetching the children of a random record (those are the queries generated by adding unaccent to the mix: |
72d39de to
803aa37
Compare
|
@robodoo rebase-ff r+ |
|
Merge method set to rebase and fast-forward |
|
@xmo-odoo, you may want to rebuild or fix this PR as it has failed CI. |
|
|
Linked pull request(s) odoo/enterprise#20822 not ready. Linked PRs are not staged until all of them are ready. |
`website` added its own sql-compatible version of `get_unaccent_wrapper` in order to use `psycopg2.sql` for safety. That is very sad. Add a condition in the "standard" unaccent wrapper which checks whether the input type is a `Composable`, and in that case return an `SQL`. This increases the cost of the wrapper a tad but probably not to a really sensible amount. Task 2634851 Part-of: #76436
For searches, Odoo uses `unaccent` if it's available. On some technical fields this is completely unnecessary and precludes the use of indexes. This PR provides: * an opt-out (`unaccent = False`) on `String` and `Text` fields * a warning if `unaccent` is enabled on *parent_path* fields as their performance can be rather critical and not using the index is quite an issue (note: the check that `parent_path` fields have been moved outside of the check for their existence as we want to check that the field is declared and correctly configured in all cases, probably) Task 2627454 Part-of: #76436
closes #76436 Related: odoo/enterprise#20822 Signed-off-by: Xavier Morel (xmo) <xmo@odoo.com>
In odoo#76436 we added `unaccent=False` on field definitions to prevent the ORM (expression.py) from using `unaccent` for matching domain operators ('(not) (=)(i)like'). However, since odoo#136007, the domain operators '=like', 'like' and 'not like' no longer use `unaccent`. We can therefore prevent the use of `unaccent` by using the right operator ('=like', 'like', 'not like') instead of overriding the behavior in the field itself. This makes the `unaccent` parameter on `Field` less relevant. In order to reduce field complexity and keep a generic behavior, we remove this parameter from `Field` and change the usage where necessary: - Remove `unaccent=False` from all `parent_path` fields. These fields are only searched with operator `=like` (see the implementation of `child_of` in expression.py). - Remove `unaccent=False` from `res.partner` fields `phone` and `mobile`. They were introduced to simplify the creation of indexes (in odoo#91788) for the voip module, which uses `ilike` on these fields. We replace `ilike` with `like` to have the same behavior as before (see Enterprise PR). - Remove `unaccent=False` from fields `ir.attachment.store_fname` and `crm.lead.email_domain_criterion`. They were already useless (no search with '...like' operators). There is a small behavior change: all the mentioned fields will be searched with `unaccent` from the webclient, since the latter always uses operator `like` by default.
In #76436 we added `unaccent=False` on field definitions to prevent the ORM (expression.py) from using `unaccent` for matching domain operators ('(not) (=)(i)like'). However, since #136007, the domain operators '=like', 'like' and 'not like' no longer use `unaccent`. We can therefore prevent the use of `unaccent` by using the right operator ('=like', 'like', 'not like') instead of overriding the behavior in the field itself. This makes the `unaccent` parameter on `Field` less relevant. In order to reduce field complexity and keep a generic behavior, we remove this parameter from `Field` and change the usage where necessary: - Remove `unaccent=False` from all `parent_path` fields. These fields are only searched with operator `=like` (see the implementation of `child_of` in expression.py). - Remove `unaccent=False` from `res.partner` fields `phone` and `mobile`. They were introduced to simplify the creation of indexes (in #91788) for the voip module, which uses `ilike` on these fields. We replace `ilike` with `like` to have the same behavior as before (see Enterprise PR). - Remove `unaccent=False` from fields `ir.attachment.store_fname` and `crm.lead.email_domain_criterion`. They were already useless (no search with '...like' operators). There is a small behavior change: all the mentioned fields will be searched with `unaccent` from the webclient, since the latter always uses operator `like` by default. closes #139568 Related: odoo/enterprise#49448 Signed-off-by: Raphael Collet <rco@odoo.com>


Covers tasks 2627454 (allow opting out of unaccent for indexing / performance reasons) and 2634851 (natively support
psycopg2.sqlin the unaccent wrapper).Task 2551518 (unaccent indexes) is ignored, as it's not clear whether that should be handled in the ORM (with workarounds for
unaccentnot beingIMMUTABLE) or just documented as a danger (generally speaking behaviour with respect tounaccentseems completely undocumented currently so...).