Allow dictionary and plain/phrase in fts
This commit is contained in:
@@ -73,6 +73,12 @@ spec =
|
||||
it "can handle fts" $ do
|
||||
get "/entities?or=(text_search_vector.fts.bar,text_search_vector.fts.baz)&select=id" `shouldRespondWith`
|
||||
[json|[{ "id": 1 }, { "id": 2 }]|] { matchHeaders = [matchContentTypeJson] }
|
||||
get "/tsearch?or=(text_search_vector.phrase.german.fts.Art%20Spass, text_search_vector.plain.french.fts.amusant%20impossible, text_search_vector.english.fts.impossible)" `shouldRespondWith`
|
||||
[json|[
|
||||
{"text_search_vector": "'fun':5 'imposs':9 'kind':3" },
|
||||
{"text_search_vector": "'amus':5 'fair':7 'impossibl':9 'peu':4" },
|
||||
{"text_search_vector": "'art':4 'spass':5 'unmog':7"}
|
||||
]|] { matchHeaders = [matchContentTypeJson] }
|
||||
-- TODO: remove in 0.5.0 as deprecated
|
||||
get "/entities?or=(text_search_vector.@@.bar,text_search_vector.@@.baz)&select=id" `shouldRespondWith`
|
||||
[json|[{ "id": 1 }, { "id": 2 }]|] { matchHeaders = [matchContentTypeJson] }
|
||||
|
||||
+100
-22
@@ -98,29 +98,107 @@ spec = do
|
||||
it "matches with ilike using not operator" $
|
||||
get "/simple_pk?k=not.ilike.xy*&order=extra.asc" `shouldRespondWith` "[]"
|
||||
|
||||
it "matches with tsearch fts" $ do
|
||||
get "/tsearch?text_search_vector=fts.impossible" `shouldRespondWith`
|
||||
[json| [{"text_search_vector": "'fun':5 'imposs':9 'kind':3" }] |]
|
||||
{ matchHeaders = [matchContentTypeJson] }
|
||||
get "/tsearch?text_search_vector=fts.possible" `shouldRespondWith`
|
||||
[json| [{"text_search_vector": "'also':2 'fun':3 'possibl':8" }] |]
|
||||
{ matchHeaders = [matchContentTypeJson] }
|
||||
-- TODO: remove in 0.5.0 as deprecated
|
||||
get "/tsearch?text_search_vector=@@.impossible" `shouldRespondWith`
|
||||
[json| [{"text_search_vector": "'fun':5 'imposs':9 'kind':3" }] |]
|
||||
{ matchHeaders = [matchContentTypeJson] }
|
||||
get "/tsearch?text_search_vector=@@.possible" `shouldRespondWith`
|
||||
[json| [{"text_search_vector": "'also':2 'fun':3 'possibl':8" }] |]
|
||||
{ matchHeaders = [matchContentTypeJson] }
|
||||
describe "Full text search operator" $ do
|
||||
it "finds matches with to_tsquery" $
|
||||
get "/tsearch?text_search_vector=fts.impossible" `shouldRespondWith`
|
||||
[json| [{"text_search_vector": "'fun':5 'imposs':9 'kind':3" }] |]
|
||||
{ matchHeaders = [matchContentTypeJson] }
|
||||
|
||||
it "can use lexeme boolean operators(&=%26, |=%7C, !) in to_tsquery" $ do
|
||||
get "/tsearch?text_search_vector=fts.fun%26possible" `shouldRespondWith`
|
||||
[json| [ {"text_search_vector": "'also':2 'fun':3 'possibl':8"}] |]
|
||||
{ matchHeaders = [matchContentTypeJson] }
|
||||
get "/tsearch?text_search_vector=fts.impossible%7Cpossible" `shouldRespondWith`
|
||||
[json| [
|
||||
{"text_search_vector": "'fun':5 'imposs':9 'kind':3"},
|
||||
{"text_search_vector": "'also':2 'fun':3 'possibl':8"}] |]
|
||||
{ matchHeaders = [matchContentTypeJson] }
|
||||
get "/tsearch?text_search_vector=fts.fun%26!possible" `shouldRespondWith`
|
||||
[json| [ {"text_search_vector": "'fun':5 'imposs':9 'kind':3"}] |]
|
||||
{ matchHeaders = [matchContentTypeJson] }
|
||||
|
||||
it "finds matches with plainto_tsquery" $
|
||||
get "/tsearch?text_search_vector=plain.fts.The%20Fat%20Rats" `shouldRespondWith`
|
||||
[json| [ {"text_search_vector": "'ate':3 'cat':2 'fat':1 'rat':4" }] |]
|
||||
{ matchHeaders = [matchContentTypeJson] }
|
||||
|
||||
it "finds matches with phraseto_tsquery" $
|
||||
get "/tsearch?text_search_vector=phrase.fts.The%20Fat%20Cats" `shouldRespondWith`
|
||||
[json| [{"text_search_vector": "'ate':3 'cat':2 'fat':1 'rat':4" }] |]
|
||||
{ matchHeaders = [matchContentTypeJson] }
|
||||
|
||||
it "finds matches with different dictionaries" $ do
|
||||
get "/tsearch?text_search_vector=french.fts.amusant" `shouldRespondWith`
|
||||
[json| [{"text_search_vector": "'amus':5 'fair':7 'impossibl':9 'peu':4" }] |]
|
||||
{ matchHeaders = [matchContentTypeJson] }
|
||||
get "/tsearch?text_search_vector=plain.french.fts.amusant%20impossible" `shouldRespondWith`
|
||||
[json| [{"text_search_vector": "'amus':5 'fair':7 'impossibl':9 'peu':4" }] |]
|
||||
{ matchHeaders = [matchContentTypeJson] }
|
||||
get "/tsearch?text_search_vector=phrase.german.fts.Art%20Spass" `shouldRespondWith`
|
||||
[json| [{"text_search_vector": "'art':4 'spass':5 'unmog':7" }] |]
|
||||
{ matchHeaders = [matchContentTypeJson] }
|
||||
|
||||
it "can be negated with not operator" $ do
|
||||
get "/tsearch?text_search_vector=not.fts.impossible%7Cfat%7Cfun" `shouldRespondWith`
|
||||
[json| [
|
||||
{"text_search_vector": "'amus':5 'fair':7 'impossibl':9 'peu':4"},
|
||||
{"text_search_vector": "'art':4 'spass':5 'unmog':7"}]|]
|
||||
{ matchHeaders = [matchContentTypeJson] }
|
||||
get "/tsearch?text_search_vector=not.english.fts.impossible%7Cfat%7Cfun" `shouldRespondWith`
|
||||
[json| [
|
||||
{"text_search_vector": "'amus':5 'fair':7 'impossibl':9 'peu':4"},
|
||||
{"text_search_vector": "'art':4 'spass':5 'unmog':7"}]|]
|
||||
{ matchHeaders = [matchContentTypeJson] }
|
||||
get "/tsearch?text_search_vector=not.plain.fts.The%20Fat%20Rats" `shouldRespondWith`
|
||||
[json| [
|
||||
{"text_search_vector": "'fun':5 'imposs':9 'kind':3"},
|
||||
{"text_search_vector": "'also':2 'fun':3 'possibl':8"},
|
||||
{"text_search_vector": "'amus':5 'fair':7 'impossibl':9 'peu':4"},
|
||||
{"text_search_vector": "'art':4 'spass':5 'unmog':7"}]|]
|
||||
{ matchHeaders = [matchContentTypeJson] }
|
||||
get "/tsearch?text_search_vector=not.phrase.english.fts.The%20Fat%20Cats" `shouldRespondWith`
|
||||
[json| [
|
||||
{"text_search_vector": "'fun':5 'imposs':9 'kind':3"},
|
||||
{"text_search_vector": "'also':2 'fun':3 'possibl':8"},
|
||||
{"text_search_vector": "'amus':5 'fair':7 'impossibl':9 'peu':4"},
|
||||
{"text_search_vector": "'art':4 'spass':5 'unmog':7"}]|]
|
||||
{ matchHeaders = [matchContentTypeJson] }
|
||||
|
||||
it "matches with tsearch fts using not operator" $ do
|
||||
get "/tsearch?text_search_vector=not.fts.impossible" `shouldRespondWith`
|
||||
[json| [{"text_search_vector": "'also':2 'fun':3 'possibl':8" }] |]
|
||||
{ matchHeaders = [matchContentTypeJson] }
|
||||
-- TODO: remove in 0.5.0 as deprecated
|
||||
get "/tsearch?text_search_vector=not.@@.impossible" `shouldRespondWith`
|
||||
[json| [{"text_search_vector": "'also':2 'fun':3 'possibl':8" }] |]
|
||||
{ matchHeaders = [matchContentTypeJson] }
|
||||
it "Deprecated @@ operator, pending to remove" $ do
|
||||
get "/tsearch?text_search_vector=@@.impossible" `shouldRespondWith`
|
||||
[json| [{"text_search_vector": "'fun':5 'imposs':9 'kind':3" }] |]
|
||||
{ matchHeaders = [matchContentTypeJson] }
|
||||
get "/tsearch?text_search_vector=plain.@@.The%20Fat%20Rats" `shouldRespondWith`
|
||||
[json| [ {"text_search_vector": "'ate':3 'cat':2 'fat':1 'rat':4" }] |]
|
||||
{ matchHeaders = [matchContentTypeJson] }
|
||||
get "/tsearch?text_search_vector=phrase.@@.The%20Fat%20Cats" `shouldRespondWith`
|
||||
[json| [{"text_search_vector": "'ate':3 'cat':2 'fat':1 'rat':4" }] |]
|
||||
{ matchHeaders = [matchContentTypeJson] }
|
||||
get "/tsearch?text_search_vector=not.@@.impossible%7Cfat%7Cfun" `shouldRespondWith`
|
||||
[json| [
|
||||
{"text_search_vector": "'amus':5 'fair':7 'impossibl':9 'peu':4"},
|
||||
{"text_search_vector": "'art':4 'spass':5 'unmog':7"}]|]
|
||||
{ matchHeaders = [matchContentTypeJson] }
|
||||
get "/tsearch?text_search_vector=not.english.@@.impossible%7Cfat%7Cfun" `shouldRespondWith`
|
||||
[json| [
|
||||
{"text_search_vector": "'amus':5 'fair':7 'impossibl':9 'peu':4"},
|
||||
{"text_search_vector": "'art':4 'spass':5 'unmog':7"}]|]
|
||||
{ matchHeaders = [matchContentTypeJson] }
|
||||
get "/tsearch?text_search_vector=not.plain.@@.The%20Fat%20Rats" `shouldRespondWith`
|
||||
[json| [
|
||||
{"text_search_vector": "'fun':5 'imposs':9 'kind':3"},
|
||||
{"text_search_vector": "'also':2 'fun':3 'possibl':8"},
|
||||
{"text_search_vector": "'amus':5 'fair':7 'impossibl':9 'peu':4"},
|
||||
{"text_search_vector": "'art':4 'spass':5 'unmog':7"}]|]
|
||||
{ matchHeaders = [matchContentTypeJson] }
|
||||
get "/tsearch?text_search_vector=not.phrase.english.@@.The%20Fat%20Cats" `shouldRespondWith`
|
||||
[json| [
|
||||
{"text_search_vector": "'fun':5 'imposs':9 'kind':3"},
|
||||
{"text_search_vector": "'also':2 'fun':3 'possibl':8"},
|
||||
{"text_search_vector": "'amus':5 'fair':7 'impossibl':9 'peu':4"},
|
||||
{"text_search_vector": "'art':4 'spass':5 'unmog':7"}]|]
|
||||
{ matchHeaders = [matchContentTypeJson] }
|
||||
|
||||
it "matches with computed column" $
|
||||
get "/items?always_true=eq.true&order=id.asc" `shouldRespondWith`
|
||||
@@ -709,7 +787,7 @@ spec = do
|
||||
{ matchHeaders = [matchContentTypeJson] }
|
||||
|
||||
it "fails if an operator is not given" $
|
||||
get "/ghostBusters?id=0" `shouldRespondWith` [json| {"details":"unexpected \"0\" expecting \"not\" or operator (eq, gt, ...)","message":"\"failed to parse filter (0)\" (line 1, column 1)"} |]
|
||||
get "/ghostBusters?id=0" `shouldRespondWith` [json| {"details":"unexpected end of input expecting operator (eq, gt, ...)","message":"\"failed to parse filter (0)\" (line 1, column 2)"} |]
|
||||
{ matchStatus = 400
|
||||
, matchHeaders = [matchContentTypeJson]
|
||||
}
|
||||
|
||||
Vendored
+3
-1
@@ -248,7 +248,9 @@ INSERT INTO nullable_integer VALUES (NULL);
|
||||
TRUNCATE TABLE tsearch CASCADE;
|
||||
INSERT INTO tsearch VALUES (to_tsvector('It''s kind of fun to do the impossible'));
|
||||
INSERT INTO tsearch VALUES (to_tsvector('But also fun to do what is possible'));
|
||||
|
||||
INSERT INTO tsearch VALUES (to_tsvector('Fat cats ate rats'));
|
||||
INSERT INTO tsearch VALUES (to_tsvector('french', 'C''est un peu amusant de faire l''impossible'));
|
||||
INSERT INTO tsearch VALUES (to_tsvector('german', 'Es ist eine Art Spaß, das Unmögliche zu machen'));
|
||||
|
||||
--
|
||||
-- Data for Name: users_projects; Type: TABLE DATA; Schema: test; Owner: -
|
||||
|
||||
Reference in New Issue
Block a user