From bbbbf3f7c38b835e1ef9cfa903594fbb581b9eff Mon Sep 17 00:00:00 2001 From: Thiago Ferreira Date: Thu, 12 Jan 2023 11:51:48 -0300 Subject: [PATCH] fix: change do_filter to optmize uuid pks --- watson/backends.py | 19 +++++++++++++++---- watson/models.py | 6 ++++++ 2 files changed, 21 insertions(+), 4 deletions(-) diff --git a/watson/backends.py b/watson/backends.py index d08d46a..566b269 100644 --- a/watson/backends.py +++ b/watson/backends.py @@ -12,7 +12,7 @@ from django.db.models.expressions import RawSQL, Value from django.utils.encoding import force_str -from watson.models import SearchEntry, has_int_pk +from watson.models import SearchEntry, has_int_pk, has_uuid_pk def regex_from_word(word): @@ -282,10 +282,19 @@ def do_filter(self, engine_slug, queryset, search_text): if has_int_pk(model): ref_name = "object_id_int" ref_name_typecast = "" + watson_id_typecast = "" + elif has_uuid_pk(model): + ref_name = "object_id" + # Moving the type cast happens on the watson_searchentry table. + # This ensures the primary key will be properly used. + ref_name_typecast = "" + watson_id_typecast = "::uuid" else: ref_name = "object_id" - # Cast to text to make join work with uuid columns + # Cast to text to make join work with other column types ref_name_typecast = "::text" + watson_id_typecast = "" + return queryset.extra( tables=("watson_searchentry",), where=( @@ -293,11 +302,13 @@ def do_filter(self, engine_slug, queryset, search_text): "watson_searchentry.search_tsv @@ to_tsquery('{search_config}', %s)".format( search_config=self.search_config ), - "watson_searchentry.{ref_name} = {table_name}.{pk_name}{ref_name_typecast}".format( + "watson_searchentry.{ref_name}{watson_id_typecast} = {table_name}.{pk_name}{ref_name_typecast}".format( + ref_name=ref_name, table_name=connection.ops.quote_name(model._meta.db_table), pk_name=connection.ops.quote_name(pk.db_column or pk.attname), - ref_name_typecast=ref_name_typecast + ref_name_typecast=ref_name_typecast, + watson_id_typecast=watson_id_typecast ), "watson_searchentry.content_type_id = %s" ), diff --git a/watson/models.py b/watson/models.py index a6c7743..f88dde3 100644 --- a/watson/models.py +++ b/watson/models.py @@ -60,6 +60,12 @@ def has_int_pk(model): ) +def has_uuid_pk(model): + """Tests whether the given model has an uuid primary key.""" + pk = model._meta.pk + return isinstance(pk, models.UUIDField) + + def get_str_pk(obj, connection): return obj.pk.hex if isinstance(obj.pk, uuid.UUID) and connection.vendor != "postgresql" else force_str(obj.pk)