summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorThomasina Lee <thomasina.lee@titanemail.com>2019-05-17 15:27:01 +0100
committerMariusz Felisiak <felisiak.mariusz@gmail.com>2019-05-20 08:34:06 +0200
commitc38e7a79f4354ee831f92deb7a658fc0387e3bec (patch)
tree478dcd1c9b1b32dcf8fe54cd495af4365b9762ac
parent04042b2b440f0bf50eb908d52cfe76af430e1738 (diff)
Fixed #30488 -- Removed redundant Coalesce call in SQL generated by SearchVector.
Regression in 405c8363362063542e9e79beac53c8437d389520.
-rw-r--r--django/contrib/postgres/search.py29
-rw-r--r--docs/releases/2.2.2.txt4
-rw-r--r--tests/postgres_tests/test_search.py4
3 files changed, 23 insertions, 14 deletions
diff --git a/django/contrib/postgres/search.py b/django/contrib/postgres/search.py
index f8c691d73b..08d92e3514 100644
--- a/django/contrib/postgres/search.py
+++ b/django/contrib/postgres/search.py
@@ -60,14 +60,6 @@ class SearchVector(SearchVectorCombinable, Func):
def resolve_expression(self, query=None, allow_joins=True, reuse=None, summarize=False, for_save=False):
resolved = super().resolve_expression(query, allow_joins, reuse, summarize, for_save)
- resolved.set_source_expressions([
- Coalesce(
- expression
- if isinstance(expression.output_field, (CharField, TextField))
- else Cast(expression, TextField()),
- Value('')
- ) for expression in resolved.get_source_expressions()
- ])
if self.config:
if not hasattr(self.config, 'resolve_expression'):
resolved.config = Value(self.config).resolve_expression(query, allow_joins, reuse, summarize, for_save)
@@ -76,17 +68,26 @@ class SearchVector(SearchVectorCombinable, Func):
return resolved
def as_sql(self, compiler, connection, function=None, template=None):
+ clone = self.copy()
+ clone.set_source_expressions([
+ Coalesce(
+ expression
+ if isinstance(expression.output_field, (CharField, TextField))
+ else Cast(expression, TextField()),
+ Value('')
+ ) for expression in clone.get_source_expressions()
+ ])
config_params = []
if template is None:
- if self.config:
- config_sql, config_params = compiler.compile(self.config)
+ if clone.config:
+ config_sql, config_params = compiler.compile(clone.config)
template = '%(function)s({}::regconfig, %(expressions)s)'.format(config_sql.replace('%', '%%'))
else:
- template = self.template
- sql, params = super().as_sql(compiler, connection, function=function, template=template)
+ template = clone.template
+ sql, params = super(SearchVector, clone).as_sql(compiler, connection, function=function, template=template)
extra_params = []
- if self.weight:
- weight_sql, extra_params = compiler.compile(self.weight)
+ if clone.weight:
+ weight_sql, extra_params = compiler.compile(clone.weight)
sql = 'setweight({}, {})'.format(sql, weight_sql)
return sql, config_params + params + extra_params
diff --git a/docs/releases/2.2.2.txt b/docs/releases/2.2.2.txt
index 377abaa3c0..d68338dce2 100644
--- a/docs/releases/2.2.2.txt
+++ b/docs/releases/2.2.2.txt
@@ -14,3 +14,7 @@ Bugfixes
* Fixed a regression in Django 2.2 where deprecation message crashes if
``Meta.ordering`` contains an expression (:ticket:`30463`).
+
+* Fixed a regression in Django 2.2.1 where
+ :class:`~django.contrib.postgres.search.SearchVector` generates SQL with a
+ redundant ``Coalesce`` call (:ticket:`30488`).
diff --git a/tests/postgres_tests/test_search.py b/tests/postgres_tests/test_search.py
index 8944c6342d..f5111ce8d3 100644
--- a/tests/postgres_tests/test_search.py
+++ b/tests/postgres_tests/test_search.py
@@ -113,6 +113,10 @@ class SearchVectorFieldTest(GrailTestData, PostgreSQLTestCase):
searched = Line.objects.filter(dialogue_search_vector=SearchQuery('cadeaux', config='french'))
self.assertSequenceEqual(searched, [self.french])
+ def test_single_coalesce_expression(self):
+ searched = Line.objects.annotate(search=SearchVector('dialogue')).filter(search='cadeaux')
+ self.assertNotIn('COALESCE(COALESCE', str(searched.query))
+
class MultipleFieldsTest(GrailTestData, PostgreSQLTestCase):