feat(query): add basic regular expression operator support - refs #2236

This commit is contained in:
Michael Kane Juncker
2022-04-11 08:33:16 +02:00
committed by Wolfgang Walther
parent a768bcbf20
commit 007f49a8bc
5 changed files with 47 additions and 17 deletions
+1
View File
@@ -25,6 +25,7 @@ This project adheres to [Semantic Versioning](http://semver.org/).
- #1917, Add error codes with the `"PGRST"` prefix to the error response body to differentiate PostgREST errors from PostgreSQL errors - @laurenceisla - #1917, Add error codes with the `"PGRST"` prefix to the error response body to differentiate PostgREST errors from PostgreSQL errors - @laurenceisla
- #1917, Normalize the error response body by always having the `detail` and `hint` error fields with a `null` value if they are empty - @laurenceisla - #1917, Normalize the error response body by always having the `detail` and `hint` error fields with a `null` value if they are empty - @laurenceisla
- #2176, Errors raised with `SQLSTATE` now include the message and the code in the response body - @laurenceisla - #2176, Errors raised with `SQLSTATE` now include the message and the code in the response body - @laurenceisla
- #2236, Support POSIX regular expression operators for row filtering - @enote-kane
### Fixed ### Fixed
+2
View File
@@ -93,6 +93,8 @@ singleValOperator = \case
OpNotExtendsRight -> "&<" OpNotExtendsRight -> "&<"
OpNotExtendsLeft -> "&>" OpNotExtendsLeft -> "&>"
OpAdjacent -> "-|-" OpAdjacent -> "-|-"
OpMatch -> "~"
OpIMatch -> "~*"
ftsOperator :: FtsOperator -> SqlFragment ftsOperator :: FtsOperator -> SqlFragment
ftsOperator = \case ftsOperator = \case
+19 -17
View File
@@ -208,23 +208,25 @@ parse qs =
operator :: Text -> Maybe SimpleOperator operator :: Text -> Maybe SimpleOperator
operator = \case operator = \case
"eq" -> Just OpEqual "eq" -> Just OpEqual
"gte" -> Just OpGreaterThanEqual "gte" -> Just OpGreaterThanEqual
"gt" -> Just OpGreaterThan "gt" -> Just OpGreaterThan
"lte" -> Just OpLessThanEqual "lte" -> Just OpLessThanEqual
"lt" -> Just OpLessThan "lt" -> Just OpLessThan
"neq" -> Just OpNotEqual "neq" -> Just OpNotEqual
"like" -> Just OpLike "like" -> Just OpLike
"ilike" -> Just OpILike "ilike" -> Just OpILike
"cs" -> Just OpContains "cs" -> Just OpContains
"cd" -> Just OpContained "cd" -> Just OpContained
"ov" -> Just OpOverlap "ov" -> Just OpOverlap
"sl" -> Just OpStrictlyLeft "sl" -> Just OpStrictlyLeft
"sr" -> Just OpStrictlyRight "sr" -> Just OpStrictlyRight
"nxr" -> Just OpNotExtendsRight "nxr" -> Just OpNotExtendsRight
"nxl" -> Just OpNotExtendsLeft "nxl" -> Just OpNotExtendsLeft
"adj" -> Just OpAdjacent "adj" -> Just OpAdjacent
_ -> Nothing "match" -> Just OpMatch
"imatch" -> Just OpIMatch
_ -> Nothing
ftsOperator :: Text -> Maybe FtsOperator ftsOperator :: Text -> Maybe FtsOperator
ftsOperator = \case ftsOperator = \case
+2
View File
@@ -273,6 +273,8 @@ data SimpleOperator
| OpNotExtendsRight | OpNotExtendsRight
| OpNotExtendsLeft | OpNotExtendsLeft
| OpAdjacent | OpAdjacent
| OpMatch
| OpIMatch
deriving Eq deriving Eq
-- | Operators for full text search operators -- | Operators for full text search operators
+23
View File
@@ -129,6 +129,29 @@ spec actualPgVersion = do
it "matches with ilike using not operator" $ it "matches with ilike using not operator" $
get "/simple_pk?k=not.ilike.xy*&order=extra.asc" `shouldRespondWith` "[]" get "/simple_pk?k=not.ilike.xy*&order=extra.asc" `shouldRespondWith` "[]"
it "matches with ~" $ do
get "/simple_pk?k=match.yx$" `shouldRespondWith`
[json|[{"k":"xyyx","extra":"u"}]|]
get "/simple_pk?k=match.^xy" `shouldRespondWith`
[json|[{"k":"xyyx","extra":"u"}]|]
get "/simple_pk?k=match.YY" `shouldRespondWith`
[json|[{"k":"xYYx","extra":"v"}]|]
it "matches with ~ using not operator" $
get "/simple_pk?k=not.match.yx$" `shouldRespondWith`
[json|[{"k":"xYYx","extra":"v"}]|]
it "matches with ~*" $ do
get "/simple_pk?k=imatch.^xy&order=extra.asc" `shouldRespondWith`
[json|[{"k":"xyyx","extra":"u"},{"k":"xYYx","extra":"v"}]|]
{ matchHeaders = [matchContentTypeJson] }
get "/simple_pk?k=imatch..*YY.*&order=extra.asc" `shouldRespondWith`
[json|[{"k":"xyyx","extra":"u"},{"k":"xYYx","extra":"v"}]|]
{ matchHeaders = [matchContentTypeJson] }
it "matches with ~* using not operator" $
get "/simple_pk?k=not.imatch.^xy&order=extra.asc" `shouldRespondWith` "[]"
describe "Full text search operator" $ do describe "Full text search operator" $ do
it "finds matches with to_tsquery" $ it "finds matches with to_tsquery" $
get "/tsearch?text_search_vector=fts.impossible" `shouldRespondWith` get "/tsearch?text_search_vector=fts.impossible" `shouldRespondWith`