Change phrase/plain full text search syntax
This commit is contained in:
committed by
Steve Chávez
parent
678b855614
commit
be630aa680
@@ -40,7 +40,7 @@ import PostgREST.Types ( QualifiedIdentifier (..)
|
||||
, ApiRequestError(..)
|
||||
, toMime
|
||||
, operators
|
||||
, FtsMode(..))
|
||||
, ftsOperators)
|
||||
import Data.Ranged.Ranges (Range(..), rangeIntersection, emptyRange)
|
||||
import qualified Data.CaseInsensitive as CI
|
||||
import Web.Cookie (parseCookiesText)
|
||||
@@ -142,16 +142,10 @@ userApiRequest schema req reqBody
|
||||
ActionInvoke{isReadOnly=True} -> partition (liftM2 (||) (isEmbedPath . fst) (hasOperator . snd)) flts
|
||||
_ -> (flts, [])
|
||||
flts = [ (toS k, toS $ fromJust v) | (k,v) <- qParams, isJust v, k /= "select", not (endingIn ["order", "limit", "offset", "and", "or"] k) ]
|
||||
hasOperator val = foldr ((||) . flip T.isPrefixOf val) False ((<> ".") <$> (M.keys operators ++ ["not", show Plain, show Phrase]))
|
||||
|| hasLanguageFts val
|
||||
hasOperator val = any (`T.isPrefixOf` val) $
|
||||
((<> ".") <$> "not":M.keys operators) ++
|
||||
((<> "(") <$> M.keys ftsOperators)
|
||||
isEmbedPath = T.isInfixOf "."
|
||||
-- handle "?tsv=english.fts.possible" case
|
||||
hasLanguageFts val = case T.splitOn "." val of
|
||||
[_, "fts", _] -> True
|
||||
[_, "fts"] -> True
|
||||
[_, "@@", _] -> True -- TODO: '@@' deprecated
|
||||
[_, "@@"] -> True
|
||||
_ -> False
|
||||
isTargetingProc = fromMaybe False $ (== "rpc") <$> listToMaybe path
|
||||
payload =
|
||||
case decodeContentType . fromMaybe "application/json" $ lookupHeader "content-type" of
|
||||
|
||||
@@ -145,16 +145,14 @@ pOpExpr pSVal pLVal = try ( string "not" *> pDelimiter *> (OpExpr True <$> pOper
|
||||
<|> In <$> (string "in" *> pDelimiter *> pLVal)
|
||||
<|> pFts
|
||||
<?> "operator (eq, gt, ...)"
|
||||
pFts = do
|
||||
mode <- option Normal $
|
||||
try (string (show Phrase) *> pDelimiter *> pure Phrase)
|
||||
<|> try (string (show Plain) *> pDelimiter *> pure Plain)
|
||||
|
||||
lang <- try (Just <$> manyTill (letter <|> digit <|> oneOf "_") (try (string ".fts") <|> try (string ".@@")) <* pDelimiter) -- TODO: '@@' deprecated
|
||||
<|> try (string "fts" *> pDelimiter) *> pure Nothing
|
||||
<|> try (string "@@" *> pDelimiter) *> pure Nothing -- TODO: '@@' deprecated
|
||||
Fts mode (toS <$> lang) <$> pSVal
|
||||
ops = M.filterWithKey (const . flip notElem ["in", "fts", "@@"]) operators -- TODO: '@@' deprecated
|
||||
pFts = do
|
||||
op <- foldl1 (<|>) (try . string . toS <$> ftsOps)
|
||||
lang <- optionMaybe $ try (between (char '(') (char ')') (many (letter <|> digit <|> oneOf "_")))
|
||||
pDelimiter >> Fts (toS op) (toS <$> lang) <$> pSVal
|
||||
|
||||
ops = M.filterWithKey (const . flip notElem ("in":ftsOps)) operators
|
||||
ftsOps = M.keys ftsOperators
|
||||
|
||||
pSingleVal :: Parser SingleVal
|
||||
pSingleVal = toS <$> many anyChar
|
||||
|
||||
@@ -433,12 +433,12 @@ pgFmtFilter table (Filter fld (OpExpr hasNot oper)) = notOp <> " " <> case oper
|
||||
Just True -> emptyValForIn
|
||||
Nothing -> emptyValForIn
|
||||
|
||||
Fts mode lang val ->
|
||||
pgFmtFieldOp "fts" <> " " <> case mode of
|
||||
Normal -> "to_tsquery("
|
||||
Plain -> "plainto_tsquery("
|
||||
Phrase -> "phraseto_tsquery("
|
||||
<> maybe "" (flip (<>) ", " . pgFmtLit) lang <> unknownLiteral val <> ") "
|
||||
Fts op lang val ->
|
||||
pgFmtFieldOp op
|
||||
<> "("
|
||||
<> maybe "" ((<> ", ") . pgFmtLit) lang
|
||||
<> unknownLiteral val
|
||||
<> ") "
|
||||
|
||||
Join fQi (ForeignKey Column{colTable=Table{tableName=fTableName}, colName=fColName}) ->
|
||||
pgFmtField fQi fld <> " = " <> pgFmtColumn (removeSourceCTESchema (qiSchema fQi) fTableName) fColName
|
||||
|
||||
+11
-11
@@ -150,7 +150,7 @@ data Proxy = Proxy {
|
||||
|
||||
type Operator = Text
|
||||
operators :: M.HashMap Operator SqlFragment
|
||||
operators = M.fromList [
|
||||
operators = M.union (M.fromList [
|
||||
("eq", "="),
|
||||
("gte", ">="),
|
||||
("gt", ">"),
|
||||
@@ -161,7 +161,6 @@ operators = M.fromList [
|
||||
("ilike", "ILIKE"),
|
||||
("in", "IN"),
|
||||
("is", "IS"),
|
||||
("fts", "@@"),
|
||||
("cs", "@>"),
|
||||
("cd", "<@"),
|
||||
("ov", "&&"),
|
||||
@@ -171,21 +170,22 @@ operators = M.fromList [
|
||||
("nxl", "&>"),
|
||||
("adj", "-|-"),
|
||||
-- TODO: these are deprecated and should be removed in v0.5.0.0
|
||||
("@@", "@@"),
|
||||
("@>", "@>"),
|
||||
("<@", "<@")]
|
||||
("<@", "<@")]) ftsOperators
|
||||
|
||||
ftsOperators :: M.HashMap Operator SqlFragment
|
||||
ftsOperators = M.fromList [
|
||||
("@@", "@@ to_tsquery"), -- TODO: '@@' deprecated
|
||||
("fts", "@@ to_tsquery"),
|
||||
("plfts", "@@ plainto_tsquery"),
|
||||
("phfts", "@@ phraseto_tsquery")
|
||||
]
|
||||
|
||||
data OpExpr = OpExpr Bool Operation deriving (Eq, Show)
|
||||
data Operation = Op Operator SingleVal |
|
||||
In ListVal |
|
||||
Fts FtsMode (Maybe Language) SingleVal |
|
||||
Fts Operator (Maybe Language) SingleVal |
|
||||
Join QualifiedIdentifier ForeignKey deriving (Eq, Show)
|
||||
|
||||
data FtsMode = Normal | Plain | Phrase deriving Eq
|
||||
instance Show FtsMode where
|
||||
show Normal = mzero
|
||||
show Plain = "plain"
|
||||
show Phrase = "phrase"
|
||||
type Language = Text
|
||||
|
||||
-- | Represents a single value in a filter, e.g. id=eq.singleval
|
||||
|
||||
Reference in New Issue
Block a user