refactor: all aliasing in addRels
This commit is contained in:
committed by
Steve Chavez
parent
f9f572a5d2
commit
5d126bf0a3
@@ -107,7 +107,7 @@ initReadRequest qi@QualifiedIdentifier{..} =
|
||||
foldr (treeEntry rootDepth) $ Node defReadPlan{from=qi, relName=qiName, depth=rootDepth} []
|
||||
where
|
||||
rootDepth = 0
|
||||
defReadPlan = ReadPlan [] (QualifiedIdentifier mempty mempty) Nothing [] [] allRange mempty Nothing [] Nothing Nothing Nothing rootDepth
|
||||
defReadPlan = ReadPlan [] (QualifiedIdentifier mempty mempty) Nothing [] [] allRange mempty Nothing [] Nothing mempty Nothing Nothing rootDepth
|
||||
treeEntry :: Depth -> Tree SelectItem -> ReadPlanTree -> ReadPlanTree
|
||||
treeEntry depth (Node fld@((fldName, _),_,alias, hint, joinType) fldForest) (Node q rForest) =
|
||||
let nxtDepth = succ depth in
|
||||
@@ -128,17 +128,18 @@ treeRestrictRange maxRows _ request = pure $ nodeRestrictRange maxRows <$> reque
|
||||
|
||||
-- add relationships to the nodes of the tree by traversing the forest while keeping track of the parentNode, also adds aliasing
|
||||
addRels :: Schema -> Action -> RelationshipsMap -> Maybe ReadPlanTree -> ReadPlanTree -> Either ApiRequestError ReadPlanTree
|
||||
addRels schema action allRels parentNode (Node rPlan@ReadPlan{relName,relHint,depth} forest) =
|
||||
addRels schema action allRels parentNode (Node rPlan@ReadPlan{relName,relHint,relAlias,depth} forest) =
|
||||
case parentNode of
|
||||
Just (Node ReadPlan{from=parentNodeQi, fromAlias} _) ->
|
||||
let
|
||||
newReadPlan = (\r ->
|
||||
let newAlias = Just (qiName (relForeignTable r) <> "_" <> show depth) in
|
||||
let newAlias = Just (qiName (relForeignTable r) <> "_" <> show depth)
|
||||
aggAlias = qiName (relTable r) <> "_" <> fromMaybe relName relAlias <> "_" <> show depth in
|
||||
case r of
|
||||
Relationship{relCardinality=M2M _} ->
|
||||
rPlan{from=relForeignTable r, relToParent=Just r, relJoinConds=getJoinConditions Nothing fromAlias r}
|
||||
rPlan{from=relForeignTable r, relToParent=Just r, relAggAlias=aggAlias, relJoinConds=getJoinConditions Nothing fromAlias r}
|
||||
_ ->
|
||||
rPlan{from=relForeignTable r, relToParent=Just r, fromAlias=newAlias, relJoinConds=getJoinConditions newAlias fromAlias r}
|
||||
rPlan{from=relForeignTable r, relToParent=Just r, relAggAlias=aggAlias, fromAlias=newAlias, relJoinConds=getJoinConditions newAlias fromAlias r}
|
||||
) <$> rel
|
||||
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) fromAlias
|
||||
|
||||
@@ -39,6 +39,7 @@ data ReadPlan = ReadPlan
|
||||
, relToParent :: Maybe Relationship
|
||||
, relJoinConds :: [JoinCondition]
|
||||
, relAlias :: Maybe Alias
|
||||
, relAggAlias :: Alias
|
||||
, relHint :: Maybe Hint
|
||||
, relJoinType :: Maybe JoinType
|
||||
, depth :: Depth
|
||||
|
||||
@@ -56,11 +56,11 @@ readPlanToQuery (Node ReadPlan{select,from=mainQi,fromAlias,where_=logicForest,o
|
||||
|
||||
getSelectsJoins :: ReadPlanTree -> ([SQL.Snippet], [SQL.Snippet]) -> ([SQL.Snippet], [SQL.Snippet])
|
||||
getSelectsJoins (Node ReadPlan{relToParent=Nothing} _) _ = ([], [])
|
||||
getSelectsJoins rr@(Node ReadPlan{relName, relToParent=Just rel, relAlias, relJoinType=joinType, depth} _) (selects,joins) =
|
||||
getSelectsJoins rr@(Node ReadPlan{relName, relToParent=Just rel, relAggAlias, relAlias, relJoinType=joinType} _) (selects,joins) =
|
||||
let
|
||||
subquery = readPlanToQuery rr
|
||||
aliasOrName = fromMaybe relName relAlias
|
||||
localTableName = pgFmtIdent $ qiName (relTable rel) <> "_" <> aliasOrName <> "_" <> show depth
|
||||
aliasOrName = pgFmtIdent $ fromMaybe relName relAlias
|
||||
aggAlias = pgFmtIdent relAggAlias
|
||||
correlatedSubquery sub al cond =
|
||||
(if joinType == Just JTInner then "INNER" else "LEFT") <> " JOIN LATERAL ( " <> sub <> " ) AS " <> SQL.sql al <> " ON " <> cond
|
||||
isToOne = case rel of
|
||||
@@ -70,14 +70,14 @@ getSelectsJoins rr@(Node ReadPlan{relName, relToParent=Just rel, relAlias, relJo
|
||||
_ -> False
|
||||
(sel, joi) = if isToOne
|
||||
then
|
||||
( SQL.sql ("row_to_json(" <> localTableName <> ".*) AS " <> pgFmtIdent aliasOrName)
|
||||
, correlatedSubquery subquery localTableName "TRUE")
|
||||
( SQL.sql ("row_to_json(" <> aggAlias <> ".*) AS " <> aliasOrName)
|
||||
, correlatedSubquery subquery aggAlias "TRUE")
|
||||
else
|
||||
( SQL.sql $ "COALESCE( " <> localTableName <> "." <> localTableName <> ", '[]') AS " <> pgFmtIdent aliasOrName
|
||||
( SQL.sql $ "COALESCE( " <> aggAlias <> "." <> aggAlias <> ", '[]') AS " <> aliasOrName
|
||||
, correlatedSubquery (
|
||||
"SELECT json_agg(" <> SQL.sql localTableName <> ") AS " <> SQL.sql localTableName <>
|
||||
"FROM (" <> subquery <> " ) AS " <> SQL.sql localTableName
|
||||
) localTableName $ if joinType == Just JTInner then SQL.sql localTableName <> " IS NOT NULL" else "TRUE")
|
||||
"SELECT json_agg(" <> SQL.sql aggAlias <> ") AS " <> SQL.sql aggAlias <>
|
||||
"FROM (" <> subquery <> " ) AS " <> SQL.sql aggAlias
|
||||
) aggAlias $ if joinType == Just JTInner then SQL.sql aggAlias <> " IS NOT NULL" else "TRUE")
|
||||
in
|
||||
(sel:selects, joi:joins)
|
||||
|
||||
|
||||
Reference in New Issue
Block a user