Define index using COALESCE for nullable Char fields

Closes #14909
(grafted from 525198c97acdd19820d581411b3af0f5bb6e4237)

--HG--
branch : 8.0
This commit is contained in:
Cédric Krier
2026-07-14 21:14:05 +02:00
parent 856461f693
commit ebed93c61a
22 changed files with 65 additions and 36 deletions
+2 -2
View File
@@ -8,7 +8,7 @@ from itertools import cycle, groupby
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
@@ -164,7 +164,7 @@ class TaxCode(
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))
+1 -1
View File
@@ -98,7 +98,7 @@ class Account(
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'))
+4 -1
View File
@@ -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 @@ class PostalCode(metaclass=PoolMeta):
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())),
})
+13 -7
View File
@@ -201,7 +201,8 @@ class Template(
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 @@ class Product(
& (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)
+8 -3
View File
@@ -5,6 +5,7 @@ import datetime
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 @@ class Work(
'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
+2 -1
View File
@@ -4,6 +4,7 @@ import datetime
from collections import defaultdict
from sql.aggregate import Count, Max
from sql.conditionals import Coalesce
from trytond.i18n import gettext
from trytond.model import (
@@ -324,7 +325,7 @@ class ProductSupplier(
super().__setup__()
t = cls.__table__()
cls._sql_indexes.update({
Index(t, (t.code, Index.Similarity())),
Index(t, (Coalesce(t.code, ''), Index.Similarity())),
})
@staticmethod
+2 -1
View File
@@ -8,6 +8,7 @@ from itertools import chain, groupby
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 @@ class Purchase(
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,
@@ -6,6 +6,7 @@ from decimal import Decimal
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 @@ class BlanketAgreement(Workflow, ModelSQL, ModelView, ChatMixin):
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'])),
@@ -5,7 +5,7 @@ from functools import wraps
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 @@ class Quotation(Workflow, ModelSQL, ModelView, ChatMixin):
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'])),
+2 -1
View File
@@ -5,6 +5,7 @@ import datetime as dt
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 @@ class Inspection(Workflow, ModelSQL, ModelView, ChatMixin):
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'),
+1 -1
View File
@@ -338,7 +338,7 @@ class Sale(
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,
+2 -1
View File
@@ -6,6 +6,7 @@ from decimal import Decimal
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 @@ class BlanketAgreement(Workflow, ModelSQL, ModelView, ChatMixin):
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'])),
+2 -1
View File
@@ -6,6 +6,7 @@ from collections import defaultdict
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 @@ class Complaint(Workflow, ModelSQL, ModelView, ChatMixin):
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')),
+2 -1
View File
@@ -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 @@ class SaleOpportunity(
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,
+1 -1
View File
@@ -52,7 +52,7 @@ exclude = ['doc']
"" = "trytond/modules/sale_rental"
[tool.hatch.metadata.hooks.tryton]
dependencies = []
dependencies = ['python-sql']
copyright = 'COPYRIGHT'
readme = 'README.rst'
+3 -1
View File
@@ -5,6 +5,8 @@ import datetime as dt
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 @@ class Rental(
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,
+1 -1
View File
@@ -172,7 +172,7 @@ class Subscription(Workflow, ModelSQL, ModelView, ChatMixin):
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')),
+2 -1
View File
@@ -5,6 +5,7 @@ import operator
from decimal import Decimal
from sql import Column
from sql.conditionals import Coalesce
from trytond.cache import Cache
from trytond.i18n import gettext
@@ -197,7 +198,7 @@ class Location(DeactivableMixin, tree(), ModelSQL, ModelView):
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')),
+1 -1
View File
@@ -66,7 +66,7 @@ class ShipmentMixin:
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'),
+4 -2
View File
@@ -89,10 +89,12 @@ class User(avatar_mixin(100), DeactivableMixin, ModelSQL, ModelView):
]
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({
+7 -4
View File
@@ -12,7 +12,7 @@ from relatorio.reporting import MIMETemplateLoader
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
@@ -120,9 +120,11 @@ class Translation(
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')),
@@ -130,7 +132,8 @@ class Translation(
(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')),
+1 -1
View File
@@ -788,7 +788,7 @@ class ViewTreeState(
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