这是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: 3 additions & 0 deletions server/src-lib/Hasura/GraphQL/Resolve.hs
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,9 @@ buildTx userInfo gCtx fld = do

OCSelect tn permFilter permLimit hdrs ->
validateHdrs hdrs >> RS.convertSelect tn permFilter permLimit fld

OCSelectPkey tn permFilter hdrs ->
validateHdrs hdrs >> RS.convertSelectByPKey tn permFilter fld
-- RS.convertSelect tn permFilter fld
OCInsert tn vn cols hdrs ->
validateHdrs hdrs >> RM.convertInsert roleName (tn, vn) cols fld
Expand Down
31 changes: 28 additions & 3 deletions server/src-lib/Hasura/GraphQL/Resolve/BoolExp.hs
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@

module Hasura.GraphQL.Resolve.BoolExp
( parseBoolExp
, pgColValToBoolExp
, convertBoolExp
, prepare
) where
Expand Down Expand Up @@ -70,16 +71,24 @@ parseOpExps annVal = do
AGScalar _ _ -> throw500 "boolean value is expected"
_ -> tyMismatch "pgvalue" v

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

parseColExp
:: (MonadError QErr m, MonadReader r m, Has FieldMap r)
=> G.NamedType
-> G.Name
-> AnnGValue
-> (AnnGValue -> m [RA.OpExp])
-> m RA.AnnVal
parseColExp nt n val = do
parseColExp nt n val expParser = do
fldInfo <- getFldInfo nt n
case fldInfo of
Left pgColInfo -> RA.AVCol pgColInfo <$> parseOpExps val
Left pgColInfo -> RA.AVCol pgColInfo <$> expParser val
Right (relInfo, permExp, _, _) -> do
relBoolExp <- parseBoolExp val
return $ RA.AVRel relInfo relBoolExp permExp
Expand All @@ -95,7 +104,7 @@ parseBoolExp annGVal = do
| 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
| otherwise -> BoolCol <$> parseColExp nt k v parseOpExps
return $ BoolAnd $ fromMaybe [] boolExpsM

convertBoolExp
Expand All @@ -105,3 +114,19 @@ convertBoolExp
convertBoolExp tn whereArg = do
whereExp <- parseBoolExp whereArg
RG.convBoolRhs (RG.mkBoolExpBuilder prepare) (S.mkQual tn) whereExp

type PGColValMap = Map.HashMap G.Name AnnGValue

pgColValToBoolExp
:: QualifiedTable
-> PGColValMap
-> Convert (GBoolExp RG.AnnSQLBoolExp)
pgColValToBoolExp tn 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 prepare) (S.mkQual tn) whereExp
where
colVals = Map.toList colValMap
19 changes: 18 additions & 1 deletion server/src-lib/Hasura/GraphQL/Resolve/Select.hs
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@

module Hasura.GraphQL.Resolve.Select
( convertSelect
, convertSelectByPKey
) where

import Data.Has
Expand Down Expand Up @@ -63,10 +64,18 @@ fromField tn permFilter permLimit fld = fieldAsPath fld $ do
offsetExpM <- withArgM args "offset" $ asPGColVal >=> prepare
annFlds <- fromSelSet (_fType fld) $ _fSelSet fld
return $ RS.SelectData annFlds tn (permFilter, whereExpM) ordByExpM
[] limitExpM offsetExpM
[] limitExpM offsetExpM False
where
args = _fArguments fld

fromFieldByPKey
:: QualifiedTable -> S.BoolExp -> Field -> Convert RS.SelectData
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)
Nothing [] Nothing Nothing True

getEnumInfo
:: ( MonadError QErr m
, MonadReader r m
Expand Down Expand Up @@ -123,3 +132,11 @@ convertSelect qt permFilter permLimit fld = do
fromField qt permFilter permLimit fld
prepArgs <- get
return $ RS.selectP2 (selData, prepArgs)

convertSelectByPKey
:: QualifiedTable -> S.BoolExp -> Field -> Convert RespTx
convertSelectByPKey qt permFilter fld = do
selData <- withPathK "selectionSet" $
fromFieldByPKey qt permFilter fld
prepArgs <- get
return $ RS.selectP2 (selData, prepArgs)
81 changes: 64 additions & 17 deletions server/src-lib/Hasura/GraphQL/Schema.hs
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,8 @@ data OpCtx
= OCInsert QualifiedTable QualifiedTable [PGCol] [T.Text]
-- tn, filter exp, limit, req hdrs
| OCSelect QualifiedTable S.BoolExp (Maybe Int) [T.Text]
-- tn, filter exp, reqt hdrs
| OCSelectPkey QualifiedTable S.BoolExp [T.Text]
-- tn, filter exp, req hdrs
| OCUpdate QualifiedTable S.BoolExp [T.Text]
-- tn, filter exp, req hdrs
Expand Down Expand Up @@ -119,9 +121,12 @@ isRelNullable fim ri = isNullable
where
lCols = map fst $ riMapping ri
allCols = getCols fim
lColInfos = flip filter allCols $ \ci -> pgiName ci `elem` lCols
lColInfos = getColInfos lCols allCols
isNullable = any pgiIsNullable lColInfos

mkColName :: PGCol -> G.Name
mkColName (PGCol n) = G.Name n

mkCompExpName :: PGColType -> G.Name
mkCompExpName pgColTy =
G.Name $ T.pack (show pgColTy) <> "_comparison_exp"
Expand All @@ -142,6 +147,9 @@ mkTableTy :: QualifiedTable -> G.NamedType
mkTableTy =
G.NamedType . qualTableToName

mkTableByPKeyTy :: QualifiedTable -> G.Name
mkTableByPKeyTy tn = qualTableToName tn <> "_by_pk"

mkCompExpInp :: PGColType -> InpObjTyInfo
mkCompExpInp colTy =
InpObjTyInfo (Just tyDesc) (mkCompExpTy colTy) $ fromInpValL $ concat
Expand Down Expand Up @@ -275,6 +283,27 @@ mkSelFld tn =
fldName = qualTableToName tn
args = fromInpValL $ mkSelArgs tn
ty = G.toGT $ G.toNT $ G.toLT $ G.toNT $ mkTableTy tn
{-
table_by_pk(
col1: value1!,
. .
. .
coln: valuen!
): table
-}
mkSelFldPKey
:: QualifiedTable -> [PGColInfo]
-> ObjFldInfo
mkSelFldPKey tn cols =
ObjFldInfo (Just desc) fldName args ty
where
desc = G.Description $ "fetch data from the table: " <> tn
<<> " using primary key columns"
fldName = mkTableByPKeyTy tn
args = fromInpValL $ map colInpVal cols
ty = G.toGT $ mkTableTy tn
colInpVal (PGColInfo n typ _) =
InpValInfo Nothing (mkColName n) $ G.toGT $ G.toNT $ mkScalarTy typ

-- table_mutation_response
mkMutRespTy :: QualifiedTable -> G.NamedType
Expand Down Expand Up @@ -813,10 +842,12 @@ mkGCtxRole'
-> Maybe [PGColInfo]
-- delete cols
-> Maybe ()
-- primary key columns
-> [PGColInfo]
-- constraints
-> [TableConstraint]
-> TyAgg
mkGCtxRole' tn insColsM selFldsM updColsM delPermM constraints =
mkGCtxRole' tn insColsM selFldsM updColsM delPermM pkeyCols constraints =
TyAgg (mkTyInfoMap allTypes) fieldMap ordByEnums

where
Expand All @@ -838,7 +869,7 @@ mkGCtxRole' tn insColsM selFldsM updColsM delPermM constraints =

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

nameFromSelFld = \case
Expand Down Expand Up @@ -895,6 +926,9 @@ mkGCtxRole' tn insColsM selFldsM updColsM delPermM constraints =
selObjM = mkTableObj tn <$> selFldsM
-- the fields used in table object
selObjFldsM = mkFldMap (mkTableTy tn) <$> selFldsM
-- the field used in table_by_pkey object
selByPKeyObjFlds = Map.fromList $ flip map pkeyCols $
\pgi@(PGColInfo col ty _) -> ((mkScalarTy ty, mkColName col), Left pgi)

ordByEnumsCtxM = mkOrdByCtx tn . lefts <$> selFldsM

Expand All @@ -904,33 +938,39 @@ mkGCtxRole' tn insColsM selFldsM updColsM delPermM constraints =

getRootFldsRole'
:: QualifiedTable
-> [PGCol]
-> [TableConstraint]
-> FieldInfoMap
-> Maybe (QualifiedTable, [T.Text]) -- insert view
-> Maybe (S.BoolExp, Maybe Int, [T.Text]) -- select filter
-> Maybe ([PGCol], S.BoolExp, [T.Text]) -- update filter
-> Maybe (S.BoolExp, [T.Text]) -- delete filter
-> RootFlds
getRootFldsRole' tn constraints fields insM selM updM delM =
getRootFldsRole' tn primCols constraints fields insM selM updM delM =
RootFlds mFlds
where
getUpdColInfos cols = flip filter (getCols fields) $ \c ->
pgiName c `elem` cols
mFlds = mapFromL (either _fiName _fiName . snd) $ catMaybes
[ getInsDet <$> insM, getSelDet <$> selM
, getUpdDet <$> updM, getDelDet <$> delM]
, getUpdDet <$> updM, getDelDet <$> delM
, getPKeySelDet selM $ getColInfos primCols colInfos
]
colInfos = fst $ validPartitionFieldInfoMap fields
getInsDet (vn, hdrs) =
(OCInsert tn vn (map pgiName colInfos) hdrs, Right $ mkInsMutFld tn constraints)
getUpdDet (updCols, updFltr, hdrs) =
( OCUpdate tn updFltr hdrs
, Right $ mkUpdMutFld tn $ getUpdColInfos updCols
, Right $ mkUpdMutFld tn $ getColInfos updCols colInfos
)
getDelDet (delFltr, hdrs) =
(OCDelete tn delFltr hdrs, Right $ mkDelMutFld tn)
getSelDet (selFltr, pLimit, hdrs) =
(OCSelect tn selFltr pLimit hdrs, Left $ mkSelFld tn)

getPKeySelDet Nothing _ = Nothing
getPKeySelDet _ [] = Nothing
getPKeySelDet (Just (selFltr, _, hdrs)) pCols = Just
(OCSelectPkey tn selFltr hdrs, Left $ mkSelFldPKey tn pCols)

-- getRootFlds
-- :: TableCache
-- -> Map.HashMap RoleName RootFlds
Expand Down Expand Up @@ -975,31 +1015,34 @@ mkGCtxRole
=> TableCache
-> QualifiedTable
-> FieldInfoMap
-> [PGCol]
-> [TableConstraint]
-> RoleName
-> RolePermInfo
-> m (TyAgg, RootFlds)
mkGCtxRole tableCache tn fields constraints role permInfo = do
mkGCtxRole tableCache tn fields pCols constraints role permInfo = do
selFldsM <- mapM (getSelFlds tableCache fields role) $ _permSel permInfo
let insColsM = const colInfos <$> _permIns permInfo
updColsM = filterColInfos . upiCols <$> _permUpd permInfo
tyAgg = mkGCtxRole' tn insColsM selFldsM updColsM
(void $ _permDel permInfo) constraints
rootFlds = getRootFldsRole tn constraints fields permInfo
(void $ _permDel permInfo) pColInfos constraints
rootFlds = getRootFldsRole tn pCols constraints fields permInfo
return (tyAgg, rootFlds)
where
colInfos = fst $ validPartitionFieldInfoMap fields
pColInfos = getColInfos pCols colInfos
filterColInfos allowedSet =
filter ((`Set.member` allowedSet) . pgiName) colInfos

getRootFldsRole
:: QualifiedTable
-> [PGCol]
-> [TableConstraint]
-> FieldInfoMap
-> RolePermInfo
-> RootFlds
getRootFldsRole tn constraints fields (RolePermInfo insM selM updM delM) =
getRootFldsRole' tn constraints fields
getRootFldsRole tn pCols constraints fields (RolePermInfo insM selM updM delM) =
getRootFldsRole' tn pCols constraints fields
(mkIns <$> insM) (mkSel <$> selM)
(mkUpd <$> updM) (mkDel <$> delM)
where
Expand All @@ -1016,21 +1059,25 @@ mkGCtxMapTable
=> TableCache
-> TableInfo
-> m (Map.HashMap RoleName (TyAgg, RootFlds))
mkGCtxMapTable tableCache (TableInfo tn _ fields rolePerms constraints) = do
m <- Map.traverseWithKey (mkGCtxRole tableCache tn fields validConstraints) rolePerms
mkGCtxMapTable tableCache (TableInfo tn _ fields rolePerms constraints pkeyCols) = do
m <- Map.traverseWithKey
(mkGCtxRole tableCache tn fields pkeyCols validConstraints) rolePerms
let adminCtx = mkGCtxRole' tn (Just colInfos)
(Just selFlds) (Just colInfos) (Just ()) validConstraints
(Just selFlds) (Just colInfos) (Just ())
pkeyColInfos validConstraints
return $ Map.insert adminRole (adminCtx, adminRootFlds) m
where
validConstraints = mkValidConstraints constraints
colInfos = fst $ validPartitionFieldInfoMap fields
allCols = map pgiName colInfos
pkeyColInfos = getColInfos pkeyCols colInfos
selFlds = flip map (toValidFieldInfos fields) $ \case
FIColumn pgColInfo -> Left pgColInfo
FIRelationship relInfo -> Right (relInfo, noFilter, Nothing, isRelNullable fields relInfo)
noFilter = S.BELit True
adminRootFlds =
getRootFldsRole' tn constraints fields (Just (tn, [])) (Just (noFilter, Nothing, []))
getRootFldsRole' tn pkeyCols constraints fields
(Just (tn, [])) (Just (noFilter, Nothing, []))
(Just (allCols, noFilter, [])) (Just (noFilter, []))

mkScalarTyInfo :: PGColType -> ScalarTyInfo
Expand Down
19 changes: 16 additions & 3 deletions server/src-lib/Hasura/RQL/DDL/Schema/Table.hs
Original file line number Diff line number Diff line change
Expand Up @@ -68,16 +68,29 @@ getTableInfo qt@(QualifiedTable sn tn) isSystemDefined = do
AND table_name = $2
|] (sn, tn) False

-- Fetch primary key columns
rawPrimaryCols <- Q.listQE defaultTxErrorHandler [Q.sql|
SELECT columns
FROM hdb_catalog.hdb_primary_key
WHERE table_schema = $1
AND table_name = $2
|] (sn, tn) False
pkeyCols <- mkPKeyCols rawPrimaryCols

-- Fetch the constraint details
rawConstraints <- Q.catchE defaultTxErrorHandler $ Q.listQ [Q.sql|
SELECT constraint_type, constraint_name
FROM information_schema.table_constraints
WHERE table_schema = $1
AND table_name = $2
|] (sn, tn) False
return $ mkTableInfo qt isSystemDefined rawConstraints $
flip map colData $ \(colName, Q.AltJ colTy, isNull)
-> (colName, colTy, isNull)
let colDetails = flip map colData $ \(colName, Q.AltJ colTy, isNull)
-> (colName, colTy, isNull)
return $ mkTableInfo qt isSystemDefined rawConstraints colDetails pkeyCols
where
mkPKeyCols [] = return []
mkPKeyCols [Identity (Q.AltJ pkeyCols)] = return pkeyCols
mkPKeyCols _ = throw500 "found multiple rows for a table in hdb_primary_key"

newtype TrackTable
= TrackTable
Expand Down
Loading