Put traditional Filters inside [LogicTree] (#911)
This commit is contained in:
@@ -30,7 +30,7 @@ import PostgREST.ApiRequest ( ApiRequest(..)
|
|||||||
import PostgREST.Error (apiRequestError)
|
import PostgREST.Error (apiRequestError)
|
||||||
import PostgREST.Parsers
|
import PostgREST.Parsers
|
||||||
import PostgREST.RangeQuery (NonnegRange, restrictRange)
|
import PostgREST.RangeQuery (NonnegRange, restrictRange)
|
||||||
import PostgREST.QueryBuilder (getJoinConditions, sourceCTEName)
|
import PostgREST.QueryBuilder (getJoinFilters, sourceCTEName)
|
||||||
import PostgREST.Types
|
import PostgREST.Types
|
||||||
|
|
||||||
import Protolude hiding (from, dropWhile, drop)
|
import Protolude hiding (from, dropWhile, drop)
|
||||||
@@ -88,7 +88,7 @@ treeRestrictRange maxRows_ request = pure $ nodeRestrictRange maxRows_ `fmap` re
|
|||||||
augumentRequestWithJoin :: Schema -> [Relation] -> ReadRequest -> Either ApiRequestError ReadRequest
|
augumentRequestWithJoin :: Schema -> [Relation] -> ReadRequest -> Either ApiRequestError ReadRequest
|
||||||
augumentRequestWithJoin schema allRels request =
|
augumentRequestWithJoin schema allRels request =
|
||||||
addRelations schema allRels Nothing request
|
addRelations schema allRels Nothing request
|
||||||
>>= addJoinConditions schema
|
>>= addJoinFilters schema
|
||||||
|
|
||||||
addRelations :: Schema -> [Relation] -> Maybe ReadRequest -> ReadRequest -> Either ApiRequestError ReadRequest
|
addRelations :: Schema -> [Relation] -> Maybe ReadRequest -> ReadRequest -> Either ApiRequestError ReadRequest
|
||||||
addRelations schema allRelations parentNode (Node readNode@(query, (name, _, alias)) forest) =
|
addRelations schema allRelations parentNode (Node readNode@(query, (name, _, alias)) forest) =
|
||||||
@@ -155,21 +155,20 @@ addRelations schema allRelations parentNode (Node readNode@(query, (name, _, ali
|
|||||||
updateForest :: Maybe ReadRequest -> Either ApiRequestError [ReadRequest]
|
updateForest :: Maybe ReadRequest -> Either ApiRequestError [ReadRequest]
|
||||||
updateForest n = mapM (addRelations schema allRelations n) forest
|
updateForest n = mapM (addRelations schema allRelations n) forest
|
||||||
|
|
||||||
addJoinConditions :: Schema -> ReadRequest -> Either ApiRequestError ReadRequest
|
addJoinFilters :: Schema -> ReadRequest -> Either ApiRequestError ReadRequest
|
||||||
addJoinConditions schema (Node nn@(query, (n, r, a)) forest) =
|
addJoinFilters schema (Node node@(query, nodeProps@(_, relation, _)) forest) =
|
||||||
case r of
|
case relation of
|
||||||
Just Relation{relType=Root} -> Node nn <$> updatedForest -- this is the root node
|
Just Relation{relType=Root} -> Node node <$> updatedForest -- this is the root node
|
||||||
Just rel@Relation{relType=Child} -> Node (addCond query (getJoinConditions rel),(n,r,a)) <$> updatedForest
|
Just Relation{relType=Parent} -> Node node <$> updatedForest
|
||||||
Just Relation{relType=Parent} -> Node nn <$> updatedForest
|
Just rel@Relation{relType=Child} -> Node (augmentQuery rel, nodeProps) <$> updatedForest
|
||||||
Just rel@Relation{relType=Many, relLTable=(Just linkTable)} ->
|
Just rel@Relation{relType=Many, relLTable=(Just linkTable)} ->
|
||||||
Node (qq, (n, r, a)) <$> updatedForest
|
let rq = augmentQuery rel in
|
||||||
where
|
Node (rq{from=tableName linkTable:from rq}, nodeProps) <$> updatedForest
|
||||||
query' = addCond query (getJoinConditions rel)
|
|
||||||
qq = query'{from=tableName linkTable : from query'}
|
|
||||||
_ -> Left UnknownRelation
|
_ -> Left UnknownRelation
|
||||||
where
|
where
|
||||||
updatedForest = mapM (addJoinConditions schema) forest
|
updatedForest = mapM (addJoinFilters schema) forest
|
||||||
addCond query' con = query'{flt_=con ++ flt_ query'}
|
augmentQuery rel = foldr addFilterToReadQuery query (getJoinFilters rel)
|
||||||
|
addFilterToReadQuery flt rq@Select{where_=lf} = rq{where_=addFilterToLogicForest flt lf}::ReadQuery
|
||||||
|
|
||||||
addFiltersOrdersRanges :: ApiRequest -> Either ApiRequestError (ReadRequest -> ReadRequest)
|
addFiltersOrdersRanges :: ApiRequest -> Either ApiRequestError (ReadRequest -> ReadRequest)
|
||||||
addFiltersOrdersRanges apiRequest = foldr1 (liftA2 (.)) [
|
addFiltersOrdersRanges apiRequest = foldr1 (liftA2 (.)) [
|
||||||
@@ -198,7 +197,7 @@ addFiltersOrdersRanges apiRequest = foldr1 (liftA2 (.)) [
|
|||||||
ranges = mapM pRequestRange $ M.toList $ iRange apiRequest
|
ranges = mapM pRequestRange $ M.toList $ iRange apiRequest
|
||||||
|
|
||||||
addFilterToNode :: Filter -> ReadRequest -> ReadRequest
|
addFilterToNode :: Filter -> ReadRequest -> ReadRequest
|
||||||
addFilterToNode flt (Node (q@Select {flt_=flts}, i) f) = Node (q {flt_=flt:flts}, i) f
|
addFilterToNode flt (Node (q@Select {where_=lf}, i) f) = Node (q{where_=addFilterToLogicForest flt lf}::ReadQuery, i) f
|
||||||
|
|
||||||
addFilter :: (EmbedPath, Filter) -> ReadRequest -> ReadRequest
|
addFilter :: (EmbedPath, Filter) -> ReadRequest -> ReadRequest
|
||||||
addFilter = addProperty addFilterToNode
|
addFilter = addProperty addFilterToNode
|
||||||
@@ -216,7 +215,7 @@ addRange :: (EmbedPath, NonnegRange) -> ReadRequest -> ReadRequest
|
|||||||
addRange = addProperty addRangeToNode
|
addRange = addProperty addRangeToNode
|
||||||
|
|
||||||
addLogicTreeToNode :: LogicTree -> ReadRequest -> ReadRequest
|
addLogicTreeToNode :: LogicTree -> ReadRequest -> ReadRequest
|
||||||
addLogicTreeToNode t (Node (q@Select{logic=l},i) f) = Node (q{logic=t:l}::ReadQuery, i) f
|
addLogicTreeToNode t (Node (q@Select{where_=lf},i) f) = Node (q{where_=t:lf}::ReadQuery, i) f
|
||||||
|
|
||||||
addLogicTree :: (EmbedPath, LogicTree) -> ReadRequest -> ReadRequest
|
addLogicTree :: (EmbedPath, LogicTree) -> ReadRequest -> ReadRequest
|
||||||
addLogicTree = addProperty addLogicTreeToNode
|
addLogicTree = addProperty addLogicTreeToNode
|
||||||
@@ -258,8 +257,8 @@ mutateRequest :: ApiRequest -> [FieldName] -> Either Response MutateRequest
|
|||||||
mutateRequest apiRequest fldNames = mapLeft apiRequestError $
|
mutateRequest apiRequest fldNames = mapLeft apiRequestError $
|
||||||
case action of
|
case action of
|
||||||
ActionCreate -> Right $ Insert rootTableName payload returnings
|
ActionCreate -> Right $ Insert rootTableName payload returnings
|
||||||
ActionUpdate -> Update rootTableName <$> pure payload <*> filters <*> logic_ <*> pure returnings
|
ActionUpdate -> Update rootTableName <$> pure payload <*> combinedLogic <*> pure returnings
|
||||||
ActionDelete -> Delete rootTableName <$> filters <*> logic_ <*> pure returnings
|
ActionDelete -> Delete rootTableName <$> combinedLogic <*> pure returnings
|
||||||
_ -> Left UnsupportedVerb
|
_ -> Left UnsupportedVerb
|
||||||
where
|
where
|
||||||
action = iAction apiRequest
|
action = iAction apiRequest
|
||||||
@@ -271,10 +270,10 @@ mutateRequest apiRequest fldNames = mapLeft apiRequestError $
|
|||||||
_ -> undefined
|
_ -> undefined
|
||||||
returnings = if iPreferRepresentation apiRequest == None then [] else fldNames
|
returnings = if iPreferRepresentation apiRequest == None then [] else fldNames
|
||||||
filters = map snd <$> mapM pRequestFilter mutateFilters
|
filters = map snd <$> mapM pRequestFilter mutateFilters
|
||||||
logic_ = map snd <$> mapM pRequestLogicTree logicFilters
|
logic = map snd <$> mapM pRequestLogicTree logicFilters
|
||||||
|
combinedLogic = foldr addFilterToLogicForest <$> logic <*> filters
|
||||||
-- update/delete filters can be only on the root table
|
-- update/delete filters can be only on the root table
|
||||||
mutateFilters = onlyRoot $ iFilters apiRequest
|
(mutateFilters, logicFilters) = join (***) onlyRoot (iFilters apiRequest, iLogic apiRequest)
|
||||||
logicFilters = onlyRoot $ iLogic apiRequest
|
|
||||||
onlyRoot = filter (not . ( "." `isInfixOf` ) . fst)
|
onlyRoot = filter (not . ( "." `isInfixOf` ) . fst)
|
||||||
|
|
||||||
fieldNames :: ReadRequest -> [FieldName]
|
fieldNames :: ReadRequest -> [FieldName]
|
||||||
@@ -284,3 +283,8 @@ fieldNames (Node (sel, _) forest) =
|
|||||||
fks = concatMap (fromMaybe [] . f) forest
|
fks = concatMap (fromMaybe [] . f) forest
|
||||||
f (Node (_, (_, Just Relation{relFColumns=cols, relType=Parent}, _)) _) = Just cols
|
f (Node (_, (_, Just Relation{relFColumns=cols, relType=Parent}, _)) _) = Just cols
|
||||||
f _ = Nothing
|
f _ = Nothing
|
||||||
|
|
||||||
|
-- Traditional filters(e.g. id=eq.1) are added as root nodes of the LogicTree
|
||||||
|
-- they are later concatenated with AND in the QueryBuilder
|
||||||
|
addFilterToLogicForest :: Filter -> [LogicTree] -> [LogicTree]
|
||||||
|
addFilterToLogicForest flt lf = Stmnt flt : lf
|
||||||
|
|||||||
@@ -58,7 +58,7 @@ pReadRequest rootNodeName = do
|
|||||||
fieldTree <- pFieldForest
|
fieldTree <- pFieldForest
|
||||||
return $ foldr treeEntry (Node (readQuery, (rootNodeName, Nothing, Nothing)) []) fieldTree
|
return $ foldr treeEntry (Node (readQuery, (rootNodeName, Nothing, Nothing)) []) fieldTree
|
||||||
where
|
where
|
||||||
readQuery = Select [] [rootNodeName] [] [] Nothing allRange
|
readQuery = Select [] [rootNodeName] [] Nothing allRange
|
||||||
treeEntry :: Tree SelectItem -> ReadRequest -> ReadRequest
|
treeEntry :: Tree SelectItem -> ReadRequest -> ReadRequest
|
||||||
treeEntry (Node fld@((fn, _),_,alias) fldForest) (Node (q, i) rForest) =
|
treeEntry (Node fld@((fn, _),_,alias) fldForest) (Node (q, i) rForest) =
|
||||||
case fldForest of
|
case fldForest of
|
||||||
@@ -66,7 +66,7 @@ pReadRequest rootNodeName = do
|
|||||||
_ -> Node (q, i) newForest
|
_ -> Node (q, i) newForest
|
||||||
where
|
where
|
||||||
newForest =
|
newForest =
|
||||||
foldr treeEntry (Node (Select [] [fn] [] [] Nothing allRange, (fn, Nothing, alias)) []) fldForest:rForest
|
foldr treeEntry (Node (Select [] [fn] [] Nothing allRange, (fn, Nothing, alias)) []) fldForest:rForest
|
||||||
|
|
||||||
pTreePath :: Parser (EmbedPath, Field)
|
pTreePath :: Parser (EmbedPath, Field)
|
||||||
pTreePath = do
|
pTreePath = do
|
||||||
|
|||||||
@@ -15,7 +15,7 @@ module PostgREST.QueryBuilder (
|
|||||||
callProc
|
callProc
|
||||||
, createReadStatement
|
, createReadStatement
|
||||||
, createWriteStatement
|
, createWriteStatement
|
||||||
, getJoinConditions
|
, getJoinFilters
|
||||||
, pgFmtIdent
|
, pgFmtIdent
|
||||||
, pgFmtLit
|
, pgFmtLit
|
||||||
, requestToQuery
|
, requestToQuery
|
||||||
@@ -199,25 +199,23 @@ pgFmtLit x =
|
|||||||
|
|
||||||
requestToCountQuery :: Schema -> DbRequest -> SqlQuery
|
requestToCountQuery :: Schema -> DbRequest -> SqlQuery
|
||||||
requestToCountQuery _ (DbMutate _) = undefined
|
requestToCountQuery _ (DbMutate _) = undefined
|
||||||
requestToCountQuery schema (DbRead (Node (Select _ _ conditions logic_ _ _, (mainTbl, _, _)) _)) =
|
requestToCountQuery schema (DbRead (Node (Select _ _ logicForest _ _, (mainTbl, _, _)) _)) =
|
||||||
unwords [
|
unwords [
|
||||||
"SELECT pg_catalog.count(*)",
|
"SELECT pg_catalog.count(*)",
|
||||||
"FROM ", fromQi qi,
|
"FROM ", fromQi qi,
|
||||||
-- logic_ doesn't not need localFilter filtering because it doesn't have VForeignKey vals
|
("WHERE " <> intercalate " AND " (map (pgFmtLogicTree qi) filteredLogic)) `emptyOnFalse` null filteredLogic
|
||||||
("WHERE " <> intercalate " AND " (map (pgFmtFilter qi) localConditions ++ map (pgFmtLogicTree qi) logic_))
|
|
||||||
`emptyOnFalse` (null conditions && null logic_)
|
|
||||||
]
|
]
|
||||||
where
|
where
|
||||||
qi = removeSourceCTESchema schema mainTbl
|
qi = removeSourceCTESchema schema mainTbl
|
||||||
localFilter :: Filter -> Bool
|
-- all foreing key filters are root nodes(see addFilterToLogicForest), only those are filtered
|
||||||
localFilter Filter{operation=Operation{expr=(_, val)}} = case val of
|
nonFKRoot :: LogicTree -> Bool
|
||||||
VText _ -> True
|
nonFKRoot (Stmnt (Filter _ Operation{expr=(_, VForeignKey _ _)})) = False
|
||||||
VTextL _ -> True
|
nonFKRoot (Stmnt _) = True
|
||||||
VForeignKey _ _ -> False
|
nonFKRoot Expr{} = True
|
||||||
localConditions = filter localFilter conditions
|
filteredLogic = filter nonFKRoot logicForest
|
||||||
|
|
||||||
requestToQuery :: Schema -> Bool -> DbRequest -> SqlQuery
|
requestToQuery :: Schema -> Bool -> DbRequest -> SqlQuery
|
||||||
requestToQuery schema isParent (DbRead (Node (Select colSelects tbls conditions logic_ ord range, (nodeName, maybeRelation, _)) forest)) =
|
requestToQuery schema isParent (DbRead (Node (Select colSelects tbls logicForest ord range, (nodeName, maybeRelation, _)) forest)) =
|
||||||
query
|
query
|
||||||
where
|
where
|
||||||
mainTbl = fromMaybe nodeName (tableName . relTable <$> maybeRelation)
|
mainTbl = fromMaybe nodeName (tableName . relTable <$> maybeRelation)
|
||||||
@@ -227,8 +225,7 @@ requestToQuery schema isParent (DbRead (Node (Select colSelects tbls conditions
|
|||||||
"SELECT ", intercalate ", " (map (pgFmtSelectItem qi) colSelects ++ selects),
|
"SELECT ", intercalate ", " (map (pgFmtSelectItem qi) colSelects ++ selects),
|
||||||
"FROM ", intercalate ", " (map (fromQi . toQi) tbls),
|
"FROM ", intercalate ", " (map (fromQi . toQi) tbls),
|
||||||
unwords joins,
|
unwords joins,
|
||||||
("WHERE " <> intercalate " AND " (map (pgFmtFilter qi) conditions ++ map (pgFmtLogicTree qi) logic_))
|
("WHERE " <> intercalate " AND " (map (pgFmtLogicTree qi) logicForest)) `emptyOnFalse` null logicForest,
|
||||||
`emptyOnFalse` (null conditions && null logic_),
|
|
||||||
orderF (fromMaybe [] ord),
|
orderF (fromMaybe [] ord),
|
||||||
if isParent then "" else limitF range
|
if isParent then "" else limitF range
|
||||||
]
|
]
|
||||||
@@ -261,7 +258,7 @@ requestToQuery schema isParent (DbRead (Node (Select colSelects tbls conditions
|
|||||||
replaceTableName _ x = x
|
replaceTableName _ x = x
|
||||||
sel = "row_to_json(" <> pgFmtIdent local_table_name <> ".*) AS " <> pgFmtIdent node_name
|
sel = "row_to_json(" <> pgFmtIdent local_table_name <> ".*) AS " <> pgFmtIdent node_name
|
||||||
joi = " LEFT OUTER JOIN ( " <> subquery <> " ) AS " <> pgFmtIdent local_table_name <>
|
joi = " LEFT OUTER JOIN ( " <> subquery <> " ) AS " <> pgFmtIdent local_table_name <>
|
||||||
" ON " <> intercalate " AND " ( map (pgFmtFilter qi . replaceTableName local_table_name) (getJoinConditions r) )
|
" ON " <> intercalate " AND " ( map (pgFmtFilter qi . replaceTableName local_table_name) (getJoinFilters r) )
|
||||||
where subquery = requestToQuery schema True (DbRead (Node n forst))
|
where subquery = requestToQuery schema True (DbRead (Node n forst))
|
||||||
getQueryParts (Node n@(_, (name, Just Relation{relType=Many,relTable=Table{tableName=table}}, alias)) forst) (j,s) = (j,sel:s)
|
getQueryParts (Node n@(_, (name, Just Relation{relType=Many,relTable=Table{tableName=table}}, alias)) forst) (j,s) = (j,sel:s)
|
||||||
where
|
where
|
||||||
@@ -289,7 +286,7 @@ requestToQuery schema _ (DbMutate (Insert mainTbl (PayloadJSON rows) returnings)
|
|||||||
ret = if null returnings
|
ret = if null returnings
|
||||||
then ""
|
then ""
|
||||||
else unwords [" RETURNING ", intercalate ", " (map (pgFmtColumn qi) returnings)]
|
else unwords [" RETURNING ", intercalate ", " (map (pgFmtColumn qi) returnings)]
|
||||||
requestToQuery schema _ (DbMutate (Update mainTbl (PayloadJSON rows) conditions logic_ returnings)) =
|
requestToQuery schema _ (DbMutate (Update mainTbl (PayloadJSON rows) logicForest returnings)) =
|
||||||
case rows V.!? 0 of
|
case rows V.!? 0 of
|
||||||
Just obj ->
|
Just obj ->
|
||||||
let assignments = map
|
let assignments = map
|
||||||
@@ -297,21 +294,19 @@ requestToQuery schema _ (DbMutate (Update mainTbl (PayloadJSON rows) conditions
|
|||||||
unwords [
|
unwords [
|
||||||
"UPDATE ", fromQi qi,
|
"UPDATE ", fromQi qi,
|
||||||
" SET " <> intercalate "," assignments <> " ",
|
" SET " <> intercalate "," assignments <> " ",
|
||||||
("WHERE " <> intercalate " AND " (map (pgFmtFilter qi) conditions ++ map (pgFmtLogicTree qi) logic_))
|
("WHERE " <> intercalate " AND " (map (pgFmtLogicTree qi) logicForest)) `emptyOnFalse` null logicForest,
|
||||||
`emptyOnFalse` (null conditions && null logic_),
|
|
||||||
("RETURNING " <> intercalate ", " (map (pgFmtColumn qi) returnings)) `emptyOnFalse` null returnings
|
("RETURNING " <> intercalate ", " (map (pgFmtColumn qi) returnings)) `emptyOnFalse` null returnings
|
||||||
]
|
]
|
||||||
Nothing -> undefined
|
Nothing -> undefined
|
||||||
where
|
where
|
||||||
qi = QualifiedIdentifier schema mainTbl
|
qi = QualifiedIdentifier schema mainTbl
|
||||||
requestToQuery schema _ (DbMutate (Delete mainTbl conditions logic_ returnings)) =
|
requestToQuery schema _ (DbMutate (Delete mainTbl logicForest returnings)) =
|
||||||
query
|
query
|
||||||
where
|
where
|
||||||
qi = QualifiedIdentifier schema mainTbl
|
qi = QualifiedIdentifier schema mainTbl
|
||||||
query = unwords [
|
query = unwords [
|
||||||
"DELETE FROM ", fromQi qi,
|
"DELETE FROM ", fromQi qi,
|
||||||
("WHERE " <> intercalate " AND " (map (pgFmtFilter qi) conditions ++ map (pgFmtLogicTree qi) logic_))
|
("WHERE " <> intercalate " AND " (map (pgFmtLogicTree qi) logicForest)) `emptyOnFalse` null logicForest,
|
||||||
`emptyOnFalse` (null conditions && null logic_),
|
|
||||||
("RETURNING " <> intercalate ", " (map (pgFmtColumn qi) returnings)) `emptyOnFalse` null returnings
|
("RETURNING " <> intercalate ", " (map (pgFmtColumn qi) returnings)) `emptyOnFalse` null returnings
|
||||||
]
|
]
|
||||||
|
|
||||||
@@ -378,13 +373,13 @@ fromQi t = (if s == "" then "" else pgFmtIdent s <> ".") <> pgFmtIdent n
|
|||||||
n = qiName t
|
n = qiName t
|
||||||
s = qiSchema t
|
s = qiSchema t
|
||||||
|
|
||||||
getJoinConditions :: Relation -> [Filter]
|
getJoinFilters :: Relation -> [Filter]
|
||||||
getJoinConditions (Relation t cols ft fcs typ lt lc1 lc2) =
|
getJoinFilters (Relation t cols ft fcs typ lt lc1 lc2) =
|
||||||
case typ of
|
case typ of
|
||||||
Child -> zipWith (toFilter tN ftN) cols fcs
|
Child -> zipWith (toFilter tN ftN) cols fcs
|
||||||
Parent -> zipWith (toFilter tN ftN) cols fcs
|
Parent -> zipWith (toFilter tN ftN) cols fcs
|
||||||
Many -> zipWith (toFilter tN ltN) cols (fromMaybe [] lc1) ++ zipWith (toFilter ftN ltN) fcs (fromMaybe [] lc2)
|
Many -> zipWith (toFilter tN ltN) cols (fromMaybe [] lc1) ++ zipWith (toFilter ftN ltN) fcs (fromMaybe [] lc2)
|
||||||
Root -> undefined --error "undefined getJoinConditions"
|
Root -> undefined --error "undefined getJoinFilters"
|
||||||
where
|
where
|
||||||
s = if typ == Parent then "" else tableSchema t
|
s = if typ == Parent then "" else tableSchema t
|
||||||
tN = tableName t
|
tN = tableName t
|
||||||
|
|||||||
@@ -184,10 +184,10 @@ type SelectItem = (Field, Maybe Cast, Maybe Alias)
|
|||||||
type EmbedPath = [Text]
|
type EmbedPath = [Text]
|
||||||
data Filter = Filter { field::Field, operation::Operation } deriving (Show, Eq)
|
data Filter = Filter { field::Field, operation::Operation } deriving (Show, Eq)
|
||||||
|
|
||||||
data ReadQuery = Select { select::[SelectItem], from::[TableName], flt_::[Filter], logic::[LogicTree], order::Maybe [OrderTerm], range_::NonnegRange } deriving (Show, Eq)
|
data ReadQuery = Select { select::[SelectItem], from::[TableName], where_::[LogicTree], order::Maybe [OrderTerm], range_::NonnegRange } deriving (Show, Eq)
|
||||||
data MutateQuery = Insert { in_::TableName, qPayload::PayloadJSON, returning::[FieldName] }
|
data MutateQuery = Insert { in_::TableName, qPayload::PayloadJSON, returning::[FieldName] }
|
||||||
| Delete { in_::TableName, where_::[Filter], logic::[LogicTree], returning::[FieldName] }
|
| Delete { in_::TableName, where_::[LogicTree], returning::[FieldName] }
|
||||||
| Update { in_::TableName, qPayload::PayloadJSON, where_::[Filter], logic::[LogicTree], returning::[FieldName] } deriving (Show, Eq)
|
| Update { in_::TableName, qPayload::PayloadJSON, where_::[LogicTree], returning::[FieldName] } deriving (Show, Eq)
|
||||||
type ReadNode = (ReadQuery, (NodeName, Maybe Relation, Maybe Alias))
|
type ReadNode = (ReadQuery, (NodeName, Maybe Relation, Maybe Alias))
|
||||||
type ReadRequest = Tree ReadNode
|
type ReadRequest = Tree ReadNode
|
||||||
type MutateRequest = MutateQuery
|
type MutateRequest = MutateQuery
|
||||||
|
|||||||
Reference in New Issue
Block a user