FIX: add support for PG 14 and up (#20137)
Previously to_tsquery would split terms and join with & In PG 14 terms are split and use <-> which means followed directly by. In PG 13: discourse_test=# SELECT to_tsquery('english', '''hello world'''); to_tsquery --------------------- 'hello' & 'world' (1 row) In PG 14: discourse_test=# SELECT to_tsquery('english', '''hello world'''); to_tsquery --------------------- 'hello' <-> 'world' (1 row) Change is very unobtrosive, we simply amend our to_tsquery to behave like it used to behave and make no use of the `<->` operator More detail at: https://akorotkov.github.io/blog/2021/05/22/pg-14-query-parsing/ Note that plainto_tsquery used elsewhere in Discourse keeps the exact same function. This also corrects a faulty test that was passing by a fluke on older version of PG
This commit is contained in:
parent
277c5770b0
commit
1dba1aca27
|
@ -1262,6 +1262,9 @@ class Search
|
|||
ts_config = ActiveRecord::Base.connection.quote(ts_config) if ts_config
|
||||
escaped_term = wrap_unaccent("'#{escape_string(term)}'")
|
||||
tsquery = "TO_TSQUERY(#{ts_config || default_ts_config}, #{escaped_term})"
|
||||
# PG 14 and up default to using the followed by operator
|
||||
# this restores the old behavior
|
||||
tsquery = "REPLACE(#{tsquery}::text, '<->', '&')::tsquery"
|
||||
tsquery = "REPLACE(#{tsquery}::text, '&', '#{escape_string(joiner)}')::tsquery" if joiner
|
||||
tsquery
|
||||
end
|
||||
|
|
|
@ -969,7 +969,7 @@ RSpec.describe Search do
|
|||
|
||||
it "aggregates searches in a topic by returning the post with the lowest post number" do
|
||||
post = Fabricate(:post, topic: topic, raw: "this is a play post")
|
||||
post2 = Fabricate(:post, topic: topic, raw: "play play playing played play")
|
||||
_post2 = Fabricate(:post, topic: topic, raw: "play play playing played play")
|
||||
post3 = Fabricate(:post, raw: "this is a play post")
|
||||
|
||||
5.times { Fabricate(:post, topic: topic, raw: "play playing played") }
|
||||
|
@ -1876,7 +1876,7 @@ RSpec.describe Search do
|
|||
)
|
||||
post2 = Fabricate(:post, raw: "test URL post with")
|
||||
|
||||
expect(Search.execute("test post with 'a URL).posts").posts).to eq([post2, post])
|
||||
expect(Search.execute("test post URL l").posts).to eq([post2, post])
|
||||
expect(Search.execute(%{"test post with 'a URL"}).posts).to eq([post])
|
||||
expect(Search.execute(%{"https://some.site.com/search?q=test.test.test"}).posts).to eq([post])
|
||||
expect(
|
||||
|
@ -2311,11 +2311,11 @@ RSpec.describe Search do
|
|||
|
||||
it "escapes the term correctly" do
|
||||
expect(Search.ts_query(term: 'Title with trailing backslash\\')).to eq(
|
||||
"TO_TSQUERY('english', '''Title with trailing backslash\\\\\\\\'':*')",
|
||||
"REPLACE(TO_TSQUERY('english', '''Title with trailing backslash\\\\\\\\'':*')::text, '<->', '&')::tsquery",
|
||||
)
|
||||
|
||||
expect(Search.ts_query(term: "Title with trailing quote'")).to eq(
|
||||
"TO_TSQUERY('english', '''Title with trailing quote'''''':*')",
|
||||
"REPLACE(TO_TSQUERY('english', '''Title with trailing quote'''''':*')::text, '<->', '&')::tsquery",
|
||||
)
|
||||
end
|
||||
end
|
||||
|
|
Loading…
Reference in New Issue