[2.2.x] Fixed #30385 -- Restored SearchVector(config) immutability.

Regression in 1a28dc3887.

The usage of CONCAT to allow SearchVector to deal with non-text fields
made the generated expression non-IMMUTABLE which prevents a functional
index to be created for it.

Using a combination of COALESCE and ::text makes sure the expression
preserves its immutability.

Refs #29582. Thanks Andrew Brown for the report, Nick Pope for the
review.

Backport of 405c836336 from master
This commit is contained in:
Simon Charette 2019-04-19 02:39:25 -04:00 committed by Mariusz Felisiak
parent 47885278c6
commit 88bf635c35
3 changed files with 34 additions and 4 deletions

View file

@ -8,6 +8,7 @@ transcript.
from django.contrib.postgres.search import (
SearchQuery, SearchRank, SearchVector,
)
from django.db import connection
from django.db.models import F
from django.test import SimpleTestCase, modify_settings, skipUnlessDBFeature
@ -346,6 +347,23 @@ class TestRankingAndWeights(GrailTestData, PostgreSQLTestCase):
self.assertSequenceEqual(searched, [self.verse0])
class SearchVectorIndexTests(PostgreSQLTestCase):
def test_search_vector_index(self):
"""SearchVector generates IMMUTABLE SQL in order to be indexable."""
# This test should be moved to test_indexes and use a functional
# index instead once support lands (see #26167).
query = Line.objects.all().query
resolved = SearchVector('id', 'dialogue', config='english').resolve_expression(query)
compiler = query.get_compiler(connection.alias)
sql, params = resolved.as_sql(compiler, connection)
# Indexed function must be IMMUTABLE.
with connection.cursor() as cursor:
cursor.execute(
'CREATE INDEX search_vector_index ON %s USING GIN (%s)' % (Line._meta.db_table, sql),
params,
)
class SearchQueryTests(SimpleTestCase):
def test_str(self):
tests = (