refactor: clarify ReadPlan fields
This commit is contained in:
committed by
Steve Chavez
parent
64e047e5d7
commit
922da4520f
+17
-17
@@ -142,19 +142,19 @@ augmentRequestWithJoin schema allRels request =
|
|||||||
addJoinConditions Nothing <$> addRels schema allRels Nothing request
|
addJoinConditions Nothing <$> addRels schema allRels Nothing request
|
||||||
|
|
||||||
addRels :: Schema -> RelationshipsMap -> Maybe ReadPlanTree -> ReadPlanTree -> Either ApiRequestError ReadPlanTree
|
addRels :: Schema -> RelationshipsMap -> Maybe ReadPlanTree -> ReadPlanTree -> Either ApiRequestError ReadPlanTree
|
||||||
addRels schema allRels parentNode (Node query@ReadPlan{from=tbl,nodeName,nodeHint,nodeDepth} forest) =
|
addRels schema allRels parentNode (Node query@ReadPlan{from=tbl,relName,relHint,depth} forest) =
|
||||||
case parentNode of
|
case parentNode of
|
||||||
Just (Node ReadPlan{from=parentNodeQi, fromAlias=aliasQi} _) ->
|
Just (Node ReadPlan{from=parentNodeQi, fromAlias=aliasQi} _) ->
|
||||||
let newFrom r = if qiName tbl == nodeName then relForeignTable r else tbl
|
let newFrom r = if qiName tbl == relName then relForeignTable r else tbl
|
||||||
newReadPlan = (\r ->
|
newReadPlan = (\r ->
|
||||||
if not $ relIsSelf r -- add alias if self rel TODO consolidate aliasing in another function
|
if not $ relIsSelf r -- add alias if self rel TODO consolidate aliasing in another function
|
||||||
then query{from=newFrom r, nodeRel=Just r}
|
then query{from=newFrom r, relToParent=Just r}
|
||||||
else query{from=newFrom r, nodeRel=Just r, fromAlias=Just (qiName (newFrom r) <> "_" <> show nodeDepth)}
|
else query{from=newFrom r, relToParent=Just r, fromAlias=Just (qiName (newFrom r) <> "_" <> show depth)}
|
||||||
) <$> rel
|
) <$> rel
|
||||||
origin = if nodeDepth == 1 -- Only on depth 1 we check if the root(depth 0) has an alias so the sourceCTEName alias can be found as a relationship
|
origin = if depth == 1 -- Only on depth 1 we check if the root(depth 0) has an alias so the sourceCTEName alias can be found as a relationship
|
||||||
then fromMaybe (qiName parentNodeQi) aliasQi
|
then fromMaybe (qiName parentNodeQi) aliasQi
|
||||||
else qiName parentNodeQi
|
else qiName parentNodeQi
|
||||||
rel = findRel schema allRels origin nodeName nodeHint
|
rel = findRel schema allRels origin relName relHint
|
||||||
in
|
in
|
||||||
Node <$> newReadPlan <*> (updateForest . hush $ Node <$> newReadPlan <*> pure forest)
|
Node <$> newReadPlan <*> (updateForest . hush $ Node <$> newReadPlan <*> pure forest)
|
||||||
_ ->
|
_ ->
|
||||||
@@ -165,9 +165,9 @@ addRels schema allRels parentNode (Node query@ReadPlan{from=tbl,nodeName,nodeHin
|
|||||||
|
|
||||||
-- applies aliasing to join conditions TODO refactor, this should go into the querybuilder module
|
-- applies aliasing to join conditions TODO refactor, this should go into the querybuilder module
|
||||||
addJoinConditions :: Maybe Alias -> ReadPlanTree -> ReadPlanTree
|
addJoinConditions :: Maybe Alias -> ReadPlanTree -> ReadPlanTree
|
||||||
addJoinConditions _ (Node node@ReadPlan{fromAlias=tblAlias, nodeRel=Nothing} forest) = Node node (addJoinConditions tblAlias <$> forest)
|
addJoinConditions _ (Node node@ReadPlan{fromAlias=tblAlias, relToParent=Nothing} forest) = Node node (addJoinConditions tblAlias <$> forest)
|
||||||
addJoinConditions _ (Node node@ReadPlan{fromAlias=tblAlias, nodeRel=Just ComputedRelationship{}} forest) = Node node (addJoinConditions tblAlias <$> forest)
|
addJoinConditions _ (Node node@ReadPlan{fromAlias=tblAlias, relToParent=Just ComputedRelationship{}} forest) = Node node (addJoinConditions tblAlias <$> forest)
|
||||||
addJoinConditions previousAlias (Node query@ReadPlan{fromAlias=tblAlias, nodeRel=Just Relationship{relTable=qi,relForeignTable=fQi,relCardinality=card}} forest) =
|
addJoinConditions previousAlias (Node query@ReadPlan{fromAlias=tblAlias, relToParent=Just Relationship{relTable=qi,relForeignTable=fQi,relCardinality=card}} forest) =
|
||||||
Node query{joinConditions=joinConds} (addJoinConditions tblAlias <$> forest)
|
Node query{joinConditions=joinConds} (addJoinConditions tblAlias <$> forest)
|
||||||
where
|
where
|
||||||
QualifiedIdentifier{qiSchema=tSchema, qiName=tN} = qi
|
QualifiedIdentifier{qiSchema=tSchema, qiName=tN} = qi
|
||||||
@@ -333,7 +333,7 @@ updateNode f (targetNodeName:remainingPath, a) (Right (Node rootNode forest)) =
|
|||||||
updateNode f (remainingPath, a) (Right target)
|
updateNode f (remainingPath, a) (Right target)
|
||||||
where
|
where
|
||||||
findNode :: Maybe ReadPlanTree
|
findNode :: Maybe ReadPlanTree
|
||||||
findNode = find (\(Node ReadPlan{nodeName, nodeAlias} _) -> nodeName == targetNodeName || nodeAlias == Just targetNodeName) forest
|
findNode = find (\(Node ReadPlan{relName, relAlias} _) -> relName == targetNodeName || relAlias == Just targetNodeName) forest
|
||||||
|
|
||||||
mutatePlan :: Mutation -> QualifiedIdentifier -> ApiRequest -> SchemaCache -> ReadPlanTree -> Either Error MutatePlan
|
mutatePlan :: Mutation -> QualifiedIdentifier -> ApiRequest -> SchemaCache -> ReadPlanTree -> Either Error MutatePlan
|
||||||
mutatePlan mutation qi ApiRequest{..} sCache readReq = mapLeft ApiRequestError $
|
mutatePlan mutation qi ApiRequest{..} sCache readReq = mapLeft ApiRequestError $
|
||||||
@@ -398,21 +398,21 @@ returningCols rr@(Node _ forest) pkCols
|
|||||||
-- projects. So this adds the foreign key columns to ensure the embedding
|
-- projects. So this adds the foreign key columns to ensure the embedding
|
||||||
-- succeeds, result would be `RETURNING name, client_id`.
|
-- succeeds, result would be `RETURNING name, client_id`.
|
||||||
fkCols = concat $ mapMaybe (\case
|
fkCols = concat $ mapMaybe (\case
|
||||||
Node ReadPlan{nodeRel=Just Relationship{relCardinality=O2M _ cols}} _ ->
|
Node ReadPlan{relToParent=Just Relationship{relCardinality=O2M _ cols}} _ ->
|
||||||
Just $ fst <$> cols
|
Just $ fst <$> cols
|
||||||
Node ReadPlan{nodeRel=Just Relationship{relCardinality=M2O _ cols}} _ ->
|
Node ReadPlan{relToParent=Just Relationship{relCardinality=M2O _ cols}} _ ->
|
||||||
Just $ fst <$> cols
|
Just $ fst <$> cols
|
||||||
Node ReadPlan{nodeRel=Just Relationship{relCardinality=O2O _ cols}} _ ->
|
Node ReadPlan{relToParent=Just Relationship{relCardinality=O2O _ cols}} _ ->
|
||||||
Just $ fst <$> cols
|
Just $ fst <$> cols
|
||||||
Node ReadPlan{nodeRel=Just Relationship{relCardinality=M2M Junction{junColumns1, junColumns2}}} _ ->
|
Node ReadPlan{relToParent=Just Relationship{relCardinality=M2M Junction{junColumns1, junColumns2}}} _ ->
|
||||||
Just $ (fst <$> junColumns1) ++ (fst <$> junColumns2)
|
Just $ (fst <$> junColumns1) ++ (fst <$> junColumns2)
|
||||||
Node ReadPlan{nodeRel=Just ComputedRelationship{}} _ ->
|
Node ReadPlan{relToParent=Just ComputedRelationship{}} _ ->
|
||||||
Nothing
|
Nothing
|
||||||
Node ReadPlan{nodeRel=Nothing} _ ->
|
Node ReadPlan{relToParent=Nothing} _ ->
|
||||||
Nothing
|
Nothing
|
||||||
) forest
|
) forest
|
||||||
hasComputedRel = isJust $ find (\case
|
hasComputedRel = isJust $ find (\case
|
||||||
Node ReadPlan{nodeRel=Just ComputedRelationship{}} _ -> True
|
Node ReadPlan{relToParent=Just ComputedRelationship{}} _ -> True
|
||||||
_ -> False
|
_ -> False
|
||||||
) forest
|
) forest
|
||||||
-- However if the "client_id" is present, e.g. mutatePlan to
|
-- However if the "client_id" is present, e.g. mutatePlan to
|
||||||
|
|||||||
@@ -30,12 +30,12 @@ data ReadPlan = ReadPlan
|
|||||||
, joinConditions :: [JoinCondition]
|
, joinConditions :: [JoinCondition]
|
||||||
, order :: [OrderTerm]
|
, order :: [OrderTerm]
|
||||||
, range_ :: NonnegRange
|
, range_ :: NonnegRange
|
||||||
, nodeName :: NodeName
|
, relName :: NodeName
|
||||||
, nodeRel :: Maybe Relationship
|
, relToParent :: Maybe Relationship
|
||||||
, nodeAlias :: Maybe Alias
|
, relAlias :: Maybe Alias
|
||||||
, nodeHint :: Maybe Hint
|
, relHint :: Maybe Hint
|
||||||
, nodeJoinType :: Maybe JoinType
|
, relJoinType :: Maybe JoinType
|
||||||
, nodeDepth :: Depth
|
, depth :: Depth
|
||||||
}
|
}
|
||||||
deriving (Eq)
|
deriving (Eq)
|
||||||
|
|
||||||
|
|||||||
@@ -39,7 +39,7 @@ import PostgREST.RangeQuery (allRange)
|
|||||||
import Protolude
|
import Protolude
|
||||||
|
|
||||||
readPlanToQuery :: ReadPlanTree -> SQL.Snippet
|
readPlanToQuery :: ReadPlanTree -> SQL.Snippet
|
||||||
readPlanToQuery (Node ReadPlan{select,from=mainQi,fromAlias,where_=logicForest,joinConditions, order, range_=readRange, nodeRel} forest) =
|
readPlanToQuery (Node ReadPlan{select,from=mainQi,fromAlias,where_=logicForest,joinConditions, order, range_=readRange, relToParent} forest) =
|
||||||
"SELECT " <>
|
"SELECT " <>
|
||||||
intercalateSnippet ", " ((pgFmtSelectItem qi <$> select) ++ selects) <> " " <>
|
intercalateSnippet ", " ((pgFmtSelectItem qi <$> select) ++ selects) <> " " <>
|
||||||
fromFrag <> " " <>
|
fromFrag <> " " <>
|
||||||
@@ -50,13 +50,13 @@ readPlanToQuery (Node ReadPlan{select,from=mainQi,fromAlias,where_=logicForest,j
|
|||||||
orderF qi order <> " " <>
|
orderF qi order <> " " <>
|
||||||
limitOffsetF readRange
|
limitOffsetF readRange
|
||||||
where
|
where
|
||||||
fromFrag = fromF nodeRel mainQi fromAlias
|
fromFrag = fromF relToParent mainQi fromAlias
|
||||||
qi = getQualifiedIdentifier nodeRel mainQi fromAlias
|
qi = getQualifiedIdentifier relToParent mainQi fromAlias
|
||||||
(selects, joins) = foldr getSelectsJoins ([],[]) forest
|
(selects, joins) = foldr getSelectsJoins ([],[]) forest
|
||||||
|
|
||||||
getSelectsJoins :: ReadPlanTree -> ([SQL.Snippet], [SQL.Snippet]) -> ([SQL.Snippet], [SQL.Snippet])
|
getSelectsJoins :: ReadPlanTree -> ([SQL.Snippet], [SQL.Snippet]) -> ([SQL.Snippet], [SQL.Snippet])
|
||||||
getSelectsJoins (Node ReadPlan{nodeRel=Nothing} _) _ = ([], [])
|
getSelectsJoins (Node ReadPlan{relToParent=Nothing} _) _ = ([], [])
|
||||||
getSelectsJoins rr@(Node ReadPlan{nodeName=name, nodeRel=Just rel, nodeAlias=alias, nodeJoinType=joinType} _) (selects,joins) =
|
getSelectsJoins rr@(Node ReadPlan{relName=name, relToParent=Just rel, relAlias=alias, relJoinType=joinType} _) (selects,joins) =
|
||||||
let
|
let
|
||||||
subquery = readPlanToQuery rr
|
subquery = readPlanToQuery rr
|
||||||
aliasOrName = fromMaybe name alias
|
aliasOrName = fromMaybe name alias
|
||||||
@@ -225,7 +225,7 @@ callPlanToQuery (FunctionCall qi params args returnsScalar multipleCall returnin
|
|||||||
-- See https://github.com/PostgREST/postgrest/issues/2009#issuecomment-977473031
|
-- See https://github.com/PostgREST/postgrest/issues/2009#issuecomment-977473031
|
||||||
-- Only for the nodes that have an INNER JOIN linked to the root level.
|
-- Only for the nodes that have an INNER JOIN linked to the root level.
|
||||||
readPlanToCountQuery :: ReadPlanTree -> SQL.Snippet
|
readPlanToCountQuery :: ReadPlanTree -> SQL.Snippet
|
||||||
readPlanToCountQuery (Node ReadPlan{from=mainQi, fromAlias=tblAlias, where_=logicForest, joinConditions=joinConditions_, nodeRel=rel} forest) =
|
readPlanToCountQuery (Node ReadPlan{from=mainQi, fromAlias=tblAlias, where_=logicForest, joinConditions=joinConditions_, relToParent=rel} forest) =
|
||||||
"SELECT 1 " <> fromFrag <>
|
"SELECT 1 " <> fromFrag <>
|
||||||
(if null logicForest && null joinConditions_ && null subQueries
|
(if null logicForest && null joinConditions_ && null subQueries
|
||||||
then mempty
|
then mempty
|
||||||
@@ -240,7 +240,7 @@ readPlanToCountQuery (Node ReadPlan{from=mainQi, fromAlias=tblAlias, where_=logi
|
|||||||
fromFrag = fromF rel mainQi tblAlias
|
fromFrag = fromF rel mainQi tblAlias
|
||||||
subQueries = foldr existsSubquery [] forest
|
subQueries = foldr existsSubquery [] forest
|
||||||
existsSubquery :: ReadPlanTree -> [SQL.Snippet] -> [SQL.Snippet]
|
existsSubquery :: ReadPlanTree -> [SQL.Snippet] -> [SQL.Snippet]
|
||||||
existsSubquery readReq@(Node ReadPlan{nodeJoinType=joinType} _) rest =
|
existsSubquery readReq@(Node ReadPlan{relJoinType=joinType} _) rest =
|
||||||
if joinType == Just JTInner
|
if joinType == Just JTInner
|
||||||
then ("EXISTS (" <> readPlanToCountQuery readReq <> " )"):rest
|
then ("EXISTS (" <> readPlanToCountQuery readReq <> " )"):rest
|
||||||
else rest
|
else rest
|
||||||
|
|||||||
Reference in New Issue
Block a user