From b043d9fa648b8f5c1822dbb9752583a5b37b7d43 Mon Sep 17 00:00:00 2001 From: Xavier Morel Date: Mon, 13 Sep 2021 12:12:30 +0000 Subject: [PATCH] [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 --- addons/website/models/website.py | 6 +++--- addons/website/tools.py | 13 ------------- odoo/osv/expression.py | 10 +++++++++- 3 files changed, 12 insertions(+), 17 deletions(-) diff --git a/addons/website/models/website.py b/addons/website/models/website.py index 2cd819a792d..9d2c829246d 100644 --- a/addons/website/models/website.py +++ b/addons/website/models/website.py @@ -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 diff --git a/addons/website/tools.py b/addons/website/tools.py index 58aa86d59d2..6b47811e386 100644 --- a/addons/website/tools.py +++ b/addons/website/tools.py @@ -186,16 +186,3 @@ def text_from_html(html_fragment): # lxml requires one single root element tree = etree.fromstring('

%s

' % 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 diff --git a/odoo/osv/expression.py b/odoo/osv/expression.py index 612201c93bd..7b83a59f6bc 100644 --- a/odoo/osv/expression.py +++ b/odoo/osv/expression.py @@ -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