details: https://code.tryton.org/tryton/commit/525198c97acd
branch: default
user: Cédric Krier <[email protected]>
date: Wed Jun 24 22:07:52 2026 +0200
description:
Define index using COALESCE for nullable Char fields
Closes #14909
diffstat:
modules/account/tax.py | 4 ++--
modules/analytic_account/account.py | 2 +-
modules/party/country.py | 5 ++++-
modules/product/product.py | 20 +++++++++++++-------
modules/project/work.py | 11 ++++++++---
modules/purchase/product.py | 2 +-
modules/purchase/purchase.py | 3 ++-
modules/purchase_blanket_agreement/purchase.py | 3 ++-
modules/purchase_request_quotation/purchase.py | 4 ++--
modules/quality/quality.py | 3 ++-
modules/sale/sale.py | 2 +-
modules/sale_blanket_agreement/sale.py | 3 ++-
modules/sale_complaint/complaint.py | 3 ++-
modules/sale_opportunity/opportunity.py | 3 ++-
modules/sale_rental/pyproject.toml | 2 +-
modules/sale_rental/sale.py | 4 +++-
modules/sale_subscription/subscription.py | 2 +-
modules/stock/location.py | 3 ++-
modules/stock/shipment.py | 2 +-
modules/web_user/user.py | 6 ++++--
trytond/trytond/ir/translation.py | 11 +++++++----
trytond/trytond/ir/ui/view.py | 2 +-
22 files changed, 64 insertions(+), 36 deletions(-)
diffs (428 lines):
diff -r 776fe202ed6f -r 525198c97acd modules/account/tax.py
--- a/modules/account/tax.py Wed Jun 24 22:06:59 2026 +0200
+++ b/modules/account/tax.py Wed Jun 24 22:07:52 2026 +0200
@@ -8,7 +8,7 @@
from sql import Literal
from sql.aggregate import Sum
-from sql.conditionals import Case
+from sql.conditionals import Case, Coalesce
from trytond import backend
from trytond.i18n import gettext
@@ -163,7 +163,7 @@
super().__setup__()
t = cls.__table__()
cls._sql_indexes.add(
- Index(t, (t.code, Index.Similarity())))
+ Index(t, (Coalesce(t.code, ''), Index.Similarity())))
for date in [cls.start_date, cls.end_date]:
date.states = {
'readonly': (Bool(Eval('template', -1))
diff -r 776fe202ed6f -r 525198c97acd modules/analytic_account/account.py
--- a/modules/analytic_account/account.py Wed Jun 24 22:06:59 2026 +0200
+++ b/modules/analytic_account/account.py Wed Jun 24 22:07:52 2026 +0200
@@ -98,7 +98,7 @@
super().__setup__()
t = cls.__table__()
cls._sql_indexes.add(
- Index(t, (t.code, Index.Similarity())))
+ Index(t, (Coalesce(t.code, ''), Index.Similarity())))
cls._order.insert(0, ('code', 'ASC'))
cls._order.insert(1, ('name', 'ASC'))
diff -r 776fe202ed6f -r 525198c97acd modules/party/country.py
--- a/modules/party/country.py Wed Jun 24 22:06:59 2026 +0200
+++ b/modules/party/country.py Wed Jun 24 22:07:52 2026 +0200
@@ -1,6 +1,8 @@
# This file is part of Tryton. The COPYRIGHT file at the top level of
# this repository contains the full copyright notices and license terms.
+from sql.conditionals import Coalesce
+
from trytond.model import Index
from trytond.pool import PoolMeta
@@ -15,7 +17,8 @@
cls._sql_indexes.update({
Index(
t,
- (Index.Unaccent(t.city), Index.Similarity()),
+ (Index.Unaccent(Coalesce(t.city, '')),
+ Index.Similarity()),
(t.country, Index.Range()),
(t.subdivision, Index.Range())),
})
diff -r 776fe202ed6f -r 525198c97acd modules/product/product.py
--- a/modules/product/product.py Wed Jun 24 22:06:59 2026 +0200
+++ b/modules/product/product.py Wed Jun 24 22:07:52 2026 +0200
@@ -201,7 +201,8 @@
super().__setup__()
t = cls.__table__()
cls._sql_indexes.update({
- Index(t, (t.code, Index.Similarity())),
+ Index(t, (Coalesce(t.code, ''), Index.Equality())),
+ Index(t, (Coalesce(t.code, ''), Index.Similarity())),
})
cls._order.insert(0, ('rec_name', 'ASC'))
@@ -587,12 +588,17 @@
& (t.code != '')),
'product.msg_product_code_unique'),
]
- cls._sql_indexes.add(
- Index(t, (t.code, Index.Similarity(cardinality='high'))))
- cls._sql_indexes.add(
- Index(t,
- (t.position, Index.Range(order='ASC NULLS FIRST')),
- (t.id, Index.Range(order='ASC'))))
+ cls._sql_indexes.update({
+ Index(t,
+ (Coalesce(t.code, ''),
+ Index.Equality(cardinality='high'))),
+ Index(t,
+ (Coalesce(t.code, ''),
+ Index.Similarity(cardinality='high'))),
+ Index(t,
+ (t.position, Index.Range(order='ASC NULLS FIRST')),
+ (t.id, Index.Range(order='ASC'))),
+ })
for attr in dir(Template):
tfield = getattr(Template, attr)
diff -r 776fe202ed6f -r 525198c97acd modules/project/work.py
--- a/modules/project/work.py Wed Jun 24 22:06:59 2026 +0200
+++ b/modules/project/work.py Wed Jun 24 22:07:52 2026 +0200
@@ -5,6 +5,7 @@
from collections import defaultdict
from sql import Null
+from sql.conditionals import Coalesce
from sql.functions import CharLength
from trytond.cache import Cache
@@ -257,9 +258,13 @@
'project.msg_work_number_unique'),
]
cls._sql_indexes.update({
- Index(t, (t.number, Index.Equality(cardinality='high'))),
- Index(t, (t.number, Index.Similarity(cardinality='high'))),
- Index(t, (t.path, Index.Similarity(begin=True))),
+ Index(t,
+ (Coalesce(t.number, ''),
+ Index.Equality(cardinality='high'))),
+ Index(t,
+ (Coalesce(t.number, ''),
+ Index.Similarity(cardinality='high'))),
+ Index(t, (Coalesce(t.path, ''), Index.Similarity(begin=True))),
})
@classmethod
diff -r 776fe202ed6f -r 525198c97acd modules/purchase/product.py
--- a/modules/purchase/product.py Wed Jun 24 22:06:59 2026 +0200
+++ b/modules/purchase/product.py Wed Jun 24 22:07:52 2026 +0200
@@ -335,7 +335,7 @@
super().__setup__()
t = cls.__table__()
cls._sql_indexes.update({
- Index(t, (t.code, Index.Similarity())),
+ Index(t, (Coalesce(t.code, ''), Index.Similarity())),
})
@staticmethod
diff -r 776fe202ed6f -r 525198c97acd modules/purchase/purchase.py
--- a/modules/purchase/purchase.py Wed Jun 24 22:06:59 2026 +0200
+++ b/modules/purchase/purchase.py Wed Jun 24 22:07:52 2026 +0200
@@ -8,6 +8,7 @@
from sql import Null
from sql.aggregate import Count
+from sql.conditionals import Coalesce
from sql.functions import CharLength
from trytond import backend
@@ -269,7 +270,7 @@
super().__setup__()
t = cls.__table__()
cls._sql_indexes.update({
- Index(t, (t.reference, Index.Similarity())),
+ Index(t, (Coalesce(t.reference, ''), Index.Similarity())),
Index(t, (t.party, Index.Range())),
Index(
t,
diff -r 776fe202ed6f -r 525198c97acd
modules/purchase_blanket_agreement/purchase.py
--- a/modules/purchase_blanket_agreement/purchase.py Wed Jun 24 22:06:59
2026 +0200
+++ b/modules/purchase_blanket_agreement/purchase.py Wed Jun 24 22:07:52
2026 +0200
@@ -6,6 +6,7 @@
from itertools import groupby
from sql import Null
+from sql.conditionals import Coalesce
from sql.functions import CharLength
from trytond.i18n import gettext
@@ -192,7 +193,7 @@
super().__setup__()
t = cls.__table__()
cls._sql_indexes.update({
- Index(t, (t.reference, Index.Similarity())),
+ Index(t, (Coalesce(t.reference, ''), Index.Similarity())),
Index(
t, (t.state, Index.Equality(cardinality='low')),
where=t.state.in_(['draft', 'running'])),
diff -r 776fe202ed6f -r 525198c97acd
modules/purchase_request_quotation/purchase.py
--- a/modules/purchase_request_quotation/purchase.py Wed Jun 24 22:06:59
2026 +0200
+++ b/modules/purchase_request_quotation/purchase.py Wed Jun 24 22:07:52
2026 +0200
@@ -5,7 +5,7 @@
from itertools import groupby
from sql import Null
-from sql.conditionals import Case
+from sql.conditionals import Case, Coalesce
from sql.functions import CharLength
from trytond.i18n import gettext
@@ -140,7 +140,7 @@
super().__setup__()
t = cls.__table__()
cls._sql_indexes.update({
- Index(t, (t.reference, Index.Similarity())),
+ Index(t, (Coalesce(t.reference, ''), Index.Similarity())),
Index(
t, (t.state, Index.Equality(cardinality='low')),
where=t.state.in_(['draft', 'sent'])),
diff -r 776fe202ed6f -r 525198c97acd modules/quality/quality.py
--- a/modules/quality/quality.py Wed Jun 24 22:06:59 2026 +0200
+++ b/modules/quality/quality.py Wed Jun 24 22:07:52 2026 +0200
@@ -5,6 +5,7 @@
from functools import wraps
from random import Random
+from sql.conditionals import Coalesce
from sql.functions import CharLength
from trytond.i18n import gettext, lazy_gettext
@@ -412,7 +413,7 @@
super().__setup__()
t = cls.__table__()
cls._sql_indexes.update({
- Index(t, (t.reference, Index.Similarity())),
+ Index(t, (Coalesce(t.reference, ''), Index.Similarity())),
})
cls._transitions |= {
('pending', 'passed'),
diff -r 776fe202ed6f -r 525198c97acd modules/sale/sale.py
--- a/modules/sale/sale.py Wed Jun 24 22:06:59 2026 +0200
+++ b/modules/sale/sale.py Wed Jun 24 22:07:52 2026 +0200
@@ -338,7 +338,7 @@
super().__setup__()
t = cls.__table__()
cls._sql_indexes.update({
- Index(t, (t.reference, Index.Similarity())),
+ Index(t, (Coalesce(t.reference, ''), Index.Similarity())),
Index(t, (t.party, Index.Range())),
Index(
t,
diff -r 776fe202ed6f -r 525198c97acd modules/sale_blanket_agreement/sale.py
--- a/modules/sale_blanket_agreement/sale.py Wed Jun 24 22:06:59 2026 +0200
+++ b/modules/sale_blanket_agreement/sale.py Wed Jun 24 22:07:52 2026 +0200
@@ -6,6 +6,7 @@
from itertools import groupby
from sql import Null
+from sql.conditionals import Coalesce
from sql.functions import CharLength
from trytond.i18n import gettext
@@ -192,7 +193,7 @@
super().__setup__()
t = cls.__table__()
cls._sql_indexes.update({
- Index(t, (t.reference, Index.Similarity())),
+ Index(t, (Coalesce(t.reference, ''), Index.Similarity())),
Index(
t, (t.state, Index.Equality(cardinality='low')),
where=t.state.in_(['draft', 'running'])),
diff -r 776fe202ed6f -r 525198c97acd modules/sale_complaint/complaint.py
--- a/modules/sale_complaint/complaint.py Wed Jun 24 22:06:59 2026 +0200
+++ b/modules/sale_complaint/complaint.py Wed Jun 24 22:07:52 2026 +0200
@@ -6,6 +6,7 @@
from decimal import Decimal
from sql import Null
+from sql.conditionals import Coalesce
from sql.functions import CharLength
from trytond import backend
@@ -139,7 +140,7 @@
super().__setup__()
t = cls.__table__()
cls._sql_indexes.update({
- Index(t, (t.reference, Index.Similarity())),
+ Index(t, (Coalesce(t.reference, ''), Index.Similarity())),
Index(
t,
(t.state, Index.Equality(cardinality='low')),
diff -r 776fe202ed6f -r 525198c97acd modules/sale_opportunity/opportunity.py
--- a/modules/sale_opportunity/opportunity.py Wed Jun 24 22:06:59 2026 +0200
+++ b/modules/sale_opportunity/opportunity.py Wed Jun 24 22:07:52 2026 +0200
@@ -4,6 +4,7 @@
import datetime
from itertools import groupby
+from sql.conditionals import Coalesce
from sql.functions import CharLength
from trytond.i18n import gettext
@@ -154,7 +155,7 @@
super().__setup__()
t = cls.__table__()
cls._sql_indexes.update({
- Index(t, (t.reference, Index.Similarity())),
+ Index(t, (Coalesce(t.reference, ''), Index.Similarity())),
Index(t, (t.party, Index.Range())),
Index(
t,
diff -r 776fe202ed6f -r 525198c97acd modules/sale_rental/pyproject.toml
--- a/modules/sale_rental/pyproject.toml Wed Jun 24 22:06:59 2026 +0200
+++ b/modules/sale_rental/pyproject.toml Wed Jun 24 22:07:52 2026 +0200
@@ -52,7 +52,7 @@
"" = "trytond/modules/sale_rental"
[tool.hatch.metadata.hooks.tryton]
-dependencies = []
+dependencies = ['python-sql']
copyright = 'COPYRIGHT'
readme = 'README.rst'
diff -r 776fe202ed6f -r 525198c97acd modules/sale_rental/sale.py
--- a/modules/sale_rental/sale.py Wed Jun 24 22:06:59 2026 +0200
+++ b/modules/sale_rental/sale.py Wed Jun 24 22:07:52 2026 +0200
@@ -5,6 +5,8 @@
from decimal import Decimal
from functools import partial
+from sql.conditionals import Coalesce
+
from trytond.i18n import gettext
from trytond.ir.attachment import AttachmentCopyMixin
from trytond.ir.note import NoteCopyMixin
@@ -277,7 +279,7 @@
super().__setup__()
t = cls.__table__()
cls._sql_indexes.update({
- Index(t, (t.reference, Index.Similarity())),
+ Index(t, (Coalesce(t.reference, ''), Index.Similarity())),
Index(t, (t.party, Index.Equality())),
Index(
t,
diff -r 776fe202ed6f -r 525198c97acd modules/sale_subscription/subscription.py
--- a/modules/sale_subscription/subscription.py Wed Jun 24 22:06:59 2026 +0200
+++ b/modules/sale_subscription/subscription.py Wed Jun 24 22:07:52 2026 +0200
@@ -172,7 +172,7 @@
super().__setup__()
t = cls.__table__()
cls._sql_indexes.update({
- Index(t, (t.reference, Index.Similarity())),
+ Index(t, (Coalesce(t.reference, ''), Index.Similarity())),
Index(
t,
(t.state, Index.Equality(cardinality='low')),
diff -r 776fe202ed6f -r 525198c97acd modules/stock/location.py
--- a/modules/stock/location.py Wed Jun 24 22:06:59 2026 +0200
+++ b/modules/stock/location.py Wed Jun 24 22:07:52 2026 +0200
@@ -5,6 +5,7 @@
from decimal import Decimal
from sql import Column
+from sql.conditionals import Coalesce
from trytond.cache import Cache
from trytond.i18n import gettext
@@ -195,7 +196,7 @@
super().__setup__()
t = cls.__table__()
cls._sql_indexes.update({
- Index(t, (t.code, Index.Similarity())),
+ Index(t, (Coalesce(t.code, ''), Index.Similarity())),
Index(
t,
(t.left, Index.Range(cardinality='high')),
diff -r 776fe202ed6f -r 525198c97acd modules/stock/shipment.py
--- a/modules/stock/shipment.py Wed Jun 24 22:06:59 2026 +0200
+++ b/modules/stock/shipment.py Wed Jun 24 22:07:52 2026 +0200
@@ -66,7 +66,7 @@
super().__setup__()
t = cls.__table__()
cls._sql_indexes.update({
- Index(t, (t.reference, Index.Similarity())),
+ Index(t, (Coalesce(t.reference, ''), Index.Similarity())),
})
cls._order = [
('effective_date', 'ASC NULLS LAST'),
diff -r 776fe202ed6f -r 525198c97acd modules/web_user/user.py
--- a/modules/web_user/user.py Wed Jun 24 22:06:59 2026 +0200
+++ b/modules/web_user/user.py Wed Jun 24 22:07:52 2026 +0200
@@ -89,10 +89,12 @@
]
cls._sql_indexes.update({
Index(
- table, (table.email, Index.Equality(cardinality='high'))),
+ table, (Coalesce(table.email, ''),
+ Index.Equality(cardinality='high'))),
Index(
table,
- (table.email_token, Index.Equality(cardinality='high')),
+ (Coalesce(table.email_token, ''),
+ Index.Equality(cardinality='high')),
where=table.email_token != Null),
})
cls._buttons.update({
diff -r 776fe202ed6f -r 525198c97acd trytond/trytond/ir/translation.py
--- a/trytond/trytond/ir/translation.py Wed Jun 24 22:06:59 2026 +0200
+++ b/trytond/trytond/ir/translation.py Wed Jun 24 22:07:52 2026 +0200
@@ -12,7 +12,7 @@
from relatorio.templates.opendocument import get_zip_file
from sql import Column, Literal, Null
from sql.aggregate import Max
-from sql.conditionals import Case
+from sql.conditionals import Case, Coalesce
from sql.functions import CharLength, Position, Substring
from sql.operators import Concat
@@ -121,9 +121,11 @@
cls._sql_indexes.update({
Index(
- table, (Index.Unaccent(table.src), Index.Similarity())),
+ table, (Index.Unaccent(Coalesce(table.src, '')),
+ Index.Similarity())),
Index(
- table, (Index.Unaccent(table.value), Index.Similarity())),
+ table, (Index.Unaccent(Coalesce(table.value, '')),
+ Index.Similarity())),
Index(
table,
(table.type, Index.Equality(cardinality='low')),
@@ -131,7 +133,8 @@
(table.lang, Index.Equality(cardinality='low')),
(table.res_id, Index.Range()),
(table.fuzzy, Index.Equality(cardinality='low')),
- (Index.Unaccent(table.value), Index.Similarity())),
+ (Index.Unaccent(Coalesce(table.value, '')),
+ Index.Similarity())),
Index(
table,
(table.type, Index.Equality(cardinality='low')),
diff -r 776fe202ed6f -r 525198c97acd trytond/trytond/ir/ui/view.py
--- a/trytond/trytond/ir/ui/view.py Wed Jun 24 22:06:59 2026 +0200
+++ b/trytond/trytond/ir/ui/view.py Wed Jun 24 22:07:52 2026 +0200
@@ -844,7 +844,7 @@
table,
(table.user, Index.Range()),
(table.model, Index.Equality()),
- (table.child_name, Index.Equality()),
+ (Coalesce(table.child_name, ''), Index.Equality()),
(table.domain, Index.Equality())))
@staticmethod