#27732: django.contrib.postgres.search SearchRank doesn't handle 
SearchVectorField
references
--------------------------------------------+------------------------
               Reporter:  matt-hoskins      |          Owner:  (none)
                   Type:  Bug               |         Status:  new
              Component:  contrib.postgres  |        Version:  1.10
               Severity:  Normal            |       Keywords:
           Triage Stage:  Unreviewed        |      Has patch:  0
    Needs documentation:  0                 |    Needs tests:  0
Patch needs improvement:  0                 |  Easy pickings:  0
                  UI/UX:  0                 |
--------------------------------------------+------------------------
 For search performance I'm using SearchVectorField on a model. However if
 I reference that field in the vector argument to SearchRank I get an
 error. This is because SearchRank always wraps a vector argument that
 lacks a "resolve_expression" attribute as a SearchVector even if it would
 end up resolving to a SearchVectorField.

 If I modify tests/postgres_tests/test_search.py and add the following to
 the SearchVectorFieldTest class:
 {{{#!python
     def test_existing_vector_ranking(self):
 Line.objects.update(dialogue_search_vector=SearchVector('dialogue'))
         searched = Line.objects.filter(character=self.minstrel).annotate(
             rank=SearchRank('dialogue_search_vector', SearchQuery('brave
 sir robin')),
         ).order_by('rank')
         self.assertSequenceEqual(searched, [self.verse2, self.verse1,
 self.verse0])
 }}}

 Then this results in the following error:
 {{{
 ProgrammingError: function to_tsvector(tsvector) does not exist
 LINE 1: ... "postgres_tests_line"."dialogue_config", ts_rank(to_tsvecto...
                                                              ^
 HINT:  No function matches the given name and argument types. You might
 need to add explicit type casts.
 }}}

 As the enforced wrapping of the vector argument in a SearchVector is then
 causing the sql to wrap the tsvector field in a coalesce (which doesn't
 cause an issue) and then a to_tsvector call.

 I've not delved into the Expressions code before (my last rummaging around
 in the bowels of the query code was a few years ago) but from my quick
 look at existing code and the APIs then perhaps a solution is for
 SearchRank to not wrap the vector argument as it comes into __init__ but
 instead have a resolve_expression call which checks the first resolved
 expression on the result of calling super's resolve_expression is or isn't
 of type SearchVectorField and then if it isn't then resolve a wrapped
 version.

 I've attached a patch which both adds the test I mention above (it may be
 that it should live in the rank test rather than the search vector field
 test, or have its own test class which covers the combination of both) and
 also modifies SearchRank in the way I've suggested above. The postgres
 tests pass on my test system with this patch.

--
Ticket URL: <https://code.djangoproject.com/ticket/27732>
Django <https://code.djangoproject.com/>
The Web framework for perfectionists with deadlines.

-- 
You received this message because you are subscribed to the Google Groups 
"Django updates" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to [email protected].
To post to this group, send email to [email protected].
To view this discussion on the web visit 
https://groups.google.com/d/msgid/django-updates/055.dec0dc5f540ea7cd185568a67565177d%40djangoproject.com.
For more options, visit https://groups.google.com/d/optout.

Reply via email to