module Hasura.Backends.Postgres.Translate.Select.Internal.GenerateSelect
( generateSQLSelect,
generateSQLSelectFromArrayNode,
connectionToSelectWith,
)
where
import Data.HashMap.Strict qualified as HashMap
import Data.HashMap.Strict.InsOrd qualified as InsOrdHashMap
import Data.List.NonEmpty qualified as NE
import Hasura.Backends.Postgres.SQL.DML qualified as S
import Hasura.Backends.Postgres.SQL.Types
import Hasura.Backends.Postgres.SQL.Types qualified as S
import Hasura.Backends.Postgres.Translate.Select.Internal.Aliases (mkBaseTableAlias)
import Hasura.Backends.Postgres.Translate.Select.Internal.Helpers
( cursorIdentifier,
cursorsSelectAlias,
cursorsSelectAliasIdentifier,
endCursorIdentifier,
hasNextPageIdentifier,
hasPreviousPageIdentifier,
mkFirstElementExp,
mkLastElementExp,
pageInfoSelectAlias,
startCursorIdentifier,
)
import Hasura.Backends.Postgres.Translate.Types
import Hasura.Prelude
import Hasura.RQL.IR.Select (ConnectionSlice (SliceFirst, SliceLast))
import Hasura.RQL.Types.Relationships.Local (Nullable (..))
generateSQLSelect ::
S.BoolExp ->
SelectSource ->
SelectNode ->
S.Select
generateSQLSelect :: BoolExp -> SelectSource -> SelectNode -> Select
generateSQLSelect BoolExp
joinCondition SelectSource
selectSource SelectNode
selectNode =
Select
S.mkSelect
{ selExtr :: [Extractor]
S.selExtr =
case [SQLExp -> Maybe ColumnAlias -> Extractor
S.Extractor SQLExp
e (Maybe ColumnAlias -> Extractor) -> Maybe ColumnAlias -> Extractor
forall a b. (a -> b) -> a -> b
$ ColumnAlias -> Maybe ColumnAlias
forall a. a -> Maybe a
Just ColumnAlias
a | (ColumnAlias
a, SQLExp
e) <- InsOrdHashMap ColumnAlias SQLExp -> [(ColumnAlias, SQLExp)]
forall k v. InsOrdHashMap k v -> [(k, v)]
InsOrdHashMap.toList InsOrdHashMap ColumnAlias SQLExp
extractors] of
[] -> [Extractor]
S.dummySelectList
[Extractor]
exts -> [Extractor]
exts,
selFrom :: Maybe FromExp
S.selFrom = FromExp -> Maybe FromExp
forall a. a -> Maybe a
Just (FromExp -> Maybe FromExp) -> FromExp -> Maybe FromExp
forall a b. (a -> b) -> a -> b
$ [FromItem] -> FromExp
S.FromExp [FromItem
joinedFrom],
selOrderBy :: Maybe OrderByExp
S.selOrderBy = Maybe OrderByExp
nodeOrderBy,
selLimit :: Maybe LimitExp
S.selLimit = SQLExp -> LimitExp
S.LimitExp (SQLExp -> LimitExp) -> (Int -> SQLExp) -> Int -> LimitExp
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Int -> SQLExp
S.intToSQLExp (Int -> LimitExp) -> Maybe Int -> Maybe LimitExp
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> SelectSlicing -> Maybe Int
_ssLimit SelectSlicing
nodeSlicing,
selOffset :: Maybe OffsetExp
S.selOffset = SQLExp -> OffsetExp
S.OffsetExp (SQLExp -> OffsetExp) -> (Int64 -> SQLExp) -> Int64 -> OffsetExp
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Int64 -> SQLExp
S.int64ToSQLExp (Int64 -> OffsetExp) -> Maybe Int64 -> Maybe OffsetExp
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> SelectSlicing -> Maybe Int64
_ssOffset SelectSlicing
nodeSlicing,
selDistinct :: Maybe DistinctExpr
S.selDistinct = Maybe DistinctExpr
nodeDistinctOn
}
where
SelectSource Identifier
sourcePrefix FromItem
fromItem BoolExp
whereExp SortingAndSlicing
sortAndSlice = SelectSource
selectSource
SelectNode InsOrdHashMap ColumnAlias SQLExp
extractors JoinTree
joinTree = SelectNode
selectNode
JoinTree HashMap ObjectRelationSource SelectNode
objectRelations HashMap ArrayRelationSource MultiRowSelectNode
arrayRelations HashMap ArrayConnectionSource MultiRowSelectNode
arrayConnections HashMap ComputedFieldTableSetSource MultiRowSelectNode
computedFields = JoinTree
joinTree
ApplySortingAndSlicing
(Maybe OrderByExp
baseOrderBy, SelectSlicing
baseSlicing, Maybe DistinctExpr
baseDistinctOn)
(Maybe OrderByExp
nodeOrderBy, SelectSlicing
nodeSlicing, Maybe DistinctExpr
nodeDistinctOn) = SortingAndSlicing -> ApplySortingAndSlicing
applySortingAndSlicing SortingAndSlicing
sortAndSlice
baseSelect :: Select
baseSelect =
Select
S.mkSelect
{ selExtr :: [Extractor]
S.selExtr = [SQLExp -> Maybe ColumnAlias -> Extractor
S.Extractor (Maybe Qual -> SQLExp
S.SEStar Maybe Qual
forall a. Maybe a
Nothing) Maybe ColumnAlias
forall a. Maybe a
Nothing],
selFrom :: Maybe FromExp
S.selFrom = FromExp -> Maybe FromExp
forall a. a -> Maybe a
Just (FromExp -> Maybe FromExp) -> FromExp -> Maybe FromExp
forall a b. (a -> b) -> a -> b
$ [FromItem] -> FromExp
S.FromExp [FromItem
fromItem],
selWhere :: Maybe WhereFrag
S.selWhere = WhereFrag -> Maybe WhereFrag
forall a. a -> Maybe a
Just (WhereFrag -> Maybe WhereFrag) -> WhereFrag -> Maybe WhereFrag
forall a b. (a -> b) -> a -> b
$ BoolExp -> BoolExp -> WhereFrag
injectJoinCond BoolExp
joinCondition BoolExp
whereExp,
selOrderBy :: Maybe OrderByExp
S.selOrderBy = Maybe OrderByExp
baseOrderBy,
selLimit :: Maybe LimitExp
S.selLimit = SQLExp -> LimitExp
S.LimitExp (SQLExp -> LimitExp) -> (Int -> SQLExp) -> Int -> LimitExp
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Int -> SQLExp
S.intToSQLExp (Int -> LimitExp) -> Maybe Int -> Maybe LimitExp
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> SelectSlicing -> Maybe Int
_ssLimit SelectSlicing
baseSlicing,
selOffset :: Maybe OffsetExp
S.selOffset = SQLExp -> OffsetExp
S.OffsetExp (SQLExp -> OffsetExp) -> (Int64 -> SQLExp) -> Int64 -> OffsetExp
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Int64 -> SQLExp
S.int64ToSQLExp (Int64 -> OffsetExp) -> Maybe Int64 -> Maybe OffsetExp
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> SelectSlicing -> Maybe Int64
_ssOffset SelectSlicing
baseSlicing,
selDistinct :: Maybe DistinctExpr
S.selDistinct = Maybe DistinctExpr
baseDistinctOn
}
baseSelectAlias :: TableAlias
baseSelectAlias = TableAlias -> TableAlias
mkBaseTableAlias (Identifier -> TableAlias
forall a. IsIdentifier a => a -> TableAlias
S.toTableAlias Identifier
sourcePrefix)
baseSelectIdentifier :: TableIdentifier
baseSelectIdentifier = TableAlias -> TableIdentifier
S.tableAliasToIdentifier TableAlias
baseSelectAlias
baseFromItem :: FromItem
baseFromItem = Select -> TableAlias -> FromItem
S.mkSelFromItem Select
baseSelect TableAlias
baseSelectAlias
injectJoinCond ::
S.BoolExp ->
S.BoolExp ->
S.WhereFrag
injectJoinCond :: BoolExp -> BoolExp -> WhereFrag
injectJoinCond BoolExp
joinCond BoolExp
whereCond =
BoolExp -> WhereFrag
S.WhereFrag (BoolExp -> WhereFrag) -> BoolExp -> WhereFrag
forall a b. (a -> b) -> a -> b
$ BoolExp -> BoolExp
S.simplifyBoolExp (BoolExp -> BoolExp) -> BoolExp -> BoolExp
forall a b. (a -> b) -> a -> b
$ BinOp -> BoolExp -> BoolExp -> BoolExp
S.BEBin BinOp
S.AndOp BoolExp
joinCond BoolExp
whereCond
leftOuterJoin :: FromItem -> (FromItem, JoinType) -> FromItem
leftOuterJoin FromItem
current (FromItem
new, JoinType
joinType) =
JoinExpr -> FromItem
S.FIJoin
(JoinExpr -> FromItem) -> JoinExpr -> FromItem
forall a b. (a -> b) -> a -> b
$ FromItem -> JoinType -> FromItem -> JoinCond -> JoinExpr
S.JoinExpr FromItem
current JoinType
joinType FromItem
new
(JoinCond -> JoinExpr) -> JoinCond -> JoinExpr
forall a b. (a -> b) -> a -> b
$ BoolExp -> JoinCond
S.JoinOn
(BoolExp -> JoinCond) -> BoolExp -> JoinCond
forall a b. (a -> b) -> a -> b
$ Bool -> BoolExp
S.BELit Bool
True
joinedFrom :: S.FromItem
joinedFrom :: FromItem
joinedFrom =
(FromItem -> (FromItem, JoinType) -> FromItem)
-> FromItem -> [(FromItem, JoinType)] -> FromItem
forall b a. (b -> a -> b) -> b -> [a] -> b
forall (t :: * -> *) b a.
Foldable t =>
(b -> a -> b) -> b -> t a -> b
foldl' FromItem -> (FromItem, JoinType) -> FromItem
leftOuterJoin FromItem
baseFromItem
([(FromItem, JoinType)] -> FromItem)
-> [(FromItem, JoinType)] -> FromItem
forall a b. (a -> b) -> a -> b
$ ((ObjectRelationSource, SelectNode) -> (FromItem, JoinType))
-> [(ObjectRelationSource, SelectNode)] -> [(FromItem, JoinType)]
forall a b. (a -> b) -> [a] -> [b]
map (ObjectRelationSource, SelectNode) -> (FromItem, JoinType)
objectRelationToFromItem (HashMap ObjectRelationSource SelectNode
-> [(ObjectRelationSource, SelectNode)]
forall k v. HashMap k v -> [(k, v)]
HashMap.toList HashMap ObjectRelationSource SelectNode
objectRelations)
[(FromItem, JoinType)]
-> [(FromItem, JoinType)] -> [(FromItem, JoinType)]
forall a. Semigroup a => a -> a -> a
<> ((ArrayRelationSource, MultiRowSelectNode) -> (FromItem, JoinType))
-> [(ArrayRelationSource, MultiRowSelectNode)]
-> [(FromItem, JoinType)]
forall a b. (a -> b) -> [a] -> [b]
map (ArrayRelationSource, MultiRowSelectNode) -> (FromItem, JoinType)
arrayRelationToFromItem (HashMap ArrayRelationSource MultiRowSelectNode
-> [(ArrayRelationSource, MultiRowSelectNode)]
forall k v. HashMap k v -> [(k, v)]
HashMap.toList HashMap ArrayRelationSource MultiRowSelectNode
arrayRelations)
[(FromItem, JoinType)]
-> [(FromItem, JoinType)] -> [(FromItem, JoinType)]
forall a. Semigroup a => a -> a -> a
<> ((ArrayConnectionSource, MultiRowSelectNode)
-> (FromItem, JoinType))
-> [(ArrayConnectionSource, MultiRowSelectNode)]
-> [(FromItem, JoinType)]
forall a b. (a -> b) -> [a] -> [b]
map (ArrayConnectionSource, MultiRowSelectNode) -> (FromItem, JoinType)
arrayConnectionToFromItem (HashMap ArrayConnectionSource MultiRowSelectNode
-> [(ArrayConnectionSource, MultiRowSelectNode)]
forall k v. HashMap k v -> [(k, v)]
HashMap.toList HashMap ArrayConnectionSource MultiRowSelectNode
arrayConnections)
[(FromItem, JoinType)]
-> [(FromItem, JoinType)] -> [(FromItem, JoinType)]
forall a. Semigroup a => a -> a -> a
<> ((ComputedFieldTableSetSource, MultiRowSelectNode)
-> (FromItem, JoinType))
-> [(ComputedFieldTableSetSource, MultiRowSelectNode)]
-> [(FromItem, JoinType)]
forall a b. (a -> b) -> [a] -> [b]
map (ComputedFieldTableSetSource, MultiRowSelectNode)
-> (FromItem, JoinType)
computedFieldToFromItem (HashMap ComputedFieldTableSetSource MultiRowSelectNode
-> [(ComputedFieldTableSetSource, MultiRowSelectNode)]
forall k v. HashMap k v -> [(k, v)]
HashMap.toList HashMap ComputedFieldTableSetSource MultiRowSelectNode
computedFields)
objectRelationToFromItem ::
(ObjectRelationSource, SelectNode) -> (S.FromItem, S.JoinType)
objectRelationToFromItem :: (ObjectRelationSource, SelectNode) -> (FromItem, JoinType)
objectRelationToFromItem (ObjectRelationSource
objectRelationSource, SelectNode
node) =
let ObjectRelationSource
{ _orsRelationMapping :: ObjectRelationSource -> HashMap PGCol PGCol
_orsRelationMapping = HashMap PGCol PGCol
colMapping,
_orsSelectSource :: ObjectRelationSource -> ObjectSelectSource
_orsSelectSource = ObjectSelectSource
objectSelectSource,
_orsNullable :: ObjectRelationSource -> Nullable
_orsNullable = Nullable
nullable
} = ObjectRelationSource
objectRelationSource
alias :: TableAlias
alias = Identifier -> TableAlias
forall a. IsIdentifier a => a -> TableAlias
S.toTableAlias (Identifier -> TableAlias) -> Identifier -> TableAlias
forall a b. (a -> b) -> a -> b
$ ObjectSelectSource -> Identifier
_ossPrefix ObjectSelectSource
objectSelectSource
source :: SelectSource
source = ObjectSelectSource -> SelectSource
objectSelectSourceToSelectSource ObjectSelectSource
objectSelectSource
select :: Select
select = BoolExp -> SelectSource -> SelectNode -> Select
generateSQLSelect (TableIdentifier -> HashMap PGCol PGCol -> BoolExp
mkJoinCond TableIdentifier
baseSelectIdentifier HashMap PGCol PGCol
colMapping) SelectSource
source SelectNode
node
joinType :: JoinType
joinType = case Nullable
nullable of
Nullable
Nullable -> JoinType
S.LeftOuter
Nullable
NotNullable -> JoinType
S.Inner
in (Select -> TableAlias -> FromItem
S.mkLateralFromItem Select
select TableAlias
alias, JoinType
joinType)
arrayRelationToFromItem ::
(ArrayRelationSource, MultiRowSelectNode) -> (S.FromItem, S.JoinType)
arrayRelationToFromItem :: (ArrayRelationSource, MultiRowSelectNode) -> (FromItem, JoinType)
arrayRelationToFromItem (ArrayRelationSource
arrayRelationSource, MultiRowSelectNode
arraySelectNode) =
let ArrayRelationSource TableAlias
_ HashMap PGCol PGCol
colMapping SelectSource
source = ArrayRelationSource
arrayRelationSource
alias :: TableAlias
alias = Identifier -> TableAlias
forall a. IsIdentifier a => a -> TableAlias
S.toTableAlias (Identifier -> TableAlias) -> Identifier -> TableAlias
forall a b. (a -> b) -> a -> b
$ SelectSource -> Identifier
_ssPrefix SelectSource
source
select :: Select
select =
SelectSource -> MultiRowSelectNode -> BoolExp -> Select
generateSQLSelectFromArrayNode SelectSource
source MultiRowSelectNode
arraySelectNode
(BoolExp -> Select) -> BoolExp -> Select
forall a b. (a -> b) -> a -> b
$ TableIdentifier -> HashMap PGCol PGCol -> BoolExp
mkJoinCond TableIdentifier
baseSelectIdentifier HashMap PGCol PGCol
colMapping
in (Select -> TableAlias -> FromItem
S.mkLateralFromItem Select
select TableAlias
alias, JoinType
S.LeftOuter)
arrayConnectionToFromItem ::
(ArrayConnectionSource, MultiRowSelectNode) -> (S.FromItem, S.JoinType)
arrayConnectionToFromItem :: (ArrayConnectionSource, MultiRowSelectNode) -> (FromItem, JoinType)
arrayConnectionToFromItem (ArrayConnectionSource
arrayConnectionSource, MultiRowSelectNode
arraySelectNode) =
let selectWith :: SelectWithG Select
selectWith = TableAlias
-> ArrayConnectionSource
-> MultiRowSelectNode
-> SelectWithG Select
connectionToSelectWith TableAlias
baseSelectAlias ArrayConnectionSource
arrayConnectionSource MultiRowSelectNode
arraySelectNode
alias :: TableAlias
alias = Identifier -> TableAlias
forall a. IsIdentifier a => a -> TableAlias
S.toTableAlias (Identifier -> TableAlias) -> Identifier -> TableAlias
forall a b. (a -> b) -> a -> b
$ SelectSource -> Identifier
_ssPrefix (SelectSource -> Identifier) -> SelectSource -> Identifier
forall a b. (a -> b) -> a -> b
$ ArrayConnectionSource -> SelectSource
_acsSource ArrayConnectionSource
arrayConnectionSource
in (Lateral -> SelectWithG Select -> TableAlias -> FromItem
S.FISelectWith (Bool -> Lateral
S.Lateral Bool
True) SelectWithG Select
selectWith TableAlias
alias, JoinType
S.LeftOuter)
computedFieldToFromItem ::
(ComputedFieldTableSetSource, MultiRowSelectNode) -> (S.FromItem, S.JoinType)
computedFieldToFromItem :: (ComputedFieldTableSetSource, MultiRowSelectNode)
-> (FromItem, JoinType)
computedFieldToFromItem (ComputedFieldTableSetSource
computedFieldTableSource, MultiRowSelectNode
node) =
let ComputedFieldTableSetSource FieldName
_ SelectSource
source = ComputedFieldTableSetSource
computedFieldTableSource
internalSelect :: Select
internalSelect = BoolExp -> SelectSource -> SelectNode -> Select
generateSQLSelect (Bool -> BoolExp
S.BELit Bool
True) SelectSource
source (SelectNode -> Select) -> SelectNode -> Select
forall a b. (a -> b) -> a -> b
$ MultiRowSelectNode -> SelectNode
_mrsnSelectNode MultiRowSelectNode
node
alias :: TableAlias
alias = Identifier -> TableAlias
forall a. IsIdentifier a => a -> TableAlias
S.toTableAlias (Identifier -> TableAlias) -> Identifier -> TableAlias
forall a b. (a -> b) -> a -> b
$ SelectSource -> Identifier
_ssPrefix SelectSource
source
select :: Select
select =
Select
S.mkSelect
{ selExtr :: [Extractor]
S.selExtr = MultiRowSelectNode -> [Extractor]
_mrsnTopExtractors MultiRowSelectNode
node,
selFrom :: Maybe FromExp
S.selFrom = FromExp -> Maybe FromExp
forall a. a -> Maybe a
Just (FromExp -> Maybe FromExp) -> FromExp -> Maybe FromExp
forall a b. (a -> b) -> a -> b
$ [FromItem] -> FromExp
S.FromExp [Select -> TableAlias -> FromItem
S.mkSelFromItem Select
internalSelect TableAlias
alias]
}
in (Select -> TableAlias -> FromItem
S.mkLateralFromItem Select
select TableAlias
alias, JoinType
S.LeftOuter)
generateSQLSelectFromArrayNode ::
SelectSource ->
MultiRowSelectNode ->
S.BoolExp ->
S.Select
generateSQLSelectFromArrayNode :: SelectSource -> MultiRowSelectNode -> BoolExp -> Select
generateSQLSelectFromArrayNode SelectSource
selectSource (MultiRowSelectNode [Extractor]
topExtractors SelectNode
selectNode) BoolExp
joinCondition =
Select
S.mkSelect
{ selExtr :: [Extractor]
S.selExtr = [Extractor]
topExtractors,
selFrom :: Maybe FromExp
S.selFrom =
FromExp -> Maybe FromExp
forall a. a -> Maybe a
Just
(FromExp -> Maybe FromExp) -> FromExp -> Maybe FromExp
forall a b. (a -> b) -> a -> b
$ [FromItem] -> FromExp
S.FromExp
[ Select -> TableAlias -> FromItem
S.mkSelFromItem
(BoolExp -> SelectSource -> SelectNode -> Select
generateSQLSelect BoolExp
joinCondition SelectSource
selectSource SelectNode
selectNode)
(TableAlias -> FromItem) -> TableAlias -> FromItem
forall a b. (a -> b) -> a -> b
$ Identifier -> TableAlias
forall a. IsIdentifier a => a -> TableAlias
S.toTableAlias
(Identifier -> TableAlias) -> Identifier -> TableAlias
forall a b. (a -> b) -> a -> b
$ SelectSource -> Identifier
_ssPrefix SelectSource
selectSource
]
}
mkJoinCond :: S.TableIdentifier -> HashMap PGCol PGCol -> S.BoolExp
mkJoinCond :: TableIdentifier -> HashMap PGCol PGCol -> BoolExp
mkJoinCond TableIdentifier
baseTablepfx HashMap PGCol PGCol
colMapn =
(BoolExp -> BoolExp -> BoolExp) -> BoolExp -> [BoolExp] -> BoolExp
forall b a. (b -> a -> b) -> b -> [a] -> b
forall (t :: * -> *) b a.
Foldable t =>
(b -> a -> b) -> b -> t a -> b
foldl' (BinOp -> BoolExp -> BoolExp -> BoolExp
S.BEBin BinOp
S.AndOp) (Bool -> BoolExp
S.BELit Bool
True)
([BoolExp] -> BoolExp) -> [BoolExp] -> BoolExp
forall a b. (a -> b) -> a -> b
$ (((PGCol, PGCol) -> BoolExp) -> [(PGCol, PGCol)] -> [BoolExp])
-> [(PGCol, PGCol)] -> ((PGCol, PGCol) -> BoolExp) -> [BoolExp]
forall a b c. (a -> b -> c) -> b -> a -> c
flip ((PGCol, PGCol) -> BoolExp) -> [(PGCol, PGCol)] -> [BoolExp]
forall a b. (a -> b) -> [a] -> [b]
map (HashMap PGCol PGCol -> [(PGCol, PGCol)]
forall k v. HashMap k v -> [(k, v)]
HashMap.toList HashMap PGCol PGCol
colMapn)
(((PGCol, PGCol) -> BoolExp) -> [BoolExp])
-> ((PGCol, PGCol) -> BoolExp) -> [BoolExp]
forall a b. (a -> b) -> a -> b
$ \(PGCol
lCol, PGCol
rCol) ->
CompareOp -> SQLExp -> SQLExp -> BoolExp
S.BECompare CompareOp
S.SEQ (TableIdentifier -> PGCol -> SQLExp
forall b. IsIdentifier b => TableIdentifier -> b -> SQLExp
S.mkQIdenExp TableIdentifier
baseTablepfx PGCol
lCol) (PGCol -> SQLExp
forall a. IsIdentifier a => a -> SQLExp
S.mkSIdenExp PGCol
rCol)
connectionToSelectWith ::
S.TableAlias ->
ArrayConnectionSource ->
MultiRowSelectNode ->
S.SelectWithG S.Select
connectionToSelectWith :: TableAlias
-> ArrayConnectionSource
-> MultiRowSelectNode
-> SelectWithG Select
connectionToSelectWith TableAlias
rootSelectAlias ArrayConnectionSource
arrayConnectionSource MultiRowSelectNode
arraySelectNode =
let extractionSelect :: Select
extractionSelect =
Select
S.mkSelect
{ selExtr :: [Extractor]
S.selExtr = [Extractor]
topExtractors,
selFrom :: Maybe FromExp
S.selFrom = FromExp -> Maybe FromExp
forall a. a -> Maybe a
Just (FromExp -> Maybe FromExp) -> FromExp -> Maybe FromExp
forall a b. (a -> b) -> a -> b
$ [FromItem] -> FromExp
S.FromExp [TableIdentifier -> FromItem
S.FIIdentifier TableIdentifier
finalSelectIdentifier]
}
in [(TableAlias, Select)] -> Select -> SelectWithG Select
forall statement.
[(TableAlias, statement)] -> Select -> SelectWithG statement
S.SelectWith [(TableAlias, Select)]
fromBaseSelections Select
extractionSelect
where
ArrayConnectionSource TableAlias
_ HashMap PGCol PGCol
columnMapping Maybe BoolExp
maybeSplit Maybe ConnectionSlice
maybeSlice SelectSource
selectSource =
ArrayConnectionSource
arrayConnectionSource
MultiRowSelectNode [Extractor]
topExtractors SelectNode
selectNode = MultiRowSelectNode
arraySelectNode
rootSelectIdentifier :: TableIdentifier
rootSelectIdentifier = TableAlias -> TableIdentifier
S.tableAliasToIdentifier TableAlias
rootSelectAlias
baseSelectAlias :: TableAlias
baseSelectAlias = Text -> TableAlias
S.mkTableAlias Text
"__base_select"
baseSelectIdentifier :: TableIdentifier
baseSelectIdentifier = TableAlias -> TableIdentifier
S.tableAliasToIdentifier TableAlias
baseSelectAlias
splitSelectAlias :: TableAlias
splitSelectAlias = Text -> TableAlias
S.mkTableAlias Text
"__split_select"
splitSelectIdentifier :: TableIdentifier
splitSelectIdentifier = TableAlias -> TableIdentifier
S.tableAliasToIdentifier TableAlias
splitSelectAlias
sliceSelectAlias :: TableAlias
sliceSelectAlias = Text -> TableAlias
S.mkTableAlias Text
"__slice_select"
sliceSelectIdentifier :: TableIdentifier
sliceSelectIdentifier = TableAlias -> TableIdentifier
S.tableAliasToIdentifier TableAlias
sliceSelectAlias
finalSelectAlias :: TableAlias
finalSelectAlias = Text -> TableAlias
S.mkTableAlias Text
"__final_select"
finalSelectIdentifier :: TableIdentifier
finalSelectIdentifier = TableAlias -> TableIdentifier
S.tableAliasToIdentifier TableAlias
finalSelectAlias
rowNumberIdentifier :: Identifier
rowNumberIdentifier = Text -> Identifier
Identifier Text
"__row_number"
rowNumberExp :: SQLExp
rowNumberExp = Text -> SQLExp
S.SEUnsafe Text
"(row_number() over (partition by 1))"
startRowNumberIdentifier :: Identifier
startRowNumberIdentifier = Text -> Identifier
Identifier Text
"__start_row_number"
endRowNumberIdentifier :: Identifier
endRowNumberIdentifier = Text -> Identifier
Identifier Text
"__end_row_number"
startCursorExp :: SQLExp
startCursorExp = SQLExp -> SQLExp
mkFirstElementExp (SQLExp -> SQLExp) -> SQLExp -> SQLExp
forall a b. (a -> b) -> a -> b
$ Identifier -> SQLExp
S.SEIdentifier Identifier
cursorIdentifier
endCursorExp :: SQLExp
endCursorExp = SQLExp -> SQLExp
mkLastElementExp (SQLExp -> SQLExp) -> SQLExp -> SQLExp
forall a b. (a -> b) -> a -> b
$ Identifier -> SQLExp
S.SEIdentifier Identifier
cursorIdentifier
startRowNumberExp :: SQLExp
startRowNumberExp = SQLExp -> SQLExp
mkFirstElementExp (SQLExp -> SQLExp) -> SQLExp -> SQLExp
forall a b. (a -> b) -> a -> b
$ Identifier -> SQLExp
S.SEIdentifier Identifier
rowNumberIdentifier
endRowNumberExp :: SQLExp
endRowNumberExp = SQLExp -> SQLExp
mkLastElementExp (SQLExp -> SQLExp) -> SQLExp -> SQLExp
forall a b. (a -> b) -> a -> b
$ Identifier -> SQLExp
S.SEIdentifier Identifier
rowNumberIdentifier
fromBaseSelections :: [(TableAlias, Select)]
fromBaseSelections =
let joinCond :: BoolExp
joinCond = TableIdentifier -> HashMap PGCol PGCol -> BoolExp
mkJoinCond TableIdentifier
rootSelectIdentifier HashMap PGCol PGCol
columnMapping
baseSelectFrom :: FromItem
baseSelectFrom =
Select -> TableAlias -> FromItem
S.mkSelFromItem
(BoolExp -> SelectSource -> SelectNode -> Select
generateSQLSelect BoolExp
joinCond SelectSource
selectSource SelectNode
selectNode)
(TableAlias -> FromItem) -> TableAlias -> FromItem
forall a b. (a -> b) -> a -> b
$ Identifier -> TableAlias
forall a. IsIdentifier a => a -> TableAlias
S.toTableAlias
(Identifier -> TableAlias) -> Identifier -> TableAlias
forall a b. (a -> b) -> a -> b
$ SelectSource -> Identifier
_ssPrefix SelectSource
selectSource
select :: Select
select =
Select
S.mkSelect
{ selExtr :: [Extractor]
S.selExtr =
[ Extractor
S.selectStar,
SQLExp -> Maybe ColumnAlias -> Extractor
S.Extractor SQLExp
rowNumberExp (Maybe ColumnAlias -> Extractor) -> Maybe ColumnAlias -> Extractor
forall a b. (a -> b) -> a -> b
$ ColumnAlias -> Maybe ColumnAlias
forall a. a -> Maybe a
Just (ColumnAlias -> Maybe ColumnAlias)
-> ColumnAlias -> Maybe ColumnAlias
forall a b. (a -> b) -> a -> b
$ Identifier -> ColumnAlias
forall a. IsIdentifier a => a -> ColumnAlias
S.toColumnAlias Identifier
rowNumberIdentifier
],
selFrom :: Maybe FromExp
S.selFrom = FromExp -> Maybe FromExp
forall a. a -> Maybe a
Just (FromExp -> Maybe FromExp) -> FromExp -> Maybe FromExp
forall a b. (a -> b) -> a -> b
$ [FromItem] -> FromExp
S.FromExp [FromItem
baseSelectFrom]
}
in (TableAlias
baseSelectAlias, Select
select) (TableAlias, Select)
-> [(TableAlias, Select)] -> [(TableAlias, Select)]
forall a. a -> [a] -> [a]
: [(TableAlias, Select)]
fromSplitSelection
mkStarSelect :: TableIdentifier -> Select
mkStarSelect TableIdentifier
fromIdentifier =
Select
S.mkSelect
{ selExtr :: [Extractor]
S.selExtr = [Extractor
S.selectStar],
selFrom :: Maybe FromExp
S.selFrom = FromExp -> Maybe FromExp
forall a. a -> Maybe a
Just (FromExp -> Maybe FromExp) -> FromExp -> Maybe FromExp
forall a b. (a -> b) -> a -> b
$ [FromItem] -> FromExp
S.FromExp [TableIdentifier -> FromItem
S.FIIdentifier TableIdentifier
fromIdentifier]
}
fromSplitSelection :: [(TableAlias, Select)]
fromSplitSelection = case Maybe BoolExp
maybeSplit of
Maybe BoolExp
Nothing -> TableIdentifier -> [(TableAlias, Select)]
fromSliceSelection TableIdentifier
baseSelectIdentifier
Just BoolExp
splitBool ->
let select :: Select
select =
(TableIdentifier -> Select
mkStarSelect TableIdentifier
baseSelectIdentifier) {selWhere :: Maybe WhereFrag
S.selWhere = WhereFrag -> Maybe WhereFrag
forall a. a -> Maybe a
Just (WhereFrag -> Maybe WhereFrag) -> WhereFrag -> Maybe WhereFrag
forall a b. (a -> b) -> a -> b
$ BoolExp -> WhereFrag
S.WhereFrag BoolExp
splitBool}
in (TableAlias
splitSelectAlias, Select
select) (TableAlias, Select)
-> [(TableAlias, Select)] -> [(TableAlias, Select)]
forall a. a -> [a] -> [a]
: TableIdentifier -> [(TableAlias, Select)]
fromSliceSelection TableIdentifier
splitSelectIdentifier
fromSliceSelection :: TableIdentifier -> [(TableAlias, Select)]
fromSliceSelection TableIdentifier
prevSelect = case Maybe ConnectionSlice
maybeSlice of
Maybe ConnectionSlice
Nothing -> TableIdentifier -> [(TableAlias, Select)]
fromFinalSelect TableIdentifier
prevSelect
Just ConnectionSlice
slice ->
let select :: Select
select = case ConnectionSlice
slice of
SliceFirst Int
limit ->
(TableIdentifier -> Select
mkStarSelect TableIdentifier
prevSelect)
{ selLimit :: Maybe LimitExp
S.selLimit = (LimitExp -> Maybe LimitExp
forall a. a -> Maybe a
Just (LimitExp -> Maybe LimitExp)
-> (Int -> LimitExp) -> Int -> Maybe LimitExp
forall b c a. (b -> c) -> (a -> b) -> a -> c
. SQLExp -> LimitExp
S.LimitExp (SQLExp -> LimitExp) -> (Int -> SQLExp) -> Int -> LimitExp
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Int -> SQLExp
S.intToSQLExp) Int
limit
}
SliceLast Int
limit ->
let mkRowNumberOrderBy :: OrderType -> OrderByExp
mkRowNumberOrderBy OrderType
obType =
let orderByItem :: OrderByItem
orderByItem =
SQLExp -> Maybe OrderType -> Maybe NullsOrder -> OrderByItem
S.OrderByItem (Identifier -> SQLExp
S.SEIdentifier Identifier
rowNumberIdentifier) (OrderType -> Maybe OrderType
forall a. a -> Maybe a
Just OrderType
obType) Maybe NullsOrder
forall a. Maybe a
Nothing
in NonEmpty OrderByItem -> OrderByExp
S.OrderByExp (NonEmpty OrderByItem -> OrderByExp)
-> NonEmpty OrderByItem -> OrderByExp
forall a b. (a -> b) -> a -> b
$ OrderByItem
orderByItem OrderByItem -> [OrderByItem] -> NonEmpty OrderByItem
forall a. a -> [a] -> NonEmpty a
NE.:| []
sliceLastSelect :: Select
sliceLastSelect =
(TableIdentifier -> Select
mkStarSelect TableIdentifier
prevSelect)
{ selLimit :: Maybe LimitExp
S.selLimit = (LimitExp -> Maybe LimitExp
forall a. a -> Maybe a
Just (LimitExp -> Maybe LimitExp)
-> (Int -> LimitExp) -> Int -> Maybe LimitExp
forall b c a. (b -> c) -> (a -> b) -> a -> c
. SQLExp -> LimitExp
S.LimitExp (SQLExp -> LimitExp) -> (Int -> SQLExp) -> Int -> LimitExp
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Int -> SQLExp
S.intToSQLExp) Int
limit,
selOrderBy :: Maybe OrderByExp
S.selOrderBy = OrderByExp -> Maybe OrderByExp
forall a. a -> Maybe a
Just (OrderByExp -> Maybe OrderByExp) -> OrderByExp -> Maybe OrderByExp
forall a b. (a -> b) -> a -> b
$ OrderType -> OrderByExp
mkRowNumberOrderBy OrderType
S.OTDesc
}
sliceLastSelectFrom :: FromItem
sliceLastSelectFrom =
Select -> TableAlias -> FromItem
S.mkSelFromItem Select
sliceLastSelect (TableAlias -> FromItem) -> TableAlias -> FromItem
forall a b. (a -> b) -> a -> b
$ TableAlias
sliceSelectAlias
in Select
S.mkSelect
{ selExtr :: [Extractor]
S.selExtr = [Extractor
S.selectStar],
selFrom :: Maybe FromExp
S.selFrom = FromExp -> Maybe FromExp
forall a. a -> Maybe a
Just (FromExp -> Maybe FromExp) -> FromExp -> Maybe FromExp
forall a b. (a -> b) -> a -> b
$ [FromItem] -> FromExp
S.FromExp [FromItem
sliceLastSelectFrom],
selOrderBy :: Maybe OrderByExp
S.selOrderBy = OrderByExp -> Maybe OrderByExp
forall a. a -> Maybe a
Just (OrderByExp -> Maybe OrderByExp) -> OrderByExp -> Maybe OrderByExp
forall a b. (a -> b) -> a -> b
$ OrderType -> OrderByExp
mkRowNumberOrderBy OrderType
S.OTAsc
}
in (TableAlias
sliceSelectAlias, Select
select) (TableAlias, Select)
-> [(TableAlias, Select)] -> [(TableAlias, Select)]
forall a. a -> [a] -> [a]
: TableIdentifier -> [(TableAlias, Select)]
fromFinalSelect TableIdentifier
sliceSelectIdentifier
fromFinalSelect :: TableIdentifier -> [(TableAlias, Select)]
fromFinalSelect TableIdentifier
prevSelect =
let select :: Select
select = TableIdentifier -> Select
mkStarSelect TableIdentifier
prevSelect
in (TableAlias
finalSelectAlias, Select
select) (TableAlias, Select)
-> [(TableAlias, Select)] -> [(TableAlias, Select)]
forall a. a -> [a] -> [a]
: [(TableAlias, Select)]
fromCursorSelection
fromCursorSelection :: [(TableAlias, Select)]
fromCursorSelection =
let extrs :: [Extractor]
extrs =
[ SQLExp -> Maybe ColumnAlias -> Extractor
S.Extractor SQLExp
startCursorExp (Maybe ColumnAlias -> Extractor) -> Maybe ColumnAlias -> Extractor
forall a b. (a -> b) -> a -> b
$ ColumnAlias -> Maybe ColumnAlias
forall a. a -> Maybe a
Just (ColumnAlias -> Maybe ColumnAlias)
-> ColumnAlias -> Maybe ColumnAlias
forall a b. (a -> b) -> a -> b
$ Identifier -> ColumnAlias
forall a. IsIdentifier a => a -> ColumnAlias
S.toColumnAlias Identifier
startCursorIdentifier,
SQLExp -> Maybe ColumnAlias -> Extractor
S.Extractor SQLExp
endCursorExp (Maybe ColumnAlias -> Extractor) -> Maybe ColumnAlias -> Extractor
forall a b. (a -> b) -> a -> b
$ ColumnAlias -> Maybe ColumnAlias
forall a. a -> Maybe a
Just (ColumnAlias -> Maybe ColumnAlias)
-> ColumnAlias -> Maybe ColumnAlias
forall a b. (a -> b) -> a -> b
$ Identifier -> ColumnAlias
forall a. IsIdentifier a => a -> ColumnAlias
S.toColumnAlias Identifier
endCursorIdentifier,
SQLExp -> Maybe ColumnAlias -> Extractor
S.Extractor SQLExp
startRowNumberExp (Maybe ColumnAlias -> Extractor) -> Maybe ColumnAlias -> Extractor
forall a b. (a -> b) -> a -> b
$ ColumnAlias -> Maybe ColumnAlias
forall a. a -> Maybe a
Just (ColumnAlias -> Maybe ColumnAlias)
-> ColumnAlias -> Maybe ColumnAlias
forall a b. (a -> b) -> a -> b
$ Identifier -> ColumnAlias
forall a. IsIdentifier a => a -> ColumnAlias
S.toColumnAlias Identifier
startRowNumberIdentifier,
SQLExp -> Maybe ColumnAlias -> Extractor
S.Extractor SQLExp
endRowNumberExp (Maybe ColumnAlias -> Extractor) -> Maybe ColumnAlias -> Extractor
forall a b. (a -> b) -> a -> b
$ ColumnAlias -> Maybe ColumnAlias
forall a. a -> Maybe a
Just (ColumnAlias -> Maybe ColumnAlias)
-> ColumnAlias -> Maybe ColumnAlias
forall a b. (a -> b) -> a -> b
$ Identifier -> ColumnAlias
forall a. IsIdentifier a => a -> ColumnAlias
S.toColumnAlias Identifier
endRowNumberIdentifier
]
select :: Select
select =
Select
S.mkSelect
{ selExtr :: [Extractor]
S.selExtr = [Extractor]
extrs,
selFrom :: Maybe FromExp
S.selFrom = FromExp -> Maybe FromExp
forall a. a -> Maybe a
Just (FromExp -> Maybe FromExp) -> FromExp -> Maybe FromExp
forall a b. (a -> b) -> a -> b
$ [FromItem] -> FromExp
S.FromExp [TableIdentifier -> FromItem
S.FIIdentifier TableIdentifier
finalSelectIdentifier]
}
in (TableAlias
cursorsSelectAlias, Select
select) (TableAlias, Select)
-> [(TableAlias, Select)] -> [(TableAlias, Select)]
forall a. a -> [a] -> [a]
: [(TableAlias, Select)]
fromPageInfoSelection
fromPageInfoSelection :: [(TableAlias, Select)]
fromPageInfoSelection =
let hasPrevPage :: SQLExp
hasPrevPage =
BoolExp -> SQLExp
S.SEBool
(BoolExp -> SQLExp) -> BoolExp -> SQLExp
forall a b. (a -> b) -> a -> b
$ FromItem -> BoolExp -> BoolExp
S.mkExists (TableIdentifier -> FromItem
S.FIIdentifier TableIdentifier
baseSelectIdentifier)
(BoolExp -> BoolExp) -> BoolExp -> BoolExp
forall a b. (a -> b) -> a -> b
$ CompareOp -> SQLExp -> SQLExp -> BoolExp
S.BECompare CompareOp
S.SLT (Identifier -> SQLExp
S.SEIdentifier Identifier
rowNumberIdentifier)
(SQLExp -> BoolExp) -> SQLExp -> BoolExp
forall a b. (a -> b) -> a -> b
$ Select -> SQLExp
S.SESelect
(Select -> SQLExp) -> Select -> SQLExp
forall a b. (a -> b) -> a -> b
$ Select
S.mkSelect
{ selFrom :: Maybe FromExp
S.selFrom = FromExp -> Maybe FromExp
forall a. a -> Maybe a
Just (FromExp -> Maybe FromExp) -> FromExp -> Maybe FromExp
forall a b. (a -> b) -> a -> b
$ [FromItem] -> FromExp
S.FromExp [TableIdentifier -> FromItem
S.FIIdentifier TableIdentifier
cursorsSelectAliasIdentifier],
selExtr :: [Extractor]
S.selExtr = [SQLExp -> Maybe ColumnAlias -> Extractor
S.Extractor (Identifier -> SQLExp
S.SEIdentifier Identifier
startRowNumberIdentifier) Maybe ColumnAlias
forall a. Maybe a
Nothing]
}
hasNextPage :: SQLExp
hasNextPage =
BoolExp -> SQLExp
S.SEBool
(BoolExp -> SQLExp) -> BoolExp -> SQLExp
forall a b. (a -> b) -> a -> b
$ FromItem -> BoolExp -> BoolExp
S.mkExists (TableIdentifier -> FromItem
S.FIIdentifier TableIdentifier
baseSelectIdentifier)
(BoolExp -> BoolExp) -> BoolExp -> BoolExp
forall a b. (a -> b) -> a -> b
$ CompareOp -> SQLExp -> SQLExp -> BoolExp
S.BECompare CompareOp
S.SGT (Identifier -> SQLExp
S.SEIdentifier Identifier
rowNumberIdentifier)
(SQLExp -> BoolExp) -> SQLExp -> BoolExp
forall a b. (a -> b) -> a -> b
$ Select -> SQLExp
S.SESelect
(Select -> SQLExp) -> Select -> SQLExp
forall a b. (a -> b) -> a -> b
$ Select
S.mkSelect
{ selFrom :: Maybe FromExp
S.selFrom = FromExp -> Maybe FromExp
forall a. a -> Maybe a
Just (FromExp -> Maybe FromExp) -> FromExp -> Maybe FromExp
forall a b. (a -> b) -> a -> b
$ [FromItem] -> FromExp
S.FromExp [TableIdentifier -> FromItem
S.FIIdentifier TableIdentifier
cursorsSelectAliasIdentifier],
selExtr :: [Extractor]
S.selExtr = [SQLExp -> Maybe ColumnAlias -> Extractor
S.Extractor (Identifier -> SQLExp
S.SEIdentifier Identifier
endRowNumberIdentifier) Maybe ColumnAlias
forall a. Maybe a
Nothing]
}
select :: Select
select =
Select
S.mkSelect
{ selExtr :: [Extractor]
S.selExtr =
[ SQLExp -> Maybe ColumnAlias -> Extractor
S.Extractor SQLExp
hasPrevPage (Maybe ColumnAlias -> Extractor) -> Maybe ColumnAlias -> Extractor
forall a b. (a -> b) -> a -> b
$ ColumnAlias -> Maybe ColumnAlias
forall a. a -> Maybe a
Just (ColumnAlias -> Maybe ColumnAlias)
-> ColumnAlias -> Maybe ColumnAlias
forall a b. (a -> b) -> a -> b
$ Identifier -> ColumnAlias
forall a. IsIdentifier a => a -> ColumnAlias
S.toColumnAlias Identifier
hasPreviousPageIdentifier,
SQLExp -> Maybe ColumnAlias -> Extractor
S.Extractor SQLExp
hasNextPage (Maybe ColumnAlias -> Extractor) -> Maybe ColumnAlias -> Extractor
forall a b. (a -> b) -> a -> b
$ ColumnAlias -> Maybe ColumnAlias
forall a. a -> Maybe a
Just (ColumnAlias -> Maybe ColumnAlias)
-> ColumnAlias -> Maybe ColumnAlias
forall a b. (a -> b) -> a -> b
$ Identifier -> ColumnAlias
forall a. IsIdentifier a => a -> ColumnAlias
S.toColumnAlias Identifier
hasNextPageIdentifier
]
}
in (TableAlias, Select) -> [(TableAlias, Select)]
forall a. a -> [a]
forall (f :: * -> *) a. Applicative f => a -> f a
pure (TableAlias
pageInfoSelectAlias, Select
select)