{-# OPTIONS_GHC -fno-warn-orphans #-}
module Hasura.Backends.BigQuery.ToQuery
( fromSelect,
fromReselect,
fromExpression,
toBuilderFlat,
toBuilderPretty,
toTextFlat,
toTextPretty,
Printer (..),
renderBuilderFlat,
renderBuilderPretty,
paramName,
)
where
import Data.Aeson (ToJSON (..))
import Data.Bifunctor
import Data.Containers.ListUtils
import Data.HashMap.Strict.InsOrd qualified as OMap
import Data.List (intersperse)
import Data.List.NonEmpty qualified as NE
import Data.String
import Data.Text qualified as T
import Data.Text.Lazy qualified as LT
import Data.Text.Lazy.Builder (Builder)
import Data.Text.Lazy.Builder qualified as LT
import Data.Tuple
import Data.Vector qualified as V
import Hasura.Backends.BigQuery.Types
import Hasura.Prelude hiding (second)
data Printer
= SeqPrinter [Printer]
| SepByPrinter Printer [Printer]
| NewlinePrinter
| UnsafeTextPrinter Text
| IndentPrinter Int Printer
| ValuePrinter Value
deriving (Int -> Printer -> ShowS
[Printer] -> ShowS
Printer -> String
(Int -> Printer -> ShowS)
-> (Printer -> String) -> ([Printer] -> ShowS) -> Show Printer
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [Printer] -> ShowS
$cshowList :: [Printer] -> ShowS
show :: Printer -> String
$cshow :: Printer -> String
showsPrec :: Int -> Printer -> ShowS
$cshowsPrec :: Int -> Printer -> ShowS
Show, Printer -> Printer -> Bool
(Printer -> Printer -> Bool)
-> (Printer -> Printer -> Bool) -> Eq Printer
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: Printer -> Printer -> Bool
$c/= :: Printer -> Printer -> Bool
== :: Printer -> Printer -> Bool
$c== :: Printer -> Printer -> Bool
Eq)
instance IsString Printer where
fromString :: String -> Printer
fromString = Text -> Printer
UnsafeTextPrinter (Text -> Printer) -> (String -> Text) -> String -> Printer
forall b c a. (b -> c) -> (a -> b) -> a -> c
. String -> Text
forall a. IsString a => String -> a
fromString
(<+>) :: Printer -> Printer -> Printer
<+> :: Printer -> Printer -> Printer
(<+>) Printer
x Printer
y = [Printer] -> Printer
SeqPrinter [Printer
x, Printer
y]
instance ToJSON Expression where
toJSON :: Expression -> Value
toJSON = Text -> Value
forall a. ToJSON a => a -> Value
toJSON (Text -> Value) -> (Expression -> Text) -> Expression -> Value
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Printer -> Text
toTextPretty (Printer -> Text) -> (Expression -> Printer) -> Expression -> Text
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Expression -> Printer
fromExpression
fromExpression :: Expression -> Printer
fromExpression :: Expression -> Printer
fromExpression =
\case
CastExpression Expression
e ScalarType
scalarType ->
Printer
"CAST(" Printer -> Printer -> Printer
<+> Expression -> Printer
fromExpression Expression
e Printer -> Printer -> Printer
<+> Printer
" AS " Printer -> Printer -> Printer
<+> ScalarType -> Printer
fromScalarType ScalarType
scalarType Printer -> Printer -> Printer
<+> Printer
")"
InExpression Expression
e Value
value ->
Printer
"(" Printer -> Printer -> Printer
<+> Expression -> Printer
fromExpression Expression
e Printer -> Printer -> Printer
<+> Printer
") IN UNNEST(" Printer -> Printer -> Printer
<+> Value -> Printer
fromValue Value
value Printer -> Printer -> Printer
<+> Printer
")"
JsonQueryExpression Expression
e -> Printer
"JSON_QUERY(" Printer -> Printer -> Printer
<+> Expression -> Printer
fromExpression Expression
e Printer -> Printer -> Printer
<+> Printer
")"
JsonValueExpression Expression
e JsonPath
path ->
Printer
"JSON_VALUE(" Printer -> Printer -> Printer
<+> Expression -> Printer
fromExpression Expression
e Printer -> Printer -> Printer
<+> JsonPath -> Printer
fromPath JsonPath
path Printer -> Printer -> Printer
<+> Printer
")"
ValueExpression Value
value -> Value -> Printer
fromValue Value
value
AndExpression [Expression]
xs ->
Printer -> [Printer] -> Printer
SepByPrinter
(Printer
NewlinePrinter Printer -> Printer -> Printer
<+> Printer
"AND ")
( NonEmpty Printer -> [Printer]
forall (t :: * -> *) a. Foldable t => t a -> [a]
toList
( (Expression -> Printer) -> NonEmpty Expression -> NonEmpty Printer
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap
(\Expression
x -> Printer
"(" Printer -> Printer -> Printer
<+> Expression -> Printer
fromExpression Expression
x Printer -> Printer -> Printer
<+> Printer
")")
(NonEmpty Expression
-> Maybe (NonEmpty Expression) -> NonEmpty Expression
forall a. a -> Maybe a -> a
fromMaybe (Expression -> NonEmpty Expression
forall (f :: * -> *) a. Applicative f => a -> f a
pure Expression
trueExpression) ([Expression] -> Maybe (NonEmpty Expression)
forall a. [a] -> Maybe (NonEmpty a)
NE.nonEmpty [Expression]
xs))
)
)
OrExpression [Expression]
xs ->
Printer -> [Printer] -> Printer
SepByPrinter
(Printer
NewlinePrinter Printer -> Printer -> Printer
<+> Printer
" OR ")
( NonEmpty Printer -> [Printer]
forall (t :: * -> *) a. Foldable t => t a -> [a]
toList
( (Expression -> Printer) -> NonEmpty Expression -> NonEmpty Printer
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap
(\Expression
x -> Printer
"(" Printer -> Printer -> Printer
<+> Expression -> Printer
fromExpression Expression
x Printer -> Printer -> Printer
<+> Printer
")")
(NonEmpty Expression
-> Maybe (NonEmpty Expression) -> NonEmpty Expression
forall a. a -> Maybe a -> a
fromMaybe (Expression -> NonEmpty Expression
forall (f :: * -> *) a. Applicative f => a -> f a
pure Expression
falseExpression) ([Expression] -> Maybe (NonEmpty Expression)
forall a. [a] -> Maybe (NonEmpty a)
NE.nonEmpty [Expression]
xs))
)
)
NotExpression Expression
expression -> Printer
"NOT " Printer -> Printer -> Printer
<+> (Expression -> Printer
fromExpression Expression
expression)
ExistsExpression Select
select ->
Printer
"EXISTS (" Printer -> Printer -> Printer
<+> Int -> Printer -> Printer
IndentPrinter Int
9 (Select -> Printer
fromSelect Select
select) Printer -> Printer -> Printer
<+> Printer
")"
IsNullExpression Expression
expression ->
Printer
"(" Printer -> Printer -> Printer
<+> Expression -> Printer
fromExpression Expression
expression Printer -> Printer -> Printer
<+> Printer
") IS NULL"
IsNotNullExpression Expression
expression ->
Printer
"(" Printer -> Printer -> Printer
<+> Expression -> Printer
fromExpression Expression
expression Printer -> Printer -> Printer
<+> Printer
") IS NOT NULL"
ColumnExpression FieldName
fieldName -> FieldName -> Printer
fromFieldName FieldName
fieldName
EqualExpression Expression
x Expression
y ->
Printer
"(" Printer -> Printer -> Printer
<+> Expression -> Printer
fromExpression Expression
x Printer -> Printer -> Printer
<+> Printer
") = (" Printer -> Printer -> Printer
<+> Expression -> Printer
fromExpression Expression
y Printer -> Printer -> Printer
<+> Printer
")"
NotEqualExpression Expression
x Expression
y ->
Printer
"(" Printer -> Printer -> Printer
<+> Expression -> Printer
fromExpression Expression
x Printer -> Printer -> Printer
<+> Printer
") != (" Printer -> Printer -> Printer
<+> Expression -> Printer
fromExpression Expression
y Printer -> Printer -> Printer
<+> Printer
")"
ToStringExpression Expression
e -> Printer
"CONCAT(" Printer -> Printer -> Printer
<+> Expression -> Printer
fromExpression Expression
e Printer -> Printer -> Printer
<+> Printer
", '')"
SelectExpression Select
s -> Printer
"(" Printer -> Printer -> Printer
<+> Int -> Printer -> Printer
IndentPrinter Int
1 (Select -> Printer
fromSelect Select
s) Printer -> Printer -> Printer
<+> Printer
")"
ListExpression [Expression]
xs -> Printer
" UNNEST ([" Printer -> Printer -> Printer
<+> Printer -> [Printer] -> Printer
SepByPrinter Printer
", " (Expression -> Printer
fromExpression (Expression -> Printer) -> [Expression] -> [Printer]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> [Expression]
xs) Printer -> Printer -> Printer
<+> Printer
"])"
OpExpression Op
op Expression
x Expression
y ->
Printer
"("
Printer -> Printer -> Printer
<+> Expression -> Printer
fromExpression Expression
x
Printer -> Printer -> Printer
<+> Printer
") "
Printer -> Printer -> Printer
<+> Op -> Printer
fromOp Op
op
Printer -> Printer -> Printer
<+> Expression -> Printer
fromExpression Expression
y
FunctionExpression FunctionName
function [Expression]
args ->
FunctionName -> Printer
fromFunctionName FunctionName
function Printer -> Printer -> Printer
<+> Printer
"(" Printer -> Printer -> Printer
<+> Printer -> [Printer] -> Printer
SepByPrinter Printer
", " (Expression -> Printer
fromExpression (Expression -> Printer) -> [Expression] -> [Printer]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> [Expression]
args) Printer -> Printer -> Printer
<+> Printer
")"
ConditionalProjection Expression
expression FieldName
fieldName ->
Printer
"(CASE WHEN(" Printer -> Printer -> Printer
<+> Expression -> Printer
fromExpression Expression
expression
Printer -> Printer -> Printer
<+> Printer
") THEN "
Printer -> Printer -> Printer
<+> FieldName -> Printer
fromFieldName FieldName
fieldName
Printer -> Printer -> Printer
<+> Printer
" ELSE NULL END)"
FunctionNamedArgument Text
argName Expression
argValue ->
Text -> Printer
fromNameText Text
argName Printer -> Printer -> Printer
<+> Printer
" => " Printer -> Printer -> Printer
<+> Expression -> Printer
fromExpression Expression
argValue
fromScalarType :: ScalarType -> Printer
fromScalarType :: ScalarType -> Printer
fromScalarType =
\case
ScalarType
StringScalarType -> Printer
"STRING"
ScalarType
BytesScalarType -> Printer
"BYTES"
ScalarType
IntegerScalarType -> Printer
"INT64"
ScalarType
FloatScalarType -> Printer
"FLOAT64"
ScalarType
BoolScalarType -> Printer
"BOOL"
ScalarType
TimestampScalarType -> Printer
"TIMESTAMP"
ScalarType
DateScalarType -> Printer
"DATE"
ScalarType
TimeScalarType -> Printer
"TIME"
ScalarType
DatetimeScalarType -> Printer
"DATETIME"
ScalarType
GeographyScalarType -> Printer
"GEOGRAPHY"
ScalarType
StructScalarType -> Printer
"STRUCT"
ScalarType
DecimalScalarType -> Printer
"DECIMAL"
ScalarType
BigDecimalScalarType -> Printer
"BIGDECIMAL"
fromOp :: Op -> Printer
fromOp :: Op -> Printer
fromOp =
\case
Op
LessOp -> Printer
"<"
Op
MoreOp -> Printer
">"
Op
MoreOrEqualOp -> Printer
">="
Op
LessOrEqualOp -> Printer
"<="
Op
InOp -> Printer
"IN"
Op
NotInOp -> Printer
"NOT IN"
Op
LikeOp -> Printer
"LIKE"
Op
NotLikeOp -> Printer
"NOT LIKE"
fromPath :: JsonPath -> Printer
fromPath :: JsonPath -> Printer
fromPath JsonPath
path =
Printer
", " Printer -> Printer -> Printer
<+> JsonPath -> Printer
string JsonPath
path
where
string :: JsonPath -> Printer
string =
Expression -> Printer
fromExpression
(Expression -> Printer)
-> (JsonPath -> Expression) -> JsonPath -> Printer
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Value -> Expression
ValueExpression
(Value -> Expression)
-> (JsonPath -> Value) -> JsonPath -> Expression
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Text -> Value
StringValue
(Text -> Value) -> (JsonPath -> Text) -> JsonPath -> Value
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Text -> Text
LT.toStrict
(Text -> Text) -> (JsonPath -> Text) -> JsonPath -> Text
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Builder -> Text
LT.toLazyText
(Builder -> Text) -> (JsonPath -> Builder) -> JsonPath -> Text
forall b c a. (b -> c) -> (a -> b) -> a -> c
. JsonPath -> Builder
go
go :: JsonPath -> Builder
go =
\case
JsonPath
RootPath -> Builder
"$"
IndexPath JsonPath
r Integer
i -> JsonPath -> Builder
go JsonPath
r Builder -> Builder -> Builder
forall a. Semigroup a => a -> a -> a
<> Builder
"[" Builder -> Builder -> Builder
forall a. Semigroup a => a -> a -> a
<> String -> Builder
LT.fromString (Integer -> String
forall a. Show a => a -> String
show Integer
i) Builder -> Builder -> Builder
forall a. Semigroup a => a -> a -> a
<> Builder
"]"
FieldPath JsonPath
r Text
f -> JsonPath -> Builder
go JsonPath
r Builder -> Builder -> Builder
forall a. Semigroup a => a -> a -> a
<> Builder
"." Builder -> Builder -> Builder
forall a. Semigroup a => a -> a -> a
<> Text -> Builder
LT.fromText Text
f
fromFieldName :: FieldName -> Printer
fromFieldName :: FieldName -> Printer
fromFieldName (FieldName {Text
$sel:fieldNameEntity:FieldName :: FieldName -> Text
$sel:fieldName:FieldName :: FieldName -> Text
fieldNameEntity :: Text
fieldName :: Text
..}) =
Text -> Printer
fromNameText Text
fieldNameEntity Printer -> Printer -> Printer
<+> Printer
"." Printer -> Printer -> Printer
<+> Text -> Printer
fromNameText Text
fieldName
fromSelect :: Select -> Printer
fromSelect :: Select -> Printer
fromSelect Select {[FieldName]
[Join]
Maybe [Text]
Maybe (NonEmpty OrderBy)
Maybe Expression
NonEmpty Projection
From
Top
AsStruct
Cardinality
Where
$sel:selectCardinality:Select :: Select -> Cardinality
$sel:selectFinalWantedFields:Select :: Select -> Maybe [Text]
$sel:selectGroupBy:Select :: Select -> [FieldName]
$sel:selectOffset:Select :: Select -> Maybe Expression
$sel:selectOrderBy:Select :: Select -> Maybe (NonEmpty OrderBy)
$sel:selectWhere:Select :: Select -> Where
$sel:selectJoins:Select :: Select -> [Join]
$sel:selectFrom:Select :: Select -> From
$sel:selectProjections:Select :: Select -> NonEmpty Projection
$sel:selectAsStruct:Select :: Select -> AsStruct
$sel:selectTop:Select :: Select -> Top
selectCardinality :: Cardinality
selectFinalWantedFields :: Maybe [Text]
selectGroupBy :: [FieldName]
selectOffset :: Maybe Expression
selectOrderBy :: Maybe (NonEmpty OrderBy)
selectWhere :: Where
selectJoins :: [Join]
selectFrom :: From
selectProjections :: NonEmpty Projection
selectAsStruct :: AsStruct
selectTop :: Top
..} = Printer
finalExpression
where
finalExpression :: Printer
finalExpression = Printer
inner
projections :: Printer
projections =
Printer -> [Printer] -> Printer
SepByPrinter
(Printer
"," Printer -> Printer -> Printer
<+> Printer
NewlinePrinter)
((Projection -> Printer) -> [Projection] -> [Printer]
forall a b. (a -> b) -> [a] -> [b]
map Projection -> Printer
fromProjection (NonEmpty Projection -> [Projection]
forall (t :: * -> *) a. Foldable t => t a -> [a]
toList (NonEmpty Projection -> NonEmpty Projection
cleanProjections NonEmpty Projection
selectProjections)))
fromAsStruct :: AsStruct -> Printer
fromAsStruct = \case
AsStruct
AsStruct -> Printer
"AS STRUCT"
AsStruct
NoAsStruct -> Printer
""
inner :: Printer
inner =
Printer -> [Printer] -> Printer
SepByPrinter
Printer
NewlinePrinter
[ Printer
"SELECT ",
AsStruct -> Printer
fromAsStruct AsStruct
selectAsStruct,
Int -> Printer -> Printer
IndentPrinter Int
7 Printer
projections,
Printer
"FROM " Printer -> Printer -> Printer
<+> Int -> Printer -> Printer
IndentPrinter Int
5 (From -> Printer
fromFrom From
selectFrom),
Printer -> [Printer] -> Printer
SepByPrinter
Printer
NewlinePrinter
( (Join -> Printer) -> [Join] -> [Printer]
forall a b. (a -> b) -> [a] -> [b]
map
( \Join {[(FieldName, FieldName)]
Maybe Text
Text
EntityAlias
JoinSource
JoinProvenance
$sel:joinRightTable:Join :: Join -> EntityAlias
$sel:joinExtractPath:Join :: Join -> Maybe Text
$sel:joinFieldName:Join :: Join -> Text
$sel:joinProvenance:Join :: Join -> JoinProvenance
$sel:joinOn:Join :: Join -> [(FieldName, FieldName)]
$sel:joinAlias:Join :: Join -> EntityAlias
$sel:joinSource:Join :: Join -> JoinSource
joinRightTable :: EntityAlias
joinExtractPath :: Maybe Text
joinFieldName :: Text
joinProvenance :: JoinProvenance
joinOn :: [(FieldName, FieldName)]
joinAlias :: EntityAlias
joinSource :: JoinSource
..} ->
[Printer] -> Printer
SeqPrinter
[ Printer
"LEFT OUTER JOIN "
Printer -> Printer -> Printer
<+> Int -> Printer -> Printer
IndentPrinter Int
16 (JoinSource -> Printer
fromJoinSource JoinSource
joinSource),
Printer
NewlinePrinter,
Printer
"AS " Printer -> Printer -> Printer
<+> EntityAlias -> Printer
fromJoinAlias EntityAlias
joinAlias,
Printer
NewlinePrinter,
Printer
"ON ("
Printer -> Printer -> Printer
<+> Int -> Printer -> Printer
IndentPrinter
Int
4
( Printer -> [Printer] -> Printer
SepByPrinter
(Printer
" AND " Printer -> Printer -> Printer
<+> Printer
NewlinePrinter)
(((FieldName, FieldName) -> Printer)
-> [(FieldName, FieldName)] -> [Printer]
forall a b. (a -> b) -> [a] -> [b]
map (FieldName, FieldName) -> Printer
fromOn [(FieldName, FieldName)]
joinOn)
)
Printer -> Printer -> Printer
<+> Printer
")"
]
)
[Join]
selectJoins
),
Where -> Printer
fromWhere Where
selectWhere,
Top -> Maybe Expression -> Maybe (NonEmpty OrderBy) -> Printer
fromOrderBys Top
selectTop Maybe Expression
selectOffset Maybe (NonEmpty OrderBy)
selectOrderBy,
case [FieldName]
selectGroupBy of
[] -> Printer
""
[FieldName]
fieldNames ->
Printer
"GROUP BY " Printer -> Printer -> Printer
<+> Printer -> [Printer] -> Printer
SepByPrinter Printer
", " ((FieldName -> Printer) -> [FieldName] -> [Printer]
forall a b. (a -> b) -> [a] -> [b]
map FieldName -> Printer
fromFieldName [FieldName]
fieldNames)
]
fromOn :: (FieldName, FieldName) -> Printer
fromOn :: (FieldName, FieldName) -> Printer
fromOn (FieldName
x, FieldName
y) = FieldName -> Printer
fromFieldName FieldName
x Printer -> Printer -> Printer
<+> Printer
" = " Printer -> Printer -> Printer
<+> FieldName -> Printer
fromFieldName FieldName
y
fromJoinSource :: JoinSource -> Printer
fromJoinSource :: JoinSource -> Printer
fromJoinSource =
\case
JoinSelect Select
select -> Printer
"(" Printer -> Printer -> Printer
<+> Int -> Printer -> Printer
IndentPrinter Int
1 (Select -> Printer
fromSelect Select
select) Printer -> Printer -> Printer
<+> Printer
")"
fromReselect :: Reselect -> Printer
fromReselect :: Reselect -> Printer
fromReselect Reselect {NonEmpty Projection
Where
$sel:reselectWhere:Reselect :: Reselect -> Where
$sel:reselectProjections:Reselect :: Reselect -> NonEmpty Projection
reselectWhere :: Where
reselectProjections :: NonEmpty Projection
..} =
Printer -> [Printer] -> Printer
SepByPrinter
Printer
NewlinePrinter
[ Printer
"SELECT "
Printer -> Printer -> Printer
<+> Int -> Printer -> Printer
IndentPrinter Int
7 Printer
projections,
Where -> Printer
fromWhere Where
reselectWhere
]
where
projections :: Printer
projections =
Printer -> [Printer] -> Printer
SepByPrinter
(Printer
"," Printer -> Printer -> Printer
<+> Printer
NewlinePrinter)
((Projection -> Printer) -> [Projection] -> [Printer]
forall a b. (a -> b) -> [a] -> [b]
map Projection -> Printer
fromProjection (NonEmpty Projection -> [Projection]
forall (t :: * -> *) a. Foldable t => t a -> [a]
toList (NonEmpty Projection -> NonEmpty Projection
cleanProjections NonEmpty Projection
reselectProjections)))
fromOrderBys ::
Top -> Maybe Expression -> Maybe (NonEmpty OrderBy) -> Printer
fromOrderBys :: Top -> Maybe Expression -> Maybe (NonEmpty OrderBy) -> Printer
fromOrderBys Top
NoTop Maybe Expression
Nothing Maybe (NonEmpty OrderBy)
Nothing = Printer
""
fromOrderBys Top
top Maybe Expression
moffset Maybe (NonEmpty OrderBy)
morderBys =
Printer -> [Printer] -> Printer
SepByPrinter
Printer
NewlinePrinter
[ case Maybe (NonEmpty OrderBy)
morderBys of
Maybe (NonEmpty OrderBy)
Nothing -> Printer
""
Just NonEmpty OrderBy
orderBys ->
[Printer] -> Printer
SeqPrinter
[ Printer
"ORDER BY ",
Printer -> [Printer] -> Printer
SepByPrinter
(Printer
"," Printer -> Printer -> Printer
<+> Printer
NewlinePrinter)
((OrderBy -> Printer) -> [OrderBy] -> [Printer]
forall a b. (a -> b) -> [a] -> [b]
map OrderBy -> Printer
fromOrderBy (NonEmpty OrderBy -> [OrderBy]
forall (t :: * -> *) a. Foldable t => t a -> [a]
toList NonEmpty OrderBy
orderBys))
],
case (Top
top, Maybe Expression
moffset) of
(Top
NoTop, Maybe Expression
Nothing) -> Printer
""
(Top
NoTop, Just Expression
offset) ->
Printer
"LIMIT 9223372036854775807 /* Maximum */"
Printer -> Printer -> Printer
<+> Printer
" OFFSET "
Printer -> Printer -> Printer
<+> Expression -> Printer
fromExpression Expression
offset
(Top Int64
n, Maybe Expression
Nothing) -> Printer
"LIMIT " Printer -> Printer -> Printer
<+> Value -> Printer
fromValue (Int64 -> Value
IntegerValue (Int64 -> Int64
intToInt64 Int64
n))
(Top Int64
n, Just Expression
offset) ->
Printer
"LIMIT "
Printer -> Printer -> Printer
<+> Value -> Printer
fromValue (Int64 -> Value
IntegerValue (Int64 -> Int64
intToInt64 Int64
n))
Printer -> Printer -> Printer
<+> Printer
" OFFSET "
Printer -> Printer -> Printer
<+> Expression -> Printer
fromExpression Expression
offset
]
fromOrderBy :: OrderBy -> Printer
fromOrderBy :: OrderBy -> Printer
fromOrderBy OrderBy {FieldName
NullsOrder
Order
$sel:orderByNullsOrder:OrderBy :: OrderBy -> NullsOrder
$sel:orderByOrder:OrderBy :: OrderBy -> Order
$sel:orderByFieldName:OrderBy :: OrderBy -> FieldName
orderByNullsOrder :: NullsOrder
orderByOrder :: Order
orderByFieldName :: FieldName
..} =
Printer
"("
Printer -> Printer -> Printer
<+> FieldName -> Printer
fromFieldName FieldName
orderByFieldName
Printer -> Printer -> Printer
<+> Printer
") "
Printer -> Printer -> Printer
<+> Order -> Printer
fromOrder Order
orderByOrder
Printer -> Printer -> Printer
<+> NullsOrder -> Printer
fromNullsOrder NullsOrder
orderByNullsOrder
fromOrder :: Order -> Printer
fromOrder :: Order -> Printer
fromOrder =
\case
Order
AscOrder -> Printer
"ASC"
Order
DescOrder -> Printer
"DESC"
fromNullsOrder :: NullsOrder -> Printer
fromNullsOrder :: NullsOrder -> Printer
fromNullsOrder =
\case
NullsOrder
NullsAnyOrder -> Printer
""
NullsOrder
NullsFirst -> Printer
" NULLS FIRST"
NullsOrder
NullsLast -> Printer
" NULLS LAST"
fromJoinAlias :: EntityAlias -> Printer
fromJoinAlias :: EntityAlias -> Printer
fromJoinAlias EntityAlias {Text
$sel:entityAliasText:EntityAlias :: EntityAlias -> Text
entityAliasText :: Text
entityAliasText} =
Text -> Printer
fromNameText Text
entityAliasText
fromProjection :: Projection -> Printer
fromProjection :: Projection -> Printer
fromProjection =
\case
WindowProjection Aliased WindowFunction
aliasedWindowFunction ->
Aliased Printer -> Printer
fromAliased ((WindowFunction -> Printer)
-> Aliased WindowFunction -> Aliased Printer
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap WindowFunction -> Printer
fromWindowFunction Aliased WindowFunction
aliasedWindowFunction)
ExpressionProjection Aliased Expression
aliasedExpression ->
Aliased Printer -> Printer
fromAliased ((Expression -> Printer) -> Aliased Expression -> Aliased Printer
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap Expression -> Printer
fromExpression Aliased Expression
aliasedExpression)
FieldNameProjection Aliased FieldName
aliasedFieldName ->
Aliased Printer -> Printer
fromAliased ((FieldName -> Printer) -> Aliased FieldName -> Aliased Printer
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap FieldName -> Printer
fromFieldName Aliased FieldName
aliasedFieldName)
AggregateProjection Aliased Aggregate
aliasedAggregate ->
Aliased Printer -> Printer
fromAliased ((Aggregate -> Printer) -> Aliased Aggregate -> Aliased Printer
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap Aggregate -> Printer
fromAggregate Aliased Aggregate
aliasedAggregate)
AggregateProjections Aliased (NonEmpty (Aliased Aggregate))
aliasedAggregates ->
Aliased Printer -> Printer
fromAliased
( (NonEmpty (Aliased Aggregate) -> Printer)
-> Aliased (NonEmpty (Aliased Aggregate)) -> Aliased Printer
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap
( \NonEmpty (Aliased Aggregate)
aggs ->
Printer
"STRUCT("
Printer -> Printer -> Printer
<+> Int -> Printer -> Printer
IndentPrinter
Int
7
( Printer -> [Printer] -> Printer
SepByPrinter
Printer
", "
((Aliased Aggregate -> Printer) -> [Aliased Aggregate] -> [Printer]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap (Aliased Printer -> Printer
fromAliased (Aliased Printer -> Printer)
-> (Aliased Aggregate -> Aliased Printer)
-> Aliased Aggregate
-> Printer
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Aggregate -> Printer) -> Aliased Aggregate -> Aliased Printer
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap Aggregate -> Printer
fromAggregate) (NonEmpty (Aliased Aggregate) -> [Aliased Aggregate]
forall (t :: * -> *) a. Foldable t => t a -> [a]
toList NonEmpty (Aliased Aggregate)
aggs))
)
Printer -> Printer -> Printer
<+> Printer
")"
)
Aliased (NonEmpty (Aliased Aggregate))
aliasedAggregates
)
Projection
StarProjection -> Printer
"*"
ArrayAggProjection Aliased ArrayAgg
aliasedAgg -> Aliased Printer -> Printer
fromAliased ((ArrayAgg -> Printer) -> Aliased ArrayAgg -> Aliased Printer
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap ArrayAgg -> Printer
fromArrayAgg Aliased ArrayAgg
aliasedAgg)
EntityProjection Aliased [(FieldName, FieldOrigin)]
aliasedEntity ->
Aliased Printer -> Printer
fromAliased
( ([(FieldName, FieldOrigin)] -> Printer)
-> Aliased [(FieldName, FieldOrigin)] -> Aliased Printer
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap
( \([(FieldName, FieldOrigin)]
fields :: [(FieldName, FieldOrigin)]) ->
Printer
"STRUCT("
Printer -> Printer -> Printer
<+> ( Printer -> [Printer] -> Printer
SepByPrinter
Printer
", "
( [(FieldName, FieldOrigin)]
fields
[(FieldName, FieldOrigin)]
-> ((FieldName, FieldOrigin) -> Printer) -> [Printer]
forall (f :: * -> *) a b. Functor f => f a -> (a -> b) -> f b
<&> \(fName :: FieldName
fName@FieldName {Text
fieldNameEntity :: Text
fieldName :: Text
$sel:fieldNameEntity:FieldName :: FieldName -> Text
$sel:fieldName:FieldName :: FieldName -> Text
..}, FieldOrigin
fieldOrigin :: FieldOrigin) ->
Printer
"IFNULL(" Printer -> Printer -> Printer
<+> FieldName -> Printer
fromFieldName FieldName
fName Printer -> Printer -> Printer
<+> Printer
", " Printer -> Printer -> Printer
<+> FieldOrigin -> Printer
fromFieldOrigin FieldOrigin
fieldOrigin
Printer -> Printer -> Printer
<+> Printer
") AS "
Printer -> Printer -> Printer
<+> Text -> Printer
fromNameText Text
fieldName
)
)
Printer -> Printer -> Printer
<+> Printer
")"
)
Aliased [(FieldName, FieldOrigin)]
aliasedEntity
)
ArrayEntityProjection EntityAlias
entityAlias Aliased [FieldName]
aliasedEntity ->
Aliased Printer -> Printer
fromAliased
( ([FieldName] -> Printer) -> Aliased [FieldName] -> Aliased Printer
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap
( \[FieldName]
aggs ->
Printer
"ARRAY(SELECT AS STRUCT "
Printer -> Printer -> Printer
<+> Int -> Printer -> Printer
IndentPrinter
Int
7
(Printer -> [Printer] -> Printer
SepByPrinter Printer
", " ((FieldName -> Printer) -> [FieldName] -> [Printer]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap FieldName -> Printer
fromFieldNameNaked ([FieldName] -> [FieldName]
forall (t :: * -> *) a. Foldable t => t a -> [a]
toList [FieldName]
aggs)))
Printer -> Printer -> Printer
<+> Printer
" FROM "
Printer -> Printer -> Printer
<+> EntityAlias -> Printer
fromJoinAlias EntityAlias
entityAlias
Printer -> Printer -> Printer
<+> Printer
".agg)"
)
Aliased [FieldName]
aliasedEntity
)
where
fromFieldNameNaked :: FieldName -> Printer
fromFieldNameNaked :: FieldName -> Printer
fromFieldNameNaked (FieldName {Text
fieldNameEntity :: Text
fieldName :: Text
$sel:fieldNameEntity:FieldName :: FieldName -> Text
$sel:fieldName:FieldName :: FieldName -> Text
..}) =
Text -> Printer
fromNameText Text
fieldName
fromFieldOrigin :: FieldOrigin -> Printer
fromFieldOrigin :: FieldOrigin -> Printer
fromFieldOrigin = \case
FieldOrigin
NoOrigin -> Printer
"NULL"
AggregateOrigin [Aliased Aggregate]
aliasedAggregates ->
Printer
"STRUCT("
Printer -> Printer -> Printer
<+>
Printer -> [Printer] -> Printer
SepByPrinter Printer
", " (Aliased Printer -> Printer
fromAliased (Aliased Printer -> Printer)
-> (Aliased Aggregate -> Aliased Printer)
-> Aliased Aggregate
-> Printer
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Aggregate -> Printer) -> Aliased Aggregate -> Aliased Printer
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap Aggregate -> Printer
fromNullAggregate (Aliased Aggregate -> Printer) -> [Aliased Aggregate] -> [Printer]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> [Aliased Aggregate]
aliasedAggregates)
Printer -> Printer -> Printer
<+> Printer
")"
fromWindowFunction :: WindowFunction -> Printer
fromWindowFunction :: WindowFunction -> Printer
fromWindowFunction (RowNumberOverPartitionBy NonEmpty FieldName
fieldNames Maybe (NonEmpty OrderBy)
morderBys) =
Printer
"ROW_NUMBER() OVER(PARTITION BY "
Printer -> Printer -> Printer
<+> Printer -> [Printer] -> Printer
SepByPrinter Printer
", " ((FieldName -> Printer) -> [FieldName] -> [Printer]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap FieldName -> Printer
fromFieldName (NonEmpty FieldName -> [FieldName]
forall (t :: * -> *) a. Foldable t => t a -> [a]
toList NonEmpty FieldName
fieldNames))
Printer -> Printer -> Printer
<+> ( case Maybe (NonEmpty OrderBy)
morderBys of
Just {} -> Printer
" " Printer -> Printer -> Printer
<+> Top -> Maybe Expression -> Maybe (NonEmpty OrderBy) -> Printer
fromOrderBys Top
NoTop Maybe Expression
forall a. Maybe a
Nothing Maybe (NonEmpty OrderBy)
morderBys
Maybe (NonEmpty OrderBy)
Nothing -> Printer
""
)
Printer -> Printer -> Printer
<+> Printer
")"
fromArrayAgg :: ArrayAgg -> Printer
fromArrayAgg :: ArrayAgg -> Printer
fromArrayAgg ArrayAgg {Maybe (NonEmpty OrderBy)
NonEmpty Projection
Top
$sel:arrayAggTop:ArrayAgg :: ArrayAgg -> Top
$sel:arrayAggOrderBy:ArrayAgg :: ArrayAgg -> Maybe (NonEmpty OrderBy)
$sel:arrayAggProjections:ArrayAgg :: ArrayAgg -> NonEmpty Projection
arrayAggTop :: Top
arrayAggOrderBy :: Maybe (NonEmpty OrderBy)
arrayAggProjections :: NonEmpty Projection
..} =
[Printer] -> Printer
SeqPrinter
[ Printer
"ARRAY_AGG(",
Int -> Printer -> Printer
IndentPrinter Int
10 (Printer -> Printer) -> Printer -> Printer
forall a b. (a -> b) -> a -> b
$
Printer -> [Printer] -> Printer
SepByPrinter
Printer
" "
[ Printer
"STRUCT(" Printer -> Printer -> Printer
<+> Int -> Printer -> Printer
IndentPrinter Int
7 Printer
projections Printer -> Printer -> Printer
<+> Printer
")",
Top -> Maybe Expression -> Maybe (NonEmpty OrderBy) -> Printer
fromOrderBys
Top
arrayAggTop
Maybe Expression
forall a. Maybe a
Nothing
( (NonEmpty OrderBy -> NonEmpty OrderBy)
-> Maybe (NonEmpty OrderBy) -> Maybe (NonEmpty OrderBy)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap
( (OrderBy -> OrderBy) -> NonEmpty OrderBy -> NonEmpty OrderBy
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap
( \OrderBy
orderBy ->
OrderBy
orderBy
{ $sel:orderByNullsOrder:OrderBy :: NullsOrder
orderByNullsOrder = NullsOrder
NullsAnyOrder
}
)
)
Maybe (NonEmpty OrderBy)
arrayAggOrderBy
)
],
Printer
")"
]
where
projections :: Printer
projections =
Printer -> [Printer] -> Printer
SepByPrinter
(Printer
"," Printer -> Printer -> Printer
<+> Printer
NewlinePrinter)
((Projection -> Printer) -> [Projection] -> [Printer]
forall a b. (a -> b) -> [a] -> [b]
map Projection -> Printer
fromProjection (NonEmpty Projection -> [Projection]
forall (t :: * -> *) a. Foldable t => t a -> [a]
toList (NonEmpty Projection -> NonEmpty Projection
cleanProjections NonEmpty Projection
arrayAggProjections)))
fromNullAggregate :: Aggregate -> Printer
fromNullAggregate :: Aggregate -> Printer
fromNullAggregate = \case
CountAggregate Countable FieldName
_ -> Printer
"0"
OpAggregate Text
_text Expression
_exp -> Printer
"NULL"
OpAggregates Text
_text NonEmpty (Text, Expression)
exps ->
Printer
"STRUCT(" Printer -> Printer -> Printer
<+> Printer -> [Printer] -> Printer
SepByPrinter Printer
", " (NonEmpty (Text, Expression) -> [(Text, Expression)]
forall (t :: * -> *) a. Foldable t => t a -> [a]
toList NonEmpty (Text, Expression)
exps [(Text, Expression)]
-> ((Text, Expression) -> Printer) -> [Printer]
forall (f :: * -> *) a b. Functor f => f a -> (a -> b) -> f b
<&> \(Text
alias, Expression
_exp) -> Printer
"NULL AS " Printer -> Printer -> Printer
<+> Text -> Printer
fromNameText Text
alias) Printer -> Printer -> Printer
<+> Printer
")"
TextAggregate Text
_text -> Printer
"NULL"
fromAggregate :: Aggregate -> Printer
fromAggregate :: Aggregate -> Printer
fromAggregate =
\case
CountAggregate Countable FieldName
countable -> Printer
"COUNT(" Printer -> Printer -> Printer
<+> Countable FieldName -> Printer
fromCountable Countable FieldName
countable Printer -> Printer -> Printer
<+> Printer
")"
OpAggregate Text
text Expression
arg ->
Text -> Printer
UnsafeTextPrinter Text
text Printer -> Printer -> Printer
<+> Printer
"(" Printer -> Printer -> Printer
<+> Expression -> Printer
fromExpression Expression
arg Printer -> Printer -> Printer
<+> Printer
")"
OpAggregates Text
text NonEmpty (Text, Expression)
args ->
Printer
"STRUCT("
Printer -> Printer -> Printer
<+> Int -> Printer -> Printer
IndentPrinter
Int
7
( Printer -> [Printer] -> Printer
SepByPrinter
Printer
", "
( ((Text, Expression) -> Printer)
-> [(Text, Expression)] -> [Printer]
forall a b. (a -> b) -> [a] -> [b]
map
( \(Text
alias, Expression
arg) ->
Text -> Printer
UnsafeTextPrinter Text
text
Printer -> Printer -> Printer
<+> Printer
"("
Printer -> Printer -> Printer
<+> Expression -> Printer
fromExpression Expression
arg
Printer -> Printer -> Printer
<+> Printer
") AS "
Printer -> Printer -> Printer
<+> Text -> Printer
fromNameText Text
alias
)
(NonEmpty (Text, Expression) -> [(Text, Expression)]
forall (t :: * -> *) a. Foldable t => t a -> [a]
toList NonEmpty (Text, Expression)
args)
)
)
Printer -> Printer -> Printer
<+> Printer
")"
TextAggregate Text
text -> Expression -> Printer
fromExpression (Value -> Expression
ValueExpression (Text -> Value
StringValue Text
text))
fromCountable :: Countable FieldName -> Printer
fromCountable :: Countable FieldName -> Printer
fromCountable =
\case
Countable FieldName
StarCountable -> Printer
"*"
NonNullFieldCountable NonEmpty FieldName
fields ->
Printer -> [Printer] -> Printer
SepByPrinter Printer
", " ((FieldName -> Printer) -> [FieldName] -> [Printer]
forall a b. (a -> b) -> [a] -> [b]
map FieldName -> Printer
fromFieldName (NonEmpty FieldName -> [FieldName]
forall (t :: * -> *) a. Foldable t => t a -> [a]
toList NonEmpty FieldName
fields))
DistinctCountable NonEmpty FieldName
fields ->
Printer
"DISTINCT "
Printer -> Printer -> Printer
<+> Printer -> [Printer] -> Printer
SepByPrinter Printer
", " ((FieldName -> Printer) -> [FieldName] -> [Printer]
forall a b. (a -> b) -> [a] -> [b]
map FieldName -> Printer
fromFieldName (NonEmpty FieldName -> [FieldName]
forall (t :: * -> *) a. Foldable t => t a -> [a]
toList NonEmpty FieldName
fields))
fromWhere :: Where -> Printer
fromWhere :: Where -> Printer
fromWhere =
\case
Where [Expression]
expressions ->
case ((Expression -> Bool) -> [Expression] -> [Expression]
forall a. (a -> Bool) -> [a] -> [a]
filter ((Expression -> Expression -> Bool
forall a. Eq a => a -> a -> Bool
/= Expression
trueExpression) (Expression -> Bool)
-> (Expression -> Expression) -> Expression -> Bool
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Expression -> Expression
collapse)) [Expression]
expressions of
[] -> Printer
""
[Expression]
collapsedExpressions ->
Printer
"WHERE "
Printer -> Printer -> Printer
<+> Int -> Printer -> Printer
IndentPrinter Int
6 (Expression -> Printer
fromExpression ([Expression] -> Expression
AndExpression [Expression]
collapsedExpressions))
where
collapse :: Expression -> Expression
collapse (AndExpression [Expression
x]) = Expression -> Expression
collapse Expression
x
collapse (AndExpression []) = Expression
trueExpression
collapse (OrExpression [Expression
x]) = Expression -> Expression
collapse Expression
x
collapse Expression
x = Expression
x
fromSelectJson :: SelectJson -> Printer
fromSelectJson :: SelectJson -> Printer
fromSelectJson SelectJson {[(ColumnName, ScalarType)]
Expression
$sel:selectJsonFields:SelectJson :: SelectJson -> [(ColumnName, ScalarType)]
$sel:selectJsonBody:SelectJson :: SelectJson -> Expression
selectJsonFields :: [(ColumnName, ScalarType)]
selectJsonBody :: Expression
..} = Printer
finalExpression
where
finalExpression :: Printer
finalExpression =
Printer -> [Printer] -> Printer
SepByPrinter
Printer
NewlinePrinter
[ Printer
"SELECT " Printer -> Printer -> Printer
<+> Int -> Printer -> Printer
IndentPrinter Int
7 Printer
fields,
Printer
"FROM UNNEST(JSON_QUERY_ARRAY("
Printer -> Printer -> Printer
<+> Int -> Printer -> Printer
IndentPrinter Int
29 (Expression -> Printer
fromExpression Expression
selectJsonBody)
Printer -> Printer -> Printer
<+> Printer
"))",
Printer
" AS " Printer -> Printer -> Printer
<+> Printer
jsonStringField
]
jsonStringField :: Printer
jsonStringField = Text -> Printer
fromNameText Text
"json"
fields :: Printer
fields =
Printer -> [Printer] -> Printer
SepByPrinter
(Printer
"," Printer -> Printer -> Printer
<+> Printer
NewlinePrinter)
(((ColumnName, ScalarType) -> Printer)
-> [(ColumnName, ScalarType)] -> [Printer]
forall a b. (a -> b) -> [a] -> [b]
map (ColumnName, ScalarType) -> Printer
extractJsonField [(ColumnName, ScalarType)]
selectJsonFields)
extractJsonField :: (ColumnName, ScalarType) -> Printer
extractJsonField (ColumnName Text
name, ScalarType
scalarType) =
Printer
"CAST(JSON_VALUE(" Printer -> Printer -> Printer
<+> Printer
jsonStringField Printer -> Printer -> Printer
<+> Printer
", '$." Printer -> Printer -> Printer
<+> String -> Printer
forall a. IsString a => String -> a
fromString (Text -> String
T.unpack Text
name)
Printer -> Printer -> Printer
<+> Printer
"') AS "
Printer -> Printer -> Printer
<+> ScalarType -> Printer
fromScalarType ScalarType
scalarType
Printer -> Printer -> Printer
<+> Printer
") AS "
Printer -> Printer -> Printer
<+> Text -> Printer
fromNameText Text
name
fromFrom :: From -> Printer
fromFrom :: From -> Printer
fromFrom =
\case
FromQualifiedTable Aliased TableName
aliasedQualifiedTableName ->
Aliased Printer -> Printer
fromAliased ((TableName -> Printer) -> Aliased TableName -> Aliased Printer
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap TableName -> Printer
fromTableName Aliased TableName
aliasedQualifiedTableName)
FromSelect Aliased Select
select -> Aliased Printer -> Printer
fromAliased ((Select -> Printer) -> Aliased Select -> Aliased Printer
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap (Printer -> Printer
parens (Printer -> Printer) -> (Select -> Printer) -> Select -> Printer
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Select -> Printer
fromSelect) Aliased Select
select)
FromSelectJson Aliased SelectJson
selectJson ->
Aliased Printer -> Printer
fromAliased ((SelectJson -> Printer) -> Aliased SelectJson -> Aliased Printer
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap (Printer -> Printer
parens (Printer -> Printer)
-> (SelectJson -> Printer) -> SelectJson -> Printer
forall b c a. (b -> c) -> (a -> b) -> a -> c
. SelectJson -> Printer
fromSelectJson) Aliased SelectJson
selectJson)
FromFunction Aliased SelectFromFunction
selectFromFunction ->
Aliased Printer -> Printer
fromAliased
( (SelectFromFunction -> Printer)
-> Aliased SelectFromFunction -> Aliased Printer
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap
( \SelectFromFunction {[Expression]
FunctionName
$sel:sffArguments:SelectFromFunction :: SelectFromFunction -> [Expression]
$sel:sffFunctionName:SelectFromFunction :: SelectFromFunction -> FunctionName
sffArguments :: [Expression]
sffFunctionName :: FunctionName
..} ->
Expression -> Printer
fromExpression (Expression -> Printer) -> Expression -> Printer
forall a b. (a -> b) -> a -> b
$ FunctionName -> [Expression] -> Expression
FunctionExpression FunctionName
sffFunctionName [Expression]
sffArguments
)
Aliased SelectFromFunction
selectFromFunction
)
fromTableName :: TableName -> Printer
fromTableName :: TableName -> Printer
fromTableName TableName {Text
$sel:tableName:TableName :: TableName -> Text
tableName :: Text
tableName, Text
$sel:tableNameSchema:TableName :: TableName -> Text
tableNameSchema :: Text
tableNameSchema} =
Text -> Printer
fromNameText Text
tableNameSchema Printer -> Printer -> Printer
<+> Printer
"." Printer -> Printer -> Printer
<+> Text -> Printer
fromNameText Text
tableName
fromFunctionName :: FunctionName -> Printer
fromFunctionName :: FunctionName -> Printer
fromFunctionName = \case
FunctionName Text
name Maybe Text
Nothing ->
Text -> Printer
UnsafeTextPrinter Text
name
FunctionName Text
name (Just Text
dataset) -> Text -> Printer
fromNameText Text
dataset Printer -> Printer -> Printer
<+> Printer
"." Printer -> Printer -> Printer
<+> Text -> Printer
fromNameText Text
name
fromAliased :: Aliased Printer -> Printer
fromAliased :: Aliased Printer -> Printer
fromAliased Aliased {Text
Printer
$sel:aliasedAlias:Aliased :: forall a. Aliased a -> Text
$sel:aliasedThing:Aliased :: forall a. Aliased a -> a
aliasedAlias :: Text
aliasedThing :: Printer
..} =
Printer
aliasedThing
Printer -> Printer -> Printer
<+> ((Printer
" AS " Printer -> Printer -> Printer
<+>) (Printer -> Printer) -> (Text -> Printer) -> Text -> Printer
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Text -> Printer
fromNameText) Text
aliasedAlias
fromNameText :: Text -> Printer
fromNameText :: Text -> Printer
fromNameText Text
t = Text -> Printer
UnsafeTextPrinter (Text
"`" Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
t Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
"`")
trueExpression :: Expression
trueExpression :: Expression
trueExpression = Value -> Expression
ValueExpression (Bool -> Value
BoolValue Bool
True)
falseExpression :: Expression
falseExpression :: Expression
falseExpression = Value -> Expression
ValueExpression (Bool -> Value
BoolValue Bool
False)
fromValue :: Value -> Printer
fromValue :: Value -> Printer
fromValue = Value -> Printer
ValuePrinter
parens :: Printer -> Printer
parens :: Printer -> Printer
parens Printer
x = Printer
"(" Printer -> Printer -> Printer
<+> Int -> Printer -> Printer
IndentPrinter Int
1 Printer
x Printer -> Printer -> Printer
<+> Printer
")"
toBuilderFlat :: Printer -> Builder
toBuilderFlat :: Printer -> Builder
toBuilderFlat = (State (InsOrdHashMap Value Int) Builder
-> InsOrdHashMap Value Int -> Builder)
-> InsOrdHashMap Value Int
-> State (InsOrdHashMap Value Int) Builder
-> Builder
forall a b c. (a -> b -> c) -> b -> a -> c
flip State (InsOrdHashMap Value Int) Builder
-> InsOrdHashMap Value Int -> Builder
forall s a. State s a -> s -> a
evalState InsOrdHashMap Value Int
forall a. Monoid a => a
mempty (State (InsOrdHashMap Value Int) Builder -> Builder)
-> (Printer -> State (InsOrdHashMap Value Int) Builder)
-> Printer
-> Builder
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Printer -> State (InsOrdHashMap Value Int) Builder
runBuilderFlat
toBuilderPretty :: Printer -> Builder
toBuilderPretty :: Printer -> Builder
toBuilderPretty = (State (InsOrdHashMap Value Int) Builder
-> InsOrdHashMap Value Int -> Builder)
-> InsOrdHashMap Value Int
-> State (InsOrdHashMap Value Int) Builder
-> Builder
forall a b c. (a -> b -> c) -> b -> a -> c
flip State (InsOrdHashMap Value Int) Builder
-> InsOrdHashMap Value Int -> Builder
forall s a. State s a -> s -> a
evalState InsOrdHashMap Value Int
forall a. Monoid a => a
mempty (State (InsOrdHashMap Value Int) Builder -> Builder)
-> (Printer -> State (InsOrdHashMap Value Int) Builder)
-> Printer
-> Builder
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Printer -> State (InsOrdHashMap Value Int) Builder
runBuilderPretty
toTextPretty :: Printer -> Text
toTextPretty :: Printer -> Text
toTextPretty = Text -> Text
LT.toStrict (Text -> Text) -> (Printer -> Text) -> Printer -> Text
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Builder -> Text
LT.toLazyText (Builder -> Text) -> (Printer -> Builder) -> Printer -> Text
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Printer -> Builder
toBuilderPretty
toTextFlat :: Printer -> Text
toTextFlat :: Printer -> Text
toTextFlat = Text -> Text
LT.toStrict (Text -> Text) -> (Printer -> Text) -> Printer -> Text
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Builder -> Text
LT.toLazyText (Builder -> Text) -> (Printer -> Builder) -> Printer -> Text
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Printer -> Builder
toBuilderFlat
renderBuilderFlat :: Printer -> (Builder, InsOrdHashMap Int Value)
renderBuilderFlat :: Printer -> (Builder, InsOrdHashMap Int Value)
renderBuilderFlat =
(InsOrdHashMap Value Int -> InsOrdHashMap Int Value)
-> (Builder, InsOrdHashMap Value Int)
-> (Builder, InsOrdHashMap Int Value)
forall (p :: * -> * -> *) b c a.
Bifunctor p =>
(b -> c) -> p a b -> p a c
second ([(Int, Value)] -> InsOrdHashMap Int Value
forall k v. (Eq k, Hashable k) => [(k, v)] -> InsOrdHashMap k v
OMap.fromList ([(Int, Value)] -> InsOrdHashMap Int Value)
-> (InsOrdHashMap Value Int -> [(Int, Value)])
-> InsOrdHashMap Value Int
-> InsOrdHashMap Int Value
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ((Value, Int) -> (Int, Value)) -> [(Value, Int)] -> [(Int, Value)]
forall a b. (a -> b) -> [a] -> [b]
map (Value, Int) -> (Int, Value)
forall a b. (a, b) -> (b, a)
swap ([(Value, Int)] -> [(Int, Value)])
-> (InsOrdHashMap Value Int -> [(Value, Int)])
-> InsOrdHashMap Value Int
-> [(Int, Value)]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. InsOrdHashMap Value Int -> [(Value, Int)]
forall k v. InsOrdHashMap k v -> [(k, v)]
OMap.toList) ((Builder, InsOrdHashMap Value Int)
-> (Builder, InsOrdHashMap Int Value))
-> (Printer -> (Builder, InsOrdHashMap Value Int))
-> Printer
-> (Builder, InsOrdHashMap Int Value)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (State (InsOrdHashMap Value Int) Builder
-> InsOrdHashMap Value Int -> (Builder, InsOrdHashMap Value Int))
-> InsOrdHashMap Value Int
-> State (InsOrdHashMap Value Int) Builder
-> (Builder, InsOrdHashMap Value Int)
forall a b c. (a -> b -> c) -> b -> a -> c
flip State (InsOrdHashMap Value Int) Builder
-> InsOrdHashMap Value Int -> (Builder, InsOrdHashMap Value Int)
forall s a. State s a -> s -> (a, s)
runState InsOrdHashMap Value Int
forall a. Monoid a => a
mempty
(State (InsOrdHashMap Value Int) Builder
-> (Builder, InsOrdHashMap Value Int))
-> (Printer -> State (InsOrdHashMap Value Int) Builder)
-> Printer
-> (Builder, InsOrdHashMap Value Int)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Printer -> State (InsOrdHashMap Value Int) Builder
runBuilderFlat
renderBuilderPretty :: Printer -> (Builder, InsOrdHashMap Int Value)
renderBuilderPretty :: Printer -> (Builder, InsOrdHashMap Int Value)
renderBuilderPretty =
(InsOrdHashMap Value Int -> InsOrdHashMap Int Value)
-> (Builder, InsOrdHashMap Value Int)
-> (Builder, InsOrdHashMap Int Value)
forall (p :: * -> * -> *) b c a.
Bifunctor p =>
(b -> c) -> p a b -> p a c
second ([(Int, Value)] -> InsOrdHashMap Int Value
forall k v. (Eq k, Hashable k) => [(k, v)] -> InsOrdHashMap k v
OMap.fromList ([(Int, Value)] -> InsOrdHashMap Int Value)
-> (InsOrdHashMap Value Int -> [(Int, Value)])
-> InsOrdHashMap Value Int
-> InsOrdHashMap Int Value
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ((Value, Int) -> (Int, Value)) -> [(Value, Int)] -> [(Int, Value)]
forall a b. (a -> b) -> [a] -> [b]
map (Value, Int) -> (Int, Value)
forall a b. (a, b) -> (b, a)
swap ([(Value, Int)] -> [(Int, Value)])
-> (InsOrdHashMap Value Int -> [(Value, Int)])
-> InsOrdHashMap Value Int
-> [(Int, Value)]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. InsOrdHashMap Value Int -> [(Value, Int)]
forall k v. InsOrdHashMap k v -> [(k, v)]
OMap.toList) ((Builder, InsOrdHashMap Value Int)
-> (Builder, InsOrdHashMap Int Value))
-> (Printer -> (Builder, InsOrdHashMap Value Int))
-> Printer
-> (Builder, InsOrdHashMap Int Value)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (State (InsOrdHashMap Value Int) Builder
-> InsOrdHashMap Value Int -> (Builder, InsOrdHashMap Value Int))
-> InsOrdHashMap Value Int
-> State (InsOrdHashMap Value Int) Builder
-> (Builder, InsOrdHashMap Value Int)
forall a b c. (a -> b -> c) -> b -> a -> c
flip State (InsOrdHashMap Value Int) Builder
-> InsOrdHashMap Value Int -> (Builder, InsOrdHashMap Value Int)
forall s a. State s a -> s -> (a, s)
runState InsOrdHashMap Value Int
forall a. Monoid a => a
mempty
(State (InsOrdHashMap Value Int) Builder
-> (Builder, InsOrdHashMap Value Int))
-> (Printer -> State (InsOrdHashMap Value Int) Builder)
-> Printer
-> (Builder, InsOrdHashMap Value Int)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Printer -> State (InsOrdHashMap Value Int) Builder
runBuilderPretty
paramName :: Int -> Builder
paramName :: Int -> Builder
paramName Int
next = Builder
"param" Builder -> Builder -> Builder
forall a. Semigroup a => a -> a -> a
<> String -> Builder
forall a. IsString a => String -> a
fromString (Int -> String
forall a. Show a => a -> String
show Int
next)
runBuilderFlat :: Printer -> State (InsOrdHashMap Value Int) Builder
runBuilderFlat :: Printer -> State (InsOrdHashMap Value Int) Builder
runBuilderFlat = Int -> Printer -> State (InsOrdHashMap Value Int) Builder
go Int
0
where
go :: Int -> Printer -> State (InsOrdHashMap Value Int) Builder
go Int
level =
\case
UnsafeTextPrinter Text
q -> Builder -> State (InsOrdHashMap Value Int) Builder
forall (f :: * -> *) a. Applicative f => a -> f a
pure (Text -> Builder
LT.fromText Text
q)
SeqPrinter [Printer]
xs -> ([Builder] -> Builder)
-> StateT (InsOrdHashMap Value Int) Identity [Builder]
-> State (InsOrdHashMap Value Int) Builder
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap ([Builder] -> Builder
forall a. Monoid a => [a] -> a
mconcat ([Builder] -> Builder)
-> ([Builder] -> [Builder]) -> [Builder] -> Builder
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Builder -> Bool) -> [Builder] -> [Builder]
forall a. (a -> Bool) -> [a] -> [a]
filter Builder -> Bool
notEmpty) ((Printer -> State (InsOrdHashMap Value Int) Builder)
-> [Printer] -> StateT (InsOrdHashMap Value Int) Identity [Builder]
forall (t :: * -> *) (m :: * -> *) a b.
(Traversable t, Monad m) =>
(a -> m b) -> t a -> m (t b)
mapM (Int -> Printer -> State (InsOrdHashMap Value Int) Builder
go Int
level) [Printer]
xs)
SepByPrinter Printer
x [Printer]
xs -> do
Builder
i <- Int -> Printer -> State (InsOrdHashMap Value Int) Builder
go Int
level Printer
x
([Builder] -> Builder)
-> StateT (InsOrdHashMap Value Int) Identity [Builder]
-> State (InsOrdHashMap Value Int) Builder
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap ([Builder] -> Builder
forall a. Monoid a => [a] -> a
mconcat ([Builder] -> Builder)
-> ([Builder] -> [Builder]) -> [Builder] -> Builder
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Builder -> [Builder] -> [Builder]
forall a. a -> [a] -> [a]
intersperse Builder
i ([Builder] -> [Builder])
-> ([Builder] -> [Builder]) -> [Builder] -> [Builder]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Builder -> Bool) -> [Builder] -> [Builder]
forall a. (a -> Bool) -> [a] -> [a]
filter Builder -> Bool
notEmpty) ((Printer -> State (InsOrdHashMap Value Int) Builder)
-> [Printer] -> StateT (InsOrdHashMap Value Int) Identity [Builder]
forall (t :: * -> *) (m :: * -> *) a b.
(Traversable t, Monad m) =>
(a -> m b) -> t a -> m (t b)
mapM (Int -> Printer -> State (InsOrdHashMap Value Int) Builder
go Int
level) [Printer]
xs)
Printer
NewlinePrinter -> Builder -> State (InsOrdHashMap Value Int) Builder
forall (f :: * -> *) a. Applicative f => a -> f a
pure Builder
" "
IndentPrinter Int
n Printer
p -> Int -> Printer -> State (InsOrdHashMap Value Int) Builder
go (Int
level Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
n) Printer
p
ValuePrinter (ArrayValue Vector Value
x) | Vector Value -> Bool
forall a. Vector a -> Bool
V.null Vector Value
x -> Builder -> State (InsOrdHashMap Value Int) Builder
forall (f :: * -> *) a. Applicative f => a -> f a
pure Builder
"[]"
ValuePrinter Value
v -> do
InsOrdHashMap Value Int
themap <- StateT (InsOrdHashMap Value Int) Identity (InsOrdHashMap Value Int)
forall s (m :: * -> *). MonadState s m => m s
get
Int
next <-
Value -> InsOrdHashMap Value Int -> Maybe Int
forall k v. (Eq k, Hashable k) => k -> InsOrdHashMap k v -> Maybe v
OMap.lookup Value
v InsOrdHashMap Value Int
themap Maybe Int
-> StateT (InsOrdHashMap Value Int) Identity Int
-> StateT (InsOrdHashMap Value Int) Identity Int
forall (m :: * -> *) a. Applicative m => Maybe a -> m a -> m a
`onNothing` do
Int
next <- (InsOrdHashMap Value Int -> Int)
-> StateT (InsOrdHashMap Value Int) Identity Int
forall s (m :: * -> *) a. MonadState s m => (s -> a) -> m a
gets InsOrdHashMap Value Int -> Int
forall k v. InsOrdHashMap k v -> Int
OMap.size
(InsOrdHashMap Value Int -> InsOrdHashMap Value Int)
-> StateT (InsOrdHashMap Value Int) Identity ()
forall s (m :: * -> *). MonadState s m => (s -> s) -> m ()
modify (Value -> Int -> InsOrdHashMap Value Int -> InsOrdHashMap Value Int
forall k v.
(Eq k, Hashable k) =>
k -> v -> InsOrdHashMap k v -> InsOrdHashMap k v
OMap.insert Value
v Int
next)
Int -> StateT (InsOrdHashMap Value Int) Identity Int
forall (f :: * -> *) a. Applicative f => a -> f a
pure Int
next
Builder -> State (InsOrdHashMap Value Int) Builder
forall (f :: * -> *) a. Applicative f => a -> f a
pure (Builder
"@" Builder -> Builder -> Builder
forall a. Semigroup a => a -> a -> a
<> Int -> Builder
paramName Int
next)
notEmpty :: Builder -> Bool
notEmpty = (Builder -> Builder -> Bool
forall a. Eq a => a -> a -> Bool
/= Builder
forall a. Monoid a => a
mempty)
runBuilderPretty :: Printer -> State (InsOrdHashMap Value Int) Builder
runBuilderPretty :: Printer -> State (InsOrdHashMap Value Int) Builder
runBuilderPretty = Int -> Printer -> State (InsOrdHashMap Value Int) Builder
go Int
0
where
go :: Int -> Printer -> State (InsOrdHashMap Value Int) Builder
go Int
level =
\case
UnsafeTextPrinter Text
q -> Builder -> State (InsOrdHashMap Value Int) Builder
forall (f :: * -> *) a. Applicative f => a -> f a
pure (Text -> Builder
LT.fromText Text
q)
SeqPrinter [Printer]
xs -> ([Builder] -> Builder)
-> StateT (InsOrdHashMap Value Int) Identity [Builder]
-> State (InsOrdHashMap Value Int) Builder
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap ([Builder] -> Builder
forall a. Monoid a => [a] -> a
mconcat ([Builder] -> Builder)
-> ([Builder] -> [Builder]) -> [Builder] -> Builder
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Builder -> Bool) -> [Builder] -> [Builder]
forall a. (a -> Bool) -> [a] -> [a]
filter Builder -> Bool
notEmpty) ((Printer -> State (InsOrdHashMap Value Int) Builder)
-> [Printer] -> StateT (InsOrdHashMap Value Int) Identity [Builder]
forall (t :: * -> *) (m :: * -> *) a b.
(Traversable t, Monad m) =>
(a -> m b) -> t a -> m (t b)
mapM (Int -> Printer -> State (InsOrdHashMap Value Int) Builder
go Int
level) [Printer]
xs)
SepByPrinter Printer
x [Printer]
xs -> do
Builder
i <- Int -> Printer -> State (InsOrdHashMap Value Int) Builder
go Int
level Printer
x
([Builder] -> Builder)
-> StateT (InsOrdHashMap Value Int) Identity [Builder]
-> State (InsOrdHashMap Value Int) Builder
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap ([Builder] -> Builder
forall a. Monoid a => [a] -> a
mconcat ([Builder] -> Builder)
-> ([Builder] -> [Builder]) -> [Builder] -> Builder
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Builder -> [Builder] -> [Builder]
forall a. a -> [a] -> [a]
intersperse Builder
i ([Builder] -> [Builder])
-> ([Builder] -> [Builder]) -> [Builder] -> [Builder]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Builder -> Bool) -> [Builder] -> [Builder]
forall a. (a -> Bool) -> [a] -> [a]
filter Builder -> Bool
notEmpty) ((Printer -> State (InsOrdHashMap Value Int) Builder)
-> [Printer] -> StateT (InsOrdHashMap Value Int) Identity [Builder]
forall (t :: * -> *) (m :: * -> *) a b.
(Traversable t, Monad m) =>
(a -> m b) -> t a -> m (t b)
mapM (Int -> Printer -> State (InsOrdHashMap Value Int) Builder
go Int
level) [Printer]
xs)
Printer
NewlinePrinter -> Builder -> State (InsOrdHashMap Value Int) Builder
forall (f :: * -> *) a. Applicative f => a -> f a
pure (Builder
"\n" Builder -> Builder -> Builder
forall a. Semigroup a => a -> a -> a
<> Int -> Builder
indentation Int
level)
IndentPrinter Int
n Printer
p -> Int -> Printer -> State (InsOrdHashMap Value Int) Builder
go (Int
level Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
n) Printer
p
ValuePrinter (ArrayValue Vector Value
x)
| Vector Value -> Bool
forall a. Vector a -> Bool
V.null Vector Value
x -> Builder -> State (InsOrdHashMap Value Int) Builder
forall (f :: * -> *) a. Applicative f => a -> f a
pure Builder
"[]"
ValuePrinter Value
v -> do
InsOrdHashMap Value Int
themap <- StateT (InsOrdHashMap Value Int) Identity (InsOrdHashMap Value Int)
forall s (m :: * -> *). MonadState s m => m s
get
Int
next <-
Value -> InsOrdHashMap Value Int -> Maybe Int
forall k v. (Eq k, Hashable k) => k -> InsOrdHashMap k v -> Maybe v
OMap.lookup Value
v InsOrdHashMap Value Int
themap Maybe Int
-> StateT (InsOrdHashMap Value Int) Identity Int
-> StateT (InsOrdHashMap Value Int) Identity Int
forall (m :: * -> *) a. Applicative m => Maybe a -> m a -> m a
`onNothing` do
Int
next <- (InsOrdHashMap Value Int -> Int)
-> StateT (InsOrdHashMap Value Int) Identity Int
forall s (m :: * -> *) a. MonadState s m => (s -> a) -> m a
gets InsOrdHashMap Value Int -> Int
forall k v. InsOrdHashMap k v -> Int
OMap.size
(InsOrdHashMap Value Int -> InsOrdHashMap Value Int)
-> StateT (InsOrdHashMap Value Int) Identity ()
forall s (m :: * -> *). MonadState s m => (s -> s) -> m ()
modify (Value -> Int -> InsOrdHashMap Value Int -> InsOrdHashMap Value Int
forall k v.
(Eq k, Hashable k) =>
k -> v -> InsOrdHashMap k v -> InsOrdHashMap k v
OMap.insert Value
v Int
next)
Int -> StateT (InsOrdHashMap Value Int) Identity Int
forall (f :: * -> *) a. Applicative f => a -> f a
pure Int
next
Builder -> State (InsOrdHashMap Value Int) Builder
forall (f :: * -> *) a. Applicative f => a -> f a
pure (Builder
"@" Builder -> Builder -> Builder
forall a. Semigroup a => a -> a -> a
<> Int -> Builder
paramName Int
next)
indentation :: Int -> Builder
indentation Int
n = Text -> Builder
LT.fromText (Int -> Text -> Text
T.replicate Int
n Text
" ")
notEmpty :: Builder -> Bool
notEmpty = (Builder -> Builder -> Bool
forall a. Eq a => a -> a -> Bool
/= Builder
forall a. Monoid a => a
mempty)
cleanProjections :: NonEmpty Projection -> NonEmpty Projection
cleanProjections :: NonEmpty Projection -> NonEmpty Projection
cleanProjections = NonEmpty Projection -> NonEmpty Projection
neOrdNub
where
neOrdNub :: NonEmpty Projection -> NonEmpty Projection
neOrdNub :: NonEmpty Projection -> NonEmpty Projection
neOrdNub = [Projection] -> NonEmpty Projection
forall a. [a] -> NonEmpty a
NE.fromList ([Projection] -> NonEmpty Projection)
-> (NonEmpty Projection -> [Projection])
-> NonEmpty Projection
-> NonEmpty Projection
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Projection -> Maybe Text) -> [Projection] -> [Projection]
forall b a. Ord b => (a -> b) -> [a] -> [a]
nubOrdOn Projection -> Maybe Text
projectionAlias ([Projection] -> [Projection])
-> (NonEmpty Projection -> [Projection])
-> NonEmpty Projection
-> [Projection]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. NonEmpty Projection -> [Projection]
forall a. NonEmpty a -> [a]
NE.toList