dbsearch: use two-arg websearch_to_tsquery version

We already queried the text search config anyway for GIN and
the version with an explicit config is an immutable function
which ensures the query planner doesn’t do silly things and caches
the evaluation result.
(PostgreSQL 16 seems to execute even the one-arg version only once)

This might help with the repeated reevaluation problem reported in
AkkomaGang/akkoma#650. Note, another even more
foolproof way to ensure only a single eval happens is using a cross join
with the websearch_to_tsquery result. However this can incur significant
overhead for performing a join operation. Since PostgreSQL 13 [1], the
planner is smart enough to re-inline cross joins with immutable
functions, but before that both to_tsvector variants suffer from this
and as of PostgreSQL 16 the one-arg version still does.

Maybe fixes: AkkomaGang/akkoma#650
This commit is contained in:
Oneric 2024-05-03 23:28:12 +02:00
parent f32335742d
commit 403913a2e1

View file

@ -65,30 +65,40 @@ def restrict_public(q) do
)
end
defp query_with(q, :gin, search_query) do
defp get_text_search_config() do
%{rows: [[tsc]]} =
Ecto.Adapters.SQL.query!(
Pleroma.Repo,
"select current_setting('default_text_search_config')::regconfig::oid;"
)
tsc
end
defp query_with(q, :gin, search_query) do
tsc = get_text_search_config()
from([a, o] in q,
where:
fragment(
"to_tsvector(?::oid::regconfig, ?->>'content') @@ websearch_to_tsquery(?)",
"to_tsvector(?::oid::regconfig, ?->>'content') @@ websearch_to_tsquery(?::oid::regconfig, ?)",
^tsc,
o.data,
^tsc,
^search_query
)
)
end
defp query_with(q, :rum, search_query) do
tsc = get_text_search_config()
from([a, o] in q,
where:
fragment(
"? @@ websearch_to_tsquery(?)",
"? @@ websearch_to_tsquery(?::oid::regconfig, ?)",
o.fts_content,
^tsc,
^search_query
),
order_by: [fragment("? <=> now()::date", o.inserted_at)]