这是indexloc提供的服务,不要输入任何密码
Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion server/graphql-engine.cabal
Original file line number Diff line number Diff line change
Expand Up @@ -144,8 +144,9 @@ library
, Hasura.Server.CheckUpdates
, Hasura.RQL.Types
, Hasura.RQL.Instances
, Hasura.RQL.Types.SchemaCache
, Hasura.RQL.Types.Common
, Hasura.RQL.Types.BoolExp
, Hasura.RQL.Types.SchemaCache
, Hasura.RQL.Types.Permission
, Hasura.RQL.Types.Error
, Hasura.RQL.Types.DML
Expand Down
129 changes: 53 additions & 76 deletions server/src-lib/Hasura/GraphQL/Resolve/BoolExp.hs
Original file line number Diff line number Diff line change
Expand Up @@ -6,11 +6,7 @@

module Hasura.GraphQL.Resolve.BoolExp
( parseBoolExp
, pgColValToBoolExpG
, pgColValToBoolExp
, convertBoolExpG
, convertBoolExp
, prepare
) where

import Data.Has
Expand All @@ -20,8 +16,6 @@ import qualified Data.HashMap.Strict as Map
import qualified Data.HashMap.Strict.InsOrd as OMap
import qualified Language.GraphQL.Draft.Syntax as G

import qualified Hasura.RQL.GBoolExp as RA
import qualified Hasura.RQL.GBoolExp as RG
import qualified Hasura.SQL.DML as S

import Hasura.GraphQL.Resolve.Context
Expand All @@ -32,129 +26,112 @@ import Hasura.RQL.Types
import Hasura.SQL.Types
import Hasura.SQL.Value

type OpExp = OpExpG (PGColType, PGColValue)

parseOpExps
:: (MonadError QErr m, MonadReader r m, Has FieldMap r)
=> AnnGValue -> m [RA.OpExp]
=> AnnGValue -> m [OpExp]
parseOpExps annVal = do
opExpsM <- flip withObjectM annVal $ \nt objM -> forM objM $ \obj ->
forM (OMap.toList obj) $ \(k, v) -> case k of
"_eq" -> fmap RA.AEQ <$> asPGColValM v
"_ne" -> fmap RA.ANE <$> asPGColValM v
"_neq" -> fmap RA.ANE <$> asPGColValM v
"_eq" -> fmap AEQ <$> asPGColValM v
"_ne" -> fmap ANE <$> asPGColValM v
"_neq" -> fmap ANE <$> asPGColValM v
"_is_null" -> resolveIsNull v

"_in" -> fmap (RA.AIN . catMaybes) <$> parseMany asPGColValM v
"_nin" -> fmap (RA.ANIN . catMaybes) <$> parseMany asPGColValM v
"_in" -> fmap (AIN . catMaybes) <$> parseMany asPGColValM v
"_nin" -> fmap (ANIN . catMaybes) <$> parseMany asPGColValM v

"_gt" -> fmap RA.AGT <$> asPGColValM v
"_lt" -> fmap RA.ALT <$> asPGColValM v
"_gte" -> fmap RA.AGTE <$> asPGColValM v
"_lte" -> fmap RA.ALTE <$> asPGColValM v
"_gt" -> fmap AGT <$> asPGColValM v
"_lt" -> fmap ALT <$> asPGColValM v
"_gte" -> fmap AGTE <$> asPGColValM v
"_lte" -> fmap ALTE <$> asPGColValM v

"_like" -> fmap RA.ALIKE <$> asPGColValM v
"_nlike" -> fmap RA.ANLIKE <$> asPGColValM v
"_like" -> fmap ALIKE <$> asPGColValM v
"_nlike" -> fmap ANLIKE <$> asPGColValM v

"_ilike" -> fmap RA.AILIKE <$> asPGColValM v
"_nilike" -> fmap RA.ANILIKE <$> asPGColValM v
"_ilike" -> fmap AILIKE <$> asPGColValM v
"_nilike" -> fmap ANILIKE <$> asPGColValM v

"_similar" -> fmap RA.ASIMILAR <$> asPGColValM v
"_nsimilar" -> fmap RA.ANSIMILAR <$> asPGColValM v
"_similar" -> fmap ASIMILAR <$> asPGColValM v
"_nsimilar" -> fmap ANSIMILAR <$> asPGColValM v

-- jsonb related operators
"_contains" -> fmap RA.AContains <$> asPGColValM v
"_contained_in" -> fmap RA.AContainedIn <$> asPGColValM v
"_has_key" -> fmap RA.AHasKey <$> asPGColValM v
"_has_keys_any" -> fmap RA.AHasKeysAny <$> parseMany asPGColText v
"_has_keys_all" -> fmap RA.AHasKeysAll <$> parseMany asPGColText v
"_contains" -> fmap AContains <$> asPGColValM v
"_contained_in" -> fmap AContainedIn <$> asPGColValM v
"_has_key" -> fmap AHasKey <$> asPGColValM v
"_has_keys_any" -> fmap AHasKeysAny <$> parseMany asPGColText v
"_has_keys_all" -> fmap AHasKeysAll <$> parseMany asPGColText v

_ ->
throw500
$ "unexpected operator found in opexp of "
<> showNamedTy nt
<> ": "
<> showName k
return $ map RA.OEVal $ catMaybes $ fromMaybe [] opExpsM
return $ catMaybes $ fromMaybe [] opExpsM
where
resolveIsNull v = case v of
AGScalar _ Nothing -> return Nothing
AGScalar _ (Just (PGValBoolean b)) ->
return $ Just $ bool RA.ANISNOTNULL RA.ANISNULL b
return $ Just $ bool ANISNOTNULL ANISNULL b
AGScalar _ _ -> throw500 "boolean value is expected"
_ -> tyMismatch "pgvalue" v

parseAsEqOp
:: (MonadError QErr m)
=> AnnGValue -> m [RA.OpExp]
=> AnnGValue -> m [OpExp]
parseAsEqOp annVal = do
annValOpExp <- RA.AEQ <$> asPGColVal annVal
return [RA.OEVal annValOpExp]
annValOpExp <- AEQ <$> asPGColVal annVal
return [annValOpExp]

parseColExp
:: (MonadError QErr m, MonadReader r m, Has FieldMap r)
=> G.NamedType
=> ((PGColType, PGColValue) -> m S.SQLExp)
-> G.NamedType
-> G.Name
-> AnnGValue
-> (AnnGValue -> m [RA.OpExp])
-> m RA.AnnVal
parseColExp nt n val expParser = do
-> (AnnGValue -> m [OpExp])
-> m AnnBoolExpFldSQL
parseColExp f nt n val expParser = do
fldInfo <- getFldInfo nt n
case fldInfo of
Left pgColInfo -> RA.AVCol pgColInfo <$> expParser val
Left pgColInfo -> do
opExps <- expParser val
AVCol pgColInfo <$> traverse (traverse f) opExps
Right (relInfo, _, permExp, _) -> do
relBoolExp <- parseBoolExp val
return $ RA.AVRel relInfo relBoolExp permExp
relBoolExp <- parseBoolExp f val
return $ AVRel relInfo $ andAnnBoolExps relBoolExp permExp

parseBoolExp
:: (MonadError QErr m, MonadReader r m, Has FieldMap r)
=> AnnGValue
-> m (GBoolExp RA.AnnVal)
parseBoolExp annGVal = do
=> ((PGColType, PGColValue) -> m S.SQLExp)
-> AnnGValue
-> m AnnBoolExpSQL
parseBoolExp f annGVal = do
boolExpsM <-
flip withObjectM annGVal
$ \nt objM -> forM objM $ \obj -> forM (OMap.toList obj) $ \(k, v) -> if
| k == "_or" -> BoolOr . fromMaybe [] <$> parseMany parseBoolExp v
| k == "_and" -> BoolAnd . fromMaybe [] <$> parseMany parseBoolExp v
| k == "_not" -> BoolNot <$> parseBoolExp v
| otherwise -> BoolCol <$> parseColExp nt k v parseOpExps
| k == "_or" -> BoolOr . fromMaybe []
<$> parseMany (parseBoolExp f) v
| k == "_and" -> BoolAnd . fromMaybe []
<$> parseMany (parseBoolExp f) v
| k == "_not" -> BoolNot <$> parseBoolExp f v
| otherwise -> BoolFld <$> parseColExp f nt k v parseOpExps
return $ BoolAnd $ fromMaybe [] boolExpsM

convertBoolExpG
:: (MonadError QErr m, MonadReader r m, Has FieldMap r)
=> ((PGColType, PGColValue) -> m S.SQLExp)
-> QualifiedTable
-> AnnGValue
-> m (GBoolExp RG.AnnSQLBoolExp)
convertBoolExpG f tn whereArg = do
whereExp <- parseBoolExp whereArg
RG.convBoolRhs (RG.mkBoolExpBuilder f) (S.mkQual tn) whereExp

convertBoolExp
:: QualifiedTable
-> AnnGValue
-> Convert (GBoolExp RG.AnnSQLBoolExp)
convertBoolExp = convertBoolExpG prepare

type PGColValMap = Map.HashMap G.Name AnnGValue

pgColValToBoolExpG
pgColValToBoolExp
:: (MonadError QErr m, MonadReader r m, Has FieldMap r)
=> ((PGColType, PGColValue) -> m S.SQLExp)
-> QualifiedTable
-> PGColValMap
-> m (GBoolExp RG.AnnSQLBoolExp)
pgColValToBoolExpG f tn colValMap = do
-> m AnnBoolExpSQL
pgColValToBoolExp f colValMap = do
colExps <- forM colVals $ \(name, val) -> do
(ty, _) <- asPGColVal val
let namedTy = mkScalarTy ty
BoolCol <$> parseColExp namedTy name val parseAsEqOp
let whereExp = BoolAnd colExps
RG.convBoolRhs (RG.mkBoolExpBuilder f) (S.mkQual tn) whereExp
BoolFld <$> parseColExp f namedTy name val parseAsEqOp
return $ BoolAnd colExps
where
colVals = Map.toList colValMap

pgColValToBoolExp
:: QualifiedTable
-> PGColValMap
-> Convert (GBoolExp RG.AnnSQLBoolExp)
pgColValToBoolExp =
pgColValToBoolExpG prepare
7 changes: 4 additions & 3 deletions server/src-lib/Hasura/GraphQL/Resolve/Context.hs
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ import qualified Hasura.SQL.DML as S

type FieldMap
= Map.HashMap (G.NamedType, G.Name)
(Either PGColInfo (RelInfo, Bool, S.BoolExp, Maybe Int))
(Either PGColInfo (RelInfo, Bool, AnnBoolExpSQL, Maybe Int))

-- data OrdTy
-- = OAsc
Expand All @@ -64,7 +64,7 @@ type RespTx = Q.TxE QErr BL.ByteString
-- order by context
data OrdByItem
= OBIPGCol !PGColInfo
| OBIRel !RelInfo !S.BoolExp
| OBIRel !RelInfo !AnnBoolExpSQL
deriving (Show, Eq)

type OrdByItemMap = Map.HashMap G.Name OrdByItem
Expand All @@ -86,7 +86,8 @@ type InsCtxMap = Map.HashMap QualifiedTable InsCtx

getFldInfo
:: (MonadError QErr m, MonadReader r m, Has FieldMap r)
=> G.NamedType -> G.Name -> m (Either PGColInfo (RelInfo, Bool, S.BoolExp, Maybe Int))
=> G.NamedType -> G.Name
-> m (Either PGColInfo (RelInfo, Bool, AnnBoolExpSQL, Maybe Int))
getFldInfo nt n = do
fldMap <- asks getter
onNothing (Map.lookup (nt,n) fldMap) $
Expand Down
12 changes: 5 additions & 7 deletions server/src-lib/Hasura/GraphQL/Resolve/Insert.hs
Original file line number Diff line number Diff line change
Expand Up @@ -28,12 +28,10 @@ import qualified Database.PG.Query as Q
import qualified Hasura.RQL.DML.Insert as RI
import qualified Hasura.RQL.DML.Returning as RR
import qualified Hasura.RQL.DML.Select as RS
import qualified Hasura.RQL.GBoolExp as RG
import qualified Hasura.RQL.GBoolExp as RB

import qualified Hasura.SQL.DML as S

import Hasura.GraphQL.Resolve.BoolExp
import Hasura.GraphQL.Resolve.Context
import Hasura.GraphQL.Resolve.InputValue
import Hasura.GraphQL.Resolve.Mutation
Expand Down Expand Up @@ -214,21 +212,21 @@ mkInsertQ vn onConflictM insCols tableCols defVals role = do
mkBoolExp
:: (MonadError QErr m, MonadState PrepArgs m)
=> QualifiedTable -> [(PGColInfo, PGColValue)]
-> m (GBoolExp RG.AnnSQLBoolExp)
-> m S.BoolExp
mkBoolExp tn colInfoVals =
RG.convBoolRhs (RG.mkBoolExpBuilder prepare) (S.mkQual tn) boolExp
RB.toSQLBoolExp (S.mkQual tn) . BoolAnd <$>
mapM (fmap BoolFld . uncurry f) colInfoVals
where
boolExp = BoolAnd $ map (BoolCol . uncurry f) colInfoVals
f ci@(PGColInfo _ colTy _) colVal =
RB.AVCol ci [RB.OEVal $ RB.AEQ (colTy, colVal)]
AVCol ci . pure . AEQ <$> prepare (colTy, colVal)

mkSelQ :: MonadError QErr m => QualifiedTable
-> [PGColInfo] -> [PGColWithValue] -> m InsWithExp
mkSelQ tn allColInfos pgColsWithVal = do
(whereExp, args) <- flip runStateT Seq.Empty $ mkBoolExp tn colWithInfos
let sqlSel = S.mkSelect { S.selExtr = [S.selectStar]
, S.selFrom = Just $ S.mkSimpleFromExp tn
, S.selWhere = Just $ S.WhereFrag $ RG.cBoolExp whereExp
, S.selWhere = Just $ S.WhereFrag whereExp
}

return $ InsWithExp (S.CTESelect sqlSel) Nothing args
Expand Down
8 changes: 4 additions & 4 deletions server/src-lib/Hasura/GraphQL/Resolve/Mutation.hs
Original file line number Diff line number Diff line change
Expand Up @@ -91,14 +91,14 @@ convDeleteAtPathObj val =

convertUpdate
:: QualifiedTable -- table
-> S.BoolExp -- the filter expression
-> AnnBoolExpSQL -- the filter expression
-> Field -- the mutation field
-> Convert RespTx
convertUpdate tn filterExp fld = do
-- a set expression is same as a row object
setExpM <- withArgM args "_set" convertRowObj
-- where bool expression to filter column
whereExp <- withArg args "where" $ convertBoolExp tn
whereExp <- withArg args "where" (parseBoolExp prepare)
-- increment operator on integer columns
incExpM <- withArgM args "_inc" $
convObjWithOp $ rhsExpOp S.incOp S.intType
Expand Down Expand Up @@ -134,11 +134,11 @@ convertUpdate tn filterExp fld = do

convertDelete
:: QualifiedTable -- table
-> S.BoolExp -- the filter expression
-> AnnBoolExpSQL -- the filter expression
-> Field -- the mutation field
-> Convert RespTx
convertDelete tn filterExp fld = do
whereExp <- withArg (_fArguments fld) "where" $ convertBoolExp tn
whereExp <- withArg (_fArguments fld) "where" (parseBoolExp prepare)
mutFlds <- convertMutResp (_fType fld) $ _fSelSet fld
args <- get
let p1 = RD.DeleteQueryP1 tn (filterExp, whereExp) mutFlds
Expand Down
24 changes: 12 additions & 12 deletions server/src-lib/Hasura/GraphQL/Resolve/Select.hs
Original file line number Diff line number Diff line change
Expand Up @@ -81,9 +81,9 @@ fieldAsPath = nameAsPath . _fName
parseTableArgs
:: (MonadError QErr m, MonadReader r m, Has FieldMap r, Has OrdByCtx r)
=> ((PGColType, PGColValue) -> m S.SQLExp)
-> QualifiedTable -> ArgsMap -> m RS.TableArgs
parseTableArgs f tn args = do
whereExpM <- withArgM args "where" $ convertBoolExpG f tn
-> ArgsMap -> m RS.TableArgs
parseTableArgs f args = do
whereExpM <- withArgM args "where" $ parseBoolExp f
ordByExpML <- withArgM args "order_by" parseOrderBy
let ordByExpM = NE.nonEmpty =<< ordByExpML
limitExpM <- withArgM args "limit" parseLimit
Expand All @@ -93,10 +93,10 @@ parseTableArgs f tn args = do
fromField
:: (MonadError QErr m, MonadReader r m, Has FieldMap r, Has OrdByCtx r)
=> ((PGColType, PGColValue) -> m S.SQLExp)
-> QualifiedTable -> S.BoolExp -> Maybe Int -> Field -> m RS.AnnSel
-> QualifiedTable -> AnnBoolExpSQL -> Maybe Int -> Field -> m RS.AnnSel
fromField f tn permFilter permLimitM fld =
fieldAsPath fld $ do
tableArgs <- parseTableArgs f tn args
tableArgs <- parseTableArgs f args
annFlds <- fromSelSet f (_fType fld) $ _fSelSet fld
let tabFrom = RS.TableFrom tn Nothing
tabPerm = RS.TablePerm permFilter permLimitM
Expand Down Expand Up @@ -175,25 +175,25 @@ parseLimit v = do
fromFieldByPKey
:: (MonadError QErr m, MonadReader r m, Has FieldMap r, Has OrdByCtx r)
=> ((PGColType, PGColValue) -> m S.SQLExp)
-> QualifiedTable -> S.BoolExp -> Field -> m RS.AnnSel
-> QualifiedTable -> AnnBoolExpSQL -> Field -> m RS.AnnSel
fromFieldByPKey f tn permFilter fld = fieldAsPath fld $ do
boolExp <- pgColValToBoolExpG f tn $ _fArguments fld
boolExp <- pgColValToBoolExp f $ _fArguments fld
annFlds <- fromSelSet f (_fType fld) $ _fSelSet fld
let tabFrom = RS.TableFrom tn Nothing
tabPerm = RS.TablePerm permFilter Nothing
return $ RS.AnnSelG annFlds tabFrom tabPerm $
RS.noTableArgs { RS._taWhere = Just boolExp}

convertSelect
:: QualifiedTable -> S.BoolExp -> Maybe Int -> Field -> Convert RespTx
:: QualifiedTable -> AnnBoolExpSQL -> Maybe Int -> Field -> Convert RespTx
convertSelect qt permFilter permLimit fld = do
selData <- withPathK "selectionSet" $
fromField prepare qt permFilter permLimit fld
prepArgs <- get
return $ RS.selectP2 False (selData, prepArgs)

convertSelectByPKey
:: QualifiedTable -> S.BoolExp -> Field -> Convert RespTx
:: QualifiedTable -> AnnBoolExpSQL -> Field -> Convert RespTx
convertSelectByPKey qt permFilter fld = do
selData <- withPathK "selectionSet" $
fromFieldByPKey prepare qt permFilter fld
Expand Down Expand Up @@ -253,9 +253,9 @@ convertAggFld ty selSet =
fromAggField
:: (MonadError QErr m, MonadReader r m, Has FieldMap r, Has OrdByCtx r)
=> ((PGColType, PGColValue) -> m S.SQLExp)
-> QualifiedTable -> S.BoolExp -> Maybe Int -> Field -> m RS.AnnAggSel
-> QualifiedTable -> AnnBoolExpSQL -> Maybe Int -> Field -> m RS.AnnAggSel
fromAggField fn tn permFilter permLimitM fld = fieldAsPath fld $ do
tableArgs <- parseTableArgs fn tn args
tableArgs <- parseTableArgs fn args
aggSelFlds <- fromAggSel (_fType fld) $ _fSelSet fld
let tabFrom = RS.TableFrom tn Nothing
tabPerm = RS.TablePerm permFilter permLimitM
Expand All @@ -273,7 +273,7 @@ fromAggField fn tn permFilter permLimitM fld = fieldAsPath fld $ do
G.Name t -> throw500 $ "unexpected field in _agg node: " <> t

convertAggSelect
:: QualifiedTable -> S.BoolExp -> Maybe Int -> Field -> Convert RespTx
:: QualifiedTable -> AnnBoolExpSQL -> Maybe Int -> Field -> Convert RespTx
convertAggSelect qt permFilter permLimit fld = do
selData <- withPathK "selectionSet" $
fromAggField prepare qt permFilter permLimit fld
Expand Down
Loading