[FIX] website: survive to null texts during trigram search

Generic search bar was introduced with #65871.
But the trigram search would fail if it encounters a (SQL) NULL text
from the database. This is because when word_similarity() receives NULL
as a parameter it returns NULL, and NULL not being a number cannot be
compared with the similarity threshold.

After this commit the trigram search will exclude matches returning a
NULL similarity.

Step to reproduce:
  - Enable trigram in the DB, run `CREATE EXTENSION pg_trgm;` in psql
  - Create a product, name it `myproduct`
  - Insert NULL values inside the translation table (not sure how the
    user did it):
    `update ir_translation set value = NULL where src = 'myproduct';`
  - Search 'mypro' in the eshop search bar
    -> Traceback

opw-2680659

closes odoo/odoo#80426

X-original-commit: ef17edc32d4646c93e31e730249be83469951241
Signed-off-by: Romain Derie (rde) <rde@odoo.com>
This commit is contained in:
Benoit Socias
2021-11-26 14:26:31 +00:00
committed by Romain Derie
parent c077a1916b
commit fdd30e368c
+4 -2
View File
@@ -1657,7 +1657,7 @@ class Website(models.Model):
from_clause=from_clause,
)
self.env.cr.execute(query, {'search': search})
ids = {row[0] for row in self.env.cr.fetchall() if row[1] >= similarity_threshold}
ids = {row[0] for row in self.env.cr.fetchall() if row[1] and row[1] >= similarity_threshold}
if self.env.lang:
# Specific handling for website.page that inherits its arch_db and name fields
# TODO make more generic
@@ -1676,6 +1676,7 @@ class Website(models.Model):
WHERE t.lang = {lang}
AND t.name = ANY({names})
AND t.type = 'model_terms'
AND t.value IS NOT NULL
ORDER BY _similarity desc
LIMIT 1000
""").format(
@@ -1696,6 +1697,7 @@ class Website(models.Model):
WHERE lang = {lang}
AND name = ANY({names})
AND type = 'model'
AND value IS NOT NULL
ORDER BY _similarity desc
LIMIT 1000
""").format(
@@ -1704,7 +1706,7 @@ class Website(models.Model):
names=sql.Placeholder('names'),
)
self.env.cr.execute(query, {'lang': self.env.lang, 'names': names, 'search': search})
ids.update(row[0] for row in self.env.cr.fetchall() if row[1] >= similarity_threshold)
ids.update(row[0] for row in self.env.cr.fetchall() if row[1] and row[1] >= similarity_threshold)
domain.append([('id', 'in', list(ids))])
domain = AND(domain)
records = model.search_read(domain, fields, limit=limit)