{-# OPTIONS_GHC -Wno-missing-signatures -Wno-dodgy-imports #-}

module PostgresqlSyntax.Rendering
  ( toText,
    module PostgresqlSyntax.Rendering,
  )
where

import qualified Data.Text as Text
import qualified Data.Text.Encoding as Text
import PostgresqlSyntax.Ast
import qualified PostgresqlSyntax.Extras.NonEmpty as NonEmpty
import PostgresqlSyntax.Extras.TextBuilder
import PostgresqlSyntax.Prelude hiding (aExpr, bit, fromList, many, option, sortBy, try)
import TextBuilder

-- * Execution

toByteString :: TextBuilder -> ByteString
toByteString :: TextBuilder -> ByteString
toByteString = Text -> ByteString
Text.encodeUtf8 (Text -> ByteString)
-> (TextBuilder -> Text) -> TextBuilder -> ByteString
forall b c a. (b -> c) -> (a -> b) -> a -> c
forall {k} (cat :: k -> k -> *) (b :: k) (c :: k) (a :: k).
Category cat =>
cat b c -> cat a b -> cat a c
. TextBuilder -> Text
toText

-- * Helpers

commaNonEmpty :: (a -> TextBuilder) -> NonEmpty a -> TextBuilder
commaNonEmpty :: forall a. (a -> TextBuilder) -> NonEmpty a -> TextBuilder
commaNonEmpty = TextBuilder -> (a -> TextBuilder) -> NonEmpty a -> TextBuilder
forall m a. Monoid m => m -> (a -> m) -> NonEmpty a -> m
NonEmpty.intersperseFoldMap TextBuilder
", "

spaceNonEmpty :: (a -> TextBuilder) -> NonEmpty a -> TextBuilder
spaceNonEmpty :: forall a. (a -> TextBuilder) -> NonEmpty a -> TextBuilder
spaceNonEmpty = TextBuilder -> (a -> TextBuilder) -> NonEmpty a -> TextBuilder
forall m a. Monoid m => m -> (a -> m) -> NonEmpty a -> m
NonEmpty.intersperseFoldMap TextBuilder
" "

lexemes :: [TextBuilder] -> TextBuilder
lexemes :: [TextBuilder] -> TextBuilder
lexemes = [TextBuilder] -> TextBuilder
forall a. Monoid a => [a] -> a
mconcat ([TextBuilder] -> TextBuilder)
-> ([TextBuilder] -> [TextBuilder]) -> [TextBuilder] -> TextBuilder
forall b c a. (b -> c) -> (a -> b) -> a -> c
forall {k} (cat :: k -> k -> *) (b :: k) (c :: k) (a :: k).
Category cat =>
cat b c -> cat a b -> cat a c
. TextBuilder -> [TextBuilder] -> [TextBuilder]
forall a. a -> [a] -> [a]
intersperse TextBuilder
" "

optLexemes :: [Maybe TextBuilder] -> TextBuilder
optLexemes :: [Maybe TextBuilder] -> TextBuilder
optLexemes = [TextBuilder] -> TextBuilder
lexemes ([TextBuilder] -> TextBuilder)
-> ([Maybe TextBuilder] -> [TextBuilder])
-> [Maybe TextBuilder]
-> TextBuilder
forall b c a. (b -> c) -> (a -> b) -> a -> c
forall {k} (cat :: k -> k -> *) (b :: k) (c :: k) (a :: k).
Category cat =>
cat b c -> cat a b -> cat a c
. [Maybe TextBuilder] -> [TextBuilder]
forall a. [Maybe a] -> [a]
catMaybes

inParens :: TextBuilder -> TextBuilder
inParens :: TextBuilder -> TextBuilder
inParens TextBuilder
a = TextBuilder
"(" TextBuilder -> TextBuilder -> TextBuilder
forall a. Semigroup a => a -> a -> a
<> TextBuilder
a TextBuilder -> TextBuilder -> TextBuilder
forall a. Semigroup a => a -> a -> a
<> TextBuilder
")"

inBrackets :: TextBuilder -> TextBuilder
inBrackets :: TextBuilder -> TextBuilder
inBrackets TextBuilder
a = TextBuilder
"[" TextBuilder -> TextBuilder -> TextBuilder
forall a. Semigroup a => a -> a -> a
<> TextBuilder
a TextBuilder -> TextBuilder -> TextBuilder
forall a. Semigroup a => a -> a -> a
<> TextBuilder
"]"

prefixMaybe :: (a -> TextBuilder) -> Maybe a -> TextBuilder
prefixMaybe :: forall a. (a -> TextBuilder) -> Maybe a -> TextBuilder
prefixMaybe a -> TextBuilder
a = (a -> TextBuilder) -> Maybe a -> TextBuilder
forall m a. Monoid m => (a -> m) -> Maybe a -> m
forall (t :: * -> *) m a.
(Foldable t, Monoid m) =>
(a -> m) -> t a -> m
foldMap ((TextBuilder -> TextBuilder -> TextBuilder)
-> TextBuilder -> TextBuilder -> TextBuilder
forall a b c. (a -> b -> c) -> b -> a -> c
flip TextBuilder -> TextBuilder -> TextBuilder
forall a. Monoid a => a -> a -> a
mappend TextBuilder
" " (TextBuilder -> TextBuilder)
-> (a -> TextBuilder) -> a -> TextBuilder
forall b c a. (b -> c) -> (a -> b) -> a -> c
forall {k} (cat :: k -> k -> *) (b :: k) (c :: k) (a :: k).
Category cat =>
cat b c -> cat a b -> cat a c
. a -> TextBuilder
a)

suffixMaybe :: (a -> TextBuilder) -> Maybe a -> TextBuilder
suffixMaybe :: forall a. (a -> TextBuilder) -> Maybe a -> TextBuilder
suffixMaybe a -> TextBuilder
a = (a -> TextBuilder) -> Maybe a -> TextBuilder
forall m a. Monoid m => (a -> m) -> Maybe a -> m
forall (t :: * -> *) m a.
(Foldable t, Monoid m) =>
(a -> m) -> t a -> m
foldMap (TextBuilder -> TextBuilder -> TextBuilder
forall a. Monoid a => a -> a -> a
mappend TextBuilder
" " (TextBuilder -> TextBuilder)
-> (a -> TextBuilder) -> a -> TextBuilder
forall b c a. (b -> c) -> (a -> b) -> a -> c
forall {k} (cat :: k -> k -> *) (b :: k) (c :: k) (a :: k).
Category cat =>
cat b c -> cat a b -> cat a c
. a -> TextBuilder
a)

-- * Statements

preparableStmt :: PreparableStmt -> TextBuilder
preparableStmt = \case
  SelectPreparableStmt SelectStmt
a -> SelectStmt -> TextBuilder
selectStmt SelectStmt
a
  InsertPreparableStmt InsertStmt
a -> InsertStmt -> TextBuilder
insertStmt InsertStmt
a
  UpdatePreparableStmt UpdateStmt
a -> UpdateStmt -> TextBuilder
updateStmt UpdateStmt
a
  DeletePreparableStmt DeleteStmt
a -> DeleteStmt -> TextBuilder
deleteStmt DeleteStmt
a
  CallPreparableStmt CallStmt
a -> CallStmt -> TextBuilder
callStmt CallStmt
a

-- * Call

callStmt :: CallStmt -> TextBuilder
callStmt (CallStmt FuncApplication
a) =
  TextBuilder
"CALL " TextBuilder -> TextBuilder -> TextBuilder
forall a. Semigroup a => a -> a -> a
<> FuncApplication -> TextBuilder
funcApplication FuncApplication
a

-- * Insert

insertStmt :: InsertStmt -> TextBuilder
insertStmt (InsertStmt Maybe WithClause
a InsertTarget
b InsertRest
c Maybe OnConflict
d Maybe ReturningClause
e) =
  (WithClause -> TextBuilder) -> Maybe WithClause -> TextBuilder
forall a. (a -> TextBuilder) -> Maybe a -> TextBuilder
prefixMaybe WithClause -> TextBuilder
withClause Maybe WithClause
a
    TextBuilder -> TextBuilder -> TextBuilder
forall a. Semigroup a => a -> a -> a
<> TextBuilder
"INSERT INTO "
    TextBuilder -> TextBuilder -> TextBuilder
forall a. Semigroup a => a -> a -> a
<> InsertTarget -> TextBuilder
insertTarget InsertTarget
b
    TextBuilder -> TextBuilder -> TextBuilder
forall a. Semigroup a => a -> a -> a
<> TextBuilder
" "
    TextBuilder -> TextBuilder -> TextBuilder
forall a. Semigroup a => a -> a -> a
<> InsertRest -> TextBuilder
insertRest InsertRest
c
    TextBuilder -> TextBuilder -> TextBuilder
forall a. Semigroup a => a -> a -> a
<> (OnConflict -> TextBuilder) -> Maybe OnConflict -> TextBuilder
forall a. (a -> TextBuilder) -> Maybe a -> TextBuilder
suffixMaybe OnConflict -> TextBuilder
onConflict Maybe OnConflict
d
    TextBuilder -> TextBuilder -> TextBuilder
forall a. Semigroup a => a -> a -> a
<> (ReturningClause -> TextBuilder)
-> Maybe ReturningClause -> TextBuilder
forall a. (a -> TextBuilder) -> Maybe a -> TextBuilder
suffixMaybe ReturningClause -> TextBuilder
returningClause Maybe ReturningClause
e

insertTarget :: InsertTarget -> TextBuilder
insertTarget (InsertTarget QualifiedName
a Maybe ColId
b) =
  QualifiedName -> TextBuilder
qualifiedName QualifiedName
a TextBuilder -> TextBuilder -> TextBuilder
forall a. Semigroup a => a -> a -> a
<> (ColId -> TextBuilder) -> Maybe ColId -> TextBuilder
forall m a. Monoid m => (a -> m) -> Maybe a -> m
forall (t :: * -> *) m a.
(Foldable t, Monoid m) =>
(a -> m) -> t a -> m
foldMap (TextBuilder -> TextBuilder -> TextBuilder
forall a. Monoid a => a -> a -> a
mappend TextBuilder
" AS " (TextBuilder -> TextBuilder)
-> (ColId -> TextBuilder) -> ColId -> TextBuilder
forall b c a. (b -> c) -> (a -> b) -> a -> c
forall {k} (cat :: k -> k -> *) (b :: k) (c :: k) (a :: k).
Category cat =>
cat b c -> cat a b -> cat a c
. ColId -> TextBuilder
colId) Maybe ColId
b

insertRest :: InsertRest -> TextBuilder
insertRest = \case
  SelectInsertRest Maybe InsertColumnList
a Maybe OverrideKind
b SelectStmt
c ->
    [Maybe TextBuilder] -> TextBuilder
optLexemes
      [ (InsertColumnList -> TextBuilder)
-> Maybe InsertColumnList -> Maybe TextBuilder
forall a b. (a -> b) -> Maybe a -> Maybe b
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap (TextBuilder -> TextBuilder
inParens (TextBuilder -> TextBuilder)
-> (InsertColumnList -> TextBuilder)
-> InsertColumnList
-> TextBuilder
forall b c a. (b -> c) -> (a -> b) -> a -> c
forall {k} (cat :: k -> k -> *) (b :: k) (c :: k) (a :: k).
Category cat =>
cat b c -> cat a b -> cat a c
. InsertColumnList -> TextBuilder
insertColumnList) Maybe InsertColumnList
a,
        (OverrideKind -> TextBuilder)
-> Maybe OverrideKind -> Maybe TextBuilder
forall a b. (a -> b) -> Maybe a -> Maybe b
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap OverrideKind -> TextBuilder
forall {a}. (Semigroup a, IsString a) => OverrideKind -> a
insertRestOverriding Maybe OverrideKind
b,
        TextBuilder -> Maybe TextBuilder
forall a. a -> Maybe a
Just (SelectStmt -> TextBuilder
selectStmt SelectStmt
c)
      ]
  InsertRest
DefaultValuesInsertRest -> TextBuilder
"DEFAULT VALUES"

insertRestOverriding :: OverrideKind -> a
insertRestOverriding OverrideKind
a = a
"OVERRIDING " a -> a -> a
forall a. Semigroup a => a -> a -> a
<> OverrideKind -> a
forall {a}. IsString a => OverrideKind -> a
overrideKind OverrideKind
a a -> a -> a
forall a. Semigroup a => a -> a -> a
<> a
" VALUE"

overrideKind :: OverrideKind -> a
overrideKind = \case
  OverrideKind
UserOverrideKind -> a
"USER"
  OverrideKind
SystemOverrideKind -> a
"SYSTEM"

insertColumnList :: InsertColumnList -> TextBuilder
insertColumnList = (InsertColumnItem -> TextBuilder)
-> InsertColumnList -> TextBuilder
forall a. (a -> TextBuilder) -> NonEmpty a -> TextBuilder
commaNonEmpty InsertColumnItem -> TextBuilder
insertColumnItem

insertColumnItem :: InsertColumnItem -> TextBuilder
insertColumnItem (InsertColumnItem ColId
a Maybe Indirection
b) = ColId -> TextBuilder
colId ColId
a TextBuilder -> TextBuilder -> TextBuilder
forall a. Semigroup a => a -> a -> a
<> (Indirection -> TextBuilder) -> Maybe Indirection -> TextBuilder
forall a. (a -> TextBuilder) -> Maybe a -> TextBuilder
suffixMaybe Indirection -> TextBuilder
indirection Maybe Indirection
b

onConflict :: OnConflict -> TextBuilder
onConflict (OnConflict Maybe ConfExpr
a OnConflictDo
b) = TextBuilder
"ON CONFLICT" TextBuilder -> TextBuilder -> TextBuilder
forall a. Semigroup a => a -> a -> a
<> (ConfExpr -> TextBuilder) -> Maybe ConfExpr -> TextBuilder
forall a. (a -> TextBuilder) -> Maybe a -> TextBuilder
suffixMaybe ConfExpr -> TextBuilder
confExpr Maybe ConfExpr
a TextBuilder -> TextBuilder -> TextBuilder
forall a. Semigroup a => a -> a -> a
<> TextBuilder
" DO " TextBuilder -> TextBuilder -> TextBuilder
forall a. Semigroup a => a -> a -> a
<> OnConflictDo -> TextBuilder
onConflictDo OnConflictDo
b

onConflictDo :: OnConflictDo -> TextBuilder
onConflictDo = \case
  UpdateOnConflictDo SetClauseList
a Maybe WhereClause
b -> TextBuilder
"UPDATE SET " TextBuilder -> TextBuilder -> TextBuilder
forall a. Semigroup a => a -> a -> a
<> SetClauseList -> TextBuilder
setClauseList SetClauseList
a TextBuilder -> TextBuilder -> TextBuilder
forall a. Semigroup a => a -> a -> a
<> (WhereClause -> TextBuilder) -> Maybe WhereClause -> TextBuilder
forall a. (a -> TextBuilder) -> Maybe a -> TextBuilder
suffixMaybe WhereClause -> TextBuilder
whereClause Maybe WhereClause
b
  OnConflictDo
NothingOnConflictDo -> TextBuilder
"NOTHING"

confExpr :: ConfExpr -> TextBuilder
confExpr = \case
  WhereConfExpr IndexParams
a Maybe WhereClause
b -> TextBuilder -> TextBuilder
inParens (IndexParams -> TextBuilder
indexParams IndexParams
a) TextBuilder -> TextBuilder -> TextBuilder
forall a. Semigroup a => a -> a -> a
<> (WhereClause -> TextBuilder) -> Maybe WhereClause -> TextBuilder
forall a. (a -> TextBuilder) -> Maybe a -> TextBuilder
suffixMaybe WhereClause -> TextBuilder
whereClause Maybe WhereClause
b
  ConstraintConfExpr ColId
a -> TextBuilder
"ON CONSTRAINT " TextBuilder -> TextBuilder -> TextBuilder
forall a. Semigroup a => a -> a -> a
<> ColId -> TextBuilder
name ColId
a

returningClause :: ReturningClause -> TextBuilder
returningClause = TextBuilder -> TextBuilder -> TextBuilder
forall a. Monoid a => a -> a -> a
mappend TextBuilder
"RETURNING " (TextBuilder -> TextBuilder)
-> (ReturningClause -> TextBuilder)
-> ReturningClause
-> TextBuilder
forall b c a. (b -> c) -> (a -> b) -> a -> c
forall {k} (cat :: k -> k -> *) (b :: k) (c :: k) (a :: k).
Category cat =>
cat b c -> cat a b -> cat a c
. ReturningClause -> TextBuilder
targetList

-- * Update

updateStmt :: UpdateStmt -> TextBuilder
updateStmt (UpdateStmt Maybe WithClause
a RelationExprOptAlias
b SetClauseList
c Maybe FromClause
d Maybe WhereOrCurrentClause
e Maybe ReturningClause
f) =
  (WithClause -> TextBuilder) -> Maybe WithClause -> TextBuilder
forall a. (a -> TextBuilder) -> Maybe a -> TextBuilder
prefixMaybe WithClause -> TextBuilder
withClause Maybe WithClause
a
    TextBuilder -> TextBuilder -> TextBuilder
forall a. Semigroup a => a -> a -> a
<> TextBuilder
"UPDATE "
    TextBuilder -> TextBuilder -> TextBuilder
forall a. Semigroup a => a -> a -> a
<> RelationExprOptAlias -> TextBuilder
relationExprOptAlias RelationExprOptAlias
b
    TextBuilder -> TextBuilder -> TextBuilder
forall a. Semigroup a => a -> a -> a
<> TextBuilder
" "
    TextBuilder -> TextBuilder -> TextBuilder
forall a. Semigroup a => a -> a -> a
<> TextBuilder
"SET "
    TextBuilder -> TextBuilder -> TextBuilder
forall a. Semigroup a => a -> a -> a
<> SetClauseList -> TextBuilder
setClauseList SetClauseList
c
    TextBuilder -> TextBuilder -> TextBuilder
forall a. Semigroup a => a -> a -> a
<> (FromClause -> TextBuilder) -> Maybe FromClause -> TextBuilder
forall a. (a -> TextBuilder) -> Maybe a -> TextBuilder
suffixMaybe FromClause -> TextBuilder
fromClause Maybe FromClause
d
    TextBuilder -> TextBuilder -> TextBuilder
forall a. Semigroup a => a -> a -> a
<> (WhereOrCurrentClause -> TextBuilder)
-> Maybe WhereOrCurrentClause -> TextBuilder
forall a. (a -> TextBuilder) -> Maybe a -> TextBuilder
suffixMaybe WhereOrCurrentClause -> TextBuilder
whereOrCurrentClause Maybe WhereOrCurrentClause
e
    TextBuilder -> TextBuilder -> TextBuilder
forall a. Semigroup a => a -> a -> a
<> (ReturningClause -> TextBuilder)
-> Maybe ReturningClause -> TextBuilder
forall a. (a -> TextBuilder) -> Maybe a -> TextBuilder
suffixMaybe ReturningClause -> TextBuilder
returningClause Maybe ReturningClause
f

setClauseList :: SetClauseList -> TextBuilder
setClauseList = (SetClause -> TextBuilder) -> SetClauseList -> TextBuilder
forall a. (a -> TextBuilder) -> NonEmpty a -> TextBuilder
commaNonEmpty SetClause -> TextBuilder
setClause

setClause :: SetClause -> TextBuilder
setClause = \case
  TargetSetClause SetTarget
a WhereClause
b -> SetTarget -> TextBuilder
setTarget SetTarget
a TextBuilder -> TextBuilder -> TextBuilder
forall a. Semigroup a => a -> a -> a
<> TextBuilder
" = " TextBuilder -> TextBuilder -> TextBuilder
forall a. Semigroup a => a -> a -> a
<> WhereClause -> TextBuilder
aExpr WhereClause
b
  TargetListSetClause SetTargetList
a WhereClause
b -> TextBuilder -> TextBuilder
inParens (SetTargetList -> TextBuilder
setTargetList SetTargetList
a) TextBuilder -> TextBuilder -> TextBuilder
forall a. Semigroup a => a -> a -> a
<> TextBuilder
" = " TextBuilder -> TextBuilder -> TextBuilder
forall a. Semigroup a => a -> a -> a
<> WhereClause -> TextBuilder
aExpr WhereClause
b

setTarget :: SetTarget -> TextBuilder
setTarget (SetTarget ColId
a Maybe Indirection
b) = ColId -> TextBuilder
colId ColId
a TextBuilder -> TextBuilder -> TextBuilder
forall a. Semigroup a => a -> a -> a
<> (Indirection -> TextBuilder) -> Maybe Indirection -> TextBuilder
forall a. (a -> TextBuilder) -> Maybe a -> TextBuilder
suffixMaybe Indirection -> TextBuilder
indirection Maybe Indirection
b

setTargetList :: SetTargetList -> TextBuilder
setTargetList = (SetTarget -> TextBuilder) -> SetTargetList -> TextBuilder
forall a. (a -> TextBuilder) -> NonEmpty a -> TextBuilder
commaNonEmpty SetTarget -> TextBuilder
setTarget

-- * Delete

deleteStmt :: DeleteStmt -> TextBuilder
deleteStmt (DeleteStmt Maybe WithClause
a RelationExprOptAlias
b Maybe FromClause
c Maybe WhereOrCurrentClause
d Maybe ReturningClause
e) =
  (WithClause -> TextBuilder) -> Maybe WithClause -> TextBuilder
forall a. (a -> TextBuilder) -> Maybe a -> TextBuilder
prefixMaybe WithClause -> TextBuilder
withClause Maybe WithClause
a
    TextBuilder -> TextBuilder -> TextBuilder
forall a. Semigroup a => a -> a -> a
<> TextBuilder
"DELETE FROM "
    TextBuilder -> TextBuilder -> TextBuilder
forall a. Semigroup a => a -> a -> a
<> RelationExprOptAlias -> TextBuilder
relationExprOptAlias RelationExprOptAlias
b
    TextBuilder -> TextBuilder -> TextBuilder
forall a. Semigroup a => a -> a -> a
<> (FromClause -> TextBuilder) -> Maybe FromClause -> TextBuilder
forall a. (a -> TextBuilder) -> Maybe a -> TextBuilder
suffixMaybe FromClause -> TextBuilder
usingClause Maybe FromClause
c
    TextBuilder -> TextBuilder -> TextBuilder
forall a. Semigroup a => a -> a -> a
<> (WhereOrCurrentClause -> TextBuilder)
-> Maybe WhereOrCurrentClause -> TextBuilder
forall a. (a -> TextBuilder) -> Maybe a -> TextBuilder
suffixMaybe WhereOrCurrentClause -> TextBuilder
whereOrCurrentClause Maybe WhereOrCurrentClause
d
    TextBuilder -> TextBuilder -> TextBuilder
forall a. Semigroup a => a -> a -> a
<> (ReturningClause -> TextBuilder)
-> Maybe ReturningClause -> TextBuilder
forall a. (a -> TextBuilder) -> Maybe a -> TextBuilder
suffixMaybe ReturningClause -> TextBuilder
returningClause Maybe ReturningClause
e

usingClause :: FromClause -> TextBuilder
usingClause = TextBuilder -> TextBuilder -> TextBuilder
forall a. Monoid a => a -> a -> a
mappend TextBuilder
"USING " (TextBuilder -> TextBuilder)
-> (FromClause -> TextBuilder) -> FromClause -> TextBuilder
forall b c a. (b -> c) -> (a -> b) -> a -> c
forall {k} (cat :: k -> k -> *) (b :: k) (c :: k) (a :: k).
Category cat =>
cat b c -> cat a b -> cat a c
. FromClause -> TextBuilder
fromList

-- * Select

selectStmt :: SelectStmt -> TextBuilder
selectStmt = \case
  Left SelectNoParens
a -> SelectNoParens -> TextBuilder
selectNoParens SelectNoParens
a
  Right SelectWithParens
a -> SelectWithParens -> TextBuilder
selectWithParens SelectWithParens
a

selectNoParens :: SelectNoParens -> TextBuilder
selectNoParens (SelectNoParens Maybe WithClause
a SelectClause
b Maybe SortClause
c Maybe SelectLimit
d Maybe ForLockingClause
e) =
  [Maybe TextBuilder] -> TextBuilder
optLexemes
    [ (WithClause -> TextBuilder)
-> Maybe WithClause -> Maybe TextBuilder
forall a b. (a -> b) -> Maybe a -> Maybe b
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap WithClause -> TextBuilder
withClause Maybe WithClause
a,
      TextBuilder -> Maybe TextBuilder
forall a. a -> Maybe a
Just (SelectClause -> TextBuilder
selectClause SelectClause
b),
      (SortClause -> TextBuilder)
-> Maybe SortClause -> Maybe TextBuilder
forall a b. (a -> b) -> Maybe a -> Maybe b
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap SortClause -> TextBuilder
sortClause Maybe SortClause
c,
      (SelectLimit -> TextBuilder)
-> Maybe SelectLimit -> Maybe TextBuilder
forall a b. (a -> b) -> Maybe a -> Maybe b
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap SelectLimit -> TextBuilder
selectLimit Maybe SelectLimit
d,
      (ForLockingClause -> TextBuilder)
-> Maybe ForLockingClause -> Maybe TextBuilder
forall a b. (a -> b) -> Maybe a -> Maybe b
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap ForLockingClause -> TextBuilder
forLockingClause Maybe ForLockingClause
e
    ]

selectWithParens :: SelectWithParens -> TextBuilder
selectWithParens =
  TextBuilder -> TextBuilder
inParens (TextBuilder -> TextBuilder)
-> (SelectWithParens -> TextBuilder)
-> SelectWithParens
-> TextBuilder
forall b c a. (b -> c) -> (a -> b) -> a -> c
forall {k} (cat :: k -> k -> *) (b :: k) (c :: k) (a :: k).
Category cat =>
cat b c -> cat a b -> cat a c
. \case
    NoParensSelectWithParens SelectNoParens
a -> SelectNoParens -> TextBuilder
selectNoParens SelectNoParens
a
    WithParensSelectWithParens SelectWithParens
a -> SelectWithParens -> TextBuilder
selectWithParens SelectWithParens
a

withClause :: WithClause -> TextBuilder
withClause (WithClause Bool
a NonEmpty CommonTableExpr
b) =
  TextBuilder
"WITH " TextBuilder -> TextBuilder -> TextBuilder
forall a. Semigroup a => a -> a -> a
<> TextBuilder -> TextBuilder -> Bool -> TextBuilder
forall a. a -> a -> Bool -> a
bool TextBuilder
"" TextBuilder
"RECURSIVE " Bool
a TextBuilder -> TextBuilder -> TextBuilder
forall a. Semigroup a => a -> a -> a
<> (CommonTableExpr -> TextBuilder)
-> NonEmpty CommonTableExpr -> TextBuilder
forall a. (a -> TextBuilder) -> NonEmpty a -> TextBuilder
commaNonEmpty CommonTableExpr -> TextBuilder
commonTableExpr NonEmpty CommonTableExpr
b

commonTableExpr :: CommonTableExpr -> TextBuilder
commonTableExpr (CommonTableExpr ColId
a Maybe (NonEmpty ColId)
b Maybe Bool
c PreparableStmt
d) =
  [Maybe TextBuilder] -> TextBuilder
optLexemes
    [ TextBuilder -> Maybe TextBuilder
forall a. a -> Maybe a
Just (ColId -> TextBuilder
ident ColId
a),
      (NonEmpty ColId -> TextBuilder)
-> Maybe (NonEmpty ColId) -> Maybe TextBuilder
forall a b. (a -> b) -> Maybe a -> Maybe b
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap (TextBuilder -> TextBuilder
inParens (TextBuilder -> TextBuilder)
-> (NonEmpty ColId -> TextBuilder) -> NonEmpty ColId -> TextBuilder
forall b c a. (b -> c) -> (a -> b) -> a -> c
forall {k} (cat :: k -> k -> *) (b :: k) (c :: k) (a :: k).
Category cat =>
cat b c -> cat a b -> cat a c
. (ColId -> TextBuilder) -> NonEmpty ColId -> TextBuilder
forall a. (a -> TextBuilder) -> NonEmpty a -> TextBuilder
commaNonEmpty ColId -> TextBuilder
ident) Maybe (NonEmpty ColId)
b,
      TextBuilder -> Maybe TextBuilder
forall a. a -> Maybe a
Just TextBuilder
"AS",
      (Bool -> TextBuilder) -> Maybe Bool -> Maybe TextBuilder
forall a b. (a -> b) -> Maybe a -> Maybe b
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap Bool -> TextBuilder
forall {a}. IsString a => Bool -> a
materialization Maybe Bool
c,
      TextBuilder -> Maybe TextBuilder
forall a. a -> Maybe a
Just (TextBuilder -> TextBuilder
inParens (PreparableStmt -> TextBuilder
preparableStmt PreparableStmt
d))
    ]

materialization :: Bool -> a
materialization = a -> a -> Bool -> a
forall a. a -> a -> Bool -> a
bool a
"NOT MATERIALIZED" a
"MATERIALIZED"

selectLimit :: SelectLimit -> TextBuilder
selectLimit = \case
  LimitOffsetSelectLimit LimitClause
a OffsetClause
b -> [TextBuilder] -> TextBuilder
lexemes [LimitClause -> TextBuilder
limitClause LimitClause
a, OffsetClause -> TextBuilder
offsetClause OffsetClause
b]
  OffsetLimitSelectLimit OffsetClause
a LimitClause
b -> [TextBuilder] -> TextBuilder
lexemes [OffsetClause -> TextBuilder
offsetClause OffsetClause
a, LimitClause -> TextBuilder
limitClause LimitClause
b]
  LimitSelectLimit LimitClause
a -> LimitClause -> TextBuilder
limitClause LimitClause
a
  OffsetSelectLimit OffsetClause
a -> OffsetClause -> TextBuilder
offsetClause OffsetClause
a

limitClause :: LimitClause -> TextBuilder
limitClause = \case
  LimitLimitClause SelectLimitValue
a Maybe WhereClause
b -> TextBuilder
"LIMIT " TextBuilder -> TextBuilder -> TextBuilder
forall a. Semigroup a => a -> a -> a
<> SelectLimitValue -> TextBuilder
selectLimitValue SelectLimitValue
a TextBuilder -> TextBuilder -> TextBuilder
forall a. Semigroup a => a -> a -> a
<> (WhereClause -> TextBuilder) -> Maybe WhereClause -> TextBuilder
forall m a. Monoid m => (a -> m) -> Maybe a -> m
forall (t :: * -> *) m a.
(Foldable t, Monoid m) =>
(a -> m) -> t a -> m
foldMap (TextBuilder -> TextBuilder -> TextBuilder
forall a. Monoid a => a -> a -> a
mappend TextBuilder
", " (TextBuilder -> TextBuilder)
-> (WhereClause -> TextBuilder) -> WhereClause -> TextBuilder
forall b c a. (b -> c) -> (a -> b) -> a -> c
forall {k} (cat :: k -> k -> *) (b :: k) (c :: k) (a :: k).
Category cat =>
cat b c -> cat a b -> cat a c
. WhereClause -> TextBuilder
aExpr) Maybe WhereClause
b
  FetchOnlyLimitClause Bool
a Maybe SelectFetchFirstValue
b Bool
c ->
    [Maybe TextBuilder] -> TextBuilder
optLexemes
      [ TextBuilder -> Maybe TextBuilder
forall a. a -> Maybe a
Just TextBuilder
"FETCH",
        TextBuilder -> Maybe TextBuilder
forall a. a -> Maybe a
Just (Bool -> TextBuilder
forall {a}. IsString a => Bool -> a
firstOrNext Bool
a),
        (SelectFetchFirstValue -> TextBuilder)
-> Maybe SelectFetchFirstValue -> Maybe TextBuilder
forall a b. (a -> b) -> Maybe a -> Maybe b
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap SelectFetchFirstValue -> TextBuilder
selectFetchFirstValue Maybe SelectFetchFirstValue
b,
        TextBuilder -> Maybe TextBuilder
forall a. a -> Maybe a
Just (Bool -> TextBuilder
forall {a}. IsString a => Bool -> a
rowOrRows Bool
c),
        TextBuilder -> Maybe TextBuilder
forall a. a -> Maybe a
Just TextBuilder
"ONLY"
      ]

firstOrNext :: Bool -> a
firstOrNext = a -> a -> Bool -> a
forall a. a -> a -> Bool -> a
bool a
"FIRST" a
"NEXT"

rowOrRows :: Bool -> a
rowOrRows = a -> a -> Bool -> a
forall a. a -> a -> Bool -> a
bool a
"ROW" a
"ROWS"

selectFetchFirstValue :: SelectFetchFirstValue -> TextBuilder
selectFetchFirstValue = \case
  ExprSelectFetchFirstValue CExpr
a -> CExpr -> TextBuilder
cExpr CExpr
a
  NumSelectFetchFirstValue Bool
a Either Int64 Double
b -> TextBuilder -> TextBuilder -> Bool -> TextBuilder
forall a. a -> a -> Bool -> a
bool TextBuilder
"+" TextBuilder
"-" Bool
a TextBuilder -> TextBuilder -> TextBuilder
forall a. Semigroup a => a -> a -> a
<> Either Int64 Double -> TextBuilder
intOrFloat Either Int64 Double
b

intOrFloat :: Either Int64 Double -> TextBuilder
intOrFloat = (Int64 -> TextBuilder)
-> (Double -> TextBuilder) -> Either Int64 Double -> TextBuilder
forall a c b. (a -> c) -> (b -> c) -> Either a b -> c
either Int64 -> TextBuilder
int64Dec Double -> TextBuilder
doubleDec

selectLimitValue :: SelectLimitValue -> TextBuilder
selectLimitValue = \case
  ExprSelectLimitValue WhereClause
a -> WhereClause -> TextBuilder
aExpr WhereClause
a
  SelectLimitValue
AllSelectLimitValue -> TextBuilder
"ALL"

offsetClause :: OffsetClause -> TextBuilder
offsetClause = \case
  ExprOffsetClause WhereClause
a -> TextBuilder
"OFFSET " TextBuilder -> TextBuilder -> TextBuilder
forall a. Semigroup a => a -> a -> a
<> WhereClause -> TextBuilder
aExpr WhereClause
a
  FetchFirstOffsetClause SelectFetchFirstValue
a Bool
b -> TextBuilder
"OFFSET " TextBuilder -> TextBuilder -> TextBuilder
forall a. Semigroup a => a -> a -> a
<> SelectFetchFirstValue -> TextBuilder
selectFetchFirstValue SelectFetchFirstValue
a TextBuilder -> TextBuilder -> TextBuilder
forall a. Semigroup a => a -> a -> a
<> TextBuilder
" " TextBuilder -> TextBuilder -> TextBuilder
forall a. Semigroup a => a -> a -> a
<> Bool -> TextBuilder
forall {a}. IsString a => Bool -> a
rowOrRows Bool
b

forLockingClause :: ForLockingClause -> TextBuilder
forLockingClause = \case
  ItemsForLockingClause NonEmpty ForLockingItem
a -> (ForLockingItem -> TextBuilder)
-> NonEmpty ForLockingItem -> TextBuilder
forall a. (a -> TextBuilder) -> NonEmpty a -> TextBuilder
spaceNonEmpty ForLockingItem -> TextBuilder
forLockingItem NonEmpty ForLockingItem
a
  ForLockingClause
ReadOnlyForLockingClause -> TextBuilder
"FOR READ ONLY"

forLockingItem :: ForLockingItem -> TextBuilder
forLockingItem (ForLockingItem ForLockingStrength
a Maybe (NonEmpty QualifiedName)
b Maybe Bool
c) =
  [Maybe TextBuilder] -> TextBuilder
optLexemes
    [ TextBuilder -> Maybe TextBuilder
forall a. a -> Maybe a
Just (ForLockingStrength -> TextBuilder
forall {a}. IsString a => ForLockingStrength -> a
forLockingStrength ForLockingStrength
a),
      (NonEmpty QualifiedName -> TextBuilder)
-> Maybe (NonEmpty QualifiedName) -> Maybe TextBuilder
forall a b. (a -> b) -> Maybe a -> Maybe b
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap NonEmpty QualifiedName -> TextBuilder
lockedRelsList Maybe (NonEmpty QualifiedName)
b,
      (Bool -> TextBuilder) -> Maybe Bool -> Maybe TextBuilder
forall a b. (a -> b) -> Maybe a -> Maybe b
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap Bool -> TextBuilder
forall {a}. IsString a => Bool -> a
nowaitOrSkip Maybe Bool
c
    ]

forLockingStrength :: ForLockingStrength -> a
forLockingStrength = \case
  ForLockingStrength
UpdateForLockingStrength -> a
"FOR UPDATE"
  ForLockingStrength
NoKeyUpdateForLockingStrength -> a
"FOR NO KEY UPDATE"
  ForLockingStrength
ShareForLockingStrength -> a
"FOR SHARE"
  ForLockingStrength
KeyForLockingStrength -> a
"FOR KEY SHARE"

lockedRelsList :: NonEmpty QualifiedName -> TextBuilder
lockedRelsList NonEmpty QualifiedName
a = TextBuilder
"OF " TextBuilder -> TextBuilder -> TextBuilder
forall a. Semigroup a => a -> a -> a
<> (QualifiedName -> TextBuilder)
-> NonEmpty QualifiedName -> TextBuilder
forall a. (a -> TextBuilder) -> NonEmpty a -> TextBuilder
commaNonEmpty QualifiedName -> TextBuilder
qualifiedName NonEmpty QualifiedName
a

nowaitOrSkip :: Bool -> a
nowaitOrSkip = a -> a -> Bool -> a
forall a. a -> a -> Bool -> a
bool a
"NOWAIT" a
"SKIP LOCKED"

selectClause :: SelectClause -> TextBuilder
selectClause = (SimpleSelect -> TextBuilder)
-> (SelectWithParens -> TextBuilder) -> SelectClause -> TextBuilder
forall a c b. (a -> c) -> (b -> c) -> Either a b -> c
either SimpleSelect -> TextBuilder
simpleSelect SelectWithParens -> TextBuilder
selectWithParens

simpleSelect :: SimpleSelect -> TextBuilder
simpleSelect = \case
  NormalSimpleSelect Maybe Targeting
a Maybe IntoClause
b Maybe FromClause
c Maybe WhereClause
d Maybe GroupClause
e Maybe WhereClause
f Maybe WindowClause
g ->
    [Maybe TextBuilder] -> TextBuilder
optLexemes
      [ TextBuilder -> Maybe TextBuilder
forall a. a -> Maybe a
Just TextBuilder
"SELECT",
        (Targeting -> TextBuilder) -> Maybe Targeting -> Maybe TextBuilder
forall a b. (a -> b) -> Maybe a -> Maybe b
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap Targeting -> TextBuilder
targeting Maybe Targeting
a,
        (IntoClause -> TextBuilder)
-> Maybe IntoClause -> Maybe TextBuilder
forall a b. (a -> b) -> Maybe a -> Maybe b
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap IntoClause -> TextBuilder
intoClause Maybe IntoClause
b,
        (FromClause -> TextBuilder)
-> Maybe FromClause -> Maybe TextBuilder
forall a b. (a -> b) -> Maybe a -> Maybe b
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap FromClause -> TextBuilder
fromClause Maybe FromClause
c,
        (WhereClause -> TextBuilder)
-> Maybe WhereClause -> Maybe TextBuilder
forall a b. (a -> b) -> Maybe a -> Maybe b
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap WhereClause -> TextBuilder
whereClause Maybe WhereClause
d,
        (GroupClause -> TextBuilder)
-> Maybe GroupClause -> Maybe TextBuilder
forall a b. (a -> b) -> Maybe a -> Maybe b
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap GroupClause -> TextBuilder
groupClause Maybe GroupClause
e,
        (WhereClause -> TextBuilder)
-> Maybe WhereClause -> Maybe TextBuilder
forall a b. (a -> b) -> Maybe a -> Maybe b
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap WhereClause -> TextBuilder
havingClause Maybe WhereClause
f,
        (WindowClause -> TextBuilder)
-> Maybe WindowClause -> Maybe TextBuilder
forall a b. (a -> b) -> Maybe a -> Maybe b
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap WindowClause -> TextBuilder
windowClause Maybe WindowClause
g
      ]
  ValuesSimpleSelect ValuesClause
a -> ValuesClause -> TextBuilder
valuesClause ValuesClause
a
  TableSimpleSelect RelationExpr
a -> TextBuilder
"TABLE " TextBuilder -> TextBuilder -> TextBuilder
forall a. Semigroup a => a -> a -> a
<> RelationExpr -> TextBuilder
relationExpr RelationExpr
a
  BinSimpleSelect SelectBinOp
a SelectClause
b Maybe Bool
c SelectClause
d -> SelectClause -> TextBuilder
selectClause SelectClause
b TextBuilder -> TextBuilder -> TextBuilder
forall a. Semigroup a => a -> a -> a
<> TextBuilder
" " TextBuilder -> TextBuilder -> TextBuilder
forall a. Semigroup a => a -> a -> a
<> SelectBinOp -> TextBuilder
forall {a}. IsString a => SelectBinOp -> a
selectBinOp SelectBinOp
a TextBuilder -> TextBuilder -> TextBuilder
forall a. Semigroup a => a -> a -> a
<> (Bool -> TextBuilder) -> Maybe Bool -> TextBuilder
forall m a. Monoid m => (a -> m) -> Maybe a -> m
forall (t :: * -> *) m a.
(Foldable t, Monoid m) =>
(a -> m) -> t a -> m
foldMap (TextBuilder -> TextBuilder -> TextBuilder
forall a. Monoid a => a -> a -> a
mappend TextBuilder
" " (TextBuilder -> TextBuilder)
-> (Bool -> TextBuilder) -> Bool -> TextBuilder
forall b c a. (b -> c) -> (a -> b) -> a -> c
forall {k} (cat :: k -> k -> *) (b :: k) (c :: k) (a :: k).
Category cat =>
cat b c -> cat a b -> cat a c
. Bool -> TextBuilder
forall {a}. IsString a => Bool -> a
allOrDistinct) Maybe Bool
c TextBuilder -> TextBuilder -> TextBuilder
forall a. Semigroup a => a -> a -> a
<> TextBuilder
" " TextBuilder -> TextBuilder -> TextBuilder
forall a. Semigroup a => a -> a -> a
<> SelectClause -> TextBuilder
selectClause SelectClause
d

selectBinOp :: SelectBinOp -> a
selectBinOp = \case
  SelectBinOp
UnionSelectBinOp -> a
"UNION"
  SelectBinOp
IntersectSelectBinOp -> a
"INTERSECT"
  SelectBinOp
ExceptSelectBinOp -> a
"EXCEPT"

targeting :: Targeting -> TextBuilder
targeting = \case
  NormalTargeting ReturningClause
a -> ReturningClause -> TextBuilder
targetList ReturningClause
a
  AllTargeting Maybe ReturningClause
a -> TextBuilder
"ALL" TextBuilder -> TextBuilder -> TextBuilder
forall a. Semigroup a => a -> a -> a
<> (ReturningClause -> TextBuilder)
-> Maybe ReturningClause -> TextBuilder
forall a. (a -> TextBuilder) -> Maybe a -> TextBuilder
suffixMaybe ReturningClause -> TextBuilder
targetList Maybe ReturningClause
a
  DistinctTargeting Maybe ExprList
a ReturningClause
b -> TextBuilder
"DISTINCT" TextBuilder -> TextBuilder -> TextBuilder
forall a. Semigroup a => a -> a -> a
<> (ExprList -> TextBuilder) -> Maybe ExprList -> TextBuilder
forall a. (a -> TextBuilder) -> Maybe a -> TextBuilder
suffixMaybe ExprList -> TextBuilder
onExpressionsClause Maybe ExprList
a TextBuilder -> TextBuilder -> TextBuilder
forall a. Semigroup a => a -> a -> a
<> TextBuilder
" " TextBuilder -> TextBuilder -> TextBuilder
forall a. Semigroup a => a -> a -> a
<> (TargetEl -> TextBuilder) -> ReturningClause -> TextBuilder
forall a. (a -> TextBuilder) -> NonEmpty a -> TextBuilder
commaNonEmpty TargetEl -> TextBuilder
targetEl ReturningClause
b

targetList :: ReturningClause -> TextBuilder
targetList = (TargetEl -> TextBuilder) -> ReturningClause -> TextBuilder
forall a. (a -> TextBuilder) -> NonEmpty a -> TextBuilder
commaNonEmpty TargetEl -> TextBuilder
targetEl

onExpressionsClause :: ExprList -> TextBuilder
onExpressionsClause ExprList
a = TextBuilder
"ON (" TextBuilder -> TextBuilder -> TextBuilder
forall a. Semigroup a => a -> a -> a
<> (WhereClause -> TextBuilder) -> ExprList -> TextBuilder
forall a. (a -> TextBuilder) -> NonEmpty a -> TextBuilder
commaNonEmpty WhereClause -> TextBuilder
aExpr ExprList
a TextBuilder -> TextBuilder -> TextBuilder
forall a. Semigroup a => a -> a -> a
<> TextBuilder
")"

targetEl :: TargetEl -> TextBuilder
targetEl = \case
  AliasedExprTargetEl WhereClause
a ColId
b -> WhereClause -> TextBuilder
aExpr WhereClause
a TextBuilder -> TextBuilder -> TextBuilder
forall a. Semigroup a => a -> a -> a
<> TextBuilder
" AS " TextBuilder -> TextBuilder -> TextBuilder
forall a. Semigroup a => a -> a -> a
<> ColId -> TextBuilder
ident ColId
b
  ImplicitlyAliasedExprTargetEl WhereClause
a ColId
b -> WhereClause -> TextBuilder
aExpr WhereClause
a TextBuilder -> TextBuilder -> TextBuilder
forall a. Semigroup a => a -> a -> a
<> TextBuilder
" " TextBuilder -> TextBuilder -> TextBuilder
forall a. Semigroup a => a -> a -> a
<> ColId -> TextBuilder
ident ColId
b
  ExprTargetEl WhereClause
a -> WhereClause -> TextBuilder
aExpr WhereClause
a
  TargetEl
AsteriskTargetEl -> TextBuilder
"*"

-- * Select Into

intoClause :: IntoClause -> TextBuilder
intoClause IntoClause
a = TextBuilder
"INTO " TextBuilder -> TextBuilder -> TextBuilder
forall a. Semigroup a => a -> a -> a
<> IntoClause -> TextBuilder
optTempTableName IntoClause
a

optTempTableName :: IntoClause -> TextBuilder
optTempTableName = \case
  TemporaryOptTempTableName Bool
a QualifiedName
b -> [Maybe TextBuilder] -> TextBuilder
optLexemes [TextBuilder -> Maybe TextBuilder
forall a. a -> Maybe a
Just TextBuilder
"TEMPORARY", Maybe TextBuilder -> Maybe TextBuilder -> Bool -> Maybe TextBuilder
forall a. a -> a -> Bool -> a
bool Maybe TextBuilder
forall a. Maybe a
Nothing (TextBuilder -> Maybe TextBuilder
forall a. a -> Maybe a
Just TextBuilder
"TABLE") Bool
a, TextBuilder -> Maybe TextBuilder
forall a. a -> Maybe a
Just (QualifiedName -> TextBuilder
qualifiedName QualifiedName
b)]
  TempOptTempTableName Bool
a QualifiedName
b -> [Maybe TextBuilder] -> TextBuilder
optLexemes [TextBuilder -> Maybe TextBuilder
forall a. a -> Maybe a
Just TextBuilder
"TEMP", Maybe TextBuilder -> Maybe TextBuilder -> Bool -> Maybe TextBuilder
forall a. a -> a -> Bool -> a
bool Maybe TextBuilder
forall a. Maybe a
Nothing (TextBuilder -> Maybe TextBuilder
forall a. a -> Maybe a
Just TextBuilder
"TABLE") Bool
a, TextBuilder -> Maybe TextBuilder
forall a. a -> Maybe a
Just (QualifiedName -> TextBuilder
qualifiedName QualifiedName
b)]
  LocalTemporaryOptTempTableName Bool
a QualifiedName
b -> [Maybe TextBuilder] -> TextBuilder
optLexemes [TextBuilder -> Maybe TextBuilder
forall a. a -> Maybe a
Just TextBuilder
"LOCAL TEMPORARY", Maybe TextBuilder -> Maybe TextBuilder -> Bool -> Maybe TextBuilder
forall a. a -> a -> Bool -> a
bool Maybe TextBuilder
forall a. Maybe a
Nothing (TextBuilder -> Maybe TextBuilder
forall a. a -> Maybe a
Just TextBuilder
"TABLE") Bool
a, TextBuilder -> Maybe TextBuilder
forall a. a -> Maybe a
Just (QualifiedName -> TextBuilder
qualifiedName QualifiedName
b)]
  LocalTempOptTempTableName Bool
a QualifiedName
b -> [Maybe TextBuilder] -> TextBuilder
optLexemes [TextBuilder -> Maybe TextBuilder
forall a. a -> Maybe a
Just TextBuilder
"LOCAL TEMP", Maybe TextBuilder -> Maybe TextBuilder -> Bool -> Maybe TextBuilder
forall a. a -> a -> Bool -> a
bool Maybe TextBuilder
forall a. Maybe a
Nothing (TextBuilder -> Maybe TextBuilder
forall a. a -> Maybe a
Just TextBuilder
"TABLE") Bool
a, TextBuilder -> Maybe TextBuilder
forall a. a -> Maybe a
Just (QualifiedName -> TextBuilder
qualifiedName QualifiedName
b)]
  GlobalTemporaryOptTempTableName Bool
a QualifiedName
b -> [Maybe TextBuilder] -> TextBuilder
optLexemes [TextBuilder -> Maybe TextBuilder
forall a. a -> Maybe a
Just TextBuilder
"GLOBAL TEMPORARY", Maybe TextBuilder -> Maybe TextBuilder -> Bool -> Maybe TextBuilder
forall a. a -> a -> Bool -> a
bool Maybe TextBuilder
forall a. Maybe a
Nothing (TextBuilder -> Maybe TextBuilder
forall a. a -> Maybe a
Just TextBuilder
"TABLE") Bool
a, TextBuilder -> Maybe TextBuilder
forall a. a -> Maybe a
Just (QualifiedName -> TextBuilder
qualifiedName QualifiedName
b)]
  GlobalTempOptTempTableName Bool
a QualifiedName
b -> [Maybe TextBuilder] -> TextBuilder
optLexemes [TextBuilder -> Maybe TextBuilder
forall a. a -> Maybe a
Just TextBuilder
"GLOBAL TEMP", Maybe TextBuilder -> Maybe TextBuilder -> Bool -> Maybe TextBuilder
forall a. a -> a -> Bool -> a
bool Maybe TextBuilder
forall a. Maybe a
Nothing (TextBuilder -> Maybe TextBuilder
forall a. a -> Maybe a
Just TextBuilder
"TABLE") Bool
a, TextBuilder -> Maybe TextBuilder
forall a. a -> Maybe a
Just (QualifiedName -> TextBuilder
qualifiedName QualifiedName
b)]
  UnloggedOptTempTableName Bool
a QualifiedName
b -> [Maybe TextBuilder] -> TextBuilder
optLexemes [TextBuilder -> Maybe TextBuilder
forall a. a -> Maybe a
Just TextBuilder
"UNLOGGED", Maybe TextBuilder -> Maybe TextBuilder -> Bool -> Maybe TextBuilder
forall a. a -> a -> Bool -> a
bool Maybe TextBuilder
forall a. Maybe a
Nothing (TextBuilder -> Maybe TextBuilder
forall a. a -> Maybe a
Just TextBuilder
"TABLE") Bool
a, TextBuilder -> Maybe TextBuilder
forall a. a -> Maybe a
Just (QualifiedName -> TextBuilder
qualifiedName QualifiedName
b)]
  TableOptTempTableName QualifiedName
a -> TextBuilder
"TABLE " TextBuilder -> TextBuilder -> TextBuilder
forall a. Semigroup a => a -> a -> a
<> QualifiedName -> TextBuilder
qualifiedName QualifiedName
a
  QualifedOptTempTableName QualifiedName
a -> QualifiedName -> TextBuilder
qualifiedName QualifiedName
a

-- * From

fromClause :: FromClause -> TextBuilder
fromClause FromClause
a = TextBuilder
"FROM " TextBuilder -> TextBuilder -> TextBuilder
forall a. Semigroup a => a -> a -> a
<> FromClause -> TextBuilder
fromList FromClause
a

fromList :: FromClause -> TextBuilder
fromList = (TableRef -> TextBuilder) -> FromClause -> TextBuilder
forall a. (a -> TextBuilder) -> NonEmpty a -> TextBuilder
commaNonEmpty TableRef -> TextBuilder
tableRef

tableRef :: TableRef -> TextBuilder
tableRef = \case
  RelationExprTableRef RelationExpr
a Maybe AliasClause
b Maybe TablesampleClause
c ->
    [Maybe TextBuilder] -> TextBuilder
optLexemes
      [ TextBuilder -> Maybe TextBuilder
forall a. a -> Maybe a
Just (RelationExpr -> TextBuilder
relationExpr RelationExpr
a),
        (AliasClause -> TextBuilder)
-> Maybe AliasClause -> Maybe TextBuilder
forall a b. (a -> b) -> Maybe a -> Maybe b
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap AliasClause -> TextBuilder
aliasClause Maybe AliasClause
b,
        (TablesampleClause -> TextBuilder)
-> Maybe TablesampleClause -> Maybe TextBuilder
forall a b. (a -> b) -> Maybe a -> Maybe b
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap TablesampleClause -> TextBuilder
tablesampleClause Maybe TablesampleClause
c
      ]
  FuncTableRef Bool
a FuncTable
b Maybe FuncAliasClause
c ->
    [Maybe TextBuilder] -> TextBuilder
optLexemes
      [ if Bool
a then TextBuilder -> Maybe TextBuilder
forall a. a -> Maybe a
Just TextBuilder
"LATERAL" else Maybe TextBuilder
forall a. Maybe a
Nothing,
        TextBuilder -> Maybe TextBuilder
forall a. a -> Maybe a
Just (FuncTable -> TextBuilder
funcTable FuncTable
b),
        (FuncAliasClause -> TextBuilder)
-> Maybe FuncAliasClause -> Maybe TextBuilder
forall a b. (a -> b) -> Maybe a -> Maybe b
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap FuncAliasClause -> TextBuilder
funcAliasClause Maybe FuncAliasClause
c
      ]
  SelectTableRef Bool
a SelectWithParens
b Maybe AliasClause
c ->
    [Maybe TextBuilder] -> TextBuilder
optLexemes
      [ if Bool
a then TextBuilder -> Maybe TextBuilder
forall a. a -> Maybe a
Just TextBuilder
"LATERAL" else Maybe TextBuilder
forall a. Maybe a
Nothing,
        TextBuilder -> Maybe TextBuilder
forall a. a -> Maybe a
Just (SelectWithParens -> TextBuilder
selectWithParens SelectWithParens
b),
        (AliasClause -> TextBuilder)
-> Maybe AliasClause -> Maybe TextBuilder
forall a b. (a -> b) -> Maybe a -> Maybe b
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap AliasClause -> TextBuilder
aliasClause Maybe AliasClause
c
      ]
  JoinTableRef JoinedTable
a Maybe AliasClause
b -> case Maybe AliasClause
b of
    Just AliasClause
c -> TextBuilder -> TextBuilder
inParens (JoinedTable -> TextBuilder
joinedTable JoinedTable
a) TextBuilder -> TextBuilder -> TextBuilder
forall a. Semigroup a => a -> a -> a
<> TextBuilder
" " TextBuilder -> TextBuilder -> TextBuilder
forall a. Semigroup a => a -> a -> a
<> AliasClause -> TextBuilder
aliasClause AliasClause
c
    Maybe AliasClause
Nothing -> JoinedTable -> TextBuilder
joinedTable JoinedTable
a

relationExpr :: RelationExpr -> TextBuilder
relationExpr = \case
  SimpleRelationExpr QualifiedName
a Bool
b -> QualifiedName -> TextBuilder
qualifiedName QualifiedName
a TextBuilder -> TextBuilder -> TextBuilder
forall a. Semigroup a => a -> a -> a
<> TextBuilder -> TextBuilder -> Bool -> TextBuilder
forall a. a -> a -> Bool -> a
bool TextBuilder
"" TextBuilder
" *" Bool
b
  OnlyRelationExpr QualifiedName
a Bool
b -> TextBuilder
"ONLY " TextBuilder -> TextBuilder -> TextBuilder
forall a. Semigroup a => a -> a -> a
<> (QualifiedName -> TextBuilder)
-> (QualifiedName -> TextBuilder)
-> Bool
-> QualifiedName
-> TextBuilder
forall a. a -> a -> Bool -> a
bool QualifiedName -> TextBuilder
qualifiedName (TextBuilder -> TextBuilder
inParens (TextBuilder -> TextBuilder)
-> (QualifiedName -> TextBuilder) -> QualifiedName -> TextBuilder
forall b c a. (b -> c) -> (a -> b) -> a -> c
forall {k} (cat :: k -> k -> *) (b :: k) (c :: k) (a :: k).
Category cat =>
cat b c -> cat a b -> cat a c
. QualifiedName -> TextBuilder
qualifiedName) Bool
b QualifiedName
a

relationExprOptAlias :: RelationExprOptAlias -> TextBuilder
relationExprOptAlias (RelationExprOptAlias RelationExpr
a Maybe (Bool, ColId)
b) = RelationExpr -> TextBuilder
relationExpr RelationExpr
a TextBuilder -> TextBuilder -> TextBuilder
forall a. Semigroup a => a -> a -> a
<> ((Bool, ColId) -> TextBuilder)
-> Maybe (Bool, ColId) -> TextBuilder
forall a. (a -> TextBuilder) -> Maybe a -> TextBuilder
suffixMaybe (Bool, ColId) -> TextBuilder
optAlias Maybe (Bool, ColId)
b

optAlias :: (Bool, ColId) -> TextBuilder
optAlias (Bool
a, ColId
b) = TextBuilder -> TextBuilder -> Bool -> TextBuilder
forall a. a -> a -> Bool -> a
bool TextBuilder
"" TextBuilder
"AS " Bool
a TextBuilder -> TextBuilder -> TextBuilder
forall a. Semigroup a => a -> a -> a
<> ColId -> TextBuilder
colId ColId
b

tablesampleClause :: TablesampleClause -> TextBuilder
tablesampleClause (TablesampleClause FuncName
a ExprList
b Maybe WhereClause
c) =
  TextBuilder
"TABLESAMPLE " TextBuilder -> TextBuilder -> TextBuilder
forall a. Semigroup a => a -> a -> a
<> FuncName -> TextBuilder
funcName FuncName
a TextBuilder -> TextBuilder -> TextBuilder
forall a. Semigroup a => a -> a -> a
<> TextBuilder
" (" TextBuilder -> TextBuilder -> TextBuilder
forall a. Semigroup a => a -> a -> a
<> ExprList -> TextBuilder
exprList ExprList
b TextBuilder -> TextBuilder -> TextBuilder
forall a. Semigroup a => a -> a -> a
<> TextBuilder
")" TextBuilder -> TextBuilder -> TextBuilder
forall a. Semigroup a => a -> a -> a
<> (WhereClause -> TextBuilder) -> Maybe WhereClause -> TextBuilder
forall a. (a -> TextBuilder) -> Maybe a -> TextBuilder
suffixMaybe WhereClause -> TextBuilder
repeatableClause Maybe WhereClause
c

repeatableClause :: WhereClause -> TextBuilder
repeatableClause WhereClause
a = TextBuilder
"REPEATABLE (" TextBuilder -> TextBuilder -> TextBuilder
forall a. Semigroup a => a -> a -> a
<> WhereClause -> TextBuilder
aExpr WhereClause
a TextBuilder -> TextBuilder -> TextBuilder
forall a. Semigroup a => a -> a -> a
<> TextBuilder
")"

funcTable :: FuncTable -> TextBuilder
funcTable = \case
  FuncExprFuncTable FuncExprWindowless
a Bool
b -> FuncExprWindowless -> TextBuilder
funcExprWindownless FuncExprWindowless
a TextBuilder -> TextBuilder -> TextBuilder
forall a. Semigroup a => a -> a -> a
<> TextBuilder -> TextBuilder -> Bool -> TextBuilder
forall a. a -> a -> Bool -> a
bool TextBuilder
"" TextBuilder
" WITH ORDINALITY" Bool
b
  RowsFromFuncTable RowsfromList
a Bool
b -> TextBuilder
"ROWS FROM (" TextBuilder -> TextBuilder -> TextBuilder
forall a. Semigroup a => a -> a -> a
<> RowsfromList -> TextBuilder
rowsfromList RowsfromList
a TextBuilder -> TextBuilder -> TextBuilder
forall a. Semigroup a => a -> a -> a
<> TextBuilder
")" TextBuilder -> TextBuilder -> TextBuilder
forall a. Semigroup a => a -> a -> a
<> TextBuilder -> TextBuilder -> Bool -> TextBuilder
forall a. a -> a -> Bool -> a
bool TextBuilder
"" TextBuilder
" WITH ORDINALITY" Bool
b

rowsfromItem :: RowsfromItem -> TextBuilder
rowsfromItem (RowsfromItem FuncExprWindowless
a Maybe ColDefList
b) = FuncExprWindowless -> TextBuilder
funcExprWindownless FuncExprWindowless
a TextBuilder -> TextBuilder -> TextBuilder
forall a. Semigroup a => a -> a -> a
<> (ColDefList -> TextBuilder) -> Maybe ColDefList -> TextBuilder
forall a. (a -> TextBuilder) -> Maybe a -> TextBuilder
suffixMaybe ColDefList -> TextBuilder
colDefList Maybe ColDefList
b

rowsfromList :: RowsfromList -> TextBuilder
rowsfromList = (RowsfromItem -> TextBuilder) -> RowsfromList -> TextBuilder
forall a. (a -> TextBuilder) -> NonEmpty a -> TextBuilder
commaNonEmpty RowsfromItem -> TextBuilder
rowsfromItem

colDefList :: ColDefList -> TextBuilder
colDefList ColDefList
a = TextBuilder
"AS (" TextBuilder -> TextBuilder -> TextBuilder
forall a. Semigroup a => a -> a -> a
<> ColDefList -> TextBuilder
tableFuncElementList ColDefList
a TextBuilder -> TextBuilder -> TextBuilder
forall a. Semigroup a => a -> a -> a
<> TextBuilder
")"

tableFuncElementList :: ColDefList -> TextBuilder
tableFuncElementList = (TableFuncElement -> TextBuilder) -> ColDefList -> TextBuilder
forall a. (a -> TextBuilder) -> NonEmpty a -> TextBuilder
commaNonEmpty TableFuncElement -> TextBuilder
tableFuncElement

tableFuncElement :: TableFuncElement -> TextBuilder
tableFuncElement (TableFuncElement ColId
a Typename
b Maybe CollateClause
c) = ColId -> TextBuilder
colId ColId
a TextBuilder -> TextBuilder -> TextBuilder
forall a. Semigroup a => a -> a -> a
<> TextBuilder
" " TextBuilder -> TextBuilder -> TextBuilder
forall a. Semigroup a => a -> a -> a
<> Typename -> TextBuilder
typename Typename
b TextBuilder -> TextBuilder -> TextBuilder
forall a. Semigroup a => a -> a -> a
<> (CollateClause -> TextBuilder)
-> Maybe CollateClause -> TextBuilder
forall a. (a -> TextBuilder) -> Maybe a -> TextBuilder
suffixMaybe CollateClause -> TextBuilder
collateClause Maybe CollateClause
c

collateClause :: CollateClause -> TextBuilder
collateClause CollateClause
a = TextBuilder
"COLLATE " TextBuilder -> TextBuilder -> TextBuilder
forall a. Semigroup a => a -> a -> a
<> CollateClause -> TextBuilder
anyName CollateClause
a

aliasClause :: AliasClause -> TextBuilder
aliasClause (AliasClause Bool
a ColId
b Maybe (NonEmpty ColId)
c) =
  [Maybe TextBuilder] -> TextBuilder
optLexemes
    [ if Bool
a then TextBuilder -> Maybe TextBuilder
forall a. a -> Maybe a
Just TextBuilder
"AS" else Maybe TextBuilder
forall a. Maybe a
Nothing,
      TextBuilder -> Maybe TextBuilder
forall a. a -> Maybe a
Just (ColId -> TextBuilder
ident ColId
b),
      (NonEmpty ColId -> TextBuilder)
-> Maybe (NonEmpty ColId) -> Maybe TextBuilder
forall a b. (a -> b) -> Maybe a -> Maybe b
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap (TextBuilder -> TextBuilder
inParens (TextBuilder -> TextBuilder)
-> (NonEmpty ColId -> TextBuilder) -> NonEmpty ColId -> TextBuilder
forall b c a. (b -> c) -> (a -> b) -> a -> c
forall {k} (cat :: k -> k -> *) (b :: k) (c :: k) (a :: k).
Category cat =>
cat b c -> cat a b -> cat a c
. (ColId -> TextBuilder) -> NonEmpty ColId -> TextBuilder
forall a. (a -> TextBuilder) -> NonEmpty a -> TextBuilder
commaNonEmpty ColId -> TextBuilder
ident) Maybe (NonEmpty ColId)
c
    ]

funcAliasClause :: FuncAliasClause -> TextBuilder
funcAliasClause = \case
  AliasFuncAliasClause AliasClause
a -> AliasClause -> TextBuilder
aliasClause AliasClause
a
  AsFuncAliasClause ColDefList
a -> TextBuilder
"AS (" TextBuilder -> TextBuilder -> TextBuilder
forall a. Semigroup a => a -> a -> a
<> ColDefList -> TextBuilder
tableFuncElementList ColDefList
a TextBuilder -> TextBuilder -> TextBuilder
forall a. Semigroup a => a -> a -> a
<> TextBuilder
")"
  AsColIdFuncAliasClause ColId
a ColDefList
b -> TextBuilder
"AS " TextBuilder -> TextBuilder -> TextBuilder
forall a. Semigroup a => a -> a -> a
<> ColId -> TextBuilder
colId ColId
a TextBuilder -> TextBuilder -> TextBuilder
forall a. Semigroup a => a -> a -> a
<> TextBuilder
" (" TextBuilder -> TextBuilder -> TextBuilder
forall a. Semigroup a => a -> a -> a
<> ColDefList -> TextBuilder
tableFuncElementList ColDefList
b TextBuilder -> TextBuilder -> TextBuilder
forall a. Semigroup a => a -> a -> a
<> TextBuilder
")"
  ColIdFuncAliasClause ColId
a ColDefList
b -> ColId -> TextBuilder
colId ColId
a TextBuilder -> TextBuilder -> TextBuilder
forall a. Semigroup a => a -> a -> a
<> TextBuilder
" (" TextBuilder -> TextBuilder -> TextBuilder
forall a. Semigroup a => a -> a -> a
<> ColDefList -> TextBuilder
tableFuncElementList ColDefList
b TextBuilder -> TextBuilder -> TextBuilder
forall a. Semigroup a => a -> a -> a
<> TextBuilder
")"

joinedTable :: JoinedTable -> TextBuilder
joinedTable = \case
  InParensJoinedTable JoinedTable
a -> TextBuilder -> TextBuilder
inParens (JoinedTable -> TextBuilder
joinedTable JoinedTable
a)
  MethJoinedTable JoinMeth
a TableRef
b TableRef
c -> case JoinMeth
a of
    JoinMeth
CrossJoinMeth -> TableRef -> TextBuilder
tableRef TableRef
b TextBuilder -> TextBuilder -> TextBuilder
forall a. Semigroup a => a -> a -> a
<> TextBuilder
" CROSS JOIN " TextBuilder -> TextBuilder -> TextBuilder
forall a. Semigroup a => a -> a -> a
<> TableRef -> TextBuilder
tableRef TableRef
c
    QualJoinMeth Maybe JoinType
d JoinQual
e -> TableRef -> TextBuilder
tableRef TableRef
b TextBuilder -> TextBuilder -> TextBuilder
forall a. Semigroup a => a -> a -> a
<> (JoinType -> TextBuilder) -> Maybe JoinType -> TextBuilder
forall a. (a -> TextBuilder) -> Maybe a -> TextBuilder
suffixMaybe JoinType -> TextBuilder
forall {a}. (Semigroup a, IsString a) => JoinType -> a
joinType Maybe JoinType
d TextBuilder -> TextBuilder -> TextBuilder
forall a. Semigroup a => a -> a -> a
<> TextBuilder
" JOIN " TextBuilder -> TextBuilder -> TextBuilder
forall a. Semigroup a => a -> a -> a
<> TableRef -> TextBuilder
tableRef TableRef
c TextBuilder -> TextBuilder -> TextBuilder
forall a. Semigroup a => a -> a -> a
<> TextBuilder
" " TextBuilder -> TextBuilder -> TextBuilder
forall a. Semigroup a => a -> a -> a
<> JoinQual -> TextBuilder
joinQual JoinQual
e
    NaturalJoinMeth Maybe JoinType
d -> TableRef -> TextBuilder
tableRef TableRef
b TextBuilder -> TextBuilder -> TextBuilder
forall a. Semigroup a => a -> a -> a
<> TextBuilder
" NATURAL" TextBuilder -> TextBuilder -> TextBuilder
forall a. Semigroup a => a -> a -> a
<> (JoinType -> TextBuilder) -> Maybe JoinType -> TextBuilder
forall a. (a -> TextBuilder) -> Maybe a -> TextBuilder
suffixMaybe JoinType -> TextBuilder
forall {a}. (Semigroup a, IsString a) => JoinType -> a
joinType Maybe JoinType
d TextBuilder -> TextBuilder -> TextBuilder
forall a. Semigroup a => a -> a -> a
<> TextBuilder
" JOIN " TextBuilder -> TextBuilder -> TextBuilder
forall a. Semigroup a => a -> a -> a
<> TableRef -> TextBuilder
tableRef TableRef
c

joinType :: JoinType -> a
joinType = \case
  FullJoinType Bool
a -> a
"FULL" a -> a -> a
forall a. Semigroup a => a -> a -> a
<> if Bool
a then a
" OUTER" else a
""
  LeftJoinType Bool
a -> a
"LEFT" a -> a -> a
forall a. Semigroup a => a -> a -> a
<> if Bool
a then a
" OUTER" else a
""
  RightJoinType Bool
a -> a
"RIGHT" a -> a -> a
forall a. Semigroup a => a -> a -> a
<> if Bool
a then a
" OUTER" else a
""
  JoinType
InnerJoinType -> a
"INNER"

joinQual :: JoinQual -> TextBuilder
joinQual = \case
  UsingJoinQual NonEmpty ColId
a -> TextBuilder
"USING (" TextBuilder -> TextBuilder -> TextBuilder
forall a. Semigroup a => a -> a -> a
<> (ColId -> TextBuilder) -> NonEmpty ColId -> TextBuilder
forall a. (a -> TextBuilder) -> NonEmpty a -> TextBuilder
commaNonEmpty ColId -> TextBuilder
ident NonEmpty ColId
a TextBuilder -> TextBuilder -> TextBuilder
forall a. Semigroup a => a -> a -> a
<> TextBuilder
")"
  OnJoinQual WhereClause
a -> TextBuilder
"ON " TextBuilder -> TextBuilder -> TextBuilder
forall a. Semigroup a => a -> a -> a
<> WhereClause -> TextBuilder
aExpr WhereClause
a

-- * Where

whereClause :: WhereClause -> TextBuilder
whereClause WhereClause
a = TextBuilder
"WHERE " TextBuilder -> TextBuilder -> TextBuilder
forall a. Semigroup a => a -> a -> a
<> WhereClause -> TextBuilder
aExpr WhereClause
a

whereOrCurrentClause :: WhereOrCurrentClause -> TextBuilder
whereOrCurrentClause = \case
  ExprWhereOrCurrentClause WhereClause
a -> TextBuilder
"WHERE " TextBuilder -> TextBuilder -> TextBuilder
forall a. Semigroup a => a -> a -> a
<> WhereClause -> TextBuilder
aExpr WhereClause
a
  CursorWhereOrCurrentClause ColId
a -> TextBuilder
"WHERE CURRENT OF " TextBuilder -> TextBuilder -> TextBuilder
forall a. Semigroup a => a -> a -> a
<> ColId -> TextBuilder
cursorName ColId
a

-- * Group By

groupClause :: GroupClause -> TextBuilder
groupClause GroupClause
a = TextBuilder
"GROUP BY " TextBuilder -> TextBuilder -> TextBuilder
forall a. Semigroup a => a -> a -> a
<> (GroupByItem -> TextBuilder) -> GroupClause -> TextBuilder
forall a. (a -> TextBuilder) -> NonEmpty a -> TextBuilder
commaNonEmpty GroupByItem -> TextBuilder
groupByItem GroupClause
a

groupByItem :: GroupByItem -> TextBuilder
groupByItem = \case
  ExprGroupByItem WhereClause
a -> WhereClause -> TextBuilder
aExpr WhereClause
a
  GroupByItem
EmptyGroupingSetGroupByItem -> TextBuilder
"()"
  RollupGroupByItem ExprList
a -> TextBuilder
"ROLLUP (" TextBuilder -> TextBuilder -> TextBuilder
forall a. Semigroup a => a -> a -> a
<> (WhereClause -> TextBuilder) -> ExprList -> TextBuilder
forall a. (a -> TextBuilder) -> NonEmpty a -> TextBuilder
commaNonEmpty WhereClause -> TextBuilder
aExpr ExprList
a TextBuilder -> TextBuilder -> TextBuilder
forall a. Semigroup a => a -> a -> a
<> TextBuilder
")"
  CubeGroupByItem ExprList
a -> TextBuilder
"CUBE (" TextBuilder -> TextBuilder -> TextBuilder
forall a. Semigroup a => a -> a -> a
<> (WhereClause -> TextBuilder) -> ExprList -> TextBuilder
forall a. (a -> TextBuilder) -> NonEmpty a -> TextBuilder
commaNonEmpty WhereClause -> TextBuilder
aExpr ExprList
a TextBuilder -> TextBuilder -> TextBuilder
forall a. Semigroup a => a -> a -> a
<> TextBuilder
")"
  GroupingSetsGroupByItem GroupClause
a -> TextBuilder
"GROUPING SETS (" TextBuilder -> TextBuilder -> TextBuilder
forall a. Semigroup a => a -> a -> a
<> (GroupByItem -> TextBuilder) -> GroupClause -> TextBuilder
forall a. (a -> TextBuilder) -> NonEmpty a -> TextBuilder
commaNonEmpty GroupByItem -> TextBuilder
groupByItem GroupClause
a TextBuilder -> TextBuilder -> TextBuilder
forall a. Semigroup a => a -> a -> a
<> TextBuilder
")"

-- * Having

havingClause :: WhereClause -> TextBuilder
havingClause WhereClause
a = TextBuilder
"HAVING " TextBuilder -> TextBuilder -> TextBuilder
forall a. Semigroup a => a -> a -> a
<> WhereClause -> TextBuilder
aExpr WhereClause
a

-- * Window

windowClause :: WindowClause -> TextBuilder
windowClause WindowClause
a = TextBuilder
"WINDOW " TextBuilder -> TextBuilder -> TextBuilder
forall a. Semigroup a => a -> a -> a
<> (WindowDefinition -> TextBuilder) -> WindowClause -> TextBuilder
forall a. (a -> TextBuilder) -> NonEmpty a -> TextBuilder
commaNonEmpty WindowDefinition -> TextBuilder
windowDefinition WindowClause
a

windowDefinition :: WindowDefinition -> TextBuilder
windowDefinition (WindowDefinition ColId
a WindowSpecification
b) = ColId -> TextBuilder
ident ColId
a TextBuilder -> TextBuilder -> TextBuilder
forall a. Semigroup a => a -> a -> a
<> TextBuilder
" AS " TextBuilder -> TextBuilder -> TextBuilder
forall a. Semigroup a => a -> a -> a
<> WindowSpecification -> TextBuilder
windowSpecification WindowSpecification
b

windowSpecification :: WindowSpecification -> TextBuilder
windowSpecification (WindowSpecification Maybe ColId
a Maybe ExprList
b Maybe SortClause
c Maybe FrameClause
d) =
  TextBuilder -> TextBuilder
inParens
    (TextBuilder -> TextBuilder) -> TextBuilder -> TextBuilder
forall a b. (a -> b) -> a -> b
$ [Maybe TextBuilder] -> TextBuilder
optLexemes
      [ (ColId -> TextBuilder) -> Maybe ColId -> Maybe TextBuilder
forall a b. (a -> b) -> Maybe a -> Maybe b
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap ColId -> TextBuilder
ident Maybe ColId
a,
        (ExprList -> TextBuilder) -> Maybe ExprList -> Maybe TextBuilder
forall a b. (a -> b) -> Maybe a -> Maybe b
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap ExprList -> TextBuilder
partitionClause Maybe ExprList
b,
        (SortClause -> TextBuilder)
-> Maybe SortClause -> Maybe TextBuilder
forall a b. (a -> b) -> Maybe a -> Maybe b
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap SortClause -> TextBuilder
sortClause Maybe SortClause
c,
        (FrameClause -> TextBuilder)
-> Maybe FrameClause -> Maybe TextBuilder
forall a b. (a -> b) -> Maybe a -> Maybe b
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap FrameClause -> TextBuilder
frameClause Maybe FrameClause
d
      ]

partitionClause :: ExprList -> TextBuilder
partitionClause ExprList
a = TextBuilder
"PARTITION BY " TextBuilder -> TextBuilder -> TextBuilder
forall a. Semigroup a => a -> a -> a
<> (WhereClause -> TextBuilder) -> ExprList -> TextBuilder
forall a. (a -> TextBuilder) -> NonEmpty a -> TextBuilder
commaNonEmpty WhereClause -> TextBuilder
aExpr ExprList
a

frameClause :: FrameClause -> TextBuilder
frameClause (FrameClause FrameClauseMode
a FrameExtent
b Maybe WindowExclusionClause
c) =
  [Maybe TextBuilder] -> TextBuilder
optLexemes
    [ TextBuilder -> Maybe TextBuilder
forall a. a -> Maybe a
Just (FrameClauseMode -> TextBuilder
forall {a}. IsString a => FrameClauseMode -> a
frameClauseMode FrameClauseMode
a),
      TextBuilder -> Maybe TextBuilder
forall a. a -> Maybe a
Just (FrameExtent -> TextBuilder
frameExtent FrameExtent
b),
      (WindowExclusionClause -> TextBuilder)
-> Maybe WindowExclusionClause -> Maybe TextBuilder
forall a b. (a -> b) -> Maybe a -> Maybe b
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap WindowExclusionClause -> TextBuilder
forall {a}. IsString a => WindowExclusionClause -> a
windowExclusionCause Maybe WindowExclusionClause
c
    ]

frameClauseMode :: FrameClauseMode -> a
frameClauseMode = \case
  FrameClauseMode
RangeFrameClauseMode -> a
"RANGE"
  FrameClauseMode
RowsFrameClauseMode -> a
"ROWS"
  FrameClauseMode
GroupsFrameClauseMode -> a
"GROUPS"

frameExtent :: FrameExtent -> TextBuilder
frameExtent = \case
  SingularFrameExtent FrameBound
a -> FrameBound -> TextBuilder
frameBound FrameBound
a
  BetweenFrameExtent FrameBound
a FrameBound
b -> TextBuilder
"BETWEEN " TextBuilder -> TextBuilder -> TextBuilder
forall a. Semigroup a => a -> a -> a
<> FrameBound -> TextBuilder
frameBound FrameBound
a TextBuilder -> TextBuilder -> TextBuilder
forall a. Semigroup a => a -> a -> a
<> TextBuilder
" AND " TextBuilder -> TextBuilder -> TextBuilder
forall a. Semigroup a => a -> a -> a
<> FrameBound -> TextBuilder
frameBound FrameBound
b

frameBound :: FrameBound -> TextBuilder
frameBound = \case
  FrameBound
UnboundedPrecedingFrameBound -> TextBuilder
"UNBOUNDED PRECEDING"
  FrameBound
UnboundedFollowingFrameBound -> TextBuilder
"UNBOUNDED FOLLOWING"
  FrameBound
CurrentRowFrameBound -> TextBuilder
"CURRENT ROW"
  PrecedingFrameBound WhereClause
a -> WhereClause -> TextBuilder
aExpr WhereClause
a TextBuilder -> TextBuilder -> TextBuilder
forall a. Semigroup a => a -> a -> a
<> TextBuilder
" PRECEDING"
  FollowingFrameBound WhereClause
a -> WhereClause -> TextBuilder
aExpr WhereClause
a TextBuilder -> TextBuilder -> TextBuilder
forall a. Semigroup a => a -> a -> a
<> TextBuilder
" FOLLOWING"

windowExclusionCause :: WindowExclusionClause -> a
windowExclusionCause = \case
  WindowExclusionClause
CurrentRowWindowExclusionClause -> a
"EXCLUDE CURRENT ROW"
  WindowExclusionClause
GroupWindowExclusionClause -> a
"EXCLUDE GROUP"
  WindowExclusionClause
TiesWindowExclusionClause -> a
"EXCLUDE TIES"
  WindowExclusionClause
NoOthersWindowExclusionClause -> a
"EXCLUDE NO OTHERS"

-- * Order By

sortClause :: SortClause -> TextBuilder
sortClause SortClause
a = TextBuilder
"ORDER BY " TextBuilder -> TextBuilder -> TextBuilder
forall a. Semigroup a => a -> a -> a
<> (SortBy -> TextBuilder) -> SortClause -> TextBuilder
forall a. (a -> TextBuilder) -> NonEmpty a -> TextBuilder
commaNonEmpty SortBy -> TextBuilder
sortBy SortClause
a

sortBy :: SortBy -> TextBuilder
sortBy = \case
  UsingSortBy WhereClause
a QualAllOp
b Maybe NullsOrder
c -> WhereClause -> TextBuilder
aExpr WhereClause
a TextBuilder -> TextBuilder -> TextBuilder
forall a. Semigroup a => a -> a -> a
<> TextBuilder
" USING " TextBuilder -> TextBuilder -> TextBuilder
forall a. Semigroup a => a -> a -> a
<> QualAllOp -> TextBuilder
qualAllOp QualAllOp
b TextBuilder -> TextBuilder -> TextBuilder
forall a. Semigroup a => a -> a -> a
<> (NullsOrder -> TextBuilder) -> Maybe NullsOrder -> TextBuilder
forall a. (a -> TextBuilder) -> Maybe a -> TextBuilder
suffixMaybe NullsOrder -> TextBuilder
forall {a}. IsString a => NullsOrder -> a
nullsOrder Maybe NullsOrder
c
  AscDescSortBy WhereClause
a Maybe AscDesc
b Maybe NullsOrder
c -> WhereClause -> TextBuilder
aExpr WhereClause
a TextBuilder -> TextBuilder -> TextBuilder
forall a. Semigroup a => a -> a -> a
<> (AscDesc -> TextBuilder) -> Maybe AscDesc -> TextBuilder
forall a. (a -> TextBuilder) -> Maybe a -> TextBuilder
suffixMaybe AscDesc -> TextBuilder
forall {a}. IsString a => AscDesc -> a
ascDesc Maybe AscDesc
b TextBuilder -> TextBuilder -> TextBuilder
forall a. Semigroup a => a -> a -> a
<> (NullsOrder -> TextBuilder) -> Maybe NullsOrder -> TextBuilder
forall a. (a -> TextBuilder) -> Maybe a -> TextBuilder
suffixMaybe NullsOrder -> TextBuilder
forall {a}. IsString a => NullsOrder -> a
nullsOrder Maybe NullsOrder
c

-- * Values

valuesClause :: ValuesClause -> TextBuilder
valuesClause ValuesClause
a = TextBuilder
"VALUES " TextBuilder -> TextBuilder -> TextBuilder
forall a. Semigroup a => a -> a -> a
<> (ExprList -> TextBuilder) -> ValuesClause -> TextBuilder
forall a. (a -> TextBuilder) -> NonEmpty a -> TextBuilder
commaNonEmpty (TextBuilder -> TextBuilder
inParens (TextBuilder -> TextBuilder)
-> (ExprList -> TextBuilder) -> ExprList -> TextBuilder
forall b c a. (b -> c) -> (a -> b) -> a -> c
forall {k} (cat :: k -> k -> *) (b :: k) (c :: k) (a :: k).
Category cat =>
cat b c -> cat a b -> cat a c
. (WhereClause -> TextBuilder) -> ExprList -> TextBuilder
forall a. (a -> TextBuilder) -> NonEmpty a -> TextBuilder
commaNonEmpty WhereClause -> TextBuilder
aExpr) ValuesClause
a

-- * Exprs

exprList :: ExprList -> TextBuilder
exprList = (WhereClause -> TextBuilder) -> ExprList -> TextBuilder
forall a. (a -> TextBuilder) -> NonEmpty a -> TextBuilder
commaNonEmpty WhereClause -> TextBuilder
aExpr

aExpr :: WhereClause -> TextBuilder
aExpr = \case
  CExprAExpr CExpr
a -> CExpr -> TextBuilder
cExpr CExpr
a
  TypecastAExpr WhereClause
a Typename
b -> WhereClause -> TextBuilder
aExpr WhereClause
a TextBuilder -> TextBuilder -> TextBuilder
forall a. Semigroup a => a -> a -> a
<> TextBuilder
" :: " TextBuilder -> TextBuilder -> TextBuilder
forall a. Semigroup a => a -> a -> a
<> Typename -> TextBuilder
typename Typename
b
  CollateAExpr WhereClause
a CollateClause
b -> WhereClause -> TextBuilder
aExpr WhereClause
a TextBuilder -> TextBuilder -> TextBuilder
forall a. Semigroup a => a -> a -> a
<> TextBuilder
" COLLATE " TextBuilder -> TextBuilder -> TextBuilder
forall a. Semigroup a => a -> a -> a
<> CollateClause -> TextBuilder
anyName CollateClause
b
  AtTimeZoneAExpr WhereClause
a WhereClause
b -> WhereClause -> TextBuilder
aExpr WhereClause
a TextBuilder -> TextBuilder -> TextBuilder
forall a. Semigroup a => a -> a -> a
<> TextBuilder
" AT TIME ZONE " TextBuilder -> TextBuilder -> TextBuilder
forall a. Semigroup a => a -> a -> a
<> WhereClause -> TextBuilder
aExpr WhereClause
b
  PlusAExpr WhereClause
a -> TextBuilder
"+ " TextBuilder -> TextBuilder -> TextBuilder
forall a. Semigroup a => a -> a -> a
<> WhereClause -> TextBuilder
aExpr WhereClause
a
  MinusAExpr WhereClause
a -> TextBuilder
"- " TextBuilder -> TextBuilder -> TextBuilder
forall a. Semigroup a => a -> a -> a
<> WhereClause -> TextBuilder
aExpr WhereClause
a
  SymbolicBinOpAExpr WhereClause
a SymbolicExprBinOp
b WhereClause
c -> WhereClause -> TextBuilder
aExpr WhereClause
a TextBuilder -> TextBuilder -> TextBuilder
forall a. Semigroup a => a -> a -> a
<> TextBuilder
" " TextBuilder -> TextBuilder -> TextBuilder
forall a. Semigroup a => a -> a -> a
<> SymbolicExprBinOp -> TextBuilder
symbolicExprBinOp SymbolicExprBinOp
b TextBuilder -> TextBuilder -> TextBuilder
forall a. Semigroup a => a -> a -> a
<> TextBuilder
" " TextBuilder -> TextBuilder -> TextBuilder
forall a. Semigroup a => a -> a -> a
<> WhereClause -> TextBuilder
aExpr WhereClause
c
  PrefixQualOpAExpr QualOp
a WhereClause
b -> QualOp -> TextBuilder
qualOp QualOp
a TextBuilder -> TextBuilder -> TextBuilder
forall a. Semigroup a => a -> a -> a
<> TextBuilder
" " TextBuilder -> TextBuilder -> TextBuilder
forall a. Semigroup a => a -> a -> a
<> WhereClause -> TextBuilder
aExpr WhereClause
b
  SuffixQualOpAExpr WhereClause
a QualOp
b -> WhereClause -> TextBuilder
aExpr WhereClause
a TextBuilder -> TextBuilder -> TextBuilder
forall a. Semigroup a => a -> a -> a
<> TextBuilder
" " TextBuilder -> TextBuilder -> TextBuilder
forall a. Semigroup a => a -> a -> a
<> QualOp -> TextBuilder
qualOp QualOp
b
  AndAExpr WhereClause
a WhereClause
b -> WhereClause -> TextBuilder
aExpr WhereClause
a TextBuilder -> TextBuilder -> TextBuilder
forall a. Semigroup a => a -> a -> a
<> TextBuilder
" AND " TextBuilder -> TextBuilder -> TextBuilder
forall a. Semigroup a => a -> a -> a
<> WhereClause -> TextBuilder
aExpr WhereClause
b
  OrAExpr WhereClause
a WhereClause
b -> WhereClause -> TextBuilder
aExpr WhereClause
a TextBuilder -> TextBuilder -> TextBuilder
forall a. Semigroup a => a -> a -> a
<> TextBuilder
" OR " TextBuilder -> TextBuilder -> TextBuilder
forall a. Semigroup a => a -> a -> a
<> WhereClause -> TextBuilder
aExpr WhereClause
b
  NotAExpr WhereClause
a -> TextBuilder
"NOT " TextBuilder -> TextBuilder -> TextBuilder
forall a. Semigroup a => a -> a -> a
<> WhereClause -> TextBuilder
aExpr WhereClause
a
  VerbalExprBinOpAExpr WhereClause
a Bool
b VerbalExprBinOp
c WhereClause
d Maybe WhereClause
e -> WhereClause -> TextBuilder
aExpr WhereClause
a TextBuilder -> TextBuilder -> TextBuilder
forall a. Semigroup a => a -> a -> a
<> TextBuilder
" " TextBuilder -> TextBuilder -> TextBuilder
forall a. Semigroup a => a -> a -> a
<> Bool -> VerbalExprBinOp -> TextBuilder
forall {b}. (Monoid b, IsString b) => Bool -> VerbalExprBinOp -> b
verbalExprBinOp Bool
b VerbalExprBinOp
c TextBuilder -> TextBuilder -> TextBuilder
forall a. Semigroup a => a -> a -> a
<> TextBuilder
" " TextBuilder -> TextBuilder -> TextBuilder
forall a. Semigroup a => a -> a -> a
<> WhereClause -> TextBuilder
aExpr WhereClause
d TextBuilder -> TextBuilder -> TextBuilder
forall a. Semigroup a => a -> a -> a
<> (WhereClause -> TextBuilder) -> Maybe WhereClause -> TextBuilder
forall m a. Monoid m => (a -> m) -> Maybe a -> m
forall (t :: * -> *) m a.
(Foldable t, Monoid m) =>
(a -> m) -> t a -> m
foldMap (TextBuilder -> TextBuilder -> TextBuilder
forall a. Monoid a => a -> a -> a
mappend TextBuilder
" ESCAPE " (TextBuilder -> TextBuilder)
-> (WhereClause -> TextBuilder) -> WhereClause -> TextBuilder
forall b c a. (b -> c) -> (a -> b) -> a -> c
forall {k} (cat :: k -> k -> *) (b :: k) (c :: k) (a :: k).
Category cat =>
cat b c -> cat a b -> cat a c
. WhereClause -> TextBuilder
aExpr) Maybe WhereClause
e
  ReversableOpAExpr WhereClause
a Bool
b AExprReversableOp
c -> WhereClause -> TextBuilder
aExpr WhereClause
a TextBuilder -> TextBuilder -> TextBuilder
forall a. Semigroup a => a -> a -> a
<> TextBuilder
" " TextBuilder -> TextBuilder -> TextBuilder
forall a. Semigroup a => a -> a -> a
<> Bool -> AExprReversableOp -> TextBuilder
aExprReversableOp Bool
b AExprReversableOp
c
  IsnullAExpr WhereClause
a -> WhereClause -> TextBuilder
aExpr WhereClause
a TextBuilder -> TextBuilder -> TextBuilder
forall a. Semigroup a => a -> a -> a
<> TextBuilder
" ISNULL"
  NotnullAExpr WhereClause
a -> WhereClause -> TextBuilder
aExpr WhereClause
a TextBuilder -> TextBuilder -> TextBuilder
forall a. Semigroup a => a -> a -> a
<> TextBuilder
" NOTNULL"
  OverlapsAExpr Row
a Row
b -> Row -> TextBuilder
row Row
a TextBuilder -> TextBuilder -> TextBuilder
forall a. Semigroup a => a -> a -> a
<> TextBuilder
" OVERLAPS " TextBuilder -> TextBuilder -> TextBuilder
forall a. Semigroup a => a -> a -> a
<> Row -> TextBuilder
row Row
b
  SubqueryAExpr WhereClause
a SubqueryOp
b SubType
c Either SelectWithParens WhereClause
d -> WhereClause -> TextBuilder
aExpr WhereClause
a TextBuilder -> TextBuilder -> TextBuilder
forall a. Semigroup a => a -> a -> a
<> TextBuilder
" " TextBuilder -> TextBuilder -> TextBuilder
forall a. Semigroup a => a -> a -> a
<> SubqueryOp -> TextBuilder
subqueryOp SubqueryOp
b TextBuilder -> TextBuilder -> TextBuilder
forall a. Semigroup a => a -> a -> a
<> TextBuilder
" " TextBuilder -> TextBuilder -> TextBuilder
forall a. Semigroup a => a -> a -> a
<> SubType -> TextBuilder
forall {a}. IsString a => SubType -> a
subType SubType
c TextBuilder -> TextBuilder -> TextBuilder
forall a. Semigroup a => a -> a -> a
<> TextBuilder
" " TextBuilder -> TextBuilder -> TextBuilder
forall a. Semigroup a => a -> a -> a
<> (SelectWithParens -> TextBuilder)
-> (WhereClause -> TextBuilder)
-> Either SelectWithParens WhereClause
-> TextBuilder
forall a c b. (a -> c) -> (b -> c) -> Either a b -> c
either SelectWithParens -> TextBuilder
selectWithParens (TextBuilder -> TextBuilder
inParens (TextBuilder -> TextBuilder)
-> (WhereClause -> TextBuilder) -> WhereClause -> TextBuilder
forall b c a. (b -> c) -> (a -> b) -> a -> c
forall {k} (cat :: k -> k -> *) (b :: k) (c :: k) (a :: k).
Category cat =>
cat b c -> cat a b -> cat a c
. WhereClause -> TextBuilder
aExpr) Either SelectWithParens WhereClause
d
  UniqueAExpr SelectWithParens
a -> TextBuilder
"UNIQUE " TextBuilder -> TextBuilder -> TextBuilder
forall a. Semigroup a => a -> a -> a
<> SelectWithParens -> TextBuilder
selectWithParens SelectWithParens
a
  WhereClause
DefaultAExpr -> TextBuilder
"DEFAULT"

bExpr :: BExpr -> TextBuilder
bExpr = \case
  CExprBExpr CExpr
a -> CExpr -> TextBuilder
cExpr CExpr
a
  TypecastBExpr BExpr
a Typename
b -> BExpr -> TextBuilder
bExpr BExpr
a TextBuilder -> TextBuilder -> TextBuilder
forall a. Semigroup a => a -> a -> a
<> TextBuilder
" :: " TextBuilder -> TextBuilder -> TextBuilder
forall a. Semigroup a => a -> a -> a
<> Typename -> TextBuilder
typename Typename
b
  PlusBExpr BExpr
a -> TextBuilder
"+ " TextBuilder -> TextBuilder -> TextBuilder
forall a. Semigroup a => a -> a -> a
<> BExpr -> TextBuilder
bExpr BExpr
a
  MinusBExpr BExpr
a -> TextBuilder
"- " TextBuilder -> TextBuilder -> TextBuilder
forall a. Semigroup a => a -> a -> a
<> BExpr -> TextBuilder
bExpr BExpr
a
  SymbolicBinOpBExpr BExpr
a SymbolicExprBinOp
b BExpr
c -> BExpr -> TextBuilder
bExpr BExpr
a TextBuilder -> TextBuilder -> TextBuilder
forall a. Semigroup a => a -> a -> a
<> TextBuilder
" " TextBuilder -> TextBuilder -> TextBuilder
forall a. Semigroup a => a -> a -> a
<> SymbolicExprBinOp -> TextBuilder
symbolicExprBinOp SymbolicExprBinOp
b TextBuilder -> TextBuilder -> TextBuilder
forall a. Semigroup a => a -> a -> a
<> TextBuilder
" " TextBuilder -> TextBuilder -> TextBuilder
forall a. Semigroup a => a -> a -> a
<> BExpr -> TextBuilder
bExpr BExpr
c
  QualOpBExpr QualOp
a BExpr
b -> QualOp -> TextBuilder
qualOp QualOp
a TextBuilder -> TextBuilder -> TextBuilder
forall a. Semigroup a => a -> a -> a
<> TextBuilder
" " TextBuilder -> TextBuilder -> TextBuilder
forall a. Semigroup a => a -> a -> a
<> BExpr -> TextBuilder
bExpr BExpr
b
  IsOpBExpr BExpr
a Bool
b BExprIsOp
c -> BExpr -> TextBuilder
bExpr BExpr
a TextBuilder -> TextBuilder -> TextBuilder
forall a. Semigroup a => a -> a -> a
<> TextBuilder
" " TextBuilder -> TextBuilder -> TextBuilder
forall a. Semigroup a => a -> a -> a
<> Bool -> BExprIsOp -> TextBuilder
bExprIsOp Bool
b BExprIsOp
c

cExpr :: CExpr -> TextBuilder
cExpr = \case
  ColumnrefCExpr Columnref
a -> Columnref -> TextBuilder
columnref Columnref
a
  AexprConstCExpr AexprConst
a -> AexprConst -> TextBuilder
aexprConst AexprConst
a
  ParamCExpr Int
a Maybe Indirection
b -> TextBuilder
"$" TextBuilder -> TextBuilder -> TextBuilder
forall a. Semigroup a => a -> a -> a
<> Int -> TextBuilder
intDec Int
a TextBuilder -> TextBuilder -> TextBuilder
forall a. Semigroup a => a -> a -> a
<> (Indirection -> TextBuilder) -> Maybe Indirection -> TextBuilder
forall m a. Monoid m => (a -> m) -> Maybe a -> m
forall (t :: * -> *) m a.
(Foldable t, Monoid m) =>
(a -> m) -> t a -> m
foldMap Indirection -> TextBuilder
indirection Maybe Indirection
b
  InParensCExpr WhereClause
a Maybe Indirection
b -> TextBuilder -> TextBuilder
inParens (WhereClause -> TextBuilder
aExpr WhereClause
a) TextBuilder -> TextBuilder -> TextBuilder
forall a. Semigroup a => a -> a -> a
<> (Indirection -> TextBuilder) -> Maybe Indirection -> TextBuilder
forall m a. Monoid m => (a -> m) -> Maybe a -> m
forall (t :: * -> *) m a.
(Foldable t, Monoid m) =>
(a -> m) -> t a -> m
foldMap Indirection -> TextBuilder
indirection Maybe Indirection
b
  CaseCExpr CaseExpr
a -> CaseExpr -> TextBuilder
caseExpr CaseExpr
a
  FuncCExpr FuncExpr
a -> FuncExpr -> TextBuilder
funcExpr FuncExpr
a
  SelectWithParensCExpr SelectWithParens
a Maybe Indirection
b -> SelectWithParens -> TextBuilder
selectWithParens SelectWithParens
a TextBuilder -> TextBuilder -> TextBuilder
forall a. Semigroup a => a -> a -> a
<> (Indirection -> TextBuilder) -> Maybe Indirection -> TextBuilder
forall m a. Monoid m => (a -> m) -> Maybe a -> m
forall (t :: * -> *) m a.
(Foldable t, Monoid m) =>
(a -> m) -> t a -> m
foldMap Indirection -> TextBuilder
indirection Maybe Indirection
b
  ExistsCExpr SelectWithParens
a -> TextBuilder
"EXISTS " TextBuilder -> TextBuilder -> TextBuilder
forall a. Semigroup a => a -> a -> a
<> SelectWithParens -> TextBuilder
selectWithParens SelectWithParens
a
  ArrayCExpr Either SelectWithParens ArrayExpr
a -> TextBuilder
"ARRAY " TextBuilder -> TextBuilder -> TextBuilder
forall a. Semigroup a => a -> a -> a
<> (SelectWithParens -> TextBuilder)
-> (ArrayExpr -> TextBuilder)
-> Either SelectWithParens ArrayExpr
-> TextBuilder
forall a c b. (a -> c) -> (b -> c) -> Either a b -> c
either SelectWithParens -> TextBuilder
selectWithParens ArrayExpr -> TextBuilder
arrayExpr Either SelectWithParens ArrayExpr
a
  ExplicitRowCExpr Maybe ExprList
a -> Maybe ExprList -> TextBuilder
explicitRow Maybe ExprList
a
  ImplicitRowCExpr ImplicitRow
a -> ImplicitRow -> TextBuilder
implicitRow ImplicitRow
a
  GroupingCExpr ExprList
a -> TextBuilder
"GROUPING " TextBuilder -> TextBuilder -> TextBuilder
forall a. Semigroup a => a -> a -> a
<> TextBuilder -> TextBuilder
inParens (ExprList -> TextBuilder
exprList ExprList
a)

-- * Ops

aExprReversableOp :: Bool -> AExprReversableOp -> TextBuilder
aExprReversableOp Bool
a = \case
  AExprReversableOp
NullAExprReversableOp -> TextBuilder -> TextBuilder -> Bool -> TextBuilder
forall a. a -> a -> Bool -> a
bool TextBuilder
"IS " TextBuilder
"IS NOT " Bool
a TextBuilder -> TextBuilder -> TextBuilder
forall a. Semigroup a => a -> a -> a
<> TextBuilder
"NULL"
  AExprReversableOp
TrueAExprReversableOp -> TextBuilder -> TextBuilder -> Bool -> TextBuilder
forall a. a -> a -> Bool -> a
bool TextBuilder
"IS " TextBuilder
"IS NOT " Bool
a TextBuilder -> TextBuilder -> TextBuilder
forall a. Semigroup a => a -> a -> a
<> TextBuilder
"TRUE"
  AExprReversableOp
FalseAExprReversableOp -> TextBuilder -> TextBuilder -> Bool -> TextBuilder
forall a. a -> a -> Bool -> a
bool TextBuilder
"IS " TextBuilder
"IS NOT " Bool
a TextBuilder -> TextBuilder -> TextBuilder
forall a. Semigroup a => a -> a -> a
<> TextBuilder
"FALSE"
  AExprReversableOp
UnknownAExprReversableOp -> TextBuilder -> TextBuilder -> Bool -> TextBuilder
forall a. a -> a -> Bool -> a
bool TextBuilder
"IS " TextBuilder
"IS NOT " Bool
a TextBuilder -> TextBuilder -> TextBuilder
forall a. Semigroup a => a -> a -> a
<> TextBuilder
"UNKNOWN"
  DistinctFromAExprReversableOp WhereClause
b -> TextBuilder -> TextBuilder -> Bool -> TextBuilder
forall a. a -> a -> Bool -> a
bool TextBuilder
"IS " TextBuilder
"IS NOT " Bool
a TextBuilder -> TextBuilder -> TextBuilder
forall a. Semigroup a => a -> a -> a
<> TextBuilder
"DISTINCT FROM " TextBuilder -> TextBuilder -> TextBuilder
forall a. Semigroup a => a -> a -> a
<> WhereClause -> TextBuilder
aExpr WhereClause
b
  OfAExprReversableOp TypeList
b -> TextBuilder -> TextBuilder -> Bool -> TextBuilder
forall a. a -> a -> Bool -> a
bool TextBuilder
"IS " TextBuilder
"IS NOT " Bool
a TextBuilder -> TextBuilder -> TextBuilder
forall a. Semigroup a => a -> a -> a
<> TextBuilder
"OF " TextBuilder -> TextBuilder -> TextBuilder
forall a. Semigroup a => a -> a -> a
<> TextBuilder -> TextBuilder
inParens (TypeList -> TextBuilder
typeList TypeList
b)
  BetweenAExprReversableOp Bool
b BExpr
c WhereClause
d -> TextBuilder -> TextBuilder -> Bool -> TextBuilder
forall a. a -> a -> Bool -> a
bool TextBuilder
"" TextBuilder
"NOT " Bool
a TextBuilder -> TextBuilder -> TextBuilder
forall a. Semigroup a => a -> a -> a
<> TextBuilder -> TextBuilder -> Bool -> TextBuilder
forall a. a -> a -> Bool -> a
bool TextBuilder
"BETWEEN " TextBuilder
"BETWEEN ASYMMETRIC " Bool
b TextBuilder -> TextBuilder -> TextBuilder
forall a. Semigroup a => a -> a -> a
<> BExpr -> TextBuilder
bExpr BExpr
c TextBuilder -> TextBuilder -> TextBuilder
forall a. Semigroup a => a -> a -> a
<> TextBuilder
" AND " TextBuilder -> TextBuilder -> TextBuilder
forall a. Semigroup a => a -> a -> a
<> WhereClause -> TextBuilder
aExpr WhereClause
d
  BetweenSymmetricAExprReversableOp BExpr
b WhereClause
c -> TextBuilder -> TextBuilder -> Bool -> TextBuilder
forall a. a -> a -> Bool -> a
bool TextBuilder
"" TextBuilder
"NOT " Bool
a TextBuilder -> TextBuilder -> TextBuilder
forall a. Semigroup a => a -> a -> a
<> TextBuilder
"BETWEEN SYMMETRIC " TextBuilder -> TextBuilder -> TextBuilder
forall a. Semigroup a => a -> a -> a
<> BExpr -> TextBuilder
bExpr BExpr
b TextBuilder -> TextBuilder -> TextBuilder
forall a. Semigroup a => a -> a -> a
<> TextBuilder
" AND " TextBuilder -> TextBuilder -> TextBuilder
forall a. Semigroup a => a -> a -> a
<> WhereClause -> TextBuilder
aExpr WhereClause
c
  InAExprReversableOp InExpr
b -> TextBuilder -> TextBuilder -> Bool -> TextBuilder
forall a. a -> a -> Bool -> a
bool TextBuilder
"" TextBuilder
"NOT " Bool
a TextBuilder -> TextBuilder -> TextBuilder
forall a. Semigroup a => a -> a -> a
<> TextBuilder
"IN " TextBuilder -> TextBuilder -> TextBuilder
forall a. Semigroup a => a -> a -> a
<> InExpr -> TextBuilder
inExpr InExpr
b
  AExprReversableOp
DocumentAExprReversableOp -> TextBuilder -> TextBuilder -> Bool -> TextBuilder
forall a. a -> a -> Bool -> a
bool TextBuilder
"IS " TextBuilder
"IS NOT " Bool
a TextBuilder -> TextBuilder -> TextBuilder
forall a. Semigroup a => a -> a -> a
<> TextBuilder
"DOCUMENT"

verbalExprBinOp :: Bool -> VerbalExprBinOp -> b
verbalExprBinOp Bool
a =
  b -> b -> b
forall a. Monoid a => a -> a -> a
mappend (b -> b -> Bool -> b
forall a. a -> a -> Bool -> a
bool b
"" b
"NOT " Bool
a) (b -> b) -> (VerbalExprBinOp -> b) -> VerbalExprBinOp -> b
forall b c a. (b -> c) -> (a -> b) -> a -> c
forall {k} (cat :: k -> k -> *) (b :: k) (c :: k) (a :: k).
Category cat =>
cat b c -> cat a b -> cat a c
. \case
    VerbalExprBinOp
LikeVerbalExprBinOp -> b
"LIKE"
    VerbalExprBinOp
IlikeVerbalExprBinOp -> b
"ILIKE"
    VerbalExprBinOp
SimilarToVerbalExprBinOp -> b
"SIMILAR TO"

subqueryOp :: SubqueryOp -> TextBuilder
subqueryOp = \case
  AllSubqueryOp AllOp
a -> AllOp -> TextBuilder
allOp AllOp
a
  AnySubqueryOp AnyOperator
a -> TextBuilder
"OPERATOR " TextBuilder -> TextBuilder -> TextBuilder
forall a. Semigroup a => a -> a -> a
<> TextBuilder -> TextBuilder
inParens (AnyOperator -> TextBuilder
anyOperator AnyOperator
a)
  LikeSubqueryOp Bool
a -> TextBuilder -> TextBuilder -> Bool -> TextBuilder
forall a. a -> a -> Bool -> a
bool TextBuilder
"" TextBuilder
"NOT " Bool
a TextBuilder -> TextBuilder -> TextBuilder
forall a. Semigroup a => a -> a -> a
<> TextBuilder
"LIKE"
  IlikeSubqueryOp Bool
a -> TextBuilder -> TextBuilder -> Bool -> TextBuilder
forall a. a -> a -> Bool -> a
bool TextBuilder
"" TextBuilder
"NOT " Bool
a TextBuilder -> TextBuilder -> TextBuilder
forall a. Semigroup a => a -> a -> a
<> TextBuilder
"ILIKE"

bExprIsOp :: Bool -> BExprIsOp -> TextBuilder
bExprIsOp Bool
a =
  TextBuilder -> TextBuilder -> TextBuilder
forall a. Monoid a => a -> a -> a
mappend (TextBuilder -> TextBuilder -> Bool -> TextBuilder
forall a. a -> a -> Bool -> a
bool TextBuilder
"IS " TextBuilder
"IS NOT " Bool
a) (TextBuilder -> TextBuilder)
-> (BExprIsOp -> TextBuilder) -> BExprIsOp -> TextBuilder
forall b c a. (b -> c) -> (a -> b) -> a -> c
forall {k} (cat :: k -> k -> *) (b :: k) (c :: k) (a :: k).
Category cat =>
cat b c -> cat a b -> cat a c
. \case
    DistinctFromBExprIsOp BExpr
b -> TextBuilder
"DISTINCT FROM " TextBuilder -> TextBuilder -> TextBuilder
forall a. Semigroup a => a -> a -> a
<> BExpr -> TextBuilder
bExpr BExpr
b
    OfBExprIsOp TypeList
a -> TextBuilder
"OF " TextBuilder -> TextBuilder -> TextBuilder
forall a. Semigroup a => a -> a -> a
<> TextBuilder -> TextBuilder
inParens (TypeList -> TextBuilder
typeList TypeList
a)
    BExprIsOp
DocumentBExprIsOp -> TextBuilder
"DOCUMENT"

symbolicExprBinOp :: SymbolicExprBinOp -> TextBuilder
symbolicExprBinOp = \case
  MathSymbolicExprBinOp MathOp
a -> MathOp -> TextBuilder
mathOp MathOp
a
  QualSymbolicExprBinOp QualOp
a -> QualOp -> TextBuilder
qualOp QualOp
a

qualOp :: QualOp -> TextBuilder
qualOp = \case
  OpQualOp Text
a -> Text -> TextBuilder
op Text
a
  OperatorQualOp AnyOperator
a -> TextBuilder
"OPERATOR (" TextBuilder -> TextBuilder -> TextBuilder
forall a. Semigroup a => a -> a -> a
<> AnyOperator -> TextBuilder
anyOperator AnyOperator
a TextBuilder -> TextBuilder -> TextBuilder
forall a. Semigroup a => a -> a -> a
<> TextBuilder
")"

qualAllOp :: QualAllOp -> TextBuilder
qualAllOp = \case
  AllQualAllOp AllOp
a -> AllOp -> TextBuilder
allOp AllOp
a
  AnyQualAllOp AnyOperator
a -> TextBuilder
"OPERATOR (" TextBuilder -> TextBuilder -> TextBuilder
forall a. Semigroup a => a -> a -> a
<> AnyOperator -> TextBuilder
anyOperator AnyOperator
a TextBuilder -> TextBuilder -> TextBuilder
forall a. Semigroup a => a -> a -> a
<> TextBuilder
")"

op :: Text -> TextBuilder
op = Text -> TextBuilder
text

anyOperator :: AnyOperator -> TextBuilder
anyOperator = \case
  AllOpAnyOperator AllOp
a -> AllOp -> TextBuilder
allOp AllOp
a
  QualifiedAnyOperator ColId
a AnyOperator
b -> ColId -> TextBuilder
colId ColId
a TextBuilder -> TextBuilder -> TextBuilder
forall a. Semigroup a => a -> a -> a
<> TextBuilder
"." TextBuilder -> TextBuilder -> TextBuilder
forall a. Semigroup a => a -> a -> a
<> AnyOperator -> TextBuilder
anyOperator AnyOperator
b

allOp :: AllOp -> TextBuilder
allOp = \case
  OpAllOp Text
a -> Text -> TextBuilder
op Text
a
  MathAllOp MathOp
a -> MathOp -> TextBuilder
mathOp MathOp
a

mathOp :: MathOp -> TextBuilder
mathOp = \case
  MathOp
PlusMathOp -> Char -> TextBuilder
char7 Char
'+'
  MathOp
MinusMathOp -> Char -> TextBuilder
char7 Char
'-'
  MathOp
AsteriskMathOp -> Char -> TextBuilder
char7 Char
'*'
  MathOp
SlashMathOp -> Char -> TextBuilder
char7 Char
'/'
  MathOp
PercentMathOp -> Char -> TextBuilder
char7 Char
'%'
  MathOp
ArrowUpMathOp -> Char -> TextBuilder
char7 Char
'^'
  MathOp
ArrowLeftMathOp -> Char -> TextBuilder
char7 Char
'<'
  MathOp
ArrowRightMathOp -> Char -> TextBuilder
char7 Char
'>'
  MathOp
EqualsMathOp -> Char -> TextBuilder
char7 Char
'='
  MathOp
LessEqualsMathOp -> TextBuilder
"<="
  MathOp
GreaterEqualsMathOp -> TextBuilder
">="
  MathOp
ArrowLeftArrowRightMathOp -> TextBuilder
"<>"
  MathOp
ExclamationEqualsMathOp -> TextBuilder
"!="

inExpr :: InExpr -> TextBuilder
inExpr = \case
  SelectInExpr SelectWithParens
a -> SelectWithParens -> TextBuilder
selectWithParens SelectWithParens
a
  ExprListInExpr ExprList
a -> TextBuilder -> TextBuilder
inParens (ExprList -> TextBuilder
exprList ExprList
a)

caseExpr :: CaseExpr -> TextBuilder
caseExpr (CaseExpr Maybe WhereClause
a WhenClauseList
b Maybe WhereClause
c) =
  [Maybe TextBuilder] -> TextBuilder
optLexemes
    [ TextBuilder -> Maybe TextBuilder
forall a. a -> Maybe a
Just TextBuilder
"CASE",
      (WhereClause -> TextBuilder)
-> Maybe WhereClause -> Maybe TextBuilder
forall a b. (a -> b) -> Maybe a -> Maybe b
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap WhereClause -> TextBuilder
aExpr Maybe WhereClause
a,
      TextBuilder -> Maybe TextBuilder
forall a. a -> Maybe a
Just ((WhenClause -> TextBuilder) -> WhenClauseList -> TextBuilder
forall a. (a -> TextBuilder) -> NonEmpty a -> TextBuilder
spaceNonEmpty WhenClause -> TextBuilder
whenClause WhenClauseList
b),
      (WhereClause -> TextBuilder)
-> Maybe WhereClause -> Maybe TextBuilder
forall a b. (a -> b) -> Maybe a -> Maybe b
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap WhereClause -> TextBuilder
caseDefault Maybe WhereClause
c,
      TextBuilder -> Maybe TextBuilder
forall a. a -> Maybe a
Just TextBuilder
"END"
    ]

whenClause :: WhenClause -> TextBuilder
whenClause (WhenClause WhereClause
a WhereClause
b) = TextBuilder
"WHEN " TextBuilder -> TextBuilder -> TextBuilder
forall a. Semigroup a => a -> a -> a
<> WhereClause -> TextBuilder
aExpr WhereClause
a TextBuilder -> TextBuilder -> TextBuilder
forall a. Semigroup a => a -> a -> a
<> TextBuilder
" THEN " TextBuilder -> TextBuilder -> TextBuilder
forall a. Semigroup a => a -> a -> a
<> WhereClause -> TextBuilder
aExpr WhereClause
b

caseDefault :: WhereClause -> TextBuilder
caseDefault WhereClause
a = TextBuilder
"ELSE " TextBuilder -> TextBuilder -> TextBuilder
forall a. Semigroup a => a -> a -> a
<> WhereClause -> TextBuilder
aExpr WhereClause
a

arrayExpr :: ArrayExpr -> TextBuilder
arrayExpr =
  TextBuilder -> TextBuilder
inBrackets (TextBuilder -> TextBuilder)
-> (ArrayExpr -> TextBuilder) -> ArrayExpr -> TextBuilder
forall b c a. (b -> c) -> (a -> b) -> a -> c
forall {k} (cat :: k -> k -> *) (b :: k) (c :: k) (a :: k).
Category cat =>
cat b c -> cat a b -> cat a c
. \case
    ExprListArrayExpr ExprList
a -> ExprList -> TextBuilder
exprList ExprList
a
    ArrayExprListArrayExpr ArrayExprList
a -> ArrayExprList -> TextBuilder
arrayExprList ArrayExprList
a
    ArrayExpr
EmptyArrayExpr -> TextBuilder
forall a. Monoid a => a
mempty

arrayExprList :: ArrayExprList -> TextBuilder
arrayExprList = (ArrayExpr -> TextBuilder) -> ArrayExprList -> TextBuilder
forall a. (a -> TextBuilder) -> NonEmpty a -> TextBuilder
commaNonEmpty ArrayExpr -> TextBuilder
arrayExpr

row :: Row -> TextBuilder
row = \case
  ExplicitRowRow Maybe ExprList
a -> Maybe ExprList -> TextBuilder
explicitRow Maybe ExprList
a
  ImplicitRowRow ImplicitRow
a -> ImplicitRow -> TextBuilder
implicitRow ImplicitRow
a

explicitRow :: Maybe ExprList -> TextBuilder
explicitRow Maybe ExprList
a = TextBuilder
"ROW " TextBuilder -> TextBuilder -> TextBuilder
forall a. Semigroup a => a -> a -> a
<> TextBuilder -> TextBuilder
inParens ((ExprList -> TextBuilder) -> Maybe ExprList -> TextBuilder
forall m a. Monoid m => (a -> m) -> Maybe a -> m
forall (t :: * -> *) m a.
(Foldable t, Monoid m) =>
(a -> m) -> t a -> m
foldMap ExprList -> TextBuilder
exprList Maybe ExprList
a)

implicitRow :: ImplicitRow -> TextBuilder
implicitRow (ImplicitRow ExprList
a WhereClause
b) = TextBuilder -> TextBuilder
inParens (ExprList -> TextBuilder
exprList ExprList
a TextBuilder -> TextBuilder -> TextBuilder
forall a. Semigroup a => a -> a -> a
<> TextBuilder
", " TextBuilder -> TextBuilder -> TextBuilder
forall a. Semigroup a => a -> a -> a
<> WhereClause -> TextBuilder
aExpr WhereClause
b)

funcApplication :: FuncApplication -> TextBuilder
funcApplication (FuncApplication FuncName
a Maybe FuncApplicationParams
b) =
  FuncName -> TextBuilder
funcName FuncName
a TextBuilder -> TextBuilder -> TextBuilder
forall a. Semigroup a => a -> a -> a
<> TextBuilder
"(" TextBuilder -> TextBuilder -> TextBuilder
forall a. Semigroup a => a -> a -> a
<> (FuncApplicationParams -> TextBuilder)
-> Maybe FuncApplicationParams -> TextBuilder
forall m a. Monoid m => (a -> m) -> Maybe a -> m
forall (t :: * -> *) m a.
(Foldable t, Monoid m) =>
(a -> m) -> t a -> m
foldMap FuncApplicationParams -> TextBuilder
funcApplicationParams Maybe FuncApplicationParams
b TextBuilder -> TextBuilder -> TextBuilder
forall a. Semigroup a => a -> a -> a
<> TextBuilder
")"

funcApplicationParams :: FuncApplicationParams -> TextBuilder
funcApplicationParams = \case
  NormalFuncApplicationParams Maybe Bool
a NonEmpty FuncArgExpr
b Maybe SortClause
c ->
    [Maybe TextBuilder] -> TextBuilder
optLexemes
      [ (Bool -> TextBuilder) -> Maybe Bool -> Maybe TextBuilder
forall a b. (a -> b) -> Maybe a -> Maybe b
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap Bool -> TextBuilder
forall {a}. IsString a => Bool -> a
allOrDistinct Maybe Bool
a,
        TextBuilder -> Maybe TextBuilder
forall a. a -> Maybe a
Just ((FuncArgExpr -> TextBuilder) -> NonEmpty FuncArgExpr -> TextBuilder
forall a. (a -> TextBuilder) -> NonEmpty a -> TextBuilder
commaNonEmpty FuncArgExpr -> TextBuilder
funcArgExpr NonEmpty FuncArgExpr
b),
        (SortClause -> TextBuilder)
-> Maybe SortClause -> Maybe TextBuilder
forall a b. (a -> b) -> Maybe a -> Maybe b
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap SortClause -> TextBuilder
sortClause Maybe SortClause
c
      ]
  VariadicFuncApplicationParams Maybe (NonEmpty FuncArgExpr)
a FuncArgExpr
b Maybe SortClause
c ->
    [Maybe TextBuilder] -> TextBuilder
optLexemes
      [ (NonEmpty FuncArgExpr -> TextBuilder)
-> Maybe (NonEmpty FuncArgExpr) -> Maybe TextBuilder
forall a b. (a -> b) -> Maybe a -> Maybe b
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap ((TextBuilder -> TextBuilder -> TextBuilder)
-> TextBuilder -> TextBuilder -> TextBuilder
forall a b c. (a -> b -> c) -> b -> a -> c
flip TextBuilder -> TextBuilder -> TextBuilder
forall a. Monoid a => a -> a -> a
mappend TextBuilder
"," (TextBuilder -> TextBuilder)
-> (NonEmpty FuncArgExpr -> TextBuilder)
-> NonEmpty FuncArgExpr
-> TextBuilder
forall b c a. (b -> c) -> (a -> b) -> a -> c
forall {k} (cat :: k -> k -> *) (b :: k) (c :: k) (a :: k).
Category cat =>
cat b c -> cat a b -> cat a c
. (FuncArgExpr -> TextBuilder) -> NonEmpty FuncArgExpr -> TextBuilder
forall a. (a -> TextBuilder) -> NonEmpty a -> TextBuilder
commaNonEmpty FuncArgExpr -> TextBuilder
funcArgExpr) Maybe (NonEmpty FuncArgExpr)
a,
        TextBuilder -> Maybe TextBuilder
forall a. a -> Maybe a
Just TextBuilder
"VARIADIC",
        TextBuilder -> Maybe TextBuilder
forall a. a -> Maybe a
Just (FuncArgExpr -> TextBuilder
funcArgExpr FuncArgExpr
b),
        (SortClause -> TextBuilder)
-> Maybe SortClause -> Maybe TextBuilder
forall a b. (a -> b) -> Maybe a -> Maybe b
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap SortClause -> TextBuilder
sortClause Maybe SortClause
c
      ]
  FuncApplicationParams
StarFuncApplicationParams -> TextBuilder
"*"

allOrDistinct :: Bool -> a
allOrDistinct = \case
  Bool
False -> a
"ALL"
  Bool
True -> a
"DISTINCT"

funcArgExpr :: FuncArgExpr -> TextBuilder
funcArgExpr = \case
  ExprFuncArgExpr WhereClause
a -> WhereClause -> TextBuilder
aExpr WhereClause
a
  ColonEqualsFuncArgExpr ColId
a WhereClause
b -> ColId -> TextBuilder
ident ColId
a TextBuilder -> TextBuilder -> TextBuilder
forall a. Semigroup a => a -> a -> a
<> TextBuilder
" := " TextBuilder -> TextBuilder -> TextBuilder
forall a. Semigroup a => a -> a -> a
<> WhereClause -> TextBuilder
aExpr WhereClause
b
  EqualsGreaterFuncArgExpr ColId
a WhereClause
b -> ColId -> TextBuilder
ident ColId
a TextBuilder -> TextBuilder -> TextBuilder
forall a. Semigroup a => a -> a -> a
<> TextBuilder
" => " TextBuilder -> TextBuilder -> TextBuilder
forall a. Semigroup a => a -> a -> a
<> WhereClause -> TextBuilder
aExpr WhereClause
b

-- ** Func Expr

funcExpr :: FuncExpr -> TextBuilder
funcExpr = \case
  ApplicationFuncExpr FuncApplication
a Maybe SortClause
b Maybe WhereClause
c Maybe OverClause
d ->
    [Maybe TextBuilder] -> TextBuilder
optLexemes
      [ TextBuilder -> Maybe TextBuilder
forall a. a -> Maybe a
Just (FuncApplication -> TextBuilder
funcApplication FuncApplication
a),
        (SortClause -> TextBuilder)
-> Maybe SortClause -> Maybe TextBuilder
forall a b. (a -> b) -> Maybe a -> Maybe b
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap SortClause -> TextBuilder
withinGroupClause Maybe SortClause
b,
        (WhereClause -> TextBuilder)
-> Maybe WhereClause -> Maybe TextBuilder
forall a b. (a -> b) -> Maybe a -> Maybe b
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap WhereClause -> TextBuilder
filterClause Maybe WhereClause
c,
        (OverClause -> TextBuilder)
-> Maybe OverClause -> Maybe TextBuilder
forall a b. (a -> b) -> Maybe a -> Maybe b
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap OverClause -> TextBuilder
overClause Maybe OverClause
d
      ]
  SubexprFuncExpr FuncExprCommonSubexpr
a -> FuncExprCommonSubexpr -> TextBuilder
funcExprCommonSubexpr FuncExprCommonSubexpr
a

funcExprWindownless :: FuncExprWindowless -> TextBuilder
funcExprWindownless = \case
  ApplicationFuncExprWindowless FuncApplication
a -> FuncApplication -> TextBuilder
funcApplication FuncApplication
a
  CommonSubexprFuncExprWindowless FuncExprCommonSubexpr
a -> FuncExprCommonSubexpr -> TextBuilder
funcExprCommonSubexpr FuncExprCommonSubexpr
a

withinGroupClause :: SortClause -> TextBuilder
withinGroupClause SortClause
a = TextBuilder
"WITHIN GROUP (" TextBuilder -> TextBuilder -> TextBuilder
forall a. Semigroup a => a -> a -> a
<> SortClause -> TextBuilder
sortClause SortClause
a TextBuilder -> TextBuilder -> TextBuilder
forall a. Semigroup a => a -> a -> a
<> TextBuilder
")"

filterClause :: WhereClause -> TextBuilder
filterClause WhereClause
a = TextBuilder
"FILTER (WHERE " TextBuilder -> TextBuilder -> TextBuilder
forall a. Semigroup a => a -> a -> a
<> WhereClause -> TextBuilder
aExpr WhereClause
a TextBuilder -> TextBuilder -> TextBuilder
forall a. Semigroup a => a -> a -> a
<> TextBuilder
")"

overClause :: OverClause -> TextBuilder
overClause = \case
  WindowOverClause WindowSpecification
a -> TextBuilder
"OVER " TextBuilder -> TextBuilder -> TextBuilder
forall a. Semigroup a => a -> a -> a
<> WindowSpecification -> TextBuilder
windowSpecification WindowSpecification
a
  ColIdOverClause ColId
a -> TextBuilder
"OVER " TextBuilder -> TextBuilder -> TextBuilder
forall a. Semigroup a => a -> a -> a
<> ColId -> TextBuilder
colId ColId
a

funcExprCommonSubexpr :: FuncExprCommonSubexpr -> TextBuilder
funcExprCommonSubexpr = \case
  CollationForFuncExprCommonSubexpr WhereClause
a -> TextBuilder
"COLLATION FOR (" TextBuilder -> TextBuilder -> TextBuilder
forall a. Semigroup a => a -> a -> a
<> WhereClause -> TextBuilder
aExpr WhereClause
a TextBuilder -> TextBuilder -> TextBuilder
forall a. Semigroup a => a -> a -> a
<> TextBuilder
")"
  FuncExprCommonSubexpr
CurrentDateFuncExprCommonSubexpr -> TextBuilder
"CURRENT_DATE"
  CurrentTimeFuncExprCommonSubexpr Maybe Int64
a -> TextBuilder
"CURRENT_TIME" TextBuilder -> TextBuilder -> TextBuilder
forall a. Semigroup a => a -> a -> a
<> (Int64 -> TextBuilder) -> Maybe Int64 -> TextBuilder
forall a. (a -> TextBuilder) -> Maybe a -> TextBuilder
suffixMaybe (TextBuilder -> TextBuilder
inParens (TextBuilder -> TextBuilder)
-> (Int64 -> TextBuilder) -> Int64 -> TextBuilder
forall b c a. (b -> c) -> (a -> b) -> a -> c
forall {k} (cat :: k -> k -> *) (b :: k) (c :: k) (a :: k).
Category cat =>
cat b c -> cat a b -> cat a c
. Int64 -> TextBuilder
iconst) Maybe Int64
a
  CurrentTimestampFuncExprCommonSubexpr Maybe Int64
a -> TextBuilder
"CURRENT_TIMESTAMP" TextBuilder -> TextBuilder -> TextBuilder
forall a. Semigroup a => a -> a -> a
<> (Int64 -> TextBuilder) -> Maybe Int64 -> TextBuilder
forall a. (a -> TextBuilder) -> Maybe a -> TextBuilder
suffixMaybe (TextBuilder -> TextBuilder
inParens (TextBuilder -> TextBuilder)
-> (Int64 -> TextBuilder) -> Int64 -> TextBuilder
forall b c a. (b -> c) -> (a -> b) -> a -> c
forall {k} (cat :: k -> k -> *) (b :: k) (c :: k) (a :: k).
Category cat =>
cat b c -> cat a b -> cat a c
. Int64 -> TextBuilder
iconst) Maybe Int64
a
  LocalTimeFuncExprCommonSubexpr Maybe Int64
a -> TextBuilder
"LOCALTIME" TextBuilder -> TextBuilder -> TextBuilder
forall a. Semigroup a => a -> a -> a
<> (Int64 -> TextBuilder) -> Maybe Int64 -> TextBuilder
forall a. (a -> TextBuilder) -> Maybe a -> TextBuilder
suffixMaybe (TextBuilder -> TextBuilder
inParens (TextBuilder -> TextBuilder)
-> (Int64 -> TextBuilder) -> Int64 -> TextBuilder
forall b c a. (b -> c) -> (a -> b) -> a -> c
forall {k} (cat :: k -> k -> *) (b :: k) (c :: k) (a :: k).
Category cat =>
cat b c -> cat a b -> cat a c
. Int64 -> TextBuilder
iconst) Maybe Int64
a
  LocalTimestampFuncExprCommonSubexpr Maybe Int64
a -> TextBuilder
"LOCALTIMESTAMP" TextBuilder -> TextBuilder -> TextBuilder
forall a. Semigroup a => a -> a -> a
<> (Int64 -> TextBuilder) -> Maybe Int64 -> TextBuilder
forall a. (a -> TextBuilder) -> Maybe a -> TextBuilder
suffixMaybe (TextBuilder -> TextBuilder
inParens (TextBuilder -> TextBuilder)
-> (Int64 -> TextBuilder) -> Int64 -> TextBuilder
forall b c a. (b -> c) -> (a -> b) -> a -> c
forall {k} (cat :: k -> k -> *) (b :: k) (c :: k) (a :: k).
Category cat =>
cat b c -> cat a b -> cat a c
. Int64 -> TextBuilder
iconst) Maybe Int64
a
  FuncExprCommonSubexpr
CurrentRoleFuncExprCommonSubexpr -> TextBuilder
"CURRENT_ROLE"
  FuncExprCommonSubexpr
CurrentUserFuncExprCommonSubexpr -> TextBuilder
"CURRENT_USER"
  FuncExprCommonSubexpr
SessionUserFuncExprCommonSubexpr -> TextBuilder
"SESSION_USER"
  FuncExprCommonSubexpr
UserFuncExprCommonSubexpr -> TextBuilder
"USER"
  FuncExprCommonSubexpr
CurrentCatalogFuncExprCommonSubexpr -> TextBuilder
"CURRENT_CATALOG"
  FuncExprCommonSubexpr
CurrentSchemaFuncExprCommonSubexpr -> TextBuilder
"CURRENT_SCHEMA"
  CastFuncExprCommonSubexpr WhereClause
a Typename
b -> TextBuilder
"CAST (" TextBuilder -> TextBuilder -> TextBuilder
forall a. Semigroup a => a -> a -> a
<> WhereClause -> TextBuilder
aExpr WhereClause
a TextBuilder -> TextBuilder -> TextBuilder
forall a. Semigroup a => a -> a -> a
<> TextBuilder
" AS " TextBuilder -> TextBuilder -> TextBuilder
forall a. Semigroup a => a -> a -> a
<> Typename -> TextBuilder
typename Typename
b TextBuilder -> TextBuilder -> TextBuilder
forall a. Semigroup a => a -> a -> a
<> TextBuilder
")"
  ExtractFuncExprCommonSubexpr Maybe ExtractList
a -> TextBuilder
"EXTRACT (" TextBuilder -> TextBuilder -> TextBuilder
forall a. Semigroup a => a -> a -> a
<> (ExtractList -> TextBuilder) -> Maybe ExtractList -> TextBuilder
forall m a. Monoid m => (a -> m) -> Maybe a -> m
forall (t :: * -> *) m a.
(Foldable t, Monoid m) =>
(a -> m) -> t a -> m
foldMap ExtractList -> TextBuilder
extractList Maybe ExtractList
a TextBuilder -> TextBuilder -> TextBuilder
forall a. Semigroup a => a -> a -> a
<> TextBuilder
")"
  OverlayFuncExprCommonSubexpr OverlayList
a -> TextBuilder
"OVERLAY (" TextBuilder -> TextBuilder -> TextBuilder
forall a. Semigroup a => a -> a -> a
<> OverlayList -> TextBuilder
overlayList OverlayList
a TextBuilder -> TextBuilder -> TextBuilder
forall a. Semigroup a => a -> a -> a
<> TextBuilder
")"
  PositionFuncExprCommonSubexpr Maybe PositionList
a -> TextBuilder
"POSITION (" TextBuilder -> TextBuilder -> TextBuilder
forall a. Semigroup a => a -> a -> a
<> (PositionList -> TextBuilder) -> Maybe PositionList -> TextBuilder
forall m a. Monoid m => (a -> m) -> Maybe a -> m
forall (t :: * -> *) m a.
(Foldable t, Monoid m) =>
(a -> m) -> t a -> m
foldMap PositionList -> TextBuilder
positionList Maybe PositionList
a TextBuilder -> TextBuilder -> TextBuilder
forall a. Semigroup a => a -> a -> a
<> TextBuilder
")"
  SubstringFuncExprCommonSubexpr Maybe SubstrList
a -> TextBuilder
"SUBSTRING (" TextBuilder -> TextBuilder -> TextBuilder
forall a. Semigroup a => a -> a -> a
<> (SubstrList -> TextBuilder) -> Maybe SubstrList -> TextBuilder
forall m a. Monoid m => (a -> m) -> Maybe a -> m
forall (t :: * -> *) m a.
(Foldable t, Monoid m) =>
(a -> m) -> t a -> m
foldMap SubstrList -> TextBuilder
substrList Maybe SubstrList
a TextBuilder -> TextBuilder -> TextBuilder
forall a. Semigroup a => a -> a -> a
<> TextBuilder
")"
  TreatFuncExprCommonSubexpr WhereClause
a Typename
b -> TextBuilder
"TREAT (" TextBuilder -> TextBuilder -> TextBuilder
forall a. Semigroup a => a -> a -> a
<> WhereClause -> TextBuilder
aExpr WhereClause
a TextBuilder -> TextBuilder -> TextBuilder
forall a. Semigroup a => a -> a -> a
<> TextBuilder
" AS " TextBuilder -> TextBuilder -> TextBuilder
forall a. Semigroup a => a -> a -> a
<> Typename -> TextBuilder
typename Typename
b TextBuilder -> TextBuilder -> TextBuilder
forall a. Semigroup a => a -> a -> a
<> TextBuilder
")"
  TrimFuncExprCommonSubexpr Maybe TrimModifier
a TrimList
b -> TextBuilder
"TRIM (" TextBuilder -> TextBuilder -> TextBuilder
forall a. Semigroup a => a -> a -> a
<> (TrimModifier -> TextBuilder) -> Maybe TrimModifier -> TextBuilder
forall a. (a -> TextBuilder) -> Maybe a -> TextBuilder
prefixMaybe TrimModifier -> TextBuilder
forall {a}. IsString a => TrimModifier -> a
trimModifier Maybe TrimModifier
a TextBuilder -> TextBuilder -> TextBuilder
forall a. Semigroup a => a -> a -> a
<> TrimList -> TextBuilder
trimList TrimList
b TextBuilder -> TextBuilder -> TextBuilder
forall a. Semigroup a => a -> a -> a
<> TextBuilder
")"
  NullIfFuncExprCommonSubexpr WhereClause
a WhereClause
b -> TextBuilder
"NULLIF (" TextBuilder -> TextBuilder -> TextBuilder
forall a. Semigroup a => a -> a -> a
<> WhereClause -> TextBuilder
aExpr WhereClause
a TextBuilder -> TextBuilder -> TextBuilder
forall a. Semigroup a => a -> a -> a
<> TextBuilder
", " TextBuilder -> TextBuilder -> TextBuilder
forall a. Semigroup a => a -> a -> a
<> WhereClause -> TextBuilder
aExpr WhereClause
b TextBuilder -> TextBuilder -> TextBuilder
forall a. Semigroup a => a -> a -> a
<> TextBuilder
")"
  CoalesceFuncExprCommonSubexpr ExprList
a -> TextBuilder
"COALESCE (" TextBuilder -> TextBuilder -> TextBuilder
forall a. Semigroup a => a -> a -> a
<> ExprList -> TextBuilder
exprList ExprList
a TextBuilder -> TextBuilder -> TextBuilder
forall a. Semigroup a => a -> a -> a
<> TextBuilder
")"
  GreatestFuncExprCommonSubexpr ExprList
a -> TextBuilder
"GREATEST (" TextBuilder -> TextBuilder -> TextBuilder
forall a. Semigroup a => a -> a -> a
<> ExprList -> TextBuilder
exprList ExprList
a TextBuilder -> TextBuilder -> TextBuilder
forall a. Semigroup a => a -> a -> a
<> TextBuilder
")"
  LeastFuncExprCommonSubexpr ExprList
a -> TextBuilder
"LEAST (" TextBuilder -> TextBuilder -> TextBuilder
forall a. Semigroup a => a -> a -> a
<> ExprList -> TextBuilder
exprList ExprList
a TextBuilder -> TextBuilder -> TextBuilder
forall a. Semigroup a => a -> a -> a
<> TextBuilder
")"

extractList :: ExtractList -> TextBuilder
extractList (ExtractList ExtractArg
a WhereClause
b) = ExtractArg -> TextBuilder
extractArg ExtractArg
a TextBuilder -> TextBuilder -> TextBuilder
forall a. Semigroup a => a -> a -> a
<> TextBuilder
" FROM " TextBuilder -> TextBuilder -> TextBuilder
forall a. Semigroup a => a -> a -> a
<> WhereClause -> TextBuilder
aExpr WhereClause
b

extractArg :: ExtractArg -> TextBuilder
extractArg = \case
  IdentExtractArg ColId
a -> ColId -> TextBuilder
ident ColId
a
  ExtractArg
YearExtractArg -> TextBuilder
"YEAR"
  ExtractArg
MonthExtractArg -> TextBuilder
"MONTH"
  ExtractArg
DayExtractArg -> TextBuilder
"DAY"
  ExtractArg
HourExtractArg -> TextBuilder
"HOUR"
  ExtractArg
MinuteExtractArg -> TextBuilder
"MINUTE"
  ExtractArg
SecondExtractArg -> TextBuilder
"SECOND"
  SconstExtractArg Text
a -> Text -> TextBuilder
sconst Text
a

overlayList :: OverlayList -> TextBuilder
overlayList (OverlayList WhereClause
a WhereClause
b WhereClause
c Maybe WhereClause
d) = WhereClause -> TextBuilder
aExpr WhereClause
a TextBuilder -> TextBuilder -> TextBuilder
forall a. Semigroup a => a -> a -> a
<> TextBuilder
" " TextBuilder -> TextBuilder -> TextBuilder
forall a. Semigroup a => a -> a -> a
<> WhereClause -> TextBuilder
overlayPlacing WhereClause
b TextBuilder -> TextBuilder -> TextBuilder
forall a. Semigroup a => a -> a -> a
<> TextBuilder
" " TextBuilder -> TextBuilder -> TextBuilder
forall a. Semigroup a => a -> a -> a
<> WhereClause -> TextBuilder
substrFrom WhereClause
c TextBuilder -> TextBuilder -> TextBuilder
forall a. Semigroup a => a -> a -> a
<> (WhereClause -> TextBuilder) -> Maybe WhereClause -> TextBuilder
forall a. (a -> TextBuilder) -> Maybe a -> TextBuilder
suffixMaybe WhereClause -> TextBuilder
substrFor Maybe WhereClause
d

overlayPlacing :: WhereClause -> TextBuilder
overlayPlacing WhereClause
a = TextBuilder
"PLACING " TextBuilder -> TextBuilder -> TextBuilder
forall a. Semigroup a => a -> a -> a
<> WhereClause -> TextBuilder
aExpr WhereClause
a

positionList :: PositionList -> TextBuilder
positionList (PositionList BExpr
a BExpr
b) = BExpr -> TextBuilder
bExpr BExpr
a TextBuilder -> TextBuilder -> TextBuilder
forall a. Semigroup a => a -> a -> a
<> TextBuilder
" IN " TextBuilder -> TextBuilder -> TextBuilder
forall a. Semigroup a => a -> a -> a
<> BExpr -> TextBuilder
bExpr BExpr
b

substrList :: SubstrList -> TextBuilder
substrList = \case
  ExprSubstrList WhereClause
a SubstrListFromFor
b -> WhereClause -> TextBuilder
aExpr WhereClause
a TextBuilder -> TextBuilder -> TextBuilder
forall a. Semigroup a => a -> a -> a
<> TextBuilder
" " TextBuilder -> TextBuilder -> TextBuilder
forall a. Semigroup a => a -> a -> a
<> SubstrListFromFor -> TextBuilder
substrListFromFor SubstrListFromFor
b
  ExprListSubstrList ExprList
a -> ExprList -> TextBuilder
exprList ExprList
a

substrListFromFor :: SubstrListFromFor -> TextBuilder
substrListFromFor = \case
  FromForSubstrListFromFor WhereClause
a WhereClause
b -> WhereClause -> TextBuilder
substrFrom WhereClause
a TextBuilder -> TextBuilder -> TextBuilder
forall a. Semigroup a => a -> a -> a
<> TextBuilder
" " TextBuilder -> TextBuilder -> TextBuilder
forall a. Semigroup a => a -> a -> a
<> WhereClause -> TextBuilder
substrFor WhereClause
b
  ForFromSubstrListFromFor WhereClause
a WhereClause
b -> WhereClause -> TextBuilder
substrFor WhereClause
a TextBuilder -> TextBuilder -> TextBuilder
forall a. Semigroup a => a -> a -> a
<> TextBuilder
" " TextBuilder -> TextBuilder -> TextBuilder
forall a. Semigroup a => a -> a -> a
<> WhereClause -> TextBuilder
substrFrom WhereClause
b
  FromSubstrListFromFor WhereClause
a -> WhereClause -> TextBuilder
substrFrom WhereClause
a
  ForSubstrListFromFor WhereClause
a -> WhereClause -> TextBuilder
substrFor WhereClause
a

substrFrom :: WhereClause -> TextBuilder
substrFrom WhereClause
a = TextBuilder
"FROM " TextBuilder -> TextBuilder -> TextBuilder
forall a. Semigroup a => a -> a -> a
<> WhereClause -> TextBuilder
aExpr WhereClause
a

substrFor :: WhereClause -> TextBuilder
substrFor WhereClause
a = TextBuilder
"FOR " TextBuilder -> TextBuilder -> TextBuilder
forall a. Semigroup a => a -> a -> a
<> WhereClause -> TextBuilder
aExpr WhereClause
a

trimModifier :: TrimModifier -> a
trimModifier = \case
  TrimModifier
BothTrimModifier -> a
"BOTH"
  TrimModifier
LeadingTrimModifier -> a
"LEADING"
  TrimModifier
TrailingTrimModifier -> a
"TRAILING"

trimList :: TrimList -> TextBuilder
trimList = \case
  ExprFromExprListTrimList WhereClause
a ExprList
b -> WhereClause -> TextBuilder
aExpr WhereClause
a TextBuilder -> TextBuilder -> TextBuilder
forall a. Semigroup a => a -> a -> a
<> TextBuilder
" FROM " TextBuilder -> TextBuilder -> TextBuilder
forall a. Semigroup a => a -> a -> a
<> ExprList -> TextBuilder
exprList ExprList
b
  FromExprListTrimList ExprList
a -> TextBuilder
"FROM " TextBuilder -> TextBuilder -> TextBuilder
forall a. Semigroup a => a -> a -> a
<> ExprList -> TextBuilder
exprList ExprList
a
  ExprListTrimList ExprList
a -> ExprList -> TextBuilder
exprList ExprList
a

-- * AexprConsts

aexprConst :: AexprConst -> TextBuilder
aexprConst = \case
  IAexprConst Int64
a -> Int64 -> TextBuilder
iconst Int64
a
  FAexprConst Double
a -> Double -> TextBuilder
fconst Double
a
  SAexprConst Text
a -> Text -> TextBuilder
sconst Text
a
  BAexprConst Text
a -> TextBuilder
"B'" TextBuilder -> TextBuilder -> TextBuilder
forall a. Semigroup a => a -> a -> a
<> Text -> TextBuilder
text Text
a TextBuilder -> TextBuilder -> TextBuilder
forall a. Semigroup a => a -> a -> a
<> TextBuilder
"'"
  XAexprConst Text
a -> TextBuilder
"X'" TextBuilder -> TextBuilder -> TextBuilder
forall a. Semigroup a => a -> a -> a
<> Text -> TextBuilder
text Text
a TextBuilder -> TextBuilder -> TextBuilder
forall a. Semigroup a => a -> a -> a
<> TextBuilder
"'"
  FuncAexprConst FuncName
a Maybe FuncConstArgs
b Text
c -> FuncName -> TextBuilder
funcName FuncName
a TextBuilder -> TextBuilder -> TextBuilder
forall a. Semigroup a => a -> a -> a
<> (FuncConstArgs -> TextBuilder)
-> Maybe FuncConstArgs -> TextBuilder
forall m a. Monoid m => (a -> m) -> Maybe a -> m
forall (t :: * -> *) m a.
(Foldable t, Monoid m) =>
(a -> m) -> t a -> m
foldMap (TextBuilder -> TextBuilder
inParens (TextBuilder -> TextBuilder)
-> (FuncConstArgs -> TextBuilder) -> FuncConstArgs -> TextBuilder
forall b c a. (b -> c) -> (a -> b) -> a -> c
forall {k} (cat :: k -> k -> *) (b :: k) (c :: k) (a :: k).
Category cat =>
cat b c -> cat a b -> cat a c
. FuncConstArgs -> TextBuilder
funcAexprConstArgList) Maybe FuncConstArgs
b TextBuilder -> TextBuilder -> TextBuilder
forall a. Semigroup a => a -> a -> a
<> TextBuilder
" " TextBuilder -> TextBuilder -> TextBuilder
forall a. Semigroup a => a -> a -> a
<> Text -> TextBuilder
sconst Text
c
  ConstTypenameAexprConst ConstTypename
a Text
b -> ConstTypename -> TextBuilder
constTypename ConstTypename
a TextBuilder -> TextBuilder -> TextBuilder
forall a. Semigroup a => a -> a -> a
<> TextBuilder
" " TextBuilder -> TextBuilder -> TextBuilder
forall a. Semigroup a => a -> a -> a
<> Text -> TextBuilder
sconst Text
b
  StringIntervalAexprConst Text
a Maybe Interval
b -> TextBuilder
"INTERVAL " TextBuilder -> TextBuilder -> TextBuilder
forall a. Semigroup a => a -> a -> a
<> Text -> TextBuilder
sconst Text
a TextBuilder -> TextBuilder -> TextBuilder
forall a. Semigroup a => a -> a -> a
<> (Interval -> TextBuilder) -> Maybe Interval -> TextBuilder
forall a. (a -> TextBuilder) -> Maybe a -> TextBuilder
suffixMaybe Interval -> TextBuilder
interval Maybe Interval
b
  IntIntervalAexprConst Int64
a Text
b -> TextBuilder
"INTERVAL " TextBuilder -> TextBuilder -> TextBuilder
forall a. Semigroup a => a -> a -> a
<> TextBuilder -> TextBuilder
inParens (Int64 -> TextBuilder
int64Dec Int64
a) TextBuilder -> TextBuilder -> TextBuilder
forall a. Semigroup a => a -> a -> a
<> TextBuilder
" " TextBuilder -> TextBuilder -> TextBuilder
forall a. Semigroup a => a -> a -> a
<> Text -> TextBuilder
sconst Text
b
  BoolAexprConst Bool
a -> if Bool
a then TextBuilder
"TRUE" else TextBuilder
"FALSE"
  AexprConst
NullAexprConst -> TextBuilder
"NULL"

iconst :: Int64 -> TextBuilder
iconst = Int64 -> TextBuilder
int64Dec

fconst :: Double -> TextBuilder
fconst = Double -> TextBuilder
doubleDec

sconst :: Text -> TextBuilder
sconst Text
a = TextBuilder
"'" TextBuilder -> TextBuilder -> TextBuilder
forall a. Semigroup a => a -> a -> a
<> Text -> TextBuilder
text (HasCallStack => Text -> Text -> Text -> Text
Text -> Text -> Text -> Text
Text.replace Text
"'" Text
"''" Text
a) TextBuilder -> TextBuilder -> TextBuilder
forall a. Semigroup a => a -> a -> a
<> TextBuilder
"'"

funcAexprConstArgList :: FuncConstArgs -> TextBuilder
funcAexprConstArgList (FuncConstArgs NonEmpty FuncArgExpr
a Maybe SortClause
b) = (FuncArgExpr -> TextBuilder) -> NonEmpty FuncArgExpr -> TextBuilder
forall a. (a -> TextBuilder) -> NonEmpty a -> TextBuilder
commaNonEmpty FuncArgExpr -> TextBuilder
funcArgExpr NonEmpty FuncArgExpr
a TextBuilder -> TextBuilder -> TextBuilder
forall a. Semigroup a => a -> a -> a
<> (SortClause -> TextBuilder) -> Maybe SortClause -> TextBuilder
forall a. (a -> TextBuilder) -> Maybe a -> TextBuilder
suffixMaybe SortClause -> TextBuilder
sortClause Maybe SortClause
b

constTypename :: ConstTypename -> TextBuilder
constTypename = \case
  NumericConstTypename Numeric
a -> Numeric -> TextBuilder
numeric Numeric
a
  ConstBitConstTypename ConstBit
a -> ConstBit -> TextBuilder
constBit ConstBit
a
  ConstCharacterConstTypename ConstCharacter
a -> ConstCharacter -> TextBuilder
constCharacter ConstCharacter
a
  ConstDatetimeConstTypename ConstDatetime
a -> ConstDatetime -> TextBuilder
constDatetime ConstDatetime
a

numeric :: Numeric -> TextBuilder
numeric = \case
  Numeric
IntNumeric -> TextBuilder
"INT"
  Numeric
IntegerNumeric -> TextBuilder
"INTEGER"
  Numeric
SmallintNumeric -> TextBuilder
"SMALLINT"
  Numeric
BigintNumeric -> TextBuilder
"BIGINT"
  Numeric
RealNumeric -> TextBuilder
"REAL"
  FloatNumeric Maybe Int64
a -> TextBuilder
"FLOAT" TextBuilder -> TextBuilder -> TextBuilder
forall a. Semigroup a => a -> a -> a
<> (Int64 -> TextBuilder) -> Maybe Int64 -> TextBuilder
forall a. (a -> TextBuilder) -> Maybe a -> TextBuilder
suffixMaybe (TextBuilder -> TextBuilder
inParens (TextBuilder -> TextBuilder)
-> (Int64 -> TextBuilder) -> Int64 -> TextBuilder
forall b c a. (b -> c) -> (a -> b) -> a -> c
forall {k} (cat :: k -> k -> *) (b :: k) (c :: k) (a :: k).
Category cat =>
cat b c -> cat a b -> cat a c
. Int64 -> TextBuilder
int64Dec) Maybe Int64
a
  Numeric
DoublePrecisionNumeric -> TextBuilder
"DOUBLE PRECISION"
  DecimalNumeric Maybe ExprList
a -> TextBuilder
"DECIMAL" TextBuilder -> TextBuilder -> TextBuilder
forall a. Semigroup a => a -> a -> a
<> (ExprList -> TextBuilder) -> Maybe ExprList -> TextBuilder
forall a. (a -> TextBuilder) -> Maybe a -> TextBuilder
suffixMaybe (TextBuilder -> TextBuilder
inParens (TextBuilder -> TextBuilder)
-> (ExprList -> TextBuilder) -> ExprList -> TextBuilder
forall b c a. (b -> c) -> (a -> b) -> a -> c
forall {k} (cat :: k -> k -> *) (b :: k) (c :: k) (a :: k).
Category cat =>
cat b c -> cat a b -> cat a c
. (WhereClause -> TextBuilder) -> ExprList -> TextBuilder
forall a. (a -> TextBuilder) -> NonEmpty a -> TextBuilder
commaNonEmpty WhereClause -> TextBuilder
aExpr) Maybe ExprList
a
  DecNumeric Maybe ExprList
a -> TextBuilder
"DEC" TextBuilder -> TextBuilder -> TextBuilder
forall a. Semigroup a => a -> a -> a
<> (ExprList -> TextBuilder) -> Maybe ExprList -> TextBuilder
forall a. (a -> TextBuilder) -> Maybe a -> TextBuilder
suffixMaybe (TextBuilder -> TextBuilder
inParens (TextBuilder -> TextBuilder)
-> (ExprList -> TextBuilder) -> ExprList -> TextBuilder
forall b c a. (b -> c) -> (a -> b) -> a -> c
forall {k} (cat :: k -> k -> *) (b :: k) (c :: k) (a :: k).
Category cat =>
cat b c -> cat a b -> cat a c
. (WhereClause -> TextBuilder) -> ExprList -> TextBuilder
forall a. (a -> TextBuilder) -> NonEmpty a -> TextBuilder
commaNonEmpty WhereClause -> TextBuilder
aExpr) Maybe ExprList
a
  NumericNumeric Maybe ExprList
a -> TextBuilder
"NUMERIC" TextBuilder -> TextBuilder -> TextBuilder
forall a. Semigroup a => a -> a -> a
<> (ExprList -> TextBuilder) -> Maybe ExprList -> TextBuilder
forall a. (a -> TextBuilder) -> Maybe a -> TextBuilder
suffixMaybe (TextBuilder -> TextBuilder
inParens (TextBuilder -> TextBuilder)
-> (ExprList -> TextBuilder) -> ExprList -> TextBuilder
forall b c a. (b -> c) -> (a -> b) -> a -> c
forall {k} (cat :: k -> k -> *) (b :: k) (c :: k) (a :: k).
Category cat =>
cat b c -> cat a b -> cat a c
. (WhereClause -> TextBuilder) -> ExprList -> TextBuilder
forall a. (a -> TextBuilder) -> NonEmpty a -> TextBuilder
commaNonEmpty WhereClause -> TextBuilder
aExpr) Maybe ExprList
a
  Numeric
BooleanNumeric -> TextBuilder
"BOOLEAN"

bit :: ConstBit -> TextBuilder
bit (Bit Bool
a Maybe ExprList
b) =
  [Maybe TextBuilder] -> TextBuilder
optLexemes
    [ TextBuilder -> Maybe TextBuilder
forall a. a -> Maybe a
Just TextBuilder
"BIT",
      Maybe TextBuilder -> Maybe TextBuilder -> Bool -> Maybe TextBuilder
forall a. a -> a -> Bool -> a
bool Maybe TextBuilder
forall a. Maybe a
Nothing (TextBuilder -> Maybe TextBuilder
forall a. a -> Maybe a
Just TextBuilder
"VARYING") Bool
a,
      (ExprList -> TextBuilder) -> Maybe ExprList -> Maybe TextBuilder
forall a b. (a -> b) -> Maybe a -> Maybe b
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap (TextBuilder -> TextBuilder
inParens (TextBuilder -> TextBuilder)
-> (ExprList -> TextBuilder) -> ExprList -> TextBuilder
forall b c a. (b -> c) -> (a -> b) -> a -> c
forall {k} (cat :: k -> k -> *) (b :: k) (c :: k) (a :: k).
Category cat =>
cat b c -> cat a b -> cat a c
. (WhereClause -> TextBuilder) -> ExprList -> TextBuilder
forall a. (a -> TextBuilder) -> NonEmpty a -> TextBuilder
commaNonEmpty WhereClause -> TextBuilder
aExpr) Maybe ExprList
b
    ]

constBit :: ConstBit -> TextBuilder
constBit = ConstBit -> TextBuilder
bit

constCharacter :: ConstCharacter -> TextBuilder
constCharacter (ConstCharacter Character
a Maybe Int64
b) = Character -> TextBuilder
forall {a}. (Semigroup a, IsString a) => Character -> a
character Character
a TextBuilder -> TextBuilder -> TextBuilder
forall a. Semigroup a => a -> a -> a
<> (Int64 -> TextBuilder) -> Maybe Int64 -> TextBuilder
forall a. (a -> TextBuilder) -> Maybe a -> TextBuilder
suffixMaybe (TextBuilder -> TextBuilder
inParens (TextBuilder -> TextBuilder)
-> (Int64 -> TextBuilder) -> Int64 -> TextBuilder
forall b c a. (b -> c) -> (a -> b) -> a -> c
forall {k} (cat :: k -> k -> *) (b :: k) (c :: k) (a :: k).
Category cat =>
cat b c -> cat a b -> cat a c
. Int64 -> TextBuilder
int64Dec) Maybe Int64
b

character :: Character -> a
character = \case
  CharacterCharacter Bool
a -> a
"CHARACTER" a -> a -> a
forall a. Semigroup a => a -> a -> a
<> a -> a -> Bool -> a
forall a. a -> a -> Bool -> a
bool a
"" a
" VARYING" Bool
a
  CharCharacter Bool
a -> a
"CHAR" a -> a -> a
forall a. Semigroup a => a -> a -> a
<> a -> a -> Bool -> a
forall a. a -> a -> Bool -> a
bool a
"" a
" VARYING" Bool
a
  Character
VarcharCharacter -> a
"VARCHAR"
  NationalCharacterCharacter Bool
a -> a
"NATIONAL CHARACTER" a -> a -> a
forall a. Semigroup a => a -> a -> a
<> a -> a -> Bool -> a
forall a. a -> a -> Bool -> a
bool a
"" a
" VARYING" Bool
a
  NationalCharCharacter Bool
a -> a
"NATIONAL CHAR" a -> a -> a
forall a. Semigroup a => a -> a -> a
<> a -> a -> Bool -> a
forall a. a -> a -> Bool -> a
bool a
"" a
" VARYING" Bool
a
  NcharCharacter Bool
a -> a
"NCHAR" a -> a -> a
forall a. Semigroup a => a -> a -> a
<> a -> a -> Bool -> a
forall a. a -> a -> Bool -> a
bool a
"" a
" VARYING" Bool
a

constDatetime :: ConstDatetime -> TextBuilder
constDatetime = \case
  TimestampConstDatetime Maybe Int64
a Maybe Bool
b ->
    [Maybe TextBuilder] -> TextBuilder
optLexemes
      [ TextBuilder -> Maybe TextBuilder
forall a. a -> Maybe a
Just TextBuilder
"TIMESTAMP",
        (Int64 -> TextBuilder) -> Maybe Int64 -> Maybe TextBuilder
forall a b. (a -> b) -> Maybe a -> Maybe b
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap (TextBuilder -> TextBuilder
inParens (TextBuilder -> TextBuilder)
-> (Int64 -> TextBuilder) -> Int64 -> TextBuilder
forall b c a. (b -> c) -> (a -> b) -> a -> c
forall {k} (cat :: k -> k -> *) (b :: k) (c :: k) (a :: k).
Category cat =>
cat b c -> cat a b -> cat a c
. Int64 -> TextBuilder
int64Dec) Maybe Int64
a,
        (Bool -> TextBuilder) -> Maybe Bool -> Maybe TextBuilder
forall a b. (a -> b) -> Maybe a -> Maybe b
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap Bool -> TextBuilder
forall {a}. IsString a => Bool -> a
timezone Maybe Bool
b
      ]
  TimeConstDatetime Maybe Int64
a Maybe Bool
b ->
    [Maybe TextBuilder] -> TextBuilder
optLexemes
      [ TextBuilder -> Maybe TextBuilder
forall a. a -> Maybe a
Just TextBuilder
"TIME",
        (Int64 -> TextBuilder) -> Maybe Int64 -> Maybe TextBuilder
forall a b. (a -> b) -> Maybe a -> Maybe b
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap (TextBuilder -> TextBuilder
inParens (TextBuilder -> TextBuilder)
-> (Int64 -> TextBuilder) -> Int64 -> TextBuilder
forall b c a. (b -> c) -> (a -> b) -> a -> c
forall {k} (cat :: k -> k -> *) (b :: k) (c :: k) (a :: k).
Category cat =>
cat b c -> cat a b -> cat a c
. Int64 -> TextBuilder
int64Dec) Maybe Int64
a,
        (Bool -> TextBuilder) -> Maybe Bool -> Maybe TextBuilder
forall a b. (a -> b) -> Maybe a -> Maybe b
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap Bool -> TextBuilder
forall {a}. IsString a => Bool -> a
timezone Maybe Bool
b
      ]

timezone :: Bool -> a
timezone = \case
  Bool
False -> a
"WITH TIME ZONE"
  Bool
True -> a
"WITHOUT TIME ZONE"

interval :: Interval -> TextBuilder
interval = \case
  Interval
YearInterval -> TextBuilder
"YEAR"
  Interval
MonthInterval -> TextBuilder
"MONTH"
  Interval
DayInterval -> TextBuilder
"DAY"
  Interval
HourInterval -> TextBuilder
"HOUR"
  Interval
MinuteInterval -> TextBuilder
"MINUTE"
  SecondInterval Maybe Int64
a -> Maybe Int64 -> TextBuilder
intervalSecond Maybe Int64
a
  Interval
YearToMonthInterval -> TextBuilder
"YEAR TO MONTH"
  Interval
DayToHourInterval -> TextBuilder
"DAY TO HOUR"
  Interval
DayToMinuteInterval -> TextBuilder
"DAY TO MINUTE"
  DayToSecondInterval Maybe Int64
a -> TextBuilder
"DAY TO " TextBuilder -> TextBuilder -> TextBuilder
forall a. Semigroup a => a -> a -> a
<> Maybe Int64 -> TextBuilder
intervalSecond Maybe Int64
a
  Interval
HourToMinuteInterval -> TextBuilder
"HOUR TO MINUTE"
  HourToSecondInterval Maybe Int64
a -> TextBuilder
"HOUR TO " TextBuilder -> TextBuilder -> TextBuilder
forall a. Semigroup a => a -> a -> a
<> Maybe Int64 -> TextBuilder
intervalSecond Maybe Int64
a
  MinuteToSecondInterval Maybe Int64
a -> TextBuilder
"MINUTE TO " TextBuilder -> TextBuilder -> TextBuilder
forall a. Semigroup a => a -> a -> a
<> Maybe Int64 -> TextBuilder
intervalSecond Maybe Int64
a

intervalSecond :: Maybe Int64 -> TextBuilder
intervalSecond = \case
  Maybe Int64
Nothing -> TextBuilder
"SECOND"
  Just Int64
a -> TextBuilder
"SECOND " TextBuilder -> TextBuilder -> TextBuilder
forall a. Semigroup a => a -> a -> a
<> TextBuilder -> TextBuilder
inParens (Int64 -> TextBuilder
int64Dec Int64
a)

-- * Names and refs

columnref :: Columnref -> TextBuilder
columnref (Columnref ColId
a Maybe Indirection
b) = ColId -> TextBuilder
colId ColId
a TextBuilder -> TextBuilder -> TextBuilder
forall a. Semigroup a => a -> a -> a
<> (Indirection -> TextBuilder) -> Maybe Indirection -> TextBuilder
forall m a. Monoid m => (a -> m) -> Maybe a -> m
forall (t :: * -> *) m a.
(Foldable t, Monoid m) =>
(a -> m) -> t a -> m
foldMap Indirection -> TextBuilder
indirection Maybe Indirection
b

ident :: ColId -> TextBuilder
ident = \case
  QuotedIdent Text
a -> Char -> TextBuilder
char7 Char
'"' TextBuilder -> TextBuilder -> TextBuilder
forall a. Semigroup a => a -> a -> a
<> Text -> TextBuilder
text (HasCallStack => Text -> Text -> Text -> Text
Text -> Text -> Text -> Text
Text.replace Text
"\"" Text
"\"\"" Text
a) TextBuilder -> TextBuilder -> TextBuilder
forall a. Semigroup a => a -> a -> a
<> Char -> TextBuilder
char7 Char
'"'
  UnquotedIdent Text
a -> Text -> TextBuilder
text Text
a

qualifiedName :: QualifiedName -> TextBuilder
qualifiedName = \case
  SimpleQualifiedName ColId
a -> ColId -> TextBuilder
ident ColId
a
  IndirectedQualifiedName ColId
a Indirection
b -> ColId -> TextBuilder
ident ColId
a TextBuilder -> TextBuilder -> TextBuilder
forall a. Semigroup a => a -> a -> a
<> Indirection -> TextBuilder
indirection Indirection
b

indirection :: Indirection -> TextBuilder
indirection = (IndirectionEl -> TextBuilder) -> Indirection -> TextBuilder
forall m a. Monoid m => (a -> m) -> NonEmpty a -> m
forall (t :: * -> *) m a.
(Foldable t, Monoid m) =>
(a -> m) -> t a -> m
foldMap IndirectionEl -> TextBuilder
indirectionEl

indirectionEl :: IndirectionEl -> TextBuilder
indirectionEl = \case
  AttrNameIndirectionEl ColId
a -> TextBuilder
"." TextBuilder -> TextBuilder -> TextBuilder
forall a. Semigroup a => a -> a -> a
<> ColId -> TextBuilder
ident ColId
a
  IndirectionEl
AllIndirectionEl -> TextBuilder
".*"
  ExprIndirectionEl WhereClause
a -> TextBuilder
"[" TextBuilder -> TextBuilder -> TextBuilder
forall a. Semigroup a => a -> a -> a
<> WhereClause -> TextBuilder
aExpr WhereClause
a TextBuilder -> TextBuilder -> TextBuilder
forall a. Semigroup a => a -> a -> a
<> TextBuilder
"]"
  SliceIndirectionEl Maybe WhereClause
a Maybe WhereClause
b -> TextBuilder
"[" TextBuilder -> TextBuilder -> TextBuilder
forall a. Semigroup a => a -> a -> a
<> (WhereClause -> TextBuilder) -> Maybe WhereClause -> TextBuilder
forall m a. Monoid m => (a -> m) -> Maybe a -> m
forall (t :: * -> *) m a.
(Foldable t, Monoid m) =>
(a -> m) -> t a -> m
foldMap WhereClause -> TextBuilder
aExpr Maybe WhereClause
a TextBuilder -> TextBuilder -> TextBuilder
forall a. Semigroup a => a -> a -> a
<> TextBuilder
":" TextBuilder -> TextBuilder -> TextBuilder
forall a. Semigroup a => a -> a -> a
<> (WhereClause -> TextBuilder) -> Maybe WhereClause -> TextBuilder
forall m a. Monoid m => (a -> m) -> Maybe a -> m
forall (t :: * -> *) m a.
(Foldable t, Monoid m) =>
(a -> m) -> t a -> m
foldMap WhereClause -> TextBuilder
aExpr Maybe WhereClause
b TextBuilder -> TextBuilder -> TextBuilder
forall a. Semigroup a => a -> a -> a
<> TextBuilder
"]"

colId :: ColId -> TextBuilder
colId = ColId -> TextBuilder
ident

name :: ColId -> TextBuilder
name = ColId -> TextBuilder
colId

cursorName :: ColId -> TextBuilder
cursorName = ColId -> TextBuilder
name

colLabel :: ColId -> TextBuilder
colLabel = ColId -> TextBuilder
ident

attrName :: ColId -> TextBuilder
attrName = ColId -> TextBuilder
colLabel

typeFunctionName :: ColId -> TextBuilder
typeFunctionName = ColId -> TextBuilder
ident

funcName :: FuncName -> TextBuilder
funcName = \case
  TypeFuncName ColId
a -> ColId -> TextBuilder
typeFunctionName ColId
a
  IndirectedFuncName ColId
a Indirection
b -> ColId -> TextBuilder
colId ColId
a TextBuilder -> TextBuilder -> TextBuilder
forall a. Semigroup a => a -> a -> a
<> Indirection -> TextBuilder
indirection Indirection
b

anyName :: CollateClause -> TextBuilder
anyName (AnyName ColId
a Maybe (NonEmpty ColId)
b) = ColId -> TextBuilder
colId ColId
a TextBuilder -> TextBuilder -> TextBuilder
forall a. Semigroup a => a -> a -> a
<> (NonEmpty ColId -> TextBuilder)
-> Maybe (NonEmpty ColId) -> TextBuilder
forall m a. Monoid m => (a -> m) -> Maybe a -> m
forall (t :: * -> *) m a.
(Foldable t, Monoid m) =>
(a -> m) -> t a -> m
foldMap NonEmpty ColId -> TextBuilder
forall {t :: * -> *}. Foldable t => t ColId -> TextBuilder
attrs Maybe (NonEmpty ColId)
b

-- * Types

typename :: Typename -> TextBuilder
typename (Typename Bool
a SimpleTypename
b Bool
_ Maybe (TypenameArrayDimensions, Bool)
d) =
  TextBuilder -> TextBuilder -> Bool -> TextBuilder
forall a. a -> a -> Bool -> a
bool TextBuilder
"" TextBuilder
"SETOF " Bool
a TextBuilder -> TextBuilder -> TextBuilder
forall a. Semigroup a => a -> a -> a
<> SimpleTypename -> TextBuilder
simpleTypename SimpleTypename
b TextBuilder -> TextBuilder -> TextBuilder
forall a. Semigroup a => a -> a -> a
<> ((TypenameArrayDimensions, Bool) -> TextBuilder)
-> Maybe (TypenameArrayDimensions, Bool) -> TextBuilder
forall m a. Monoid m => (a -> m) -> Maybe a -> m
forall (t :: * -> *) m a.
(Foldable t, Monoid m) =>
(a -> m) -> t a -> m
foldMap (TypenameArrayDimensions, Bool) -> TextBuilder
forall {b}. (TypenameArrayDimensions, b) -> TextBuilder
typenameArrayDimensionsWithQuestionMark Maybe (TypenameArrayDimensions, Bool)
d

typenameArrayDimensionsWithQuestionMark :: (TypenameArrayDimensions, b) -> TextBuilder
typenameArrayDimensionsWithQuestionMark (TypenameArrayDimensions
a, b
_) =
  TypenameArrayDimensions -> TextBuilder
typenameArrayDimensions TypenameArrayDimensions
a

typenameArrayDimensions :: TypenameArrayDimensions -> TextBuilder
typenameArrayDimensions = \case
  BoundsTypenameArrayDimensions ArrayBounds
a -> ArrayBounds -> TextBuilder
forall {t :: * -> *}.
Foldable t =>
NonEmpty (t Int64) -> TextBuilder
arrayBounds ArrayBounds
a
  ExplicitTypenameArrayDimensions Maybe Int64
a -> TextBuilder
" ARRAY" TextBuilder -> TextBuilder -> TextBuilder
forall a. Semigroup a => a -> a -> a
<> (Int64 -> TextBuilder) -> Maybe Int64 -> TextBuilder
forall m a. Monoid m => (a -> m) -> Maybe a -> m
forall (t :: * -> *) m a.
(Foldable t, Monoid m) =>
(a -> m) -> t a -> m
foldMap (TextBuilder -> TextBuilder
inBrackets (TextBuilder -> TextBuilder)
-> (Int64 -> TextBuilder) -> Int64 -> TextBuilder
forall b c a. (b -> c) -> (a -> b) -> a -> c
forall {k} (cat :: k -> k -> *) (b :: k) (c :: k) (a :: k).
Category cat =>
cat b c -> cat a b -> cat a c
. Int64 -> TextBuilder
iconst) Maybe Int64
a

arrayBounds :: NonEmpty (t Int64) -> TextBuilder
arrayBounds = (t Int64 -> TextBuilder) -> NonEmpty (t Int64) -> TextBuilder
forall a. (a -> TextBuilder) -> NonEmpty a -> TextBuilder
spaceNonEmpty (TextBuilder -> TextBuilder
inBrackets (TextBuilder -> TextBuilder)
-> (t Int64 -> TextBuilder) -> t Int64 -> TextBuilder
forall b c a. (b -> c) -> (a -> b) -> a -> c
forall {k} (cat :: k -> k -> *) (b :: k) (c :: k) (a :: k).
Category cat =>
cat b c -> cat a b -> cat a c
. (Int64 -> TextBuilder) -> t Int64 -> TextBuilder
forall m a. Monoid m => (a -> m) -> t a -> m
forall (t :: * -> *) m a.
(Foldable t, Monoid m) =>
(a -> m) -> t a -> m
foldMap Int64 -> TextBuilder
iconst)

simpleTypename :: SimpleTypename -> TextBuilder
simpleTypename = \case
  GenericTypeSimpleTypename GenericType
a -> GenericType -> TextBuilder
genericType GenericType
a
  NumericSimpleTypename Numeric
a -> Numeric -> TextBuilder
numeric Numeric
a
  BitSimpleTypename ConstBit
a -> ConstBit -> TextBuilder
bit ConstBit
a
  CharacterSimpleTypename Character
a -> Character -> TextBuilder
forall {a}. (Semigroup a, IsString a) => Character -> a
character Character
a
  ConstDatetimeSimpleTypename ConstDatetime
a -> ConstDatetime -> TextBuilder
constDatetime ConstDatetime
a
  ConstIntervalSimpleTypename Either (Maybe Interval) Int64
a -> TextBuilder
"INTERVAL" TextBuilder -> TextBuilder -> TextBuilder
forall a. Semigroup a => a -> a -> a
<> (Maybe Interval -> TextBuilder)
-> (Int64 -> TextBuilder)
-> Either (Maybe Interval) Int64
-> TextBuilder
forall a c b. (a -> c) -> (b -> c) -> Either a b -> c
either ((Interval -> TextBuilder) -> Maybe Interval -> TextBuilder
forall a. (a -> TextBuilder) -> Maybe a -> TextBuilder
suffixMaybe Interval -> TextBuilder
interval) (TextBuilder -> TextBuilder -> TextBuilder
forall a. Monoid a => a -> a -> a
mappend TextBuilder
" " (TextBuilder -> TextBuilder)
-> (Int64 -> TextBuilder) -> Int64 -> TextBuilder
forall b c a. (b -> c) -> (a -> b) -> a -> c
forall {k} (cat :: k -> k -> *) (b :: k) (c :: k) (a :: k).
Category cat =>
cat b c -> cat a b -> cat a c
. TextBuilder -> TextBuilder
inParens (TextBuilder -> TextBuilder)
-> (Int64 -> TextBuilder) -> Int64 -> TextBuilder
forall b c a. (b -> c) -> (a -> b) -> a -> c
forall {k} (cat :: k -> k -> *) (b :: k) (c :: k) (a :: k).
Category cat =>
cat b c -> cat a b -> cat a c
. Int64 -> TextBuilder
iconst) Either (Maybe Interval) Int64
a

genericType :: GenericType -> TextBuilder
genericType (GenericType ColId
a Maybe (NonEmpty ColId)
b Maybe ExprList
c) = ColId -> TextBuilder
typeFunctionName ColId
a TextBuilder -> TextBuilder -> TextBuilder
forall a. Semigroup a => a -> a -> a
<> (NonEmpty ColId -> TextBuilder)
-> Maybe (NonEmpty ColId) -> TextBuilder
forall m a. Monoid m => (a -> m) -> Maybe a -> m
forall (t :: * -> *) m a.
(Foldable t, Monoid m) =>
(a -> m) -> t a -> m
foldMap NonEmpty ColId -> TextBuilder
forall {t :: * -> *}. Foldable t => t ColId -> TextBuilder
attrs Maybe (NonEmpty ColId)
b TextBuilder -> TextBuilder -> TextBuilder
forall a. Semigroup a => a -> a -> a
<> (ExprList -> TextBuilder) -> Maybe ExprList -> TextBuilder
forall a. (a -> TextBuilder) -> Maybe a -> TextBuilder
suffixMaybe ExprList -> TextBuilder
typeModifiers Maybe ExprList
c

attrs :: t ColId -> TextBuilder
attrs = (ColId -> TextBuilder) -> t ColId -> TextBuilder
forall m a. Monoid m => (a -> m) -> t a -> m
forall (t :: * -> *) m a.
(Foldable t, Monoid m) =>
(a -> m) -> t a -> m
foldMap (TextBuilder -> TextBuilder -> TextBuilder
forall a. Monoid a => a -> a -> a
mappend TextBuilder
"." (TextBuilder -> TextBuilder)
-> (ColId -> TextBuilder) -> ColId -> TextBuilder
forall b c a. (b -> c) -> (a -> b) -> a -> c
forall {k} (cat :: k -> k -> *) (b :: k) (c :: k) (a :: k).
Category cat =>
cat b c -> cat a b -> cat a c
. ColId -> TextBuilder
attrName)

typeModifiers :: ExprList -> TextBuilder
typeModifiers = TextBuilder -> TextBuilder
inParens (TextBuilder -> TextBuilder)
-> (ExprList -> TextBuilder) -> ExprList -> TextBuilder
forall b c a. (b -> c) -> (a -> b) -> a -> c
forall {k} (cat :: k -> k -> *) (b :: k) (c :: k) (a :: k).
Category cat =>
cat b c -> cat a b -> cat a c
. ExprList -> TextBuilder
exprList

typeList :: TypeList -> TextBuilder
typeList = (Typename -> TextBuilder) -> TypeList -> TextBuilder
forall a. (a -> TextBuilder) -> NonEmpty a -> TextBuilder
commaNonEmpty Typename -> TextBuilder
typename

subType :: SubType -> a
subType = \case
  SubType
AnySubType -> a
"ANY"
  SubType
SomeSubType -> a
"SOME"
  SubType
AllSubType -> a
"ALL"

-- * Indexes

indexParams :: IndexParams -> TextBuilder
indexParams = (IndexElem -> TextBuilder) -> IndexParams -> TextBuilder
forall a. (a -> TextBuilder) -> NonEmpty a -> TextBuilder
commaNonEmpty IndexElem -> TextBuilder
indexElem

indexElem :: IndexElem -> TextBuilder
indexElem (IndexElem IndexElemDef
a Maybe CollateClause
b Maybe CollateClause
c Maybe AscDesc
d Maybe NullsOrder
e) =
  IndexElemDef -> TextBuilder
indexElemDef IndexElemDef
a
    TextBuilder -> TextBuilder -> TextBuilder
forall a. Semigroup a => a -> a -> a
<> (CollateClause -> TextBuilder)
-> Maybe CollateClause -> TextBuilder
forall a. (a -> TextBuilder) -> Maybe a -> TextBuilder
suffixMaybe CollateClause -> TextBuilder
collate Maybe CollateClause
b
    TextBuilder -> TextBuilder -> TextBuilder
forall a. Semigroup a => a -> a -> a
<> (CollateClause -> TextBuilder)
-> Maybe CollateClause -> TextBuilder
forall a. (a -> TextBuilder) -> Maybe a -> TextBuilder
suffixMaybe CollateClause -> TextBuilder
class_ Maybe CollateClause
c
    TextBuilder -> TextBuilder -> TextBuilder
forall a. Semigroup a => a -> a -> a
<> (AscDesc -> TextBuilder) -> Maybe AscDesc -> TextBuilder
forall a. (a -> TextBuilder) -> Maybe a -> TextBuilder
suffixMaybe AscDesc -> TextBuilder
forall {a}. IsString a => AscDesc -> a
ascDesc Maybe AscDesc
d
    TextBuilder -> TextBuilder -> TextBuilder
forall a. Semigroup a => a -> a -> a
<> (NullsOrder -> TextBuilder) -> Maybe NullsOrder -> TextBuilder
forall a. (a -> TextBuilder) -> Maybe a -> TextBuilder
suffixMaybe NullsOrder -> TextBuilder
forall {a}. IsString a => NullsOrder -> a
nullsOrder Maybe NullsOrder
e

indexElemDef :: IndexElemDef -> TextBuilder
indexElemDef = \case
  IdIndexElemDef ColId
a -> ColId -> TextBuilder
colId ColId
a
  FuncIndexElemDef FuncExprWindowless
a -> FuncExprWindowless -> TextBuilder
funcExprWindownless FuncExprWindowless
a
  ExprIndexElemDef WhereClause
a -> TextBuilder -> TextBuilder
inParens (WhereClause -> TextBuilder
aExpr WhereClause
a)

collate :: CollateClause -> TextBuilder
collate = TextBuilder -> TextBuilder -> TextBuilder
forall a. Monoid a => a -> a -> a
mappend TextBuilder
"COLLATE " (TextBuilder -> TextBuilder)
-> (CollateClause -> TextBuilder) -> CollateClause -> TextBuilder
forall b c a. (b -> c) -> (a -> b) -> a -> c
forall {k} (cat :: k -> k -> *) (b :: k) (c :: k) (a :: k).
Category cat =>
cat b c -> cat a b -> cat a c
. CollateClause -> TextBuilder
anyName

class_ :: CollateClause -> TextBuilder
class_ = CollateClause -> TextBuilder
anyName

ascDesc :: AscDesc -> a
ascDesc = \case
  AscDesc
AscAscDesc -> a
"ASC"
  AscDesc
DescAscDesc -> a
"DESC"

nullsOrder :: NullsOrder -> a
nullsOrder = \case
  NullsOrder
FirstNullsOrder -> a
"NULLS FIRST"
  NullsOrder
LastNullsOrder -> a
"NULLS LAST"