这是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
33 changes: 16 additions & 17 deletions server/src-lib/Hasura/GraphQL/Resolve/Mutation.hs
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,6 @@ module Hasura.GraphQL.Resolve.Mutation
, convertDelete
) where

import Data.Has
import Hasura.Prelude

import qualified Data.HashMap.Strict as Map
Expand All @@ -19,13 +18,15 @@ import qualified Language.GraphQL.Draft.Syntax as G
import qualified Hasura.RQL.DML.Delete as RD
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.DML.Update as RU

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.Select (fromSelSet)
import Hasura.GraphQL.Validate.Field
import Hasura.GraphQL.Validate.Types
import Hasura.RQL.Types
Expand All @@ -39,25 +40,23 @@ withSelSet selSet f =
return (G.unName $ G.unAlias $ _fAlias fld, res)

convertReturning
:: (MonadError QErr m, MonadReader r m, Has FieldMap r)
=> G.NamedType -> SelSet -> m RR.RetFlds
convertReturning ty selSet =
withSelSet selSet $ \fld ->
case _fName fld of
"__typename" -> return $ RR.RExp $ G.unName $ G.unNamedType ty
_ -> do
PGColInfo col colTy _ <- getPGColInfo ty $ _fName fld
return $ RR.RCol (col, colTy)
:: QualifiedTable -> G.NamedType -> SelSet -> Convert RS.SelectData
convertReturning qt ty selSet = do
annFlds <- fromSelSet ty selSet
return $ RS.SelectData annFlds qt frmExpM
(S.BELit True, Nothing) Nothing [] Nothing Nothing False
where
frmExpM = Just $ S.FromExp $ pure $
S.FIIden $ qualTableToAliasIden qt

convertMutResp
:: (MonadError QErr m, MonadReader r m, Has FieldMap r)
=> G.NamedType -> SelSet -> m RR.MutFlds
convertMutResp ty selSet =
:: QualifiedTable -> G.NamedType -> SelSet -> Convert RR.MutFlds
convertMutResp qt ty selSet =
withSelSet selSet $ \fld ->
case _fName fld of
"__typename" -> return $ RR.MExp $ G.unName $ G.unNamedType ty
"affected_rows" -> return RR.MCount
_ -> fmap RR.MRet $ convertReturning (_fType fld) $ _fSelSet fld
_ -> fmap RR.MRet $ convertReturning qt (_fType fld) $ _fSelSet fld

convertRowObj
:: (MonadError QErr m, MonadState PrepArgs m)
Expand Down Expand Up @@ -124,7 +123,7 @@ convertInsert role (tn, vn) tableCols fld = do
conflictCtxM <- withPathK "on_conflict" $
withArgM arguments "on_conflict" parseOnConflict
onConflictM <- mapM (mkConflictClause tableCols) conflictCtxM
mutFlds <- convertMutResp (_fType fld) $ _fSelSet fld
mutFlds <- convertMutResp tn (_fType fld) $ _fSelSet fld
args <- get
let p1Query = RI.InsertQueryP1 tn vn tableCols rows onConflictM mutFlds
p1 = (p1Query, args)
Expand Down Expand Up @@ -205,7 +204,7 @@ convertUpdate tn filterExp fld = do
-- delete at path in jsonb value
deleteAtPathExpM <- withArgM args "_delete_at_path" convDeleteAtPathObj

mutFlds <- convertMutResp (_fType fld) $ _fSelSet fld
mutFlds <- convertMutResp tn (_fType fld) $ _fSelSet fld
prepArgs <- get
let updExpsM = [ setExpM, incExpM, appendExpM, prependExpM
, deleteKeyExpM, deleteElemExpM, deleteAtPathExpM
Expand All @@ -227,7 +226,7 @@ convertDelete
-> Convert RespTx
convertDelete tn filterExp fld = do
whereExp <- withArg (_fArguments fld) "where" $ convertBoolExp tn
mutFlds <- convertMutResp (_fType fld) $ _fSelSet fld
mutFlds <- convertMutResp tn (_fType fld) $ _fSelSet fld
args <- get
let p1 = RD.DeleteQueryP1 tn (filterExp, whereExp) mutFlds
return $ RD.deleteP2 (p1, args)
5 changes: 3 additions & 2 deletions server/src-lib/Hasura/GraphQL/Resolve/Select.hs
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
module Hasura.GraphQL.Resolve.Select
( convertSelect
, convertSelectByPKey
, fromSelSet
) where

import Data.Has
Expand Down Expand Up @@ -63,7 +64,7 @@ fromField tn permFilter permLimit fld = fieldAsPath fld $ do
<$> withArgM args "limit" parseLimit
offsetExpM <- withArgM args "offset" $ asPGColVal >=> prepare
annFlds <- fromSelSet (_fType fld) $ _fSelSet fld
return $ RS.SelectData annFlds tn (permFilter, whereExpM) ordByExpM
return $ RS.SelectData annFlds tn Nothing (permFilter, whereExpM) ordByExpM
[] limitExpM offsetExpM False
where
args = _fArguments fld
Expand All @@ -73,7 +74,7 @@ fromFieldByPKey
fromFieldByPKey tn permFilter fld = fieldAsPath fld $ do
boolExp <- pgColValToBoolExp tn $ _fArguments fld
annFlds <- fromSelSet (_fType fld) $ _fSelSet fld
return $ RS.SelectData annFlds tn (permFilter, Just boolExp)
return $ RS.SelectData annFlds tn Nothing (permFilter, Just boolExp)
Nothing [] Nothing Nothing True

getEnumInfo
Expand Down
41 changes: 9 additions & 32 deletions server/src-lib/Hasura/GraphQL/Schema.hs
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,7 @@ data OpCtx
| OCSelectPkey QualifiedTable S.BoolExp [T.Text]
-- tn, filter exp, req hdrs
| OCUpdate QualifiedTable S.BoolExp [T.Text]

-- tn, filter exp, req hdrs
| OCDelete QualifiedTable S.BoolExp [T.Text]
deriving (Show, Eq)
Expand Down Expand Up @@ -313,7 +314,7 @@ mkMutRespTy tn =
{-
type table_mutation_response {
affected_rows: Int!
returning: [table_no_rels!]!
returning: [table!]!
}
-}
mkMutRespObj
Expand All @@ -332,26 +333,10 @@ mkMutRespObj tn =
desc = "number of affected rows by the mutation"
returningFld =
ObjFldInfo (Just desc) "returning" Map.empty $
G.toGT $ G.toNT $ G.toLT $ G.toNT $ mkTableNoRelsTy tn
G.toGT $ G.toNT $ G.toLT $ G.toNT $ mkTableTy tn
where
desc = "data of the affected rows by the mutation"

-- table_no_rels
mkTableNoRelsTy :: QualifiedTable -> G.NamedType
mkTableNoRelsTy tn =
G.NamedType $ qualTableToName tn <> "_no_rels"

mkTableNoRelsObj
:: QualifiedTable
-> [SelField]
-> ObjTyInfo
mkTableNoRelsObj tn fields =
mkObjTyInfo (Just desc) (mkTableNoRelsTy tn) $ mapFromL _fiName pgCols
where
pgCols = map mkPGColFld $ lefts fields
desc = G.Description $
"only postgres columns (no relationships) from " <>> tn

mkBoolExpInp
:: QualifiedTable
-- the fields that are allowed
Expand Down Expand Up @@ -810,9 +795,9 @@ mkOrdByEnumsOfCol colInfo@(PGColInfo col _ _) =
colN = pgColToFld col
pgColToFld = G.Name . getPGColTxt

data RootFlds
newtype RootFlds
= RootFlds
{ _taMutation :: !(Map.HashMap G.Name (OpCtx, Either ObjFldInfo ObjFldInfo))
{ _taMutation :: Map.HashMap G.Name (OpCtx, Either ObjFldInfo ObjFldInfo)
} deriving (Show, Eq)

instance Semigroup RootFlds where
Expand Down Expand Up @@ -861,15 +846,14 @@ mkGCtxRole' tn insColsM selFldsM updColsM delPermM pkeyCols constraints =
, TIInpObj <$> updSetInpObjM
, TIInpObj <$> updIncInpObjM
, TIInpObj <$> boolExpInpObjM
, TIObj <$> noRelsObjM
, TIObj <$> mutRespObjM
, TIObj <$> selObjM
, TIEnum <$> ordByTyInfoM
]

fieldMap = Map.unions $ catMaybes
[ insInpObjFldsM, updSetInpObjFldsM, boolExpInpObjFldsM
, noRelsObjFldsM, selObjFldsM, Just selByPKeyObjFlds
, selObjFldsM, Just selByPKeyObjFlds
]

nameFromSelFld = \case
Expand Down Expand Up @@ -909,18 +893,11 @@ mkGCtxRole' tn insColsM selFldsM updColsM delPermM pkeyCols constraints =
-- the fields used in bool exp
boolExpInpObjFldsM = mkFldMap (mkBoolExpTy tn) <$> selFldsM

-- no rels obj
noRelsObjM =
-- mut resp obj
mutRespObjM =
if isJust insColsM || isJust updColsM || isJust delPermM
then Just $ mkTableNoRelsObj tn $ fromMaybe [] selFldsM
then Just $ mkMutRespObj tn
else Nothing
-- the fields used in returning object
noRelsObjFldsM = const (
mkColFldMap (mkTableNoRelsTy tn) $ lefts $ fromMaybe [] selFldsM
) <$> noRelsObjM

-- mut resp obj (only when noRelsObjM is needed)
mutRespObjM = const (mkMutRespObj tn) <$> noRelsObjM

-- table obj
selObjM = mkTableObj tn <$> selFldsM
Expand Down
4 changes: 2 additions & 2 deletions server/src-lib/Hasura/RQL/DML/Delete.hs
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ data DeleteQueryP1
mkSQLDelete
:: DeleteQueryP1 -> S.SelectWith
mkSQLDelete (DeleteQueryP1 tn (fltr, wc) mutFlds) =
mkSelWith (S.CTEDelete delete) mutFlds
mkSelWith tn (S.CTEDelete delete) mutFlds
where
delete = S.SQLDelete tn Nothing tableFltr $ Just S.returningStar
tableFltr = Just $ S.WhereFrag $ S.BEBin S.AndOp fltr $ cBoolExp wc
Expand Down Expand Up @@ -75,7 +75,7 @@ convDeleteQuery prepValBuilder (DeleteQuery tableName rqlBE mRetCols) = do

return $ DeleteQueryP1 tableName
(dpiFilter delPerm, annSQLBoolExp)
(mkDefaultMutFlds mAnnRetCols)
(mkDefaultMutFlds tableName mAnnRetCols)

where
selNecessaryMsg =
Expand Down
6 changes: 3 additions & 3 deletions server/src-lib/Hasura/RQL/DML/Insert.hs
Original file line number Diff line number Diff line change
Expand Up @@ -45,8 +45,8 @@ data InsertQueryP1
} deriving (Show, Eq)

mkSQLInsert :: InsertQueryP1 -> S.SelectWith
mkSQLInsert (InsertQueryP1 _ vn cols vals c mutFlds) =
mkSelWith (S.CTEInsert insert) mutFlds
mkSQLInsert (InsertQueryP1 tn vn cols vals c mutFlds) =
mkSelWith tn (S.CTEInsert insert) mutFlds
where
insert =
S.SQLInsert vn cols vals (toSQLConflict c) $ Just S.returningStar
Expand Down Expand Up @@ -161,7 +161,7 @@ convInsertQuery objsParser prepFn (InsertQuery tableName val oC mRetCols) = do
withPathK "returning" $
zip retCols <$> checkRetCols fieldInfoMap selPerm retCols

let mutFlds = mkDefaultMutFlds mAnnRetCols
let mutFlds = mkDefaultMutFlds tableName mAnnRetCols

let defInsVals = mkDefValMap fieldInfoMap
insCols = HM.keys defInsVals
Expand Down
68 changes: 27 additions & 41 deletions server/src-lib/Hasura/RQL/DML/Returning.hs
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ module Hasura.RQL.DML.Returning where

import Hasura.Prelude
import Hasura.RQL.DML.Internal
import Hasura.RQL.DML.Select
import Hasura.RQL.Types
import Hasura.SQL.Types

Expand All @@ -16,34 +17,10 @@ import qualified Data.Text as T
import qualified Data.Vector as V
import qualified Hasura.SQL.DML as S

data RetFld
= RExp !T.Text
| RCol (PGCol, PGColType)
deriving (Show, Eq)

pgColsFromRetFld :: RetFld -> Maybe (PGCol, PGColType)
pgColsFromRetFld = \case
RExp _ -> Nothing
RCol c -> Just c

type RetFlds = Map.HashMap T.Text RetFld

mkRetFlds :: [(PGCol, PGColType)] -> RetFlds
mkRetFlds flds =
Map.fromList $ flip map flds $
\(c, ty) -> (getPGColTxt c, RCol (c, ty))

mkRetFldsExp :: RetFlds -> S.SQLExp
mkRetFldsExp retFlds =
S.mkRowExp $ flip map (Map.toList retFlds) $ \(k, retFld) ->
case retFld of
RExp t -> S.mkAliasedExtrFromExp (S.SELit t) $ Just $ PGCol k
RCol colInfo -> mkColExtrAl (Just $ PGCol k) colInfo

data MutFld
= MCount
| MExp !T.Text
| MRet !RetFlds
| MRet !SelectData
deriving (Show, Eq)

type MutFlds = Map.HashMap T.Text MutFld
Expand All @@ -52,39 +29,48 @@ pgColsFromMutFld :: MutFld -> [(PGCol, PGColType)]
pgColsFromMutFld = \case
MCount -> []
MExp _ -> []
MRet retFlds -> mapMaybe pgColsFromRetFld $ Map.elems retFlds
MRet selData -> fst $ partAnnFlds $ Map.elems $ sdFlds selData

pgColsToSelData :: QualifiedTable -> [(PGCol, PGColType)] -> SelectData
pgColsToSelData qt cols = SelectData flds qt Nothing (S.BELit True, Nothing)
Nothing [] Nothing Nothing False
where
flds = Map.fromList $ flip map cols $ \(c, ty) ->
(fromPGCol c, FCol (c, ty))

pgColsFromMutFlds :: MutFlds -> [(PGCol, PGColType)]
pgColsFromMutFlds = concatMap pgColsFromMutFld . Map.elems

mkDefaultMutFlds :: Maybe [(PGCol, PGColType)] -> MutFlds
mkDefaultMutFlds = \case
mkDefaultMutFlds :: QualifiedTable -> Maybe [(PGCol, PGColType)] -> MutFlds
mkDefaultMutFlds qt = \case
Nothing -> mutFlds
Just cols -> Map.insert "returning" (MRet $ mkRetFlds cols) mutFlds
Just cols -> Map.insert "returning" (MRet $ pgColsToSelData qt cols) mutFlds
where
mutFlds = Map.singleton "affected_rows" MCount

mkMutFldExp :: MutFld -> S.SQLExp
mkMutFldExp = \case
MCount -> S.SEUnsafe "count(*)"
mkMutFldExp :: QualifiedTable -> MutFld -> S.SQLExp
mkMutFldExp qt = \case
MCount -> S.SESelect $
S.mkSelect
{ S.selExtr = [S.Extractor (S.SEUnsafe "count(*)") Nothing]
, S.selFrom = Just $ S.FromExp $ pure $
S.FIIden $ qualTableToAliasIden qt
}
MExp t -> S.SELit t
MRet retFlds -> S.toEmptyArrWhenNull $
S.SEFnApp "json_agg" [mkRetFldsExp retFlds] Nothing
MRet selData -> S.SESelect $ mkSQLSelect selData

mkSelWith :: S.CTE -> MutFlds -> S.SelectWith
mkSelWith cte mutFlds =
mkSelWith :: QualifiedTable -> S.CTE -> MutFlds -> S.SelectWith
mkSelWith qt cte mutFlds =
S.SelectWith [(alias, cte)] sel
where
alias = S.Alias $ toIden tableNameAlias
tableNameAlias = TableName "r"
sel = S.mkSelect { S.selExtr = [S.Extractor extrExp Nothing]
, S.selFrom = Just $ S.mkIdenFromExp tableNameAlias}
alias = S.Alias $ qualTableToAliasIden qt
sel = S.mkSelect { S.selExtr = [S.Extractor extrExp Nothing] }

extrExp = S.SEFnApp "json_build_object" jsonBuildObjArgs Nothing

jsonBuildObjArgs =
flip concatMap (Map.toList mutFlds) $
\(k, mutFld) -> [S.SELit k, mkMutFldExp mutFld]
\(k, mutFld) -> [S.SELit k, mkMutFldExp qt mutFld]

encodeJSONVector :: (a -> BB.Builder) -> V.Vector a -> BB.Builder
encodeJSONVector builder xs
Expand Down
Loading