Skip to content

Commit b64a822

Browse files
authored
Merge pull request #303 from thiagoferreiraw/master
Change PostgresSearchBackend to optmize for UUID primary keys
2 parents 3674de1 + bbbbf3f commit b64a822

File tree

2 files changed

+21
-4
lines changed

2 files changed

+21
-4
lines changed

watson/backends.py

Lines changed: 15 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@
1212
from django.db.models.expressions import RawSQL, Value
1313
from django.utils.encoding import force_str
1414

15-
from watson.models import SearchEntry, has_int_pk
15+
from watson.models import SearchEntry, has_int_pk, has_uuid_pk
1616

1717

1818
def regex_from_word(word):
@@ -282,22 +282,33 @@ def do_filter(self, engine_slug, queryset, search_text):
282282
if has_int_pk(model):
283283
ref_name = "object_id_int"
284284
ref_name_typecast = ""
285+
watson_id_typecast = ""
286+
elif has_uuid_pk(model):
287+
ref_name = "object_id"
288+
# Moving the type cast happens on the watson_searchentry table.
289+
# This ensures the primary key will be properly used.
290+
ref_name_typecast = ""
291+
watson_id_typecast = "::uuid"
285292
else:
286293
ref_name = "object_id"
287-
# Cast to text to make join work with uuid columns
294+
# Cast to text to make join work with other column types
288295
ref_name_typecast = "::text"
296+
watson_id_typecast = ""
297+
289298
return queryset.extra(
290299
tables=("watson_searchentry",),
291300
where=(
292301
"watson_searchentry.engine_slug = %s",
293302
"watson_searchentry.search_tsv @@ to_tsquery('{search_config}', %s)".format(
294303
search_config=self.search_config
295304
),
296-
"watson_searchentry.{ref_name} = {table_name}.{pk_name}{ref_name_typecast}".format(
305+
"watson_searchentry.{ref_name}{watson_id_typecast} = {table_name}.{pk_name}{ref_name_typecast}".format(
306+
297307
ref_name=ref_name,
298308
table_name=connection.ops.quote_name(model._meta.db_table),
299309
pk_name=connection.ops.quote_name(pk.db_column or pk.attname),
300-
ref_name_typecast=ref_name_typecast
310+
ref_name_typecast=ref_name_typecast,
311+
watson_id_typecast=watson_id_typecast
301312
),
302313
"watson_searchentry.content_type_id = %s"
303314
),

watson/models.py

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,12 @@ def has_int_pk(model):
6060
)
6161

6262

63+
def has_uuid_pk(model):
64+
"""Tests whether the given model has an uuid primary key."""
65+
pk = model._meta.pk
66+
return isinstance(pk, models.UUIDField)
67+
68+
6369
def get_str_pk(obj, connection):
6470
return obj.pk.hex if isinstance(obj.pk, uuid.UUID) and connection.vendor != "postgresql" else force_str(obj.pk)
6571

0 commit comments

Comments
 (0)