module PostgresqlSyntax.Rendering where

import qualified Data.List.NonEmpty as NonEmpty
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 Text.Builder hiding (char7, doubleDec, int64Dec, intDec)

-- * Execution

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

toText :: Builder -> Text
toText :: Builder -> Text
toText = Builder -> Text
run

-- * Helpers

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

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

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

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

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

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

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

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

-- * Statements

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

-- * Call

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

-- * Insert

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

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

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

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

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

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

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

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

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

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

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

-- * Update

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

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

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

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

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

-- * Delete

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

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

-- * Select

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

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

selectWithParens :: SelectWithParens -> Builder
selectWithParens =
  Builder -> Builder
inParens (Builder -> Builder)
-> (SelectWithParens -> Builder) -> SelectWithParens -> Builder
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 -> Builder
selectNoParens SelectNoParens
a
    WithParensSelectWithParens SelectWithParens
a -> SelectWithParens -> Builder
selectWithParens SelectWithParens
a

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

commonTableExpr :: CommonTableExpr -> Builder
commonTableExpr (CommonTableExpr ColId
a Maybe (NonEmpty ColId)
b Maybe Bool
c PreparableStmt
d) =
  [Maybe Builder] -> Builder
optLexemes
    [ Builder -> Maybe Builder
forall a. a -> Maybe a
Just (ColId -> Builder
ident ColId
a),
      (NonEmpty ColId -> Builder)
-> Maybe (NonEmpty ColId) -> Maybe Builder
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap (Builder -> Builder
inParens (Builder -> Builder)
-> (NonEmpty ColId -> Builder) -> NonEmpty ColId -> Builder
forall k (cat :: k -> k -> *) (b :: k) (c :: k) (a :: k).
Category cat =>
cat b c -> cat a b -> cat a c
. (ColId -> Builder) -> NonEmpty ColId -> Builder
forall a. (a -> Builder) -> NonEmpty a -> Builder
commaNonEmpty ColId -> Builder
ident) Maybe (NonEmpty ColId)
b,
      Builder -> Maybe Builder
forall a. a -> Maybe a
Just Builder
"AS",
      (Bool -> Builder) -> Maybe Bool -> Maybe Builder
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap Bool -> Builder
forall a. IsString a => Bool -> a
materialization Maybe Bool
c,
      Builder -> Maybe Builder
forall a. a -> Maybe a
Just (Builder -> Builder
inParens (PreparableStmt -> Builder
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 -> Builder
selectLimit = \case
  LimitOffsetSelectLimit LimitClause
a OffsetClause
b -> [Builder] -> Builder
lexemes [LimitClause -> Builder
limitClause LimitClause
a, OffsetClause -> Builder
offsetClause OffsetClause
b]
  OffsetLimitSelectLimit OffsetClause
a LimitClause
b -> [Builder] -> Builder
lexemes [OffsetClause -> Builder
offsetClause OffsetClause
a, LimitClause -> Builder
limitClause LimitClause
b]
  LimitSelectLimit LimitClause
a -> LimitClause -> Builder
limitClause LimitClause
a
  OffsetSelectLimit OffsetClause
a -> OffsetClause -> Builder
offsetClause OffsetClause
a

limitClause :: LimitClause -> Builder
limitClause = \case
  LimitLimitClause SelectLimitValue
a Maybe WhereClause
b -> Builder
"LIMIT " Builder -> Builder -> Builder
forall a. Semigroup a => a -> a -> a
<> SelectLimitValue -> Builder
selectLimitValue SelectLimitValue
a Builder -> Builder -> Builder
forall a. Semigroup a => a -> a -> a
<> (WhereClause -> Builder) -> Maybe WhereClause -> Builder
forall (t :: * -> *) m a.
(Foldable t, Monoid m) =>
(a -> m) -> t a -> m
foldMap (Builder -> Builder -> Builder
forall a. Monoid a => a -> a -> a
mappend Builder
", " (Builder -> Builder)
-> (WhereClause -> Builder) -> WhereClause -> Builder
forall k (cat :: k -> k -> *) (b :: k) (c :: k) (a :: k).
Category cat =>
cat b c -> cat a b -> cat a c
. WhereClause -> Builder
aExpr) Maybe WhereClause
b
  FetchOnlyLimitClause Bool
a Maybe SelectFetchFirstValue
b Bool
c ->
    [Maybe Builder] -> Builder
optLexemes
      [ Builder -> Maybe Builder
forall a. a -> Maybe a
Just Builder
"FETCH",
        Builder -> Maybe Builder
forall a. a -> Maybe a
Just (Bool -> Builder
forall a. IsString a => Bool -> a
firstOrNext Bool
a),
        (SelectFetchFirstValue -> Builder)
-> Maybe SelectFetchFirstValue -> Maybe Builder
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap SelectFetchFirstValue -> Builder
selectFetchFirstValue Maybe SelectFetchFirstValue
b,
        Builder -> Maybe Builder
forall a. a -> Maybe a
Just (Bool -> Builder
forall a. IsString a => Bool -> a
rowOrRows Bool
c),
        Builder -> Maybe Builder
forall a. a -> Maybe a
Just Builder
"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 -> Builder
selectFetchFirstValue = \case
  ExprSelectFetchFirstValue CExpr
a -> CExpr -> Builder
cExpr CExpr
a
  NumSelectFetchFirstValue Bool
a Either Int64 Double
b -> Builder -> Builder -> Bool -> Builder
forall a. a -> a -> Bool -> a
bool Builder
"+" Builder
"-" Bool
a Builder -> Builder -> Builder
forall a. Semigroup a => a -> a -> a
<> Either Int64 Double -> Builder
intOrFloat Either Int64 Double
b

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

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

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

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

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

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

lockedRelsList :: NonEmpty QualifiedName -> Builder
lockedRelsList NonEmpty QualifiedName
a = Builder
"OF " Builder -> Builder -> Builder
forall a. Semigroup a => a -> a -> a
<> (QualifiedName -> Builder) -> NonEmpty QualifiedName -> Builder
forall a. (a -> Builder) -> NonEmpty a -> Builder
commaNonEmpty QualifiedName -> Builder
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 -> Builder
selectClause = (SimpleSelect -> Builder)
-> (SelectWithParens -> Builder) -> SelectClause -> Builder
forall a c b. (a -> c) -> (b -> c) -> Either a b -> c
either SimpleSelect -> Builder
simpleSelect SelectWithParens -> Builder
selectWithParens

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

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

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

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

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

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

-- * Select Into

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

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

-- * From

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

-- * Where

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

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

-- * Group By

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

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

-- * Having

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

-- * Window

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

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

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

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

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

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

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

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

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

-- * Order By

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

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

-- * Values

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

-- * Exprs

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

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

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

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

-- * Ops

aExprReversableOp :: Bool -> AExprReversableOp -> Builder
aExprReversableOp Bool
a = \case
  AExprReversableOp
NullAExprReversableOp -> Builder -> Builder -> Bool -> Builder
forall a. a -> a -> Bool -> a
bool Builder
"IS " Builder
"IS NOT " Bool
a Builder -> Builder -> Builder
forall a. Semigroup a => a -> a -> a
<> Builder
"NULL"
  AExprReversableOp
TrueAExprReversableOp -> Builder -> Builder -> Bool -> Builder
forall a. a -> a -> Bool -> a
bool Builder
"IS " Builder
"IS NOT " Bool
a Builder -> Builder -> Builder
forall a. Semigroup a => a -> a -> a
<> Builder
"TRUE"
  AExprReversableOp
FalseAExprReversableOp -> Builder -> Builder -> Bool -> Builder
forall a. a -> a -> Bool -> a
bool Builder
"IS " Builder
"IS NOT " Bool
a Builder -> Builder -> Builder
forall a. Semigroup a => a -> a -> a
<> Builder
"FALSE"
  AExprReversableOp
UnknownAExprReversableOp -> Builder -> Builder -> Bool -> Builder
forall a. a -> a -> Bool -> a
bool Builder
"IS " Builder
"IS NOT " Bool
a Builder -> Builder -> Builder
forall a. Semigroup a => a -> a -> a
<> Builder
"UNKNOWN"
  DistinctFromAExprReversableOp WhereClause
b -> Builder -> Builder -> Bool -> Builder
forall a. a -> a -> Bool -> a
bool Builder
"IS " Builder
"IS NOT " Bool
a Builder -> Builder -> Builder
forall a. Semigroup a => a -> a -> a
<> Builder
"DISTINCT FROM " Builder -> Builder -> Builder
forall a. Semigroup a => a -> a -> a
<> WhereClause -> Builder
aExpr WhereClause
b
  OfAExprReversableOp TypeList
b -> Builder -> Builder -> Bool -> Builder
forall a. a -> a -> Bool -> a
bool Builder
"IS " Builder
"IS NOT " Bool
a Builder -> Builder -> Builder
forall a. Semigroup a => a -> a -> a
<> Builder
"OF " Builder -> Builder -> Builder
forall a. Semigroup a => a -> a -> a
<> Builder -> Builder
inParens (TypeList -> Builder
typeList TypeList
b)
  BetweenAExprReversableOp Bool
b BExpr
c WhereClause
d -> Builder -> Builder -> Bool -> Builder
forall a. a -> a -> Bool -> a
bool Builder
"" Builder
"NOT " Bool
a Builder -> Builder -> Builder
forall a. Semigroup a => a -> a -> a
<> Builder -> Builder -> Bool -> Builder
forall a. a -> a -> Bool -> a
bool Builder
"BETWEEN " Builder
"BETWEEN ASYMMETRIC " Bool
b Builder -> Builder -> Builder
forall a. Semigroup a => a -> a -> a
<> BExpr -> Builder
bExpr BExpr
c Builder -> Builder -> Builder
forall a. Semigroup a => a -> a -> a
<> Builder
" AND " Builder -> Builder -> Builder
forall a. Semigroup a => a -> a -> a
<> WhereClause -> Builder
aExpr WhereClause
d
  BetweenSymmetricAExprReversableOp BExpr
b WhereClause
c -> Builder -> Builder -> Bool -> Builder
forall a. a -> a -> Bool -> a
bool Builder
"" Builder
"NOT " Bool
a Builder -> Builder -> Builder
forall a. Semigroup a => a -> a -> a
<> Builder
"BETWEEN SYMMETRIC " Builder -> Builder -> Builder
forall a. Semigroup a => a -> a -> a
<> BExpr -> Builder
bExpr BExpr
b Builder -> Builder -> Builder
forall a. Semigroup a => a -> a -> a
<> Builder
" AND " Builder -> Builder -> Builder
forall a. Semigroup a => a -> a -> a
<> WhereClause -> Builder
aExpr WhereClause
c
  InAExprReversableOp InExpr
b -> Builder -> Builder -> Bool -> Builder
forall a. a -> a -> Bool -> a
bool Builder
"" Builder
"NOT " Bool
a Builder -> Builder -> Builder
forall a. Semigroup a => a -> a -> a
<> Builder
"IN " Builder -> Builder -> Builder
forall a. Semigroup a => a -> a -> a
<> InExpr -> Builder
inExpr InExpr
b
  AExprReversableOp
DocumentAExprReversableOp -> Builder -> Builder -> Bool -> Builder
forall a. a -> a -> Bool -> a
bool Builder
"IS " Builder
"IS NOT " Bool
a Builder -> Builder -> Builder
forall a. Semigroup a => a -> a -> a
<> Builder
"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 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 -> Builder
subqueryOp = \case
  AllSubqueryOp AllOp
a -> AllOp -> Builder
allOp AllOp
a
  AnySubqueryOp AnyOperator
a -> Builder
"OPERATOR " Builder -> Builder -> Builder
forall a. Semigroup a => a -> a -> a
<> Builder -> Builder
inParens (AnyOperator -> Builder
anyOperator AnyOperator
a)
  LikeSubqueryOp Bool
a -> Builder -> Builder -> Bool -> Builder
forall a. a -> a -> Bool -> a
bool Builder
"" Builder
"NOT " Bool
a Builder -> Builder -> Builder
forall a. Semigroup a => a -> a -> a
<> Builder
"LIKE"
  IlikeSubqueryOp Bool
a -> Builder -> Builder -> Bool -> Builder
forall a. a -> a -> Bool -> a
bool Builder
"" Builder
"NOT " Bool
a Builder -> Builder -> Builder
forall a. Semigroup a => a -> a -> a
<> Builder
"ILIKE"

bExprIsOp :: Bool -> BExprIsOp -> Builder
bExprIsOp Bool
a =
  Builder -> Builder -> Builder
forall a. Monoid a => a -> a -> a
mappend (Builder -> Builder -> Bool -> Builder
forall a. a -> a -> Bool -> a
bool Builder
"IS " Builder
"IS NOT " Bool
a) (Builder -> Builder)
-> (BExprIsOp -> Builder) -> BExprIsOp -> Builder
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 -> Builder
"DISTINCT FROM " Builder -> Builder -> Builder
forall a. Semigroup a => a -> a -> a
<> BExpr -> Builder
bExpr BExpr
b
    OfBExprIsOp TypeList
a -> Builder
"OF " Builder -> Builder -> Builder
forall a. Semigroup a => a -> a -> a
<> Builder -> Builder
inParens (TypeList -> Builder
typeList TypeList
a)
    BExprIsOp
DocumentBExprIsOp -> Builder
"DOCUMENT"

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

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

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

op :: Text -> Builder
op = Text -> Builder
text

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

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

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

-- *

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

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

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

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

arrayExpr :: ArrayExpr -> Builder
arrayExpr =
  Builder -> Builder
inBrackets (Builder -> Builder)
-> (ArrayExpr -> Builder) -> ArrayExpr -> Builder
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 -> Builder
exprList ExprList
a
    ArrayExprListArrayExpr ArrayExprList
a -> ArrayExprList -> Builder
arrayExprList ArrayExprList
a
    ArrayExpr
EmptyArrayExpr -> Builder
forall a. Monoid a => a
mempty

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

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

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

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

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

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

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

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

-- ** Func Expr

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

-- * AexprConsts

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

iconst :: Int64 -> Builder
iconst = Int64 -> Builder
int64Dec

fconst :: Double -> Builder
fconst = Double -> Builder
doubleDec

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

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

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

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

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

constBit :: ConstBit -> Builder
constBit = ConstBit -> Builder
bit

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

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

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

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

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

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

-- * Names and refs

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

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

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

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

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

colId :: ColId -> Builder
colId = ColId -> Builder
ident

name :: ColId -> Builder
name = ColId -> Builder
colId

cursorName :: ColId -> Builder
cursorName = ColId -> Builder
name

colLabel :: ColId -> Builder
colLabel = ColId -> Builder
ident

attrName :: ColId -> Builder
attrName = ColId -> Builder
colLabel

typeFunctionName :: ColId -> Builder
typeFunctionName = ColId -> Builder
ident

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

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

-- * Types

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

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

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

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

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

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

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

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

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

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

-- * Indexes

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

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

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

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

class_ :: CollateClause -> Builder
class_ = CollateClause -> Builder
anyName

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

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