[IMP] core, website: add psycopg2.sql support to get_unaccent_wrapper

`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: odoo/odoo#76436
This commit is contained in:
Xavier Morel
2021-09-20 12:53:00 +00:00
parent 75f8814afd
commit b043d9fa64
3 changed files with 12 additions and 17 deletions
+3 -3
View File
@@ -18,13 +18,13 @@ from werkzeug.exceptions import NotFound
from odoo import api, fields, models, tools, http, release, registry
from odoo.addons.http_routing.models.ir_http import slugify, _guess_mimetype, url_for
from odoo.addons.website.models.ir_http import sitemap_qs2dom
from odoo.addons.website.tools import get_unaccent_sql_wrapper, similarity_score, text_from_html
from odoo.addons.website.tools import similarity_score, text_from_html
from odoo.addons.portal.controllers.portal import pager
from odoo.addons.iap.tools import iap_tools
from odoo.exceptions import UserError, AccessError
from odoo.http import request
from odoo.modules.module import get_resource_path
from odoo.osv.expression import AND, OR, FALSE_DOMAIN
from odoo.osv.expression import AND, OR, FALSE_DOMAIN, get_unaccent_wrapper
from odoo.tools.translate import _
from odoo.tools import escape_psql, pycompat
@@ -1614,7 +1614,7 @@ class Website(models.Model):
domain = search_detail['base_domain'].copy()
fields = set(fields).intersection(model._fields)
unaccent = get_unaccent_sql_wrapper(self.env.cr)
unaccent = get_unaccent_wrapper(self.env.cr)
similarities = [sql.SQL("word_similarity({search}, {field})").format(
search=unaccent(sql.Placeholder('search')),
# Specific handling for website.page that inherits its arch_db and name fields
-13
View File
@@ -186,16 +186,3 @@ def text_from_html(html_fragment):
# lxml requires one single root element
tree = etree.fromstring('<p>%s</p>' % html_fragment, etree.XMLParser(recover=True))
return ' '.join(tree.itertext())
def get_unaccent_sql_wrapper(cr):
"""
Returns a function that wraps SQL within unaccent if available
TODO remove when this tool becomes globally available
:param cr: cursor on which the wrapping is done
:return: function that wraps SQL with unaccent if available
"""
if odoo.registry(cr.dbname).has_unaccent:
return lambda x: sql.SQL("unaccent({wrapped_sql})").format(wrapped_sql=x)
return lambda x: x
+9 -1
View File
@@ -122,6 +122,9 @@ import traceback
from functools import partial
from datetime import date, datetime, time
from psycopg2.sql import Composable, SQL
import odoo.modules
from odoo.osv.query import Query
from odoo.tools import pycompat
@@ -401,9 +404,14 @@ def check_leaf(element, internal=False):
# SQL utils
# --------------------------------------------------
def _unaccent_wrapper(x):
if isinstance(x, Composable):
return SQL('unaccent({})').format(x)
return 'unaccent({})'.format(x)
def get_unaccent_wrapper(cr):
if odoo.registry(cr.dbname).has_unaccent:
return lambda x: "unaccent(%s)" % (x,)
return _unaccent_wrapper
return lambda x: x