Skip to content

[FIX] util/orm: Fix non store field issue - #485

Draft
sagu-odoo wants to merge 1 commit into
odoo:masterfrom
odoo-dev:master-fix-no-sql-sagu
Draft

[FIX] util/orm: Fix non store field issue#485
sagu-odoo wants to merge 1 commit into
odoo:masterfrom
odoo-dev:master-fix-no-sql-sagu

Conversation

@sagu-odoo

@sagu-odoo sagu-odoo commented Aug 13, 2026

Copy link
Copy Markdown
Contributor

Since 18.3, domain resolution goes strictly through _search

    domain.optimize_full(model)
    if not domain.is_true():
        query.add_where(domain._to_sql(self, self._table, query))

optimize_full() leaves a leaf untouched when the field has no search= defined, so _to_sql() calls field.to_sql() directly. For non-stored fields this now raises:

   File "/home/odoo/src/odoo/19.0/odoo/orm/models.py", line 5256, in _order_to_sql
    term = self._order_field_to_sql(alias, field_name, sql_direction, sql_nulls, query)
   File "/home/odoo/src/odoo/19.0/odoo/orm/models.py", line 5315, in _order_field_to_sql
    sql_field = self._field_to_sql(alias, field_name, query)
   File "/home/odoo/src/odoo/19.0/odoo/orm/models.py", line 2930, in _field_to_sql
    sql = field.to_sql(self, alias)
   File "/home/odoo/src/odoo/19.0/odoo/orm/fields_textual.py", line 395, in to_sql
    sql_field = super().to_sql(model, alias)
   File "/home/odoo/src/odoo/19.0/odoo/orm/fields.py", line 1216, in to_sql
    raise ValueError(f"Cannot convert {self} to SQL because it is not stored")
 ValueError: Cannot convert photovoltaics.installer.name to SQL because it is not stored

Previously (pre-18.3), such leaves were treated as always-true instead of raising:

https://github.com/odoo/odoo/blob/d9c06a66356dd9d5a50821b8cde6194967353c18/odoo/osv/expression.py#L1180-L1187

Since we don't always know if a custom/third-party field is stored or searchable, assign a dummy search= returning an always-true leaf (e.g. [(1, '=', 1)]). This makes optimize_full() resolve the domain to is_true() before _to_sql() runs, restoring the old behavior and avoiding the ValueError.

@robodoo

robodoo commented Aug 13, 2026

Copy link
Copy Markdown
Contributor

Pull request status dashboard

@sagu-odoo

sagu-odoo commented Aug 13, 2026

Copy link
Copy Markdown
Contributor Author

upgradeci retry with always base in all versions

@KangOl

KangOl commented Aug 13, 2026

Copy link
Copy Markdown
Contributor

upgradeci retry with always only base

@sagu-odoo

Copy link
Copy Markdown
Contributor Author

@KangOl

KangOl commented Aug 13, 2026

Copy link
Copy Markdown
Contributor

Not sure that it should be handled here. It looks like it can be handled by a specific script.
Either the field should be stored, or it should not be used in domains.

@sagu-odoo

sagu-odoo commented Aug 13, 2026

Copy link
Copy Markdown
Contributor Author

@KangOl FYI here is tbg https://upgrade.odoo.com/odoo/tbg/2822

Either the field should be stored

The thing is, we cannot be sure whether the client’s fields are searchable or not, as this entirely depends on their custom code.

I think we should fix this generically by patching the same behavior in mock_crawl or here. Since we cannot reliably determine whether a field is searchable, and marking the field as manual is what causes the issue here, it would be better to handle it at this level. This was not the case previously, as mentioned in the description.

It looks like it can be handled by a specific script.

that's already being managed by adding the failing menus to env variable skip_menus

@sagu-odoo
sagu-odoo force-pushed the master-fix-no-sql-sagu branch from 3597374 to c4584f8 Compare August 17, 2026 07:03
Since 18.3, domain resolution goes strictly through
` _search`

```
    domain.optimize_full(model)
    if not domain.is_true():
        query.add_where(domain._to_sql(self, self._table, query))
```
[domain]: https://github.com/odoo/odoo/blob/2f0f8e5e00685129b5bbe954117bc9f80a568e88/odoo/orm/models.py#L5365-L5371

optimize_full() leaves a leaf untouched when the field has no
`search=` defined, so `_to_sql()` calls `field.to_sql()` directly.
For non-stored fields this now raises:
```
   File "/home/odoo/src/odoo/19.0/odoo/orm/models.py", line 5256, in _order_to_sql
    term = self._order_field_to_sql(alias, field_name, sql_direction, sql_nulls, query)
   File "/home/odoo/src/odoo/19.0/odoo/orm/models.py", line 5315, in _order_field_to_sql
    sql_field = self._field_to_sql(alias, field_name, query)
   File "/home/odoo/src/odoo/19.0/odoo/orm/models.py", line 2930, in _field_to_sql
    sql = field.to_sql(self, alias)
   File "/home/odoo/src/odoo/19.0/odoo/orm/fields_textual.py", line 395, in to_sql
    sql_field = super().to_sql(model, alias)
   File "/home/odoo/src/odoo/19.0/odoo/orm/fields.py", line 1216, in to_sql
    raise ValueError(f"Cannot convert {self} to SQL because it is not stored")
 ValueError: Cannot convert photovoltaics.installer.name to SQL because it is not stored
```

Previously (pre-18.3), such leaves were treated as always-true instead
of raising:

https://github.com/odoo/odoo/blob/d9c06a66356dd9d5a50821b8cde6194967353c18/odoo/osv/expression.py#L1180-L1187

Since we don't always know if a custom/third-party field is stored or
searchable, assign a dummy `search=` returning an always-true leaf
(e.g. [(1, '=', 1)]). This makes optimize_full() resolve the domain to
is_true() before _to_sql() runs, restoring the old behavior and
avoiding the ValueError.

upg- 4578773
@sagu-odoo
sagu-odoo force-pushed the master-fix-no-sql-sagu branch from c4584f8 to 5376110 Compare August 17, 2026 07:14
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants