module Hasura.Backends.Postgres.Translate.Select.Internal.OrderBy
( processOrderByItems,
)
where
import Control.Lens ((^?))
import Data.HashMap.Strict qualified as HM
import Data.List.NonEmpty qualified as NE
import Hasura.Backends.Postgres.SQL.DML qualified as S
import Hasura.Backends.Postgres.SQL.Types
( Identifier,
IsIdentifier (toIdentifier),
PGCol (..),
)
import Hasura.Backends.Postgres.Translate.BoolExp (toSQLBoolExp)
import Hasura.Backends.Postgres.Translate.Select.Internal.Aliases
( mkAggregateOrderByAlias,
mkAnnOrderByAlias,
mkArrayRelationAlias,
mkArrayRelationSourcePrefix,
mkBaseTableAlias,
mkBaseTableColumnAlias,
mkComputedFieldTableAlias,
mkObjectRelationTableAlias,
mkOrderByFieldName,
)
import Hasura.Backends.Postgres.Translate.Select.Internal.Extractor
( aggregateFieldsToExtractorExps,
mkAggregateOrderByExtractorAndFields,
)
import Hasura.Backends.Postgres.Translate.Select.Internal.Helpers
( fromTableRowArgs,
functionToIdentifier,
selectFromToFromItem,
)
import Hasura.Backends.Postgres.Translate.Select.Internal.JoinTree
( withWriteArrayRelation,
withWriteComputedFieldTableSet,
withWriteObjectRelation,
)
import Hasura.Backends.Postgres.Translate.Types
import Hasura.GraphQL.Schema.Options qualified as Options
import Hasura.Prelude
import Hasura.RQL.IR.OrderBy
( OrderByItemG (OrderByItemG, obiColumn),
)
import Hasura.RQL.IR.Select
import Hasura.RQL.Types.Backend
import Hasura.RQL.Types.Column
import Hasura.RQL.Types.Common
import Hasura.RQL.Types.ComputedField
import Hasura.RQL.Types.Relationships.Local
import Hasura.SQL.Backend
processOrderByItems ::
forall pgKind m.
( MonadReader Options.StringifyNumbers m,
MonadWriter JoinTree m,
Backend ('Postgres pgKind)
) =>
Identifier ->
FieldName ->
SimilarArrayFields ->
Maybe (NE.NonEmpty PGCol) ->
Maybe (NE.NonEmpty (AnnotatedOrderByItem ('Postgres pgKind))) ->
m
( [(S.ColumnAlias, S.SQLExp)],
SelectSorting,
Maybe S.SQLExp
)
processOrderByItems :: Identifier
-> FieldName
-> SimilarArrayFields
-> Maybe (NonEmpty PGCol)
-> Maybe (NonEmpty (AnnotatedOrderByItem ('Postgres pgKind)))
-> m ([(ColumnAlias, SQLExp)], SelectSorting, Maybe SQLExp)
processOrderByItems Identifier
sourcePrefix' FieldName
fieldAlias' SimilarArrayFields
similarArrayFields Maybe (NonEmpty PGCol)
distOnCols = \case
Maybe (NonEmpty (AnnotatedOrderByItem ('Postgres pgKind)))
Nothing -> ([(ColumnAlias, SQLExp)], SelectSorting, Maybe SQLExp)
-> m ([(ColumnAlias, SQLExp)], SelectSorting, Maybe SQLExp)
forall (f :: * -> *) a. Applicative f => a -> f a
pure ([], Maybe DistinctExpr -> SelectSorting
NoSorting (Maybe DistinctExpr -> SelectSorting)
-> Maybe DistinctExpr -> SelectSorting
forall a b. (a -> b) -> a -> b
$ NonEmpty PGCol -> DistinctExpr
applyDistinctOnAtBase (NonEmpty PGCol -> DistinctExpr)
-> Maybe (NonEmpty PGCol) -> Maybe DistinctExpr
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Maybe (NonEmpty PGCol)
distOnCols, Maybe SQLExp
forall a. Maybe a
Nothing)
Just NonEmpty (AnnotatedOrderByItem ('Postgres pgKind))
orderByItems -> do
NonEmpty
(OrderByItemG
('Postgres pgKind)
(AnnotatedOrderByElement ('Postgres pgKind) SQLExp,
(ColumnAlias, SQLExp)))
orderByItemExps <- NonEmpty (AnnotatedOrderByItemG ('Postgres pgKind) SQLExp)
-> (AnnotatedOrderByItemG ('Postgres pgKind) SQLExp
-> m (OrderByItemG
('Postgres pgKind)
(AnnotatedOrderByElement ('Postgres pgKind) SQLExp,
(ColumnAlias, SQLExp))))
-> m (NonEmpty
(OrderByItemG
('Postgres pgKind)
(AnnotatedOrderByElement ('Postgres pgKind) SQLExp,
(ColumnAlias, SQLExp))))
forall (t :: * -> *) (m :: * -> *) a b.
(Traversable t, Monad m) =>
t a -> (a -> m b) -> m (t b)
forM NonEmpty (AnnotatedOrderByItem ('Postgres pgKind))
NonEmpty (AnnotatedOrderByItemG ('Postgres pgKind) SQLExp)
orderByItems AnnotatedOrderByItem ('Postgres pgKind)
-> m (OrderByItemG
('Postgres pgKind)
(AnnotatedOrderByElement
('Postgres pgKind) (SQLExpression ('Postgres pgKind)),
(ColumnAlias, SQLExpression ('Postgres pgKind))))
AnnotatedOrderByItemG ('Postgres pgKind) SQLExp
-> m (OrderByItemG
('Postgres pgKind)
(AnnotatedOrderByElement ('Postgres pgKind) SQLExp,
(ColumnAlias, SQLExp)))
processAnnOrderByItem
let (SelectSorting
sorting, [(ColumnAlias, SQLExp)]
distinctOnExtractors) = NonEmpty
(OrderByItemG
('Postgres pgKind)
(AnnotatedOrderByElement
('Postgres pgKind) (SQLExpression ('Postgres pgKind)),
(ColumnAlias, SQLExpression ('Postgres pgKind))))
-> (SelectSorting,
[(ColumnAlias, SQLExpression ('Postgres pgKind))])
generateSorting NonEmpty
(OrderByItemG
('Postgres pgKind)
(AnnotatedOrderByElement
('Postgres pgKind) (SQLExpression ('Postgres pgKind)),
(ColumnAlias, SQLExpression ('Postgres pgKind))))
NonEmpty
(OrderByItemG
('Postgres pgKind)
(AnnotatedOrderByElement ('Postgres pgKind) SQLExp,
(ColumnAlias, SQLExp)))
orderByItemExps
orderByExtractors :: [(ColumnAlias, SQLExp)]
orderByExtractors = [[(ColumnAlias, SQLExp)]] -> [(ColumnAlias, SQLExp)]
forall (t :: * -> *) a. Foldable t => t [a] -> [a]
concat ([[(ColumnAlias, SQLExp)]] -> [(ColumnAlias, SQLExp)])
-> [[(ColumnAlias, SQLExp)]] -> [(ColumnAlias, SQLExp)]
forall a b. (a -> b) -> a -> b
$ NonEmpty [(ColumnAlias, SQLExp)] -> [[(ColumnAlias, SQLExp)]]
forall (t :: * -> *) a. Foldable t => t a -> [a]
toList (NonEmpty [(ColumnAlias, SQLExp)] -> [[(ColumnAlias, SQLExp)]])
-> NonEmpty [(ColumnAlias, SQLExp)] -> [[(ColumnAlias, SQLExp)]]
forall a b. (a -> b) -> a -> b
$ ((AnnotatedOrderByElement ('Postgres pgKind) SQLExp,
(ColumnAlias, SQLExp))
-> (ColumnAlias, SQLExp))
-> [(AnnotatedOrderByElement ('Postgres pgKind) SQLExp,
(ColumnAlias, SQLExp))]
-> [(ColumnAlias, SQLExp)]
forall a b. (a -> b) -> [a] -> [b]
map (AnnotatedOrderByElement ('Postgres pgKind) SQLExp,
(ColumnAlias, SQLExp))
-> (ColumnAlias, SQLExp)
forall a b. (a, b) -> b
snd ([(AnnotatedOrderByElement ('Postgres pgKind) SQLExp,
(ColumnAlias, SQLExp))]
-> [(ColumnAlias, SQLExp)])
-> (OrderByItemG
('Postgres pgKind)
(AnnotatedOrderByElement ('Postgres pgKind) SQLExp,
(ColumnAlias, SQLExp))
-> [(AnnotatedOrderByElement ('Postgres pgKind) SQLExp,
(ColumnAlias, SQLExp))])
-> OrderByItemG
('Postgres pgKind)
(AnnotatedOrderByElement ('Postgres pgKind) SQLExp,
(ColumnAlias, SQLExp))
-> [(ColumnAlias, SQLExp)]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. OrderByItemG
('Postgres pgKind)
(AnnotatedOrderByElement ('Postgres pgKind) SQLExp,
(ColumnAlias, SQLExp))
-> [(AnnotatedOrderByElement ('Postgres pgKind) SQLExp,
(ColumnAlias, SQLExp))]
forall (t :: * -> *) a. Foldable t => t a -> [a]
toList (OrderByItemG
('Postgres pgKind)
(AnnotatedOrderByElement ('Postgres pgKind) SQLExp,
(ColumnAlias, SQLExp))
-> [(ColumnAlias, SQLExp)])
-> NonEmpty
(OrderByItemG
('Postgres pgKind)
(AnnotatedOrderByElement ('Postgres pgKind) SQLExp,
(ColumnAlias, SQLExp)))
-> NonEmpty [(ColumnAlias, SQLExp)]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> NonEmpty
(OrderByItemG
('Postgres pgKind)
(AnnotatedOrderByElement ('Postgres pgKind) SQLExp,
(ColumnAlias, SQLExp)))
orderByItemExps
cursor :: SQLExp
cursor = [OrderByItemG
('Postgres pgKind)
(AnnotatedOrderByElement
('Postgres pgKind) (SQLExpression ('Postgres pgKind)),
(ColumnAlias, SQLExpression ('Postgres pgKind)))]
-> SQLExp
mkCursorExp ([OrderByItemG
('Postgres pgKind)
(AnnotatedOrderByElement
('Postgres pgKind) (SQLExpression ('Postgres pgKind)),
(ColumnAlias, SQLExpression ('Postgres pgKind)))]
-> SQLExp)
-> [OrderByItemG
('Postgres pgKind)
(AnnotatedOrderByElement
('Postgres pgKind) (SQLExpression ('Postgres pgKind)),
(ColumnAlias, SQLExpression ('Postgres pgKind)))]
-> SQLExp
forall a b. (a -> b) -> a -> b
$ NonEmpty
(OrderByItemG
('Postgres pgKind)
(AnnotatedOrderByElement ('Postgres pgKind) SQLExp,
(ColumnAlias, SQLExp)))
-> [OrderByItemG
('Postgres pgKind)
(AnnotatedOrderByElement ('Postgres pgKind) SQLExp,
(ColumnAlias, SQLExp))]
forall (t :: * -> *) a. Foldable t => t a -> [a]
toList NonEmpty
(OrderByItemG
('Postgres pgKind)
(AnnotatedOrderByElement ('Postgres pgKind) SQLExp,
(ColumnAlias, SQLExp)))
orderByItemExps
([(ColumnAlias, SQLExp)], SelectSorting, Maybe SQLExp)
-> m ([(ColumnAlias, SQLExp)], SelectSorting, Maybe SQLExp)
forall (f :: * -> *) a. Applicative f => a -> f a
pure ([(ColumnAlias, SQLExp)]
orderByExtractors [(ColumnAlias, SQLExp)]
-> [(ColumnAlias, SQLExp)] -> [(ColumnAlias, SQLExp)]
forall a. Semigroup a => a -> a -> a
<> [(ColumnAlias, SQLExp)]
distinctOnExtractors, SelectSorting
sorting, SQLExp -> Maybe SQLExp
forall a. a -> Maybe a
Just SQLExp
cursor)
where
processAnnOrderByItem ::
AnnotatedOrderByItem ('Postgres pgKind) ->
m (OrderByItemG ('Postgres pgKind) (AnnotatedOrderByElement ('Postgres pgKind) (SQLExpression ('Postgres pgKind)), (S.ColumnAlias, SQLExpression ('Postgres pgKind))))
processAnnOrderByItem :: AnnotatedOrderByItem ('Postgres pgKind)
-> m (OrderByItemG
('Postgres pgKind)
(AnnotatedOrderByElement
('Postgres pgKind) (SQLExpression ('Postgres pgKind)),
(ColumnAlias, SQLExpression ('Postgres pgKind))))
processAnnOrderByItem AnnotatedOrderByItem ('Postgres pgKind)
orderByItem =
AnnotatedOrderByItemG ('Postgres pgKind) SQLExp
-> (AnnotatedOrderByElement ('Postgres pgKind) SQLExp
-> m (AnnotatedOrderByElement ('Postgres pgKind) SQLExp,
(ColumnAlias, SQLExp)))
-> m (OrderByItemG
('Postgres pgKind)
(AnnotatedOrderByElement ('Postgres pgKind) SQLExp,
(ColumnAlias, SQLExp)))
forall (t :: * -> *) (m :: * -> *) a b.
(Traversable t, Monad m) =>
t a -> (a -> m b) -> m (t b)
forM AnnotatedOrderByItem ('Postgres pgKind)
AnnotatedOrderByItemG ('Postgres pgKind) SQLExp
orderByItem ((AnnotatedOrderByElement ('Postgres pgKind) SQLExp
-> m (AnnotatedOrderByElement ('Postgres pgKind) SQLExp,
(ColumnAlias, SQLExp)))
-> m (OrderByItemG
('Postgres pgKind)
(AnnotatedOrderByElement ('Postgres pgKind) SQLExp,
(ColumnAlias, SQLExp))))
-> (AnnotatedOrderByElement ('Postgres pgKind) SQLExp
-> m (AnnotatedOrderByElement ('Postgres pgKind) SQLExp,
(ColumnAlias, SQLExp)))
-> m (OrderByItemG
('Postgres pgKind)
(AnnotatedOrderByElement ('Postgres pgKind) SQLExp,
(ColumnAlias, SQLExp)))
forall a b. (a -> b) -> a -> b
$ \AnnotatedOrderByElement ('Postgres pgKind) SQLExp
ordByCol ->
(AnnotatedOrderByElement ('Postgres pgKind) SQLExp
ordByCol,)
((ColumnAlias, SQLExp)
-> (AnnotatedOrderByElement ('Postgres pgKind) SQLExp,
(ColumnAlias, SQLExp)))
-> m (ColumnAlias, SQLExp)
-> m (AnnotatedOrderByElement ('Postgres pgKind) SQLExp,
(ColumnAlias, SQLExp))
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Identifier
-> FieldName
-> AnnotatedOrderByElement ('Postgres pgKind) SQLExp
-> m (ColumnAlias, SQLExpression ('Postgres pgKind))
processAnnotatedOrderByElement Identifier
sourcePrefix' FieldName
fieldAlias' AnnotatedOrderByElement ('Postgres pgKind) SQLExp
ordByCol
processAnnotatedOrderByElement ::
Identifier -> FieldName -> AnnotatedOrderByElement ('Postgres pgKind) S.SQLExp -> m (S.ColumnAlias, (SQLExpression ('Postgres pgKind)))
processAnnotatedOrderByElement :: Identifier
-> FieldName
-> AnnotatedOrderByElement ('Postgres pgKind) SQLExp
-> m (ColumnAlias, SQLExpression ('Postgres pgKind))
processAnnotatedOrderByElement Identifier
sourcePrefix FieldName
fieldAlias AnnotatedOrderByElement ('Postgres pgKind) SQLExp
annObCol = do
let ordByAlias :: ColumnAlias
ordByAlias = Identifier
-> FieldName
-> SimilarArrayFields
-> AnnotatedOrderByElement ('Postgres pgKind) SQLExp
-> ColumnAlias
forall (pgKind :: PostgresKind) v.
Identifier
-> FieldName
-> SimilarArrayFields
-> AnnotatedOrderByElement ('Postgres pgKind) v
-> ColumnAlias
mkAnnOrderByAlias Identifier
sourcePrefix FieldName
fieldAlias SimilarArrayFields
similarArrayFields AnnotatedOrderByElement ('Postgres pgKind) SQLExp
annObCol
(ColumnAlias
ordByAlias,) (SQLExp -> (ColumnAlias, SQLExp))
-> m SQLExp -> m (ColumnAlias, SQLExp)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> case AnnotatedOrderByElement ('Postgres pgKind) SQLExp
annObCol of
AOCColumn ColumnInfo ('Postgres pgKind)
pgColInfo ->
SQLExp -> m SQLExp
forall (f :: * -> *) a. Applicative f => a -> f a
pure (SQLExp -> m SQLExp) -> SQLExp -> m SQLExp
forall a b. (a -> b) -> a -> b
$
TableAlias -> Identifier -> SQLExp
forall a b. (IsIdentifier a, IsIdentifier b) => a -> b -> SQLExp
S.mkQIdenExp (Identifier -> TableAlias
mkBaseTableAlias Identifier
sourcePrefix) (Identifier -> SQLExp) -> Identifier -> SQLExp
forall a b. (a -> b) -> a -> b
$ PGCol -> Identifier
forall a. IsIdentifier a => a -> Identifier
toIdentifier (PGCol -> Identifier) -> PGCol -> Identifier
forall a b. (a -> b) -> a -> b
$ ColumnInfo ('Postgres pgKind) -> Column ('Postgres pgKind)
forall (b :: BackendType). ColumnInfo b -> Column b
ciColumn ColumnInfo ('Postgres pgKind)
pgColInfo
AOCObjectRelation RelInfo ('Postgres pgKind)
relInfo AnnBoolExp ('Postgres pgKind) SQLExp
relFilter AnnotatedOrderByElement ('Postgres pgKind) SQLExp
rest -> m (ObjectRelationSource, HashMap ColumnAlias SQLExp, SQLExp)
-> m SQLExp
forall (m :: * -> *) a.
MonadWriter JoinTree m =>
m (ObjectRelationSource, HashMap ColumnAlias SQLExp, a) -> m a
withWriteObjectRelation (m (ObjectRelationSource, HashMap ColumnAlias SQLExp, SQLExp)
-> m SQLExp)
-> m (ObjectRelationSource, HashMap ColumnAlias SQLExp, SQLExp)
-> m SQLExp
forall a b. (a -> b) -> a -> b
$ do
let RelInfo RelName
relName RelType
_ HashMap (Column ('Postgres pgKind)) (Column ('Postgres pgKind))
colMapping TableName ('Postgres pgKind)
relTable Bool
_ InsertOrder
_ = RelInfo ('Postgres pgKind)
relInfo
relSourcePrefix :: Identifier
relSourcePrefix = Identifier -> RelName -> Identifier
mkObjectRelationTableAlias Identifier
sourcePrefix RelName
relName
fieldName :: FieldName
fieldName = RelName -> FieldName
forall a. ToTxt a => a -> FieldName
mkOrderByFieldName RelName
relName
(ColumnAlias
relOrderByAlias, SQLExp
relOrdByExp) <-
Identifier
-> FieldName
-> AnnotatedOrderByElement ('Postgres pgKind) SQLExp
-> m (ColumnAlias, SQLExpression ('Postgres pgKind))
processAnnotatedOrderByElement Identifier
relSourcePrefix FieldName
fieldName AnnotatedOrderByElement ('Postgres pgKind) SQLExp
rest
let selectSource :: ObjectSelectSource
selectSource =
Identifier -> FromItem -> BoolExp -> ObjectSelectSource
ObjectSelectSource
Identifier
relSourcePrefix
(QualifiedTable -> Maybe TableAlias -> FromItem
S.FISimple TableName ('Postgres pgKind)
QualifiedTable
relTable Maybe TableAlias
forall a. Maybe a
Nothing)
(Qual -> AnnBoolExpSQL ('Postgres pgKind) -> BoolExp
forall (pgKind :: PostgresKind).
Backend ('Postgres pgKind) =>
Qual -> AnnBoolExpSQL ('Postgres pgKind) -> BoolExp
toSQLBoolExp (QualifiedTable -> Qual
S.QualTable TableName ('Postgres pgKind)
QualifiedTable
relTable) AnnBoolExpSQL ('Postgres pgKind)
AnnBoolExp ('Postgres pgKind) SQLExp
relFilter)
relSource :: ObjectRelationSource
relSource = RelName
-> HashMap PGCol PGCol
-> ObjectSelectSource
-> ObjectRelationSource
ObjectRelationSource RelName
relName HashMap (Column ('Postgres pgKind)) (Column ('Postgres pgKind))
HashMap PGCol PGCol
colMapping ObjectSelectSource
selectSource
(ObjectRelationSource, HashMap ColumnAlias SQLExp, SQLExp)
-> m (ObjectRelationSource, HashMap ColumnAlias SQLExp, SQLExp)
forall (f :: * -> *) a. Applicative f => a -> f a
pure
( ObjectRelationSource
relSource,
ColumnAlias -> SQLExp -> HashMap ColumnAlias SQLExp
forall k v. Hashable k => k -> v -> HashMap k v
HM.singleton ColumnAlias
relOrderByAlias SQLExp
relOrdByExp,
Identifier -> ColumnAlias -> SQLExp
forall a b. (IsIdentifier a, IsIdentifier b) => a -> b -> SQLExp
S.mkQIdenExp Identifier
relSourcePrefix ColumnAlias
relOrderByAlias
)
AOCArrayAggregation RelInfo ('Postgres pgKind)
relInfo AnnBoolExp ('Postgres pgKind) SQLExp
relFilter AnnotatedAggregateOrderBy ('Postgres pgKind)
aggOrderBy -> m (ArrayRelationSource, Extractor, HashMap ColumnAlias SQLExp,
SQLExp)
-> m SQLExp
forall (m :: * -> *) a.
MonadWriter JoinTree m =>
m (ArrayRelationSource, Extractor, HashMap ColumnAlias SQLExp, a)
-> m a
withWriteArrayRelation (m (ArrayRelationSource, Extractor, HashMap ColumnAlias SQLExp,
SQLExp)
-> m SQLExp)
-> m (ArrayRelationSource, Extractor, HashMap ColumnAlias SQLExp,
SQLExp)
-> m SQLExp
forall a b. (a -> b) -> a -> b
$ do
let RelInfo RelName
relName RelType
_ HashMap (Column ('Postgres pgKind)) (Column ('Postgres pgKind))
colMapping TableName ('Postgres pgKind)
relTable Bool
_ InsertOrder
_ = RelInfo ('Postgres pgKind)
relInfo
fieldName :: FieldName
fieldName = RelName -> FieldName
forall a. ToTxt a => a -> FieldName
mkOrderByFieldName RelName
relName
relSourcePrefix :: Identifier
relSourcePrefix =
Identifier
-> FieldName -> SimilarArrayFields -> FieldName -> Identifier
mkArrayRelationSourcePrefix
Identifier
sourcePrefix
FieldName
fieldAlias
SimilarArrayFields
similarArrayFields
FieldName
fieldName
relAlias :: TableAlias
relAlias = FieldName -> SimilarArrayFields -> FieldName -> TableAlias
mkArrayRelationAlias FieldName
fieldAlias SimilarArrayFields
similarArrayFields FieldName
fieldName
(Extractor
topExtractor, AggregateFields ('Postgres pgKind)
fields) = AnnotatedAggregateOrderBy ('Postgres pgKind)
-> (Extractor, AggregateFields ('Postgres pgKind))
forall (pgKind :: PostgresKind).
Backend ('Postgres pgKind) =>
AnnotatedAggregateOrderBy ('Postgres pgKind)
-> (Extractor, AggregateFields ('Postgres pgKind))
mkAggregateOrderByExtractorAndFields AnnotatedAggregateOrderBy ('Postgres pgKind)
aggOrderBy
selectSource :: SelectSource
selectSource =
Identifier
-> FromItem -> BoolExp -> SortingAndSlicing -> SelectSource
SelectSource
Identifier
relSourcePrefix
(QualifiedTable -> Maybe TableAlias -> FromItem
S.FISimple TableName ('Postgres pgKind)
QualifiedTable
relTable Maybe TableAlias
forall a. Maybe a
Nothing)
(Qual -> AnnBoolExpSQL ('Postgres pgKind) -> BoolExp
forall (pgKind :: PostgresKind).
Backend ('Postgres pgKind) =>
Qual -> AnnBoolExpSQL ('Postgres pgKind) -> BoolExp
toSQLBoolExp (QualifiedTable -> Qual
S.QualTable TableName ('Postgres pgKind)
QualifiedTable
relTable) AnnBoolExpSQL ('Postgres pgKind)
AnnBoolExp ('Postgres pgKind) SQLExp
relFilter)
SortingAndSlicing
noSortingAndSlicing
relSource :: ArrayRelationSource
relSource = TableAlias
-> HashMap PGCol PGCol -> SelectSource -> ArrayRelationSource
ArrayRelationSource TableAlias
relAlias HashMap (Column ('Postgres pgKind)) (Column ('Postgres pgKind))
HashMap PGCol PGCol
colMapping SelectSource
selectSource
(ArrayRelationSource, Extractor, HashMap ColumnAlias SQLExp,
SQLExp)
-> m (ArrayRelationSource, Extractor, HashMap ColumnAlias SQLExp,
SQLExp)
forall (f :: * -> *) a. Applicative f => a -> f a
pure
( ArrayRelationSource
relSource,
Extractor
topExtractor,
[(ColumnAlias, SQLExp)] -> HashMap ColumnAlias SQLExp
forall k v. (Eq k, Hashable k) => [(k, v)] -> HashMap k v
HM.fromList ([(ColumnAlias, SQLExp)] -> HashMap ColumnAlias SQLExp)
-> [(ColumnAlias, SQLExp)] -> HashMap ColumnAlias SQLExp
forall a b. (a -> b) -> a -> b
$ Identifier
-> AggregateFields ('Postgres pgKind) -> [(ColumnAlias, SQLExp)]
forall (pgKind :: PostgresKind).
Identifier
-> AggregateFields ('Postgres pgKind) -> [(ColumnAlias, SQLExp)]
aggregateFieldsToExtractorExps Identifier
relSourcePrefix AggregateFields ('Postgres pgKind)
fields,
Identifier -> ColumnAlias -> SQLExp
forall a b. (IsIdentifier a, IsIdentifier b) => a -> b -> SQLExp
S.mkQIdenExp Identifier
relSourcePrefix (AnnotatedAggregateOrderBy ('Postgres pgKind) -> ColumnAlias
forall (pgKind :: PostgresKind).
AnnotatedAggregateOrderBy ('Postgres pgKind) -> ColumnAlias
mkAggregateOrderByAlias AnnotatedAggregateOrderBy ('Postgres pgKind)
aggOrderBy)
)
AOCComputedField ComputedFieldOrderBy {FunctionName ('Postgres pgKind)
XComputedField ('Postgres pgKind)
FunctionArgsExp ('Postgres pgKind) SQLExp
ComputedFieldName
ComputedFieldOrderByElement ('Postgres pgKind) SQLExp
$sel:_cfobOrderByElement:ComputedFieldOrderBy :: forall (b :: BackendType) v.
ComputedFieldOrderBy b v -> ComputedFieldOrderByElement b v
$sel:_cfobFunctionArgsExp:ComputedFieldOrderBy :: forall (b :: BackendType) v.
ComputedFieldOrderBy b v -> FunctionArgsExp b v
$sel:_cfobFunction:ComputedFieldOrderBy :: forall (b :: BackendType) v.
ComputedFieldOrderBy b v -> FunctionName b
$sel:_cfobName:ComputedFieldOrderBy :: forall (b :: BackendType) v.
ComputedFieldOrderBy b v -> ComputedFieldName
$sel:_cfobXField:ComputedFieldOrderBy :: forall (b :: BackendType) v.
ComputedFieldOrderBy b v -> XComputedField b
_cfobOrderByElement :: ComputedFieldOrderByElement ('Postgres pgKind) SQLExp
_cfobFunctionArgsExp :: FunctionArgsExp ('Postgres pgKind) SQLExp
_cfobFunction :: FunctionName ('Postgres pgKind)
_cfobName :: ComputedFieldName
_cfobXField :: XComputedField ('Postgres pgKind)
..} ->
case ComputedFieldOrderByElement ('Postgres pgKind) SQLExp
_cfobOrderByElement of
CFOBEScalar ScalarType ('Postgres pgKind)
_ -> do
let functionArgs :: FunctionArgs
functionArgs = Identifier -> FunctionArgsExpG (ArgumentExp SQLExp) -> FunctionArgs
fromTableRowArgs Identifier
sourcePrefix FunctionArgsExp ('Postgres pgKind) SQLExp
FunctionArgsExpG (ArgumentExp SQLExp)
_cfobFunctionArgsExp
functionExp :: FunctionExp
functionExp = QualifiedFunction
-> FunctionArgs -> Maybe FunctionAlias -> FunctionExp
S.FunctionExp FunctionName ('Postgres pgKind)
QualifiedFunction
_cfobFunction FunctionArgs
functionArgs Maybe FunctionAlias
forall a. Maybe a
Nothing
SQLExp -> m SQLExp
forall (f :: * -> *) a. Applicative f => a -> f a
pure (SQLExp -> m SQLExp) -> SQLExp -> m SQLExp
forall a b. (a -> b) -> a -> b
$ FunctionExp -> SQLExp
S.SEFunction FunctionExp
functionExp
CFOBETableAggregation TableName ('Postgres pgKind)
_ AnnBoolExp ('Postgres pgKind) SQLExp
tableFilter AnnotatedAggregateOrderBy ('Postgres pgKind)
aggOrderBy -> m (ComputedFieldTableSetSource, Extractor,
HashMap ColumnAlias SQLExp, SQLExp)
-> m SQLExp
forall (m :: * -> *) a.
MonadWriter JoinTree m =>
m (ComputedFieldTableSetSource, Extractor,
HashMap ColumnAlias SQLExp, a)
-> m a
withWriteComputedFieldTableSet (m (ComputedFieldTableSetSource, Extractor,
HashMap ColumnAlias SQLExp, SQLExp)
-> m SQLExp)
-> m (ComputedFieldTableSetSource, Extractor,
HashMap ColumnAlias SQLExp, SQLExp)
-> m SQLExp
forall a b. (a -> b) -> a -> b
$ do
let fieldName :: FieldName
fieldName = ComputedFieldName -> FieldName
forall a. ToTxt a => a -> FieldName
mkOrderByFieldName ComputedFieldName
_cfobName
computedFieldSourcePrefix :: Identifier
computedFieldSourcePrefix = Identifier -> FieldName -> Identifier
mkComputedFieldTableAlias Identifier
sourcePrefix FieldName
fieldName
(Extractor
topExtractor, AggregateFields ('Postgres pgKind)
fields) = AnnotatedAggregateOrderBy ('Postgres pgKind)
-> (Extractor, AggregateFields ('Postgres pgKind))
forall (pgKind :: PostgresKind).
Backend ('Postgres pgKind) =>
AnnotatedAggregateOrderBy ('Postgres pgKind)
-> (Extractor, AggregateFields ('Postgres pgKind))
mkAggregateOrderByExtractorAndFields AnnotatedAggregateOrderBy ('Postgres pgKind)
aggOrderBy
fromItem :: FromItem
fromItem =
Identifier -> SelectFrom ('Postgres Any) -> FromItem
forall (pgKind :: PostgresKind).
Identifier -> SelectFrom ('Postgres pgKind) -> FromItem
selectFromToFromItem Identifier
sourcePrefix (SelectFrom ('Postgres Any) -> FromItem)
-> SelectFrom ('Postgres Any) -> FromItem
forall a b. (a -> b) -> a -> b
$
FunctionName ('Postgres Any)
-> FunctionArgsExp ('Postgres Any) SQLExp
-> Maybe [(Column ('Postgres Any), ScalarType ('Postgres Any))]
-> SelectFromG ('Postgres Any) SQLExp
forall (b :: BackendType) v.
FunctionName b
-> FunctionArgsExp b v
-> Maybe [(Column b, ScalarType b)]
-> SelectFromG b v
FromFunction FunctionName ('Postgres pgKind)
FunctionName ('Postgres Any)
_cfobFunction FunctionArgsExp ('Postgres pgKind) SQLExp
FunctionArgsExp ('Postgres Any) SQLExp
_cfobFunctionArgsExp Maybe [(Column ('Postgres Any), ScalarType ('Postgres Any))]
forall a. Maybe a
Nothing
functionQual :: Qual
functionQual = Identifier -> Maybe TypeAnn -> Qual
S.QualifiedIdentifier (QualifiedFunction -> Identifier
functionToIdentifier FunctionName ('Postgres pgKind)
QualifiedFunction
_cfobFunction) Maybe TypeAnn
forall a. Maybe a
Nothing
selectSource :: SelectSource
selectSource =
Identifier
-> FromItem -> BoolExp -> SortingAndSlicing -> SelectSource
SelectSource
Identifier
computedFieldSourcePrefix
FromItem
fromItem
(Qual -> AnnBoolExpSQL ('Postgres pgKind) -> BoolExp
forall (pgKind :: PostgresKind).
Backend ('Postgres pgKind) =>
Qual -> AnnBoolExpSQL ('Postgres pgKind) -> BoolExp
toSQLBoolExp Qual
functionQual AnnBoolExpSQL ('Postgres pgKind)
AnnBoolExp ('Postgres pgKind) SQLExp
tableFilter)
SortingAndSlicing
noSortingAndSlicing
source :: ComputedFieldTableSetSource
source = FieldName -> SelectSource -> ComputedFieldTableSetSource
ComputedFieldTableSetSource FieldName
fieldName SelectSource
selectSource
(ComputedFieldTableSetSource, Extractor,
HashMap ColumnAlias SQLExp, SQLExp)
-> m (ComputedFieldTableSetSource, Extractor,
HashMap ColumnAlias SQLExp, SQLExp)
forall (f :: * -> *) a. Applicative f => a -> f a
pure
( ComputedFieldTableSetSource
source,
Extractor
topExtractor,
[(ColumnAlias, SQLExp)] -> HashMap ColumnAlias SQLExp
forall k v. (Eq k, Hashable k) => [(k, v)] -> HashMap k v
HM.fromList ([(ColumnAlias, SQLExp)] -> HashMap ColumnAlias SQLExp)
-> [(ColumnAlias, SQLExp)] -> HashMap ColumnAlias SQLExp
forall a b. (a -> b) -> a -> b
$ Identifier
-> AggregateFields ('Postgres pgKind) -> [(ColumnAlias, SQLExp)]
forall (pgKind :: PostgresKind).
Identifier
-> AggregateFields ('Postgres pgKind) -> [(ColumnAlias, SQLExp)]
aggregateFieldsToExtractorExps Identifier
computedFieldSourcePrefix AggregateFields ('Postgres pgKind)
fields,
Identifier -> ColumnAlias -> SQLExp
forall a b. (IsIdentifier a, IsIdentifier b) => a -> b -> SQLExp
S.mkQIdenExp Identifier
computedFieldSourcePrefix (AnnotatedAggregateOrderBy ('Postgres pgKind) -> ColumnAlias
forall (pgKind :: PostgresKind).
AnnotatedAggregateOrderBy ('Postgres pgKind) -> ColumnAlias
mkAggregateOrderByAlias AnnotatedAggregateOrderBy ('Postgres pgKind)
aggOrderBy)
)
generateSorting ::
NE.NonEmpty (OrderByItemG ('Postgres pgKind) (AnnotatedOrderByElement ('Postgres pgKind) (SQLExpression ('Postgres pgKind)), (S.ColumnAlias, SQLExpression ('Postgres pgKind)))) ->
( SelectSorting,
[(S.ColumnAlias, SQLExpression ('Postgres pgKind))]
)
generateSorting :: NonEmpty
(OrderByItemG
('Postgres pgKind)
(AnnotatedOrderByElement
('Postgres pgKind) (SQLExpression ('Postgres pgKind)),
(ColumnAlias, SQLExpression ('Postgres pgKind))))
-> (SelectSorting,
[(ColumnAlias, SQLExpression ('Postgres pgKind))])
generateSorting orderByExps :: NonEmpty
(OrderByItemG
('Postgres pgKind)
(AnnotatedOrderByElement
('Postgres pgKind) (SQLExpression ('Postgres pgKind)),
(ColumnAlias, SQLExpression ('Postgres pgKind))))
orderByExps@(OrderByItemG
('Postgres pgKind)
(AnnotatedOrderByElement
('Postgres pgKind) (SQLExpression ('Postgres pgKind)),
(ColumnAlias, SQLExpression ('Postgres pgKind)))
firstOrderBy NE.:| [OrderByItemG
('Postgres pgKind)
(AnnotatedOrderByElement
('Postgres pgKind) (SQLExpression ('Postgres pgKind)),
(ColumnAlias, SQLExpression ('Postgres pgKind)))]
restOrderBys) =
case (AnnotatedOrderByElement ('Postgres pgKind) SQLExp,
(ColumnAlias, SQLExp))
-> AnnotatedOrderByElement ('Postgres pgKind) SQLExp
forall a b. (a, b) -> a
fst ((AnnotatedOrderByElement ('Postgres pgKind) SQLExp,
(ColumnAlias, SQLExp))
-> AnnotatedOrderByElement ('Postgres pgKind) SQLExp)
-> (AnnotatedOrderByElement ('Postgres pgKind) SQLExp,
(ColumnAlias, SQLExp))
-> AnnotatedOrderByElement ('Postgres pgKind) SQLExp
forall a b. (a -> b) -> a -> b
$ OrderByItemG
('Postgres pgKind)
(AnnotatedOrderByElement ('Postgres pgKind) SQLExp,
(ColumnAlias, SQLExp))
-> (AnnotatedOrderByElement ('Postgres pgKind) SQLExp,
(ColumnAlias, SQLExp))
forall (b :: BackendType) a. OrderByItemG b a -> a
obiColumn OrderByItemG
('Postgres pgKind)
(AnnotatedOrderByElement
('Postgres pgKind) (SQLExpression ('Postgres pgKind)),
(ColumnAlias, SQLExpression ('Postgres pgKind)))
OrderByItemG
('Postgres pgKind)
(AnnotatedOrderByElement ('Postgres pgKind) SQLExp,
(ColumnAlias, SQLExp))
firstOrderBy of
AOCColumn ColumnInfo ('Postgres pgKind)
columnInfo ->
if (OrderByItemG
('Postgres pgKind)
(AnnotatedOrderByElement ('Postgres pgKind) SQLExp,
(ColumnAlias, SQLExp))
-> Bool)
-> [OrderByItemG
('Postgres pgKind)
(AnnotatedOrderByElement ('Postgres pgKind) SQLExp,
(ColumnAlias, SQLExp))]
-> Bool
forall (t :: * -> *) a. Foldable t => (a -> Bool) -> t a -> Bool
all (Maybe (ColumnInfo ('Postgres pgKind)) -> Bool
forall a. Maybe a -> Bool
isJust (Maybe (ColumnInfo ('Postgres pgKind)) -> Bool)
-> (OrderByItemG
('Postgres pgKind)
(AnnotatedOrderByElement ('Postgres pgKind) SQLExp,
(ColumnAlias, SQLExp))
-> Maybe (ColumnInfo ('Postgres pgKind)))
-> OrderByItemG
('Postgres pgKind)
(AnnotatedOrderByElement ('Postgres pgKind) SQLExp,
(ColumnAlias, SQLExp))
-> Bool
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (AnnotatedOrderByElement ('Postgres pgKind) SQLExp,
(ColumnAlias, SQLExp))
-> Maybe (ColumnInfo ('Postgres pgKind))
forall (b :: BackendType) v b.
(AnnotatedOrderByElement b v, b) -> Maybe (ColumnInfo b)
getColumnOrderBy ((AnnotatedOrderByElement ('Postgres pgKind) SQLExp,
(ColumnAlias, SQLExp))
-> Maybe (ColumnInfo ('Postgres pgKind)))
-> (OrderByItemG
('Postgres pgKind)
(AnnotatedOrderByElement ('Postgres pgKind) SQLExp,
(ColumnAlias, SQLExp))
-> (AnnotatedOrderByElement ('Postgres pgKind) SQLExp,
(ColumnAlias, SQLExp)))
-> OrderByItemG
('Postgres pgKind)
(AnnotatedOrderByElement ('Postgres pgKind) SQLExp,
(ColumnAlias, SQLExp))
-> Maybe (ColumnInfo ('Postgres pgKind))
forall b c a. (b -> c) -> (a -> b) -> a -> c
. OrderByItemG
('Postgres pgKind)
(AnnotatedOrderByElement ('Postgres pgKind) SQLExp,
(ColumnAlias, SQLExp))
-> (AnnotatedOrderByElement ('Postgres pgKind) SQLExp,
(ColumnAlias, SQLExp))
forall (b :: BackendType) a. OrderByItemG b a -> a
obiColumn) [OrderByItemG
('Postgres pgKind)
(AnnotatedOrderByElement
('Postgres pgKind) (SQLExpression ('Postgres pgKind)),
(ColumnAlias, SQLExpression ('Postgres pgKind)))]
[OrderByItemG
('Postgres pgKind)
(AnnotatedOrderByElement ('Postgres pgKind) SQLExp,
(ColumnAlias, SQLExp))]
restOrderBys
then
let restColumnOrderBys :: [OrderByItemG ('Postgres pgKind) (ColumnInfo ('Postgres pgKind))]
restColumnOrderBys = (OrderByItemG
('Postgres pgKind)
(AnnotatedOrderByElement ('Postgres pgKind) SQLExp,
(ColumnAlias, SQLExp))
-> Maybe
(OrderByItemG ('Postgres pgKind) (ColumnInfo ('Postgres pgKind))))
-> [OrderByItemG
('Postgres pgKind)
(AnnotatedOrderByElement ('Postgres pgKind) SQLExp,
(ColumnAlias, SQLExp))]
-> [OrderByItemG
('Postgres pgKind) (ColumnInfo ('Postgres pgKind))]
forall (f :: * -> *) a b.
Filterable f =>
(a -> Maybe b) -> f a -> f b
mapMaybe (((AnnotatedOrderByElement ('Postgres pgKind) SQLExp,
(ColumnAlias, SQLExp))
-> Maybe (ColumnInfo ('Postgres pgKind)))
-> OrderByItemG
('Postgres pgKind)
(AnnotatedOrderByElement ('Postgres pgKind) SQLExp,
(ColumnAlias, SQLExp))
-> Maybe
(OrderByItemG ('Postgres pgKind) (ColumnInfo ('Postgres pgKind)))
forall (t :: * -> *) (f :: * -> *) a b.
(Traversable t, Applicative f) =>
(a -> f b) -> t a -> f (t b)
traverse (AnnotatedOrderByElement ('Postgres pgKind) SQLExp,
(ColumnAlias, SQLExp))
-> Maybe (ColumnInfo ('Postgres pgKind))
forall (b :: BackendType) v b.
(AnnotatedOrderByElement b v, b) -> Maybe (ColumnInfo b)
getColumnOrderBy) [OrderByItemG
('Postgres pgKind)
(AnnotatedOrderByElement
('Postgres pgKind) (SQLExpression ('Postgres pgKind)),
(ColumnAlias, SQLExpression ('Postgres pgKind)))]
[OrderByItemG
('Postgres pgKind)
(AnnotatedOrderByElement ('Postgres pgKind) SQLExp,
(ColumnAlias, SQLExp))]
restOrderBys
firstColumnOrderBy :: OrderByItemG ('Postgres pgKind) (ColumnInfo ('Postgres pgKind))
firstColumnOrderBy = OrderByItemG
('Postgres pgKind)
(AnnotatedOrderByElement
('Postgres pgKind) (SQLExpression ('Postgres pgKind)),
(ColumnAlias, SQLExpression ('Postgres pgKind)))
OrderByItemG
('Postgres pgKind)
(AnnotatedOrderByElement ('Postgres pgKind) SQLExp,
(ColumnAlias, SQLExp))
firstOrderBy {obiColumn :: ColumnInfo ('Postgres pgKind)
obiColumn = ColumnInfo ('Postgres pgKind)
columnInfo}
in NonEmpty
(OrderByItemG ('Postgres pgKind) (ColumnInfo ('Postgres pgKind)))
-> (SelectSorting, [(ColumnAlias, SQLExp)])
sortAtNodeAndBase (NonEmpty
(OrderByItemG ('Postgres pgKind) (ColumnInfo ('Postgres pgKind)))
-> (SelectSorting, [(ColumnAlias, SQLExp)]))
-> NonEmpty
(OrderByItemG ('Postgres pgKind) (ColumnInfo ('Postgres pgKind)))
-> (SelectSorting, [(ColumnAlias, SQLExp)])
forall a b. (a -> b) -> a -> b
$ OrderByItemG ('Postgres pgKind) (ColumnInfo ('Postgres pgKind))
firstColumnOrderBy OrderByItemG ('Postgres pgKind) (ColumnInfo ('Postgres pgKind))
-> [OrderByItemG
('Postgres pgKind) (ColumnInfo ('Postgres pgKind))]
-> NonEmpty
(OrderByItemG ('Postgres pgKind) (ColumnInfo ('Postgres pgKind)))
forall a. a -> [a] -> NonEmpty a
NE.:| [OrderByItemG ('Postgres pgKind) (ColumnInfo ('Postgres pgKind))]
restColumnOrderBys
else
(SelectSorting, [(ColumnAlias, SQLExpression ('Postgres pgKind))])
(SelectSorting, [(ColumnAlias, SQLExp)])
sortOnlyAtNode
AnnotatedOrderByElement ('Postgres pgKind) SQLExp
_ ->
(SelectSorting, [(ColumnAlias, SQLExpression ('Postgres pgKind))])
(SelectSorting, [(ColumnAlias, SQLExp)])
sortOnlyAtNode
where
getColumnOrderBy :: (AnnotatedOrderByElement b v, b) -> Maybe (ColumnInfo b)
getColumnOrderBy = (AnnotatedOrderByElement b v
-> Getting
(First (ColumnInfo b)) (AnnotatedOrderByElement b v) (ColumnInfo b)
-> Maybe (ColumnInfo b)
forall s a. s -> Getting (First a) s a -> Maybe a
^? Getting
(First (ColumnInfo b)) (AnnotatedOrderByElement b v) (ColumnInfo b)
forall (b :: BackendType) v.
Prism' (AnnotatedOrderByElement b v) (ColumnInfo b)
_AOCColumn) (AnnotatedOrderByElement b v -> Maybe (ColumnInfo b))
-> ((AnnotatedOrderByElement b v, b)
-> AnnotatedOrderByElement b v)
-> (AnnotatedOrderByElement b v, b)
-> Maybe (ColumnInfo b)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (AnnotatedOrderByElement b v, b) -> AnnotatedOrderByElement b v
forall a b. (a, b) -> a
fst
(OrderByExp
nodeOrderBy, Maybe DistinctExpr
nodeDistinctOn, [(ColumnAlias, SQLExp)]
nodeDistinctOnExtractors) =
let toOrderByExp :: OrderByItemG b (a, (a, b)) -> OrderByItem
toOrderByExp OrderByItemG b (a, (a, b))
orderByItemExp =
let OrderByItemG Maybe (BasicOrderType b)
obTyM a
expAlias Maybe (NullsOrderType b)
obNullsM = (a, b) -> a
forall a b. (a, b) -> a
fst ((a, b) -> a) -> ((a, (a, b)) -> (a, b)) -> (a, (a, b)) -> a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (a, (a, b)) -> (a, b)
forall a b. (a, b) -> b
snd ((a, (a, b)) -> a)
-> OrderByItemG b (a, (a, b)) -> OrderByItemG b a
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> OrderByItemG b (a, (a, b))
orderByItemExp
in SQLExp -> Maybe OrderType -> Maybe NullsOrder -> OrderByItem
S.OrderByItem (Identifier -> SQLExp
S.SEIdentifier (Identifier -> SQLExp) -> Identifier -> SQLExp
forall a b. (a -> b) -> a -> b
$ a -> Identifier
forall a. IsIdentifier a => a -> Identifier
toIdentifier a
expAlias) Maybe (BasicOrderType b)
Maybe OrderType
obTyM Maybe (NullsOrderType b)
Maybe NullsOrder
obNullsM
orderByExp :: OrderByExp
orderByExp = NonEmpty OrderByItem -> OrderByExp
S.OrderByExp (NonEmpty OrderByItem -> OrderByExp)
-> NonEmpty OrderByItem -> OrderByExp
forall a b. (a -> b) -> a -> b
$ OrderByItemG
('Postgres pgKind)
(AnnotatedOrderByElement ('Postgres pgKind) SQLExp,
(ColumnAlias, SQLExp))
-> OrderByItem
forall a (b :: BackendType) a b.
(IsIdentifier a, BasicOrderType b ~ OrderType,
NullsOrderType b ~ NullsOrder) =>
OrderByItemG b (a, (a, b)) -> OrderByItem
toOrderByExp (OrderByItemG
('Postgres pgKind)
(AnnotatedOrderByElement ('Postgres pgKind) SQLExp,
(ColumnAlias, SQLExp))
-> OrderByItem)
-> NonEmpty
(OrderByItemG
('Postgres pgKind)
(AnnotatedOrderByElement ('Postgres pgKind) SQLExp,
(ColumnAlias, SQLExp)))
-> NonEmpty OrderByItem
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> NonEmpty
(OrderByItemG
('Postgres pgKind)
(AnnotatedOrderByElement
('Postgres pgKind) (SQLExpression ('Postgres pgKind)),
(ColumnAlias, SQLExpression ('Postgres pgKind))))
NonEmpty
(OrderByItemG
('Postgres pgKind)
(AnnotatedOrderByElement ('Postgres pgKind) SQLExp,
(ColumnAlias, SQLExp)))
orderByExps
(Maybe DistinctExpr
maybeDistOn, Maybe [(ColumnAlias, SQLExp)]
distOnExtrs) = Maybe (DistinctExpr, [(ColumnAlias, SQLExp)])
-> (Maybe DistinctExpr, Maybe [(ColumnAlias, SQLExp)])
forall (f :: * -> *) a b. Functor f => f (a, b) -> (f a, f b)
NE.unzip (Maybe (DistinctExpr, [(ColumnAlias, SQLExp)])
-> (Maybe DistinctExpr, Maybe [(ColumnAlias, SQLExp)]))
-> Maybe (DistinctExpr, [(ColumnAlias, SQLExp)])
-> (Maybe DistinctExpr, Maybe [(ColumnAlias, SQLExp)])
forall a b. (a -> b) -> a -> b
$ Identifier
-> NonEmpty PGCol -> (DistinctExpr, [(ColumnAlias, SQLExp)])
applyDistinctOnAtNode Identifier
sourcePrefix' (NonEmpty PGCol -> (DistinctExpr, [(ColumnAlias, SQLExp)]))
-> Maybe (NonEmpty PGCol)
-> Maybe (DistinctExpr, [(ColumnAlias, SQLExp)])
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Maybe (NonEmpty PGCol)
distOnCols
in (OrderByExp
orderByExp, Maybe DistinctExpr
maybeDistOn, [(ColumnAlias, SQLExp)]
-> Maybe [(ColumnAlias, SQLExp)] -> [(ColumnAlias, SQLExp)]
forall a. a -> Maybe a -> a
fromMaybe [] Maybe [(ColumnAlias, SQLExp)]
distOnExtrs)
sortOnlyAtNode :: (SelectSorting, [(ColumnAlias, SQLExp)])
sortOnlyAtNode =
(DistinctAndOrderByExpr -> SelectSorting
Sorting (DistinctAndOrderByExpr -> SelectSorting)
-> DistinctAndOrderByExpr -> SelectSorting
forall a b. (a -> b) -> a -> b
$ (OrderByExp, Maybe DistinctExpr)
-> Maybe (OrderByExp, Maybe DistinctExpr) -> DistinctAndOrderByExpr
ASorting (OrderByExp
nodeOrderBy, Maybe DistinctExpr
nodeDistinctOn) Maybe (OrderByExp, Maybe DistinctExpr)
forall a. Maybe a
Nothing, [(ColumnAlias, SQLExp)]
nodeDistinctOnExtractors)
sortAtNodeAndBase :: NonEmpty
(OrderByItemG ('Postgres pgKind) (ColumnInfo ('Postgres pgKind)))
-> (SelectSorting, [(ColumnAlias, SQLExp)])
sortAtNodeAndBase NonEmpty
(OrderByItemG ('Postgres pgKind) (ColumnInfo ('Postgres pgKind)))
baseColumnOrderBys =
let mkBaseOrderByItem :: OrderByItemG b (ColumnInfo b) -> OrderByItem
mkBaseOrderByItem (OrderByItemG Maybe (BasicOrderType b)
orderByType ColumnInfo b
columnInfo Maybe (NullsOrderType b)
nullsOrder) =
SQLExp -> Maybe OrderType -> Maybe NullsOrder -> OrderByItem
S.OrderByItem
(Identifier -> SQLExp
S.SEIdentifier (Identifier -> SQLExp) -> Identifier -> SQLExp
forall a b. (a -> b) -> a -> b
$ Column b -> Identifier
forall a. IsIdentifier a => a -> Identifier
toIdentifier (Column b -> Identifier) -> Column b -> Identifier
forall a b. (a -> b) -> a -> b
$ ColumnInfo b -> Column b
forall (b :: BackendType). ColumnInfo b -> Column b
ciColumn ColumnInfo b
columnInfo)
Maybe (BasicOrderType b)
Maybe OrderType
orderByType
Maybe (NullsOrderType b)
Maybe NullsOrder
nullsOrder
baseOrderByExp :: OrderByExp
baseOrderByExp = NonEmpty OrderByItem -> OrderByExp
S.OrderByExp (NonEmpty OrderByItem -> OrderByExp)
-> NonEmpty OrderByItem -> OrderByExp
forall a b. (a -> b) -> a -> b
$ OrderByItemG ('Postgres pgKind) (ColumnInfo ('Postgres pgKind))
-> OrderByItem
forall (b :: BackendType) (b :: BackendType).
(IsIdentifier (Column b), BasicOrderType b ~ OrderType,
NullsOrderType b ~ NullsOrder) =>
OrderByItemG b (ColumnInfo b) -> OrderByItem
mkBaseOrderByItem (OrderByItemG ('Postgres pgKind) (ColumnInfo ('Postgres pgKind))
-> OrderByItem)
-> NonEmpty
(OrderByItemG ('Postgres pgKind) (ColumnInfo ('Postgres pgKind)))
-> NonEmpty OrderByItem
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> NonEmpty
(OrderByItemG ('Postgres pgKind) (ColumnInfo ('Postgres pgKind)))
baseColumnOrderBys
baseDistOnExp :: Maybe DistinctExpr
baseDistOnExp = NonEmpty PGCol -> DistinctExpr
applyDistinctOnAtBase (NonEmpty PGCol -> DistinctExpr)
-> Maybe (NonEmpty PGCol) -> Maybe DistinctExpr
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Maybe (NonEmpty PGCol)
distOnCols
sorting :: SelectSorting
sorting = DistinctAndOrderByExpr -> SelectSorting
Sorting (DistinctAndOrderByExpr -> SelectSorting)
-> DistinctAndOrderByExpr -> SelectSorting
forall a b. (a -> b) -> a -> b
$ (OrderByExp, Maybe DistinctExpr)
-> Maybe (OrderByExp, Maybe DistinctExpr) -> DistinctAndOrderByExpr
ASorting (OrderByExp
nodeOrderBy, Maybe DistinctExpr
nodeDistinctOn) (Maybe (OrderByExp, Maybe DistinctExpr) -> DistinctAndOrderByExpr)
-> Maybe (OrderByExp, Maybe DistinctExpr) -> DistinctAndOrderByExpr
forall a b. (a -> b) -> a -> b
$ (OrderByExp, Maybe DistinctExpr)
-> Maybe (OrderByExp, Maybe DistinctExpr)
forall a. a -> Maybe a
Just (OrderByExp
baseOrderByExp, Maybe DistinctExpr
baseDistOnExp)
in (SelectSorting
sorting, [(ColumnAlias, SQLExp)]
nodeDistinctOnExtractors)
mkCursorExp ::
[OrderByItemG ('Postgres pgKind) (AnnotatedOrderByElement ('Postgres pgKind) (SQLExpression ('Postgres pgKind)), (S.ColumnAlias, SQLExpression ('Postgres pgKind)))] ->
S.SQLExp
mkCursorExp :: [OrderByItemG
('Postgres pgKind)
(AnnotatedOrderByElement
('Postgres pgKind) (SQLExpression ('Postgres pgKind)),
(ColumnAlias, SQLExpression ('Postgres pgKind)))]
-> SQLExp
mkCursorExp [OrderByItemG
('Postgres pgKind)
(AnnotatedOrderByElement
('Postgres pgKind) (SQLExpression ('Postgres pgKind)),
(ColumnAlias, SQLExpression ('Postgres pgKind)))]
orderByItemExps =
[SQLExp] -> SQLExp
S.applyJsonBuildObj ([SQLExp] -> SQLExp) -> [SQLExp] -> SQLExp
forall a b. (a -> b) -> a -> b
$
((OrderByItemG
('Postgres pgKind)
(AnnotatedOrderByElement ('Postgres pgKind) SQLExp,
(ColumnAlias, SQLExp))
-> [SQLExp])
-> [OrderByItemG
('Postgres pgKind)
(AnnotatedOrderByElement ('Postgres pgKind) SQLExp,
(ColumnAlias, SQLExp))]
-> [SQLExp])
-> [OrderByItemG
('Postgres pgKind)
(AnnotatedOrderByElement ('Postgres pgKind) SQLExp,
(ColumnAlias, SQLExp))]
-> (OrderByItemG
('Postgres pgKind)
(AnnotatedOrderByElement ('Postgres pgKind) SQLExp,
(ColumnAlias, SQLExp))
-> [SQLExp])
-> [SQLExp]
forall a b c. (a -> b -> c) -> b -> a -> c
flip (OrderByItemG
('Postgres pgKind)
(AnnotatedOrderByElement ('Postgres pgKind) SQLExp,
(ColumnAlias, SQLExp))
-> [SQLExp])
-> [OrderByItemG
('Postgres pgKind)
(AnnotatedOrderByElement ('Postgres pgKind) SQLExp,
(ColumnAlias, SQLExp))]
-> [SQLExp]
forall (t :: * -> *) a b. Foldable t => (a -> [b]) -> t a -> [b]
concatMap [OrderByItemG
('Postgres pgKind)
(AnnotatedOrderByElement
('Postgres pgKind) (SQLExpression ('Postgres pgKind)),
(ColumnAlias, SQLExpression ('Postgres pgKind)))]
[OrderByItemG
('Postgres pgKind)
(AnnotatedOrderByElement ('Postgres pgKind) SQLExp,
(ColumnAlias, SQLExp))]
orderByItemExps ((OrderByItemG
('Postgres pgKind)
(AnnotatedOrderByElement ('Postgres pgKind) SQLExp,
(ColumnAlias, SQLExp))
-> [SQLExp])
-> [SQLExp])
-> (OrderByItemG
('Postgres pgKind)
(AnnotatedOrderByElement ('Postgres pgKind) SQLExp,
(ColumnAlias, SQLExp))
-> [SQLExp])
-> [SQLExp]
forall a b. (a -> b) -> a -> b
$
\OrderByItemG
('Postgres pgKind)
(AnnotatedOrderByElement ('Postgres pgKind) SQLExp,
(ColumnAlias, SQLExp))
orderByItemExp ->
let OrderByItemG Maybe (BasicOrderType ('Postgres pgKind))
_ (AnnotatedOrderByElement ('Postgres pgKind) SQLExp
annObCol, (ColumnAlias
_, SQLExp
valExp)) Maybe (NullsOrderType ('Postgres pgKind))
_ = OrderByItemG
('Postgres pgKind)
(AnnotatedOrderByElement ('Postgres pgKind) SQLExp,
(ColumnAlias, SQLExp))
orderByItemExp
in SQLExp
-> AnnotatedOrderByElement ('Postgres pgKind) SQLExp -> [SQLExp]
forall (b :: BackendType) v.
(Column b ~ PGCol) =>
SQLExp -> AnnotatedOrderByElement b v -> [SQLExp]
annObColToJSONField SQLExp
valExp AnnotatedOrderByElement ('Postgres pgKind) SQLExp
annObCol
where
mkAggOrderByValExp :: SQLExp -> AnnotatedAggregateOrderBy b -> [SQLExp]
mkAggOrderByValExp SQLExp
valExp = \case
AnnotatedAggregateOrderBy b
AAOCount -> [Text -> SQLExp
S.SELit Text
"count", SQLExp
valExp]
AAOOp Text
opText ColumnInfo b
colInfo ->
[ Text -> SQLExp
S.SELit Text
opText,
[SQLExp] -> SQLExp
S.applyJsonBuildObj [Text -> SQLExp
S.SELit (Text -> SQLExp) -> Text -> SQLExp
forall a b. (a -> b) -> a -> b
$ PGCol -> Text
getPGColTxt (PGCol -> Text) -> PGCol -> Text
forall a b. (a -> b) -> a -> b
$ ColumnInfo b -> Column b
forall (b :: BackendType). ColumnInfo b -> Column b
ciColumn ColumnInfo b
colInfo, SQLExp
valExp]
]
annObColToJSONField :: SQLExp -> AnnotatedOrderByElement b v -> [SQLExp]
annObColToJSONField SQLExp
valExp = \case
AOCColumn ColumnInfo b
pgCol -> [Text -> SQLExp
S.SELit (Text -> SQLExp) -> Text -> SQLExp
forall a b. (a -> b) -> a -> b
$ PGCol -> Text
getPGColTxt (PGCol -> Text) -> PGCol -> Text
forall a b. (a -> b) -> a -> b
$ ColumnInfo b -> Column b
forall (b :: BackendType). ColumnInfo b -> Column b
ciColumn ColumnInfo b
pgCol, SQLExp
valExp]
AOCObjectRelation RelInfo b
relInfo AnnBoolExp b v
_ AnnotatedOrderByElement b v
obCol ->
[ Text -> SQLExp
S.SELit (Text -> SQLExp) -> Text -> SQLExp
forall a b. (a -> b) -> a -> b
$ RelName -> Text
relNameToTxt (RelName -> Text) -> RelName -> Text
forall a b. (a -> b) -> a -> b
$ RelInfo b -> RelName
forall (b :: BackendType). RelInfo b -> RelName
riName RelInfo b
relInfo,
[SQLExp] -> SQLExp
S.applyJsonBuildObj ([SQLExp] -> SQLExp) -> [SQLExp] -> SQLExp
forall a b. (a -> b) -> a -> b
$ SQLExp -> AnnotatedOrderByElement b v -> [SQLExp]
annObColToJSONField SQLExp
valExp AnnotatedOrderByElement b v
obCol
]
AOCArrayAggregation RelInfo b
relInfo AnnBoolExp b v
_ AnnotatedAggregateOrderBy b
aggOrderBy ->
[ Text -> SQLExp
S.SELit (Text -> SQLExp) -> Text -> SQLExp
forall a b. (a -> b) -> a -> b
$ RelName -> Text
relNameToTxt (RelInfo b -> RelName
forall (b :: BackendType). RelInfo b -> RelName
riName RelInfo b
relInfo) Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
"_aggregate",
[SQLExp] -> SQLExp
S.applyJsonBuildObj ([SQLExp] -> SQLExp) -> [SQLExp] -> SQLExp
forall a b. (a -> b) -> a -> b
$ SQLExp -> AnnotatedAggregateOrderBy b -> [SQLExp]
forall (b :: BackendType).
(Column b ~ PGCol) =>
SQLExp -> AnnotatedAggregateOrderBy b -> [SQLExp]
mkAggOrderByValExp SQLExp
valExp AnnotatedAggregateOrderBy b
aggOrderBy
]
AOCComputedField ComputedFieldOrderBy b v
cfOrderBy ->
let fieldNameText :: Text
fieldNameText = ComputedFieldName -> Text
computedFieldNameToText (ComputedFieldName -> Text) -> ComputedFieldName -> Text
forall a b. (a -> b) -> a -> b
$ ComputedFieldOrderBy b v -> ComputedFieldName
forall (b :: BackendType) v.
ComputedFieldOrderBy b v -> ComputedFieldName
_cfobName ComputedFieldOrderBy b v
cfOrderBy
in case ComputedFieldOrderBy b v -> ComputedFieldOrderByElement b v
forall (b :: BackendType) v.
ComputedFieldOrderBy b v -> ComputedFieldOrderByElement b v
_cfobOrderByElement ComputedFieldOrderBy b v
cfOrderBy of
CFOBEScalar ScalarType b
_ -> [Text -> SQLExp
S.SELit Text
fieldNameText, SQLExp
valExp]
CFOBETableAggregation TableName b
_ AnnBoolExp b v
_ AnnotatedAggregateOrderBy b
aggOrderBy ->
[ Text -> SQLExp
S.SELit (Text -> SQLExp) -> Text -> SQLExp
forall a b. (a -> b) -> a -> b
$ Text
fieldNameText Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
"_aggregate",
[SQLExp] -> SQLExp
S.applyJsonBuildObj ([SQLExp] -> SQLExp) -> [SQLExp] -> SQLExp
forall a b. (a -> b) -> a -> b
$ SQLExp -> AnnotatedAggregateOrderBy b -> [SQLExp]
forall (b :: BackendType).
(Column b ~ PGCol) =>
SQLExp -> AnnotatedAggregateOrderBy b -> [SQLExp]
mkAggOrderByValExp SQLExp
valExp AnnotatedAggregateOrderBy b
aggOrderBy
]
applyDistinctOnAtBase ::
NE.NonEmpty PGCol -> S.DistinctExpr
applyDistinctOnAtBase :: NonEmpty PGCol -> DistinctExpr
applyDistinctOnAtBase =
[SQLExp] -> DistinctExpr
S.DistinctOn ([SQLExp] -> DistinctExpr)
-> (NonEmpty PGCol -> [SQLExp]) -> NonEmpty PGCol -> DistinctExpr
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (PGCol -> SQLExp) -> [PGCol] -> [SQLExp]
forall a b. (a -> b) -> [a] -> [b]
map (Identifier -> SQLExp
S.SEIdentifier (Identifier -> SQLExp) -> (PGCol -> Identifier) -> PGCol -> SQLExp
forall b c a. (b -> c) -> (a -> b) -> a -> c
. PGCol -> Identifier
forall a. IsIdentifier a => a -> Identifier
toIdentifier) ([PGCol] -> [SQLExp])
-> (NonEmpty PGCol -> [PGCol]) -> NonEmpty PGCol -> [SQLExp]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. NonEmpty PGCol -> [PGCol]
forall (t :: * -> *) a. Foldable t => t a -> [a]
toList
applyDistinctOnAtNode ::
Identifier ->
NE.NonEmpty PGCol ->
( S.DistinctExpr,
[(S.ColumnAlias, S.SQLExp)]
)
applyDistinctOnAtNode :: Identifier
-> NonEmpty PGCol -> (DistinctExpr, [(ColumnAlias, SQLExp)])
applyDistinctOnAtNode Identifier
pfx NonEmpty PGCol
neCols = (DistinctExpr
distOnExp, [(ColumnAlias, SQLExp)]
colExtrs)
where
cols :: [PGCol]
cols = NonEmpty PGCol -> [PGCol]
forall (t :: * -> *) a. Foldable t => t a -> [a]
toList NonEmpty PGCol
neCols
distOnExp :: DistinctExpr
distOnExp = [SQLExp] -> DistinctExpr
S.DistinctOn ([SQLExp] -> DistinctExpr) -> [SQLExp] -> DistinctExpr
forall a b. (a -> b) -> a -> b
$ (PGCol -> SQLExp) -> [PGCol] -> [SQLExp]
forall a b. (a -> b) -> [a] -> [b]
map (Identifier -> SQLExp
S.SEIdentifier (Identifier -> SQLExp) -> (PGCol -> Identifier) -> PGCol -> SQLExp
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ColumnAlias -> Identifier
forall a. IsIdentifier a => a -> Identifier
toIdentifier (ColumnAlias -> Identifier)
-> (PGCol -> ColumnAlias) -> PGCol -> Identifier
forall b c a. (b -> c) -> (a -> b) -> a -> c
. PGCol -> ColumnAlias
mkQColAls) [PGCol]
cols
mkQCol :: PGCol -> SQLExp
mkQCol PGCol
c = TableAlias -> Identifier -> SQLExp
forall a b. (IsIdentifier a, IsIdentifier b) => a -> b -> SQLExp
S.mkQIdenExp (Identifier -> TableAlias
mkBaseTableAlias Identifier
pfx) (Identifier -> SQLExp) -> Identifier -> SQLExp
forall a b. (a -> b) -> a -> b
$ PGCol -> Identifier
forall a. IsIdentifier a => a -> Identifier
toIdentifier PGCol
c
mkQColAls :: PGCol -> ColumnAlias
mkQColAls = Identifier -> PGCol -> ColumnAlias
mkBaseTableColumnAlias Identifier
pfx
colExtrs :: [(ColumnAlias, SQLExp)]
colExtrs = ((PGCol -> (ColumnAlias, SQLExp))
-> [PGCol] -> [(ColumnAlias, SQLExp)])
-> [PGCol]
-> (PGCol -> (ColumnAlias, SQLExp))
-> [(ColumnAlias, SQLExp)]
forall a b c. (a -> b -> c) -> b -> a -> c
flip (PGCol -> (ColumnAlias, SQLExp))
-> [PGCol] -> [(ColumnAlias, SQLExp)]
forall a b. (a -> b) -> [a] -> [b]
map [PGCol]
cols ((PGCol -> (ColumnAlias, SQLExp)) -> [(ColumnAlias, SQLExp)])
-> (PGCol -> (ColumnAlias, SQLExp)) -> [(ColumnAlias, SQLExp)]
forall a b. (a -> b) -> a -> b
$ PGCol -> ColumnAlias
mkQColAls (PGCol -> ColumnAlias)
-> (PGCol -> SQLExp) -> PGCol -> (ColumnAlias, SQLExp)
forall (a :: * -> * -> *) b c c'.
Arrow a =>
a b c -> a b c' -> a b (c, c')
&&& PGCol -> SQLExp
mkQCol