{-|
Module: IHP.IDE.SchemaDesigner.Types
Description: Parser for Application/Schema.sql
Copyright: (c) digitally induced GmbH, 2020
-}
module IHP.IDE.SchemaDesigner.Parser
( parseSchemaSql
, parseSqlFile
, schemaFilePath
, parseDDL
, expression
, sqlType
, removeTypeCasts
, parseIndexColumns
) where

import IHP.Prelude
import IHP.IDE.SchemaDesigner.Types
import qualified Prelude
import qualified Data.Text.IO as Text
import Text.Megaparsec
import Data.Void
import Text.Megaparsec.Char
import qualified Text.Megaparsec.Char.Lexer as Lexer
import Data.Char
import Control.Monad.Combinators.Expr
import Data.Functor

schemaFilePath :: String
schemaFilePath = String
"Application/Schema.sql"

parseSchemaSql :: IO (Either ByteString [Statement])
parseSchemaSql :: IO (Either ByteString [Statement])
parseSchemaSql = String -> IO (Either ByteString [Statement])
parseSqlFile String
schemaFilePath

parseSqlFile :: FilePath -> IO (Either ByteString [Statement])
parseSqlFile :: String -> IO (Either ByteString [Statement])
parseSqlFile String
schemaFilePath = do
    Text
schemaSql <- String -> IO Text
Text.readFile String
schemaFilePath
    let result :: Either (ParseErrorBundle Text Void) [Statement]
result = Parsec Void Text [Statement]
-> String
-> Text
-> Either (ParseErrorBundle Text Void) [Statement]
forall e s a.
Parsec e s a -> String -> s -> Either (ParseErrorBundle s e) a
runParser Parsec Void Text [Statement]
parseDDL (String -> String
forall a b. ConvertibleStrings a b => a -> b
cs String
schemaFilePath) Text
schemaSql
    case Either (ParseErrorBundle Text Void) [Statement]
result of
        Left ParseErrorBundle Text Void
error -> Either ByteString [Statement] -> IO (Either ByteString [Statement])
forall a. a -> IO a
forall (f :: * -> *) a. Applicative f => a -> f a
pure (ByteString -> Either ByteString [Statement]
forall a b. a -> Either a b
Left (String -> ByteString
forall a b. ConvertibleStrings a b => a -> b
cs (String -> ByteString) -> String -> ByteString
forall a b. (a -> b) -> a -> b
$ ParseErrorBundle Text Void -> String
forall s e.
(VisualStream s, TraversableStream s, ShowErrorComponent e) =>
ParseErrorBundle s e -> String
errorBundlePretty ParseErrorBundle Text Void
error))
        Right [Statement]
r -> Either ByteString [Statement] -> IO (Either ByteString [Statement])
forall a. a -> IO a
forall (f :: * -> *) a. Applicative f => a -> f a
pure ([Statement] -> Either ByteString [Statement]
forall a b. b -> Either a b
Right [Statement]
r)

type Parser = Parsec Void Text

spaceConsumer :: Parser ()
spaceConsumer :: Parser ()
spaceConsumer = Parser () -> Parser () -> Parser () -> Parser ()
forall e s (m :: * -> *).
MonadParsec e s m =>
m () -> m () -> m () -> m ()
Lexer.space
    Parser ()
forall e s (m :: * -> *).
(MonadParsec e s m, Token s ~ Char) =>
m ()
space1
    (Tokens Text -> Parser ()
forall e s (m :: * -> *).
(MonadParsec e s m, Token s ~ Char) =>
Tokens s -> m ()
Lexer.skipLineComment Tokens Text
"//")
    (Tokens Text -> Tokens Text -> Parser ()
forall e s (m :: * -> *).
(MonadParsec e s m, Token s ~ Char) =>
Tokens s -> Tokens s -> m ()
Lexer.skipBlockComment Tokens Text
"/*" Tokens Text
"*/")

lexeme :: Parser a -> Parser a
lexeme :: forall a. Parser a -> Parser a
lexeme = Parser ()
-> ParsecT Void Text Identity a -> ParsecT Void Text Identity a
forall e s (m :: * -> *) a. MonadParsec e s m => m () -> m a -> m a
Lexer.lexeme Parser ()
spaceConsumer

symbol :: Text -> Parser Text
symbol :: Text -> Parser Text
symbol = Parser ()
-> Tokens Text -> ParsecT Void Text Identity (Tokens Text)
forall e s (m :: * -> *).
MonadParsec e s m =>
m () -> Tokens s -> m (Tokens s)
Lexer.symbol Parser ()
spaceConsumer

symbol' :: Text -> Parser Text
symbol' :: Text -> Parser Text
symbol' = Parser ()
-> Tokens Text -> ParsecT Void Text Identity (Tokens Text)
forall e s (m :: * -> *).
(MonadParsec e s m, FoldCase (Tokens s)) =>
m () -> Tokens s -> m (Tokens s)
Lexer.symbol' Parser ()
spaceConsumer

stringLiteral :: Parser String
stringLiteral :: Parser String
stringLiteral = Token Text -> ParsecT Void Text Identity (Token Text)
forall e s (m :: * -> *).
(MonadParsec e s m, Token s ~ Char) =>
Token s -> m (Token s)
char Char
Token Text
'\'' ParsecT Void Text Identity Char -> Parser String -> Parser String
forall a b.
ParsecT Void Text Identity a
-> ParsecT Void Text Identity b -> ParsecT Void Text Identity b
forall (f :: * -> *) a b. Applicative f => f a -> f b -> f b
*> ParsecT Void Text Identity Char
-> ParsecT Void Text Identity Char -> Parser String
forall (m :: * -> *) a end. MonadPlus m => m a -> m end -> m [a]
manyTill ParsecT Void Text Identity Char
forall e s (m :: * -> *).
(MonadParsec e s m, Token s ~ Char) =>
m Char
Lexer.charLiteral (Token Text -> ParsecT Void Text Identity (Token Text)
forall e s (m :: * -> *).
(MonadParsec e s m, Token s ~ Char) =>
Token s -> m (Token s)
char Char
Token Text
'\'')

parseDDL :: Parser [Statement]
parseDDL :: Parsec Void Text [Statement]
parseDDL = Parser () -> ParsecT Void Text Identity (Maybe ())
forall (f :: * -> *) a. Alternative f => f a -> f (Maybe a)
optional Parser ()
forall e s (m :: * -> *).
(MonadParsec e s m, Token s ~ Char) =>
m ()
space ParsecT Void Text Identity (Maybe ())
-> Parsec Void Text [Statement] -> Parsec Void Text [Statement]
forall a b.
ParsecT Void Text Identity a
-> ParsecT Void Text Identity b -> ParsecT Void Text Identity b
forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> ParsecT Void Text Identity Statement
-> Parser () -> Parsec Void Text [Statement]
forall (m :: * -> *) a end. MonadPlus m => m a -> m end -> m [a]
manyTill ParsecT Void Text Identity Statement
statement Parser ()
forall e s (m :: * -> *). MonadParsec e s m => m ()
eof

statement :: ParsecT Void Text Identity Statement
statement = do
    Parser ()
forall e s (m :: * -> *).
(MonadParsec e s m, Token s ~ Char) =>
m ()
space
    let create :: ParsecT Void Text Identity Statement
create = ParsecT Void Text Identity Statement
-> ParsecT Void Text Identity Statement
forall a. Parser a -> Parser a
forall e s (m :: * -> *) a. MonadParsec e s m => m a -> m a
try ParsecT Void Text Identity Statement
createExtension ParsecT Void Text Identity Statement
-> ParsecT Void Text Identity Statement
-> ParsecT Void Text Identity Statement
forall a.
ParsecT Void Text Identity a
-> ParsecT Void Text Identity a -> ParsecT Void Text Identity a
forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
<|> ParsecT Void Text Identity Statement
-> ParsecT Void Text Identity Statement
forall a. Parser a -> Parser a
forall e s (m :: * -> *) a. MonadParsec e s m => m a -> m a
try (CreateTable -> Statement
StatementCreateTable (CreateTable -> Statement)
-> ParsecT Void Text Identity CreateTable
-> ParsecT Void Text Identity Statement
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> ParsecT Void Text Identity CreateTable
createTable) ParsecT Void Text Identity Statement
-> ParsecT Void Text Identity Statement
-> ParsecT Void Text Identity Statement
forall a.
ParsecT Void Text Identity a
-> ParsecT Void Text Identity a -> ParsecT Void Text Identity a
forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
<|> ParsecT Void Text Identity Statement
-> ParsecT Void Text Identity Statement
forall a. Parser a -> Parser a
forall e s (m :: * -> *) a. MonadParsec e s m => m a -> m a
try ParsecT Void Text Identity Statement
createIndex ParsecT Void Text Identity Statement
-> ParsecT Void Text Identity Statement
-> ParsecT Void Text Identity Statement
forall a.
ParsecT Void Text Identity a
-> ParsecT Void Text Identity a -> ParsecT Void Text Identity a
forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
<|> ParsecT Void Text Identity Statement
-> ParsecT Void Text Identity Statement
forall a. Parser a -> Parser a
forall e s (m :: * -> *) a. MonadParsec e s m => m a -> m a
try ParsecT Void Text Identity Statement
createFunction ParsecT Void Text Identity Statement
-> ParsecT Void Text Identity Statement
-> ParsecT Void Text Identity Statement
forall a.
ParsecT Void Text Identity a
-> ParsecT Void Text Identity a -> ParsecT Void Text Identity a
forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
<|> ParsecT Void Text Identity Statement
-> ParsecT Void Text Identity Statement
forall a. Parser a -> Parser a
forall e s (m :: * -> *) a. MonadParsec e s m => m a -> m a
try ParsecT Void Text Identity Statement
createTrigger ParsecT Void Text Identity Statement
-> ParsecT Void Text Identity Statement
-> ParsecT Void Text Identity Statement
forall a.
ParsecT Void Text Identity a
-> ParsecT Void Text Identity a -> ParsecT Void Text Identity a
forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
<|> ParsecT Void Text Identity Statement
-> ParsecT Void Text Identity Statement
forall a. Parser a -> Parser a
forall e s (m :: * -> *) a. MonadParsec e s m => m a -> m a
try ParsecT Void Text Identity Statement
createEnumType ParsecT Void Text Identity Statement
-> ParsecT Void Text Identity Statement
-> ParsecT Void Text Identity Statement
forall a.
ParsecT Void Text Identity a
-> ParsecT Void Text Identity a -> ParsecT Void Text Identity a
forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
<|> ParsecT Void Text Identity Statement
-> ParsecT Void Text Identity Statement
forall a. Parser a -> Parser a
forall e s (m :: * -> *) a. MonadParsec e s m => m a -> m a
try ParsecT Void Text Identity Statement
createPolicy ParsecT Void Text Identity Statement
-> ParsecT Void Text Identity Statement
-> ParsecT Void Text Identity Statement
forall a.
ParsecT Void Text Identity a
-> ParsecT Void Text Identity a -> ParsecT Void Text Identity a
forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
<|> ParsecT Void Text Identity Statement
-> ParsecT Void Text Identity Statement
forall a. Parser a -> Parser a
forall e s (m :: * -> *) a. MonadParsec e s m => m a -> m a
try ParsecT Void Text Identity Statement
createSequence
    let alter :: ParsecT Void Text Identity Statement
alter = do
            Parser Text -> Parser Text
forall a. Parser a -> Parser a
lexeme Parser Text
"ALTER"
            ParsecT Void Text Identity Statement
alterTable ParsecT Void Text Identity Statement
-> ParsecT Void Text Identity Statement
-> ParsecT Void Text Identity Statement
forall a.
ParsecT Void Text Identity a
-> ParsecT Void Text Identity a -> ParsecT Void Text Identity a
forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
<|> ParsecT Void Text Identity Statement
alterType ParsecT Void Text Identity Statement
-> ParsecT Void Text Identity Statement
-> ParsecT Void Text Identity Statement
forall a.
ParsecT Void Text Identity a
-> ParsecT Void Text Identity a -> ParsecT Void Text Identity a
forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
<|> ParsecT Void Text Identity Statement
alterSequence
    Statement
s <- ParsecT Void Text Identity Statement
setStatement ParsecT Void Text Identity Statement
-> ParsecT Void Text Identity Statement
-> ParsecT Void Text Identity Statement
forall a.
ParsecT Void Text Identity a
-> ParsecT Void Text Identity a -> ParsecT Void Text Identity a
forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
<|> ParsecT Void Text Identity Statement
create ParsecT Void Text Identity Statement
-> ParsecT Void Text Identity Statement
-> ParsecT Void Text Identity Statement
forall a.
ParsecT Void Text Identity a
-> ParsecT Void Text Identity a -> ParsecT Void Text Identity a
forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
<|> ParsecT Void Text Identity Statement
alter ParsecT Void Text Identity Statement
-> ParsecT Void Text Identity Statement
-> ParsecT Void Text Identity Statement
forall a.
ParsecT Void Text Identity a
-> ParsecT Void Text Identity a -> ParsecT Void Text Identity a
forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
<|> ParsecT Void Text Identity Statement
selectStatement ParsecT Void Text Identity Statement
-> ParsecT Void Text Identity Statement
-> ParsecT Void Text Identity Statement
forall a.
ParsecT Void Text Identity a
-> ParsecT Void Text Identity a -> ParsecT Void Text Identity a
forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
<|> ParsecT Void Text Identity Statement
-> ParsecT Void Text Identity Statement
forall a. Parser a -> Parser a
forall e s (m :: * -> *) a. MonadParsec e s m => m a -> m a
try ParsecT Void Text Identity Statement
dropTable ParsecT Void Text Identity Statement
-> ParsecT Void Text Identity Statement
-> ParsecT Void Text Identity Statement
forall a.
ParsecT Void Text Identity a
-> ParsecT Void Text Identity a -> ParsecT Void Text Identity a
forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
<|> ParsecT Void Text Identity Statement
-> ParsecT Void Text Identity Statement
forall a. Parser a -> Parser a
forall e s (m :: * -> *) a. MonadParsec e s m => m a -> m a
try ParsecT Void Text Identity Statement
dropIndex ParsecT Void Text Identity Statement
-> ParsecT Void Text Identity Statement
-> ParsecT Void Text Identity Statement
forall a.
ParsecT Void Text Identity a
-> ParsecT Void Text Identity a -> ParsecT Void Text Identity a
forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
<|> ParsecT Void Text Identity Statement
-> ParsecT Void Text Identity Statement
forall a. Parser a -> Parser a
forall e s (m :: * -> *) a. MonadParsec e s m => m a -> m a
try ParsecT Void Text Identity Statement
dropPolicy ParsecT Void Text Identity Statement
-> ParsecT Void Text Identity Statement
-> ParsecT Void Text Identity Statement
forall a.
ParsecT Void Text Identity a
-> ParsecT Void Text Identity a -> ParsecT Void Text Identity a
forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
<|> ParsecT Void Text Identity Statement
-> ParsecT Void Text Identity Statement
forall a. Parser a -> Parser a
forall e s (m :: * -> *) a. MonadParsec e s m => m a -> m a
try ParsecT Void Text Identity Statement
dropFunction ParsecT Void Text Identity Statement
-> ParsecT Void Text Identity Statement
-> ParsecT Void Text Identity Statement
forall a.
ParsecT Void Text Identity a
-> ParsecT Void Text Identity a -> ParsecT Void Text Identity a
forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
<|> ParsecT Void Text Identity Statement
-> ParsecT Void Text Identity Statement
forall a. Parser a -> Parser a
forall e s (m :: * -> *) a. MonadParsec e s m => m a -> m a
try ParsecT Void Text Identity Statement
dropType ParsecT Void Text Identity Statement
-> ParsecT Void Text Identity Statement
-> ParsecT Void Text Identity Statement
forall a.
ParsecT Void Text Identity a
-> ParsecT Void Text Identity a -> ParsecT Void Text Identity a
forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
<|> ParsecT Void Text Identity Statement
dropTrigger ParsecT Void Text Identity Statement
-> ParsecT Void Text Identity Statement
-> ParsecT Void Text Identity Statement
forall a.
ParsecT Void Text Identity a
-> ParsecT Void Text Identity a -> ParsecT Void Text Identity a
forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
<|> ParsecT Void Text Identity Statement
commentStatement ParsecT Void Text Identity Statement
-> ParsecT Void Text Identity Statement
-> ParsecT Void Text Identity Statement
forall a.
ParsecT Void Text Identity a
-> ParsecT Void Text Identity a -> ParsecT Void Text Identity a
forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
<|> ParsecT Void Text Identity Statement
comment ParsecT Void Text Identity Statement
-> ParsecT Void Text Identity Statement
-> ParsecT Void Text Identity Statement
forall a.
ParsecT Void Text Identity a
-> ParsecT Void Text Identity a -> ParsecT Void Text Identity a
forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
<|> ParsecT Void Text Identity Statement
begin ParsecT Void Text Identity Statement
-> ParsecT Void Text Identity Statement
-> ParsecT Void Text Identity Statement
forall a.
ParsecT Void Text Identity a
-> ParsecT Void Text Identity a -> ParsecT Void Text Identity a
forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
<|> ParsecT Void Text Identity Statement
commit
    Parser ()
forall e s (m :: * -> *).
(MonadParsec e s m, Token s ~ Char) =>
m ()
space
    Statement -> ParsecT Void Text Identity Statement
forall a. a -> ParsecT Void Text Identity a
forall (f :: * -> *) a. Applicative f => a -> f a
pure Statement
s


createExtension :: ParsecT Void Text Identity Statement
createExtension = do
    Parser Text -> Parser Text
forall a. Parser a -> Parser a
lexeme Parser Text
"CREATE"
    Parser Text -> Parser Text
forall a. Parser a -> Parser a
lexeme Parser Text
"EXTENSION"
    Bool
ifNotExists <- Maybe Text -> Bool
forall a. Maybe a -> Bool
isJust (Maybe Text -> Bool)
-> ParsecT Void Text Identity (Maybe Text)
-> ParsecT Void Text Identity Bool
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Parser Text -> ParsecT Void Text Identity (Maybe Text)
forall (f :: * -> *) a. Alternative f => f a -> f (Maybe a)
optional (Parser Text -> Parser Text
forall a. Parser a -> Parser a
lexeme Parser Text
"IF" Parser Text -> Parser Text -> Parser Text
forall a b.
ParsecT Void Text Identity a
-> ParsecT Void Text Identity b -> ParsecT Void Text Identity b
forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> Parser Text -> Parser Text
forall a. Parser a -> Parser a
lexeme Parser Text
"NOT" Parser Text -> Parser Text -> Parser Text
forall a b.
ParsecT Void Text Identity a
-> ParsecT Void Text Identity b -> ParsecT Void Text Identity b
forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> Parser Text -> Parser Text
forall a. Parser a -> Parser a
lexeme Parser Text
"EXISTS")
    Text
name <- Parser Text
qualifiedIdentifier
    Parser Text -> ParsecT Void Text Identity (Maybe Text)
forall (f :: * -> *) a. Alternative f => f a -> f (Maybe a)
optional do
        Parser ()
forall e s (m :: * -> *).
(MonadParsec e s m, Token s ~ Char) =>
m ()
space
        Parser Text -> Parser Text
forall a. Parser a -> Parser a
lexeme Parser Text
"WITH"
        Parser Text -> Parser Text
forall a. Parser a -> Parser a
lexeme Parser Text
"SCHEMA"
        Parser Text -> Parser Text
forall a. Parser a -> Parser a
lexeme Parser Text
"public"
    Token Text -> ParsecT Void Text Identity (Token Text)
forall e s (m :: * -> *).
(MonadParsec e s m, Token s ~ Char) =>
Token s -> m (Token s)
char Char
Token Text
';'
    Statement -> ParsecT Void Text Identity Statement
forall a. a -> ParsecT Void Text Identity a
forall (f :: * -> *) a. Applicative f => a -> f a
pure CreateExtension { Text
name :: Text
$sel:name:StatementCreateTable :: Text
name, $sel:ifNotExists:StatementCreateTable :: Bool
ifNotExists = Bool
True }

createTable :: ParsecT Void Text Identity CreateTable
createTable = do
    Parser Text -> Parser Text
forall a. Parser a -> Parser a
lexeme Parser Text
"CREATE"
    Bool
unlogged <- Maybe Text -> Bool
forall a. Maybe a -> Bool
isJust (Maybe Text -> Bool)
-> ParsecT Void Text Identity (Maybe Text)
-> ParsecT Void Text Identity Bool
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Parser Text -> ParsecT Void Text Identity (Maybe Text)
forall (f :: * -> *) a. Alternative f => f a -> f (Maybe a)
optional (Parser Text -> Parser Text
forall a. Parser a -> Parser a
lexeme Parser Text
"UNLOGGED")
    Parser Text -> Parser Text
forall a. Parser a -> Parser a
lexeme Parser Text
"TABLE"
    Text
name <- Parser Text
qualifiedIdentifier

    -- Process columns (tagged if they're primary key) and table constraints
    -- together, as they can be in any order
    ([(Bool, Column)]
taggedColumns, [Either PrimaryKeyConstraint Constraint]
allConstraints) <- Parser ()
-> Parser ()
-> ParsecT
     Void
     Text
     Identity
     ([(Bool, Column)], [Either PrimaryKeyConstraint Constraint])
-> ParsecT
     Void
     Text
     Identity
     ([(Bool, Column)], [Either PrimaryKeyConstraint Constraint])
forall (m :: * -> *) open close a.
Applicative m =>
m open -> m close -> m a -> m a
between (Token Text -> ParsecT Void Text Identity (Token Text)
forall e s (m :: * -> *).
(MonadParsec e s m, Token s ~ Char) =>
Token s -> m (Token s)
char Char
Token Text
'(' ParsecT Void Text Identity Char -> Parser () -> Parser ()
forall a b.
ParsecT Void Text Identity a
-> ParsecT Void Text Identity b -> ParsecT Void Text Identity b
forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> Parser ()
forall e s (m :: * -> *).
(MonadParsec e s m, Token s ~ Char) =>
m ()
space) (Token Text -> ParsecT Void Text Identity (Token Text)
forall e s (m :: * -> *).
(MonadParsec e s m, Token s ~ Char) =>
Token s -> m (Token s)
char Char
Token Text
')' ParsecT Void Text Identity Char -> Parser () -> Parser ()
forall a b.
ParsecT Void Text Identity a
-> ParsecT Void Text Identity b -> ParsecT Void Text Identity b
forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> Parser ()
forall e s (m :: * -> *).
(MonadParsec e s m, Token s ~ Char) =>
m ()
space) do
        [Either (Bool, Column) (Either PrimaryKeyConstraint Constraint)]
columnsAndConstraints <- ((Either PrimaryKeyConstraint Constraint
-> Either (Bool, Column) (Either PrimaryKeyConstraint Constraint)
forall a b. b -> Either a b
Right (Either PrimaryKeyConstraint Constraint
 -> Either (Bool, Column) (Either PrimaryKeyConstraint Constraint))
-> ParsecT
     Void Text Identity (Either PrimaryKeyConstraint Constraint)
-> ParsecT
     Void
     Text
     Identity
     (Either (Bool, Column) (Either PrimaryKeyConstraint Constraint))
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> ParsecT Void Text Identity (Either PrimaryKeyConstraint Constraint)
parseTableConstraint) ParsecT
  Void
  Text
  Identity
  (Either (Bool, Column) (Either PrimaryKeyConstraint Constraint))
-> ParsecT
     Void
     Text
     Identity
     (Either (Bool, Column) (Either PrimaryKeyConstraint Constraint))
-> ParsecT
     Void
     Text
     Identity
     (Either (Bool, Column) (Either PrimaryKeyConstraint Constraint))
forall a.
ParsecT Void Text Identity a
-> ParsecT Void Text Identity a -> ParsecT Void Text Identity a
forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
<|> ((Bool, Column)
-> Either (Bool, Column) (Either PrimaryKeyConstraint Constraint)
forall a b. a -> Either a b
Left ((Bool, Column)
 -> Either (Bool, Column) (Either PrimaryKeyConstraint Constraint))
-> ParsecT Void Text Identity (Bool, Column)
-> ParsecT
     Void
     Text
     Identity
     (Either (Bool, Column) (Either PrimaryKeyConstraint Constraint))
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> ParsecT Void Text Identity (Bool, Column)
parseColumn)) ParsecT
  Void
  Text
  Identity
  (Either (Bool, Column) (Either PrimaryKeyConstraint Constraint))
-> Parser ()
-> ParsecT
     Void
     Text
     Identity
     [Either (Bool, Column) (Either PrimaryKeyConstraint Constraint)]
forall (m :: * -> *) a end. MonadPlus m => m a -> m end -> m [a]
`sepBy` (Token Text -> ParsecT Void Text Identity (Token Text)
forall e s (m :: * -> *).
(MonadParsec e s m, Token s ~ Char) =>
Token s -> m (Token s)
char Char
Token Text
',' ParsecT Void Text Identity Char -> Parser () -> Parser ()
forall a b.
ParsecT Void Text Identity a
-> ParsecT Void Text Identity b -> ParsecT Void Text Identity b
forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> Parser ()
forall e s (m :: * -> *).
(MonadParsec e s m, Token s ~ Char) =>
m ()
space)
        ([(Bool, Column)], [Either PrimaryKeyConstraint Constraint])
-> ParsecT
     Void
     Text
     Identity
     ([(Bool, Column)], [Either PrimaryKeyConstraint Constraint])
forall a. a -> ParsecT Void Text Identity a
forall (f :: * -> *) a. Applicative f => a -> f a
pure ([Either (Bool, Column) (Either PrimaryKeyConstraint Constraint)]
-> [(Bool, Column)]
forall a b. [Either a b] -> [a]
lefts [Either (Bool, Column) (Either PrimaryKeyConstraint Constraint)]
columnsAndConstraints, [Either (Bool, Column) (Either PrimaryKeyConstraint Constraint)]
-> [Either PrimaryKeyConstraint Constraint]
forall a b. [Either a b] -> [b]
rights [Either (Bool, Column) (Either PrimaryKeyConstraint Constraint)]
columnsAndConstraints)

    Token Text -> ParsecT Void Text Identity (Token Text)
forall e s (m :: * -> *).
(MonadParsec e s m, Token s ~ Char) =>
Token s -> m (Token s)
char Char
Token Text
';'

    -- Check that either there is a single column with a PRIMARY KEY constraint,
    -- or there is a single PRIMARY KEY table constraint
    let
        columns :: [Column]
columns = ((Bool, Column) -> Column) -> [(Bool, Column)] -> [Column]
forall a b. (a -> b) -> [a] -> [b]
map (Bool, Column) -> Column
forall a b. (a, b) -> b
snd [(Bool, Column)]
taggedColumns
        constraints :: [Constraint]
constraints = [Either PrimaryKeyConstraint Constraint] -> [Constraint]
forall a b. [Either a b] -> [b]
rights [Either PrimaryKeyConstraint Constraint]
allConstraints

    PrimaryKeyConstraint
primaryKeyConstraint <- case ((Bool, Column) -> Bool) -> [(Bool, Column)] -> [(Bool, Column)]
forall a. (a -> Bool) -> [a] -> [a]
filter (Bool, Column) -> Bool
forall a b. (a, b) -> a
fst [(Bool, Column)]
taggedColumns of
        [] -> case [Either PrimaryKeyConstraint Constraint] -> [PrimaryKeyConstraint]
forall a b. [Either a b] -> [a]
lefts [Either PrimaryKeyConstraint Constraint]
allConstraints of
            [] -> PrimaryKeyConstraint
-> ParsecT Void Text Identity PrimaryKeyConstraint
forall a. a -> ParsecT Void Text Identity a
forall (f :: * -> *) a. Applicative f => a -> f a
pure (PrimaryKeyConstraint
 -> ParsecT Void Text Identity PrimaryKeyConstraint)
-> PrimaryKeyConstraint
-> ParsecT Void Text Identity PrimaryKeyConstraint
forall a b. (a -> b) -> a -> b
$ [Text] -> PrimaryKeyConstraint
PrimaryKeyConstraint []
            [PrimaryKeyConstraint
primaryKeyConstraint] -> PrimaryKeyConstraint
-> ParsecT Void Text Identity PrimaryKeyConstraint
forall a. a -> ParsecT Void Text Identity a
forall (f :: * -> *) a. Applicative f => a -> f a
pure PrimaryKeyConstraint
primaryKeyConstraint
            [PrimaryKeyConstraint]
_ -> String -> ParsecT Void Text Identity PrimaryKeyConstraint
forall a. String -> ParsecT Void Text Identity a
forall (m :: * -> *) a. MonadFail m => String -> m a
Prelude.fail (String
"Multiple PRIMARY KEY constraints on table " String -> String -> String
forall a. Semigroup a => a -> a -> a
<> Text -> String
forall a b. ConvertibleStrings a b => a -> b
cs Text
name)
        [(Bool
_, Column { Text
name :: Text
$sel:name:Column :: Column -> Text
name })] -> case [Either PrimaryKeyConstraint Constraint] -> [PrimaryKeyConstraint]
forall a b. [Either a b] -> [a]
lefts [Either PrimaryKeyConstraint Constraint]
allConstraints of
            [] -> PrimaryKeyConstraint
-> ParsecT Void Text Identity PrimaryKeyConstraint
forall a. a -> ParsecT Void Text Identity a
forall (f :: * -> *) a. Applicative f => a -> f a
pure (PrimaryKeyConstraint
 -> ParsecT Void Text Identity PrimaryKeyConstraint)
-> PrimaryKeyConstraint
-> ParsecT Void Text Identity PrimaryKeyConstraint
forall a b. (a -> b) -> a -> b
$ [Text] -> PrimaryKeyConstraint
PrimaryKeyConstraint [Text
name]
            [PrimaryKeyConstraint]
_ -> String -> ParsecT Void Text Identity PrimaryKeyConstraint
forall a. String -> ParsecT Void Text Identity a
forall (m :: * -> *) a. MonadFail m => String -> m a
Prelude.fail (String
"Primary key defined in both column and table constraints on table " String -> String -> String
forall a. Semigroup a => a -> a -> a
<> Text -> String
forall a b. ConvertibleStrings a b => a -> b
cs Text
name)
        [(Bool, Column)]
_ -> String -> ParsecT Void Text Identity PrimaryKeyConstraint
forall a. String -> ParsecT Void Text Identity a
forall (m :: * -> *) a. MonadFail m => String -> m a
Prelude.fail String
"Multiple columns with PRIMARY KEY constraint"

    CreateTable -> ParsecT Void Text Identity CreateTable
forall a. a -> ParsecT Void Text Identity a
forall (f :: * -> *) a. Applicative f => a -> f a
pure CreateTable { Text
name :: Text
$sel:name:CreateTable :: Text
name, [Column]
columns :: [Column]
$sel:columns:CreateTable :: [Column]
columns, PrimaryKeyConstraint
primaryKeyConstraint :: PrimaryKeyConstraint
$sel:primaryKeyConstraint:CreateTable :: PrimaryKeyConstraint
primaryKeyConstraint, [Constraint]
constraints :: [Constraint]
$sel:constraints:CreateTable :: [Constraint]
constraints, Bool
unlogged :: Bool
$sel:unlogged:CreateTable :: Bool
unlogged }

createEnumType :: ParsecT Void Text Identity Statement
createEnumType = do
    Parser Text -> Parser Text
forall a. Parser a -> Parser a
lexeme Parser Text
"CREATE"
    Parser Text -> Parser Text
forall a. Parser a -> Parser a
lexeme Parser Text
"TYPE"
    ParsecT Void Text Identity Char
-> ParsecT Void Text Identity (Maybe Char)
forall (f :: * -> *) a. Alternative f => f a -> f (Maybe a)
optional do
        Parser Text -> Parser Text
forall a. Parser a -> Parser a
lexeme Parser Text
"public"
        Token Text -> ParsecT Void Text Identity (Token Text)
forall e s (m :: * -> *).
(MonadParsec e s m, Token s ~ Char) =>
Token s -> m (Token s)
char Char
Token Text
'.'
    Text
name <- Parser Text
identifier
    Parser Text -> Parser Text
forall a. Parser a -> Parser a
lexeme Parser Text
"AS"
    Parser Text -> Parser Text
forall a. Parser a -> Parser a
lexeme Parser Text
"ENUM"
    [Text]
values <- Parser ()
-> Parser ()
-> ParsecT Void Text Identity [Text]
-> ParsecT Void Text Identity [Text]
forall (m :: * -> *) open close a.
Applicative m =>
m open -> m close -> m a -> m a
between (Token Text -> ParsecT Void Text Identity (Token Text)
forall e s (m :: * -> *).
(MonadParsec e s m, Token s ~ Char) =>
Token s -> m (Token s)
char Char
Token Text
'(' ParsecT Void Text Identity Char -> Parser () -> Parser ()
forall a b.
ParsecT Void Text Identity a
-> ParsecT Void Text Identity b -> ParsecT Void Text Identity b
forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> Parser ()
forall e s (m :: * -> *).
(MonadParsec e s m, Token s ~ Char) =>
m ()
space) (Parser ()
forall e s (m :: * -> *).
(MonadParsec e s m, Token s ~ Char) =>
m ()
space Parser ()
-> ParsecT Void Text Identity Char
-> ParsecT Void Text Identity Char
forall a b.
ParsecT Void Text Identity a
-> ParsecT Void Text Identity b -> ParsecT Void Text Identity b
forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> Token Text -> ParsecT Void Text Identity (Token Text)
forall e s (m :: * -> *).
(MonadParsec e s m, Token s ~ Char) =>
Token s -> m (Token s)
char Char
Token Text
')' ParsecT Void Text Identity Char -> Parser () -> Parser ()
forall a b.
ParsecT Void Text Identity a
-> ParsecT Void Text Identity b -> ParsecT Void Text Identity b
forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> Parser ()
forall e s (m :: * -> *).
(MonadParsec e s m, Token s ~ Char) =>
m ()
space) (Parser Text
textExpr' Parser Text -> Parser () -> ParsecT Void Text Identity [Text]
forall (m :: * -> *) a end. MonadPlus m => m a -> m end -> m [a]
`sepBy` (Token Text -> ParsecT Void Text Identity (Token Text)
forall e s (m :: * -> *).
(MonadParsec e s m, Token s ~ Char) =>
Token s -> m (Token s)
char Char
Token Text
',' ParsecT Void Text Identity Char -> Parser () -> Parser ()
forall a b.
ParsecT Void Text Identity a
-> ParsecT Void Text Identity b -> ParsecT Void Text Identity b
forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> Parser ()
forall e s (m :: * -> *).
(MonadParsec e s m, Token s ~ Char) =>
m ()
space))
    Parser ()
forall e s (m :: * -> *).
(MonadParsec e s m, Token s ~ Char) =>
m ()
space
    Token Text -> ParsecT Void Text Identity (Token Text)
forall e s (m :: * -> *).
(MonadParsec e s m, Token s ~ Char) =>
Token s -> m (Token s)
char Char
Token Text
';'
    Statement -> ParsecT Void Text Identity Statement
forall a. a -> ParsecT Void Text Identity a
forall (f :: * -> *) a. Applicative f => a -> f a
pure CreateEnumType { Text
$sel:name:StatementCreateTable :: Text
name :: Text
name, [Text]
values :: [Text]
$sel:values:StatementCreateTable :: [Text]
values }

addConstraint :: Text -> ParsecT Void Text Identity Statement
addConstraint Text
tableName = do
    Constraint
constraint <- ParsecT Void Text Identity (Either PrimaryKeyConstraint Constraint)
parseTableConstraint ParsecT Void Text Identity (Either PrimaryKeyConstraint Constraint)
-> (Either PrimaryKeyConstraint Constraint
    -> ParsecT Void Text Identity Constraint)
-> ParsecT Void Text Identity Constraint
forall a b.
ParsecT Void Text Identity a
-> (a -> ParsecT Void Text Identity b)
-> ParsecT Void Text Identity b
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= \case
      Left PrimaryKeyConstraint
primaryKeyConstraint -> Constraint -> ParsecT Void Text Identity Constraint
forall a. a -> ParsecT Void Text Identity a
forall (f :: * -> *) a. Applicative f => a -> f a
pure AlterTableAddPrimaryKey { $sel:name:ForeignKeyConstraint :: Maybe Text
name = Maybe Text
forall a. Maybe a
Nothing, PrimaryKeyConstraint
primaryKeyConstraint :: PrimaryKeyConstraint
$sel:primaryKeyConstraint:ForeignKeyConstraint :: PrimaryKeyConstraint
primaryKeyConstraint }
      Right Constraint
constraint -> Constraint -> ParsecT Void Text Identity Constraint
forall a. a -> ParsecT Void Text Identity a
forall (f :: * -> *) a. Applicative f => a -> f a
pure Constraint
constraint
    Maybe Bool
deferrable <- ParsecT Void Text Identity Bool
-> ParsecT Void Text Identity (Maybe Bool)
forall (f :: * -> *) a. Alternative f => f a -> f (Maybe a)
optional ParsecT Void Text Identity Bool
parseDeferrable
    Maybe DeferrableType
deferrableType <- ParsecT Void Text Identity DeferrableType
-> ParsecT Void Text Identity (Maybe DeferrableType)
forall (f :: * -> *) a. Alternative f => f a -> f (Maybe a)
optional ParsecT Void Text Identity DeferrableType
parseDeferrableType
    Token Text -> ParsecT Void Text Identity (Token Text)
forall e s (m :: * -> *).
(MonadParsec e s m, Token s ~ Char) =>
Token s -> m (Token s)
char Char
Token Text
';'
    Statement -> ParsecT Void Text Identity Statement
forall a. a -> ParsecT Void Text Identity a
forall (f :: * -> *) a. Applicative f => a -> f a
pure AddConstraint { Text
tableName :: Text
$sel:tableName:StatementCreateTable :: Text
tableName, Constraint
constraint :: Constraint
$sel:constraint:StatementCreateTable :: Constraint
constraint, Maybe Bool
deferrable :: Maybe Bool
$sel:deferrable:StatementCreateTable :: Maybe Bool
deferrable, Maybe DeferrableType
deferrableType :: Maybe DeferrableType
$sel:deferrableType:StatementCreateTable :: Maybe DeferrableType
deferrableType }

parseDeferrable :: ParsecT Void Text Identity Bool
parseDeferrable = do
    Text
isDeferrable <- Parser Text -> Parser Text
forall a. Parser a -> Parser a
lexeme Parser Text
"DEFERRABLE" Parser Text -> Parser Text -> Parser Text
forall a.
ParsecT Void Text Identity a
-> ParsecT Void Text Identity a -> ParsecT Void Text Identity a
forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
<|> Parser Text -> Parser Text
forall a. Parser a -> Parser a
lexeme Parser Text
"NOT DEFERRABLE"
    Bool -> ParsecT Void Text Identity Bool
forall a. a -> ParsecT Void Text Identity a
forall (f :: * -> *) a. Applicative f => a -> f a
pure (Bool -> ParsecT Void Text Identity Bool)
-> Bool -> ParsecT Void Text Identity Bool
forall a b. (a -> b) -> a -> b
$ case Text
isDeferrable of
        Text
"DEFERRABLE" -> Bool
True
        Text
"NOT DEFERRABLE" -> Bool
False

parseDeferrableType :: ParsecT Void Text Identity DeferrableType
parseDeferrableType = do
    Parser Text -> Parser Text
forall a. Parser a -> Parser a
lexeme Parser Text
"INITIALLY"
    Text
dtype <- Parser Text -> Parser Text
forall a. Parser a -> Parser a
lexeme Parser Text
"IMMEDIATE" Parser Text -> Parser Text -> Parser Text
forall a.
ParsecT Void Text Identity a
-> ParsecT Void Text Identity a -> ParsecT Void Text Identity a
forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
<|> Parser Text -> Parser Text
forall a. Parser a -> Parser a
lexeme Parser Text
"DEFERRED"
    case Text
dtype of
        Text
"IMMEDIATE" -> DeferrableType -> ParsecT Void Text Identity DeferrableType
forall a. a -> ParsecT Void Text Identity a
forall (f :: * -> *) a. Applicative f => a -> f a
pure DeferrableType
InitiallyImmediate
        Text
"DEFERRED" -> DeferrableType -> ParsecT Void Text Identity DeferrableType
forall a. a -> ParsecT Void Text Identity a
forall (f :: * -> *) a. Applicative f => a -> f a
pure DeferrableType
InitiallyDeferred

parseTableConstraint :: ParsecT Void Text Identity (Either PrimaryKeyConstraint Constraint)
parseTableConstraint = do
    Maybe Text
name <- Parser Text -> ParsecT Void Text Identity (Maybe Text)
forall (f :: * -> *) a. Alternative f => f a -> f (Maybe a)
optional do
        Parser Text -> Parser Text
forall a. Parser a -> Parser a
lexeme Parser Text
"CONSTRAINT"
        Parser Text
identifier
    (PrimaryKeyConstraint -> Either PrimaryKeyConstraint Constraint
forall a b. a -> Either a b
Left (PrimaryKeyConstraint -> Either PrimaryKeyConstraint Constraint)
-> ParsecT Void Text Identity PrimaryKeyConstraint
-> ParsecT
     Void Text Identity (Either PrimaryKeyConstraint Constraint)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> ParsecT Void Text Identity PrimaryKeyConstraint
parsePrimaryKeyConstraint) ParsecT Void Text Identity (Either PrimaryKeyConstraint Constraint)
-> ParsecT
     Void Text Identity (Either PrimaryKeyConstraint Constraint)
-> ParsecT
     Void Text Identity (Either PrimaryKeyConstraint Constraint)
forall a.
ParsecT Void Text Identity a
-> ParsecT Void Text Identity a -> ParsecT Void Text Identity a
forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
<|>
      (Constraint -> Either PrimaryKeyConstraint Constraint
forall a b. b -> Either a b
Right (Constraint -> Either PrimaryKeyConstraint Constraint)
-> ParsecT Void Text Identity Constraint
-> ParsecT
     Void Text Identity (Either PrimaryKeyConstraint Constraint)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> (Maybe Text -> ParsecT Void Text Identity Constraint
parseForeignKeyConstraint Maybe Text
name ParsecT Void Text Identity Constraint
-> ParsecT Void Text Identity Constraint
-> ParsecT Void Text Identity Constraint
forall a.
ParsecT Void Text Identity a
-> ParsecT Void Text Identity a -> ParsecT Void Text Identity a
forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
<|> Maybe Text -> ParsecT Void Text Identity Constraint
parseUniqueConstraint Maybe Text
name ParsecT Void Text Identity Constraint
-> ParsecT Void Text Identity Constraint
-> ParsecT Void Text Identity Constraint
forall a.
ParsecT Void Text Identity a
-> ParsecT Void Text Identity a -> ParsecT Void Text Identity a
forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
<|> Maybe Text -> ParsecT Void Text Identity Constraint
parseCheckConstraint Maybe Text
name ParsecT Void Text Identity Constraint
-> ParsecT Void Text Identity Constraint
-> ParsecT Void Text Identity Constraint
forall a.
ParsecT Void Text Identity a
-> ParsecT Void Text Identity a -> ParsecT Void Text Identity a
forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
<|> Maybe Text -> ParsecT Void Text Identity Constraint
parseExcludeConstraint Maybe Text
name))

parsePrimaryKeyConstraint :: ParsecT Void Text Identity PrimaryKeyConstraint
parsePrimaryKeyConstraint = do
    Parser Text -> Parser Text
forall a. Parser a -> Parser a
lexeme Parser Text
"PRIMARY"
    Parser Text -> Parser Text
forall a. Parser a -> Parser a
lexeme Parser Text
"KEY"
    [Text]
primaryKeyColumnNames <- Parser ()
-> Parser ()
-> ParsecT Void Text Identity [Text]
-> ParsecT Void Text Identity [Text]
forall (m :: * -> *) open close a.
Applicative m =>
m open -> m close -> m a -> m a
between (Token Text -> ParsecT Void Text Identity (Token Text)
forall e s (m :: * -> *).
(MonadParsec e s m, Token s ~ Char) =>
Token s -> m (Token s)
char Char
Token Text
'(' ParsecT Void Text Identity Char -> Parser () -> Parser ()
forall a b.
ParsecT Void Text Identity a
-> ParsecT Void Text Identity b -> ParsecT Void Text Identity b
forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> Parser ()
forall e s (m :: * -> *).
(MonadParsec e s m, Token s ~ Char) =>
m ()
space) (Token Text -> ParsecT Void Text Identity (Token Text)
forall e s (m :: * -> *).
(MonadParsec e s m, Token s ~ Char) =>
Token s -> m (Token s)
char Char
Token Text
')' ParsecT Void Text Identity Char -> Parser () -> Parser ()
forall a b.
ParsecT Void Text Identity a
-> ParsecT Void Text Identity b -> ParsecT Void Text Identity b
forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> Parser ()
forall e s (m :: * -> *).
(MonadParsec e s m, Token s ~ Char) =>
m ()
space) (Parser Text
identifier Parser Text -> Parser () -> ParsecT Void Text Identity [Text]
forall (m :: * -> *) a end. MonadPlus m => m a -> m end -> m [a]
`sepBy1` (Token Text -> ParsecT Void Text Identity (Token Text)
forall e s (m :: * -> *).
(MonadParsec e s m, Token s ~ Char) =>
Token s -> m (Token s)
char Char
Token Text
',' ParsecT Void Text Identity Char -> Parser () -> Parser ()
forall a b.
ParsecT Void Text Identity a
-> ParsecT Void Text Identity b -> ParsecT Void Text Identity b
forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> Parser ()
forall e s (m :: * -> *).
(MonadParsec e s m, Token s ~ Char) =>
m ()
space))
    PrimaryKeyConstraint
-> ParsecT Void Text Identity PrimaryKeyConstraint
forall a. a -> ParsecT Void Text Identity a
forall (f :: * -> *) a. Applicative f => a -> f a
pure PrimaryKeyConstraint { [Text]
primaryKeyColumnNames :: [Text]
$sel:primaryKeyColumnNames:PrimaryKeyConstraint :: [Text]
primaryKeyColumnNames }

parseForeignKeyConstraint :: Maybe Text -> ParsecT Void Text Identity Constraint
parseForeignKeyConstraint Maybe Text
name = do
    Parser Text -> Parser Text
forall a. Parser a -> Parser a
lexeme Parser Text
"FOREIGN"
    Parser Text -> Parser Text
forall a. Parser a -> Parser a
lexeme Parser Text
"KEY"
    Text
columnName <- Parser () -> Parser () -> Parser Text -> Parser Text
forall (m :: * -> *) open close a.
Applicative m =>
m open -> m close -> m a -> m a
between (Token Text -> ParsecT Void Text Identity (Token Text)
forall e s (m :: * -> *).
(MonadParsec e s m, Token s ~ Char) =>
Token s -> m (Token s)
char Char
Token Text
'(' ParsecT Void Text Identity Char -> Parser () -> Parser ()
forall a b.
ParsecT Void Text Identity a
-> ParsecT Void Text Identity b -> ParsecT Void Text Identity b
forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> Parser ()
forall e s (m :: * -> *).
(MonadParsec e s m, Token s ~ Char) =>
m ()
space) (Token Text -> ParsecT Void Text Identity (Token Text)
forall e s (m :: * -> *).
(MonadParsec e s m, Token s ~ Char) =>
Token s -> m (Token s)
char Char
Token Text
')' ParsecT Void Text Identity Char -> Parser () -> Parser ()
forall a b.
ParsecT Void Text Identity a
-> ParsecT Void Text Identity b -> ParsecT Void Text Identity b
forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> Parser ()
forall e s (m :: * -> *).
(MonadParsec e s m, Token s ~ Char) =>
m ()
space) Parser Text
identifier
    Parser Text -> Parser Text
forall a. Parser a -> Parser a
lexeme Parser Text
"REFERENCES"
    Text
referenceTable <- Parser Text
qualifiedIdentifier
    Maybe Text
referenceColumn <- Parser Text -> ParsecT Void Text Identity (Maybe Text)
forall (f :: * -> *) a. Alternative f => f a -> f (Maybe a)
optional (Parser Text -> ParsecT Void Text Identity (Maybe Text))
-> Parser Text -> ParsecT Void Text Identity (Maybe Text)
forall a b. (a -> b) -> a -> b
$ Parser () -> Parser () -> Parser Text -> Parser Text
forall (m :: * -> *) open close a.
Applicative m =>
m open -> m close -> m a -> m a
between (Token Text -> ParsecT Void Text Identity (Token Text)
forall e s (m :: * -> *).
(MonadParsec e s m, Token s ~ Char) =>
Token s -> m (Token s)
char Char
Token Text
'(' ParsecT Void Text Identity Char -> Parser () -> Parser ()
forall a b.
ParsecT Void Text Identity a
-> ParsecT Void Text Identity b -> ParsecT Void Text Identity b
forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> Parser ()
forall e s (m :: * -> *).
(MonadParsec e s m, Token s ~ Char) =>
m ()
space) (Token Text -> ParsecT Void Text Identity (Token Text)
forall e s (m :: * -> *).
(MonadParsec e s m, Token s ~ Char) =>
Token s -> m (Token s)
char Char
Token Text
')' ParsecT Void Text Identity Char -> Parser () -> Parser ()
forall a b.
ParsecT Void Text Identity a
-> ParsecT Void Text Identity b -> ParsecT Void Text Identity b
forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> Parser ()
forall e s (m :: * -> *).
(MonadParsec e s m, Token s ~ Char) =>
m ()
space) Parser Text
identifier
    Maybe OnDelete
onDelete <- ParsecT Void Text Identity OnDelete
-> ParsecT Void Text Identity (Maybe OnDelete)
forall (f :: * -> *) a. Alternative f => f a -> f (Maybe a)
optional do
        Parser Text -> Parser Text
forall a. Parser a -> Parser a
lexeme Parser Text
"ON"
        Parser Text -> Parser Text
forall a. Parser a -> Parser a
lexeme Parser Text
"DELETE"
        ParsecT Void Text Identity OnDelete
parseOnDelete
    Constraint -> ParsecT Void Text Identity Constraint
forall a. a -> ParsecT Void Text Identity a
forall (f :: * -> *) a. Applicative f => a -> f a
pure ForeignKeyConstraint { Maybe Text
$sel:name:ForeignKeyConstraint :: Maybe Text
name :: Maybe Text
name, Text
columnName :: Text
$sel:columnName:ForeignKeyConstraint :: Text
columnName, Text
referenceTable :: Text
$sel:referenceTable:ForeignKeyConstraint :: Text
referenceTable, Maybe Text
referenceColumn :: Maybe Text
$sel:referenceColumn:ForeignKeyConstraint :: Maybe Text
referenceColumn, Maybe OnDelete
onDelete :: Maybe OnDelete
$sel:onDelete:ForeignKeyConstraint :: Maybe OnDelete
onDelete }

parseUniqueConstraint :: Maybe Text -> ParsecT Void Text Identity Constraint
parseUniqueConstraint Maybe Text
name = do
    Parser Text -> Parser Text
forall a. Parser a -> Parser a
lexeme Parser Text
"UNIQUE"
    [Text]
columnNames <- Parser ()
-> Parser ()
-> ParsecT Void Text Identity [Text]
-> ParsecT Void Text Identity [Text]
forall (m :: * -> *) open close a.
Applicative m =>
m open -> m close -> m a -> m a
between (Token Text -> ParsecT Void Text Identity (Token Text)
forall e s (m :: * -> *).
(MonadParsec e s m, Token s ~ Char) =>
Token s -> m (Token s)
char Char
Token Text
'(' ParsecT Void Text Identity Char -> Parser () -> Parser ()
forall a b.
ParsecT Void Text Identity a
-> ParsecT Void Text Identity b -> ParsecT Void Text Identity b
forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> Parser ()
forall e s (m :: * -> *).
(MonadParsec e s m, Token s ~ Char) =>
m ()
space) (Token Text -> ParsecT Void Text Identity (Token Text)
forall e s (m :: * -> *).
(MonadParsec e s m, Token s ~ Char) =>
Token s -> m (Token s)
char Char
Token Text
')' ParsecT Void Text Identity Char -> Parser () -> Parser ()
forall a b.
ParsecT Void Text Identity a
-> ParsecT Void Text Identity b -> ParsecT Void Text Identity b
forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> Parser ()
forall e s (m :: * -> *).
(MonadParsec e s m, Token s ~ Char) =>
m ()
space) (Parser Text
identifier Parser Text -> Parser () -> ParsecT Void Text Identity [Text]
forall (m :: * -> *) a end. MonadPlus m => m a -> m end -> m [a]
`sepBy1` (Token Text -> ParsecT Void Text Identity (Token Text)
forall e s (m :: * -> *).
(MonadParsec e s m, Token s ~ Char) =>
Token s -> m (Token s)
char Char
Token Text
',' ParsecT Void Text Identity Char -> Parser () -> Parser ()
forall a b.
ParsecT Void Text Identity a
-> ParsecT Void Text Identity b -> ParsecT Void Text Identity b
forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> Parser ()
forall e s (m :: * -> *).
(MonadParsec e s m, Token s ~ Char) =>
m ()
space))
    Constraint -> ParsecT Void Text Identity Constraint
forall a. a -> ParsecT Void Text Identity a
forall (f :: * -> *) a. Applicative f => a -> f a
pure UniqueConstraint { Maybe Text
$sel:name:ForeignKeyConstraint :: Maybe Text
name :: Maybe Text
name, [Text]
columnNames :: [Text]
$sel:columnNames:ForeignKeyConstraint :: [Text]
columnNames }

parseCheckConstraint :: Maybe Text -> ParsecT Void Text Identity Constraint
parseCheckConstraint Maybe Text
name = do
    Parser Text -> Parser Text
forall a. Parser a -> Parser a
lexeme Parser Text
"CHECK"
    Expression
checkExpression <- Parser ()
-> Parser ()
-> ParsecT Void Text Identity Expression
-> ParsecT Void Text Identity Expression
forall (m :: * -> *) open close a.
Applicative m =>
m open -> m close -> m a -> m a
between (Token Text -> ParsecT Void Text Identity (Token Text)
forall e s (m :: * -> *).
(MonadParsec e s m, Token s ~ Char) =>
Token s -> m (Token s)
char Char
Token Text
'(' ParsecT Void Text Identity Char -> Parser () -> Parser ()
forall a b.
ParsecT Void Text Identity a
-> ParsecT Void Text Identity b -> ParsecT Void Text Identity b
forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> Parser ()
forall e s (m :: * -> *).
(MonadParsec e s m, Token s ~ Char) =>
m ()
space) (Token Text -> ParsecT Void Text Identity (Token Text)
forall e s (m :: * -> *).
(MonadParsec e s m, Token s ~ Char) =>
Token s -> m (Token s)
char Char
Token Text
')' ParsecT Void Text Identity Char -> Parser () -> Parser ()
forall a b.
ParsecT Void Text Identity a
-> ParsecT Void Text Identity b -> ParsecT Void Text Identity b
forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> Parser ()
forall e s (m :: * -> *).
(MonadParsec e s m, Token s ~ Char) =>
m ()
space) ParsecT Void Text Identity Expression
expression
    Constraint -> ParsecT Void Text Identity Constraint
forall a. a -> ParsecT Void Text Identity a
forall (f :: * -> *) a. Applicative f => a -> f a
pure CheckConstraint { Maybe Text
$sel:name:ForeignKeyConstraint :: Maybe Text
name :: Maybe Text
name, Expression
checkExpression :: Expression
$sel:checkExpression:ForeignKeyConstraint :: Expression
checkExpression }

parseExcludeConstraint :: Maybe Text -> ParsecT Void Text Identity Constraint
parseExcludeConstraint Maybe Text
name = do
    Parser Text -> Parser Text
forall a. Parser a -> Parser a
lexeme Parser Text
"EXCLUDE"
    Maybe IndexType
indexType <- ParsecT Void Text Identity IndexType
-> ParsecT Void Text Identity (Maybe IndexType)
forall (f :: * -> *) a. Alternative f => f a -> f (Maybe a)
optional ParsecT Void Text Identity IndexType
parseIndexType
    [ExcludeConstraintElement]
excludeElements <- Parser ()
-> Parser ()
-> ParsecT Void Text Identity [ExcludeConstraintElement]
-> ParsecT Void Text Identity [ExcludeConstraintElement]
forall (m :: * -> *) open close a.
Applicative m =>
m open -> m close -> m a -> m a
between (Token Text -> ParsecT Void Text Identity (Token Text)
forall e s (m :: * -> *).
(MonadParsec e s m, Token s ~ Char) =>
Token s -> m (Token s)
char Char
Token Text
'(' ParsecT Void Text Identity Char -> Parser () -> Parser ()
forall a b.
ParsecT Void Text Identity a
-> ParsecT Void Text Identity b -> ParsecT Void Text Identity b
forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> Parser ()
forall e s (m :: * -> *).
(MonadParsec e s m, Token s ~ Char) =>
m ()
space) (Token Text -> ParsecT Void Text Identity (Token Text)
forall e s (m :: * -> *).
(MonadParsec e s m, Token s ~ Char) =>
Token s -> m (Token s)
char Char
Token Text
')' ParsecT Void Text Identity Char -> Parser () -> Parser ()
forall a b.
ParsecT Void Text Identity a
-> ParsecT Void Text Identity b -> ParsecT Void Text Identity b
forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> Parser ()
forall e s (m :: * -> *).
(MonadParsec e s m, Token s ~ Char) =>
m ()
space) (ParsecT Void Text Identity [ExcludeConstraintElement]
 -> ParsecT Void Text Identity [ExcludeConstraintElement])
-> ParsecT Void Text Identity [ExcludeConstraintElement]
-> ParsecT Void Text Identity [ExcludeConstraintElement]
forall a b. (a -> b) -> a -> b
$ ParsecT Void Text Identity ExcludeConstraintElement
excludeElement ParsecT Void Text Identity ExcludeConstraintElement
-> Parser ()
-> ParsecT Void Text Identity [ExcludeConstraintElement]
forall (m :: * -> *) a end. MonadPlus m => m a -> m end -> m [a]
`sepBy` (Token Text -> ParsecT Void Text Identity (Token Text)
forall e s (m :: * -> *).
(MonadParsec e s m, Token s ~ Char) =>
Token s -> m (Token s)
char Char
Token Text
',' ParsecT Void Text Identity Char -> Parser () -> Parser ()
forall a b.
ParsecT Void Text Identity a
-> ParsecT Void Text Identity b -> ParsecT Void Text Identity b
forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> Parser ()
forall e s (m :: * -> *).
(MonadParsec e s m, Token s ~ Char) =>
m ()
space)
    Maybe Expression
predicate <- ParsecT Void Text Identity Expression
-> ParsecT Void Text Identity (Maybe Expression)
forall (f :: * -> *) a. Alternative f => f a -> f (Maybe a)
optional do
        Parser Text -> Parser Text
forall a. Parser a -> Parser a
lexeme Parser Text
"WHERE"
        Parser ()
-> Parser ()
-> ParsecT Void Text Identity Expression
-> ParsecT Void Text Identity Expression
forall (m :: * -> *) open close a.
Applicative m =>
m open -> m close -> m a -> m a
between (Token Text -> ParsecT Void Text Identity (Token Text)
forall e s (m :: * -> *).
(MonadParsec e s m, Token s ~ Char) =>
Token s -> m (Token s)
char Char
Token Text
'(' ParsecT Void Text Identity Char -> Parser () -> Parser ()
forall a b.
ParsecT Void Text Identity a
-> ParsecT Void Text Identity b -> ParsecT Void Text Identity b
forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> Parser ()
forall e s (m :: * -> *).
(MonadParsec e s m, Token s ~ Char) =>
m ()
space) (Token Text -> ParsecT Void Text Identity (Token Text)
forall e s (m :: * -> *).
(MonadParsec e s m, Token s ~ Char) =>
Token s -> m (Token s)
char Char
Token Text
')' ParsecT Void Text Identity Char -> Parser () -> Parser ()
forall a b.
ParsecT Void Text Identity a
-> ParsecT Void Text Identity b -> ParsecT Void Text Identity b
forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> Parser ()
forall e s (m :: * -> *).
(MonadParsec e s m, Token s ~ Char) =>
m ()
space) ParsecT Void Text Identity Expression
expression
    Constraint -> ParsecT Void Text Identity Constraint
forall a. a -> ParsecT Void Text Identity a
forall (f :: * -> *) a. Applicative f => a -> f a
pure ExcludeConstraint { Maybe Text
$sel:name:ForeignKeyConstraint :: Maybe Text
name :: Maybe Text
name, [ExcludeConstraintElement]
excludeElements :: [ExcludeConstraintElement]
$sel:excludeElements:ForeignKeyConstraint :: [ExcludeConstraintElement]
excludeElements, Maybe Expression
predicate :: Maybe Expression
$sel:predicate:ForeignKeyConstraint :: Maybe Expression
predicate, Maybe IndexType
indexType :: Maybe IndexType
$sel:indexType:ForeignKeyConstraint :: Maybe IndexType
indexType }
    where
        excludeElement :: ParsecT Void Text Identity ExcludeConstraintElement
excludeElement = do
            Text
element <- Parser Text
identifier
            Parser ()
forall e s (m :: * -> *).
(MonadParsec e s m, Token s ~ Char) =>
m ()
space
            Parser Text -> Parser Text
forall a. Parser a -> Parser a
lexeme Parser Text
"WITH"
            Parser ()
forall e s (m :: * -> *).
(MonadParsec e s m, Token s ~ Char) =>
m ()
space
            Text
operator <- Parser Text
parseCommutativeInfixOperator
            ExcludeConstraintElement
-> ParsecT Void Text Identity ExcludeConstraintElement
forall a. a -> ParsecT Void Text Identity a
forall (f :: * -> *) a. Applicative f => a -> f a
pure ExcludeConstraintElement { Text
element :: Text
$sel:element:ExcludeConstraintElement :: Text
element, Text
operator :: Text
$sel:operator:ExcludeConstraintElement :: Text
operator }

        parseCommutativeInfixOperator :: Parser Text
parseCommutativeInfixOperator = [Parser Text] -> Parser Text
forall (f :: * -> *) (m :: * -> *) a.
(Foldable f, Alternative m) =>
f (m a) -> m a
choice ([Parser Text] -> Parser Text) -> [Parser Text] -> Parser Text
forall a b. (a -> b) -> a -> b
$ (Parser Text -> Parser Text) -> [Parser Text] -> [Parser Text]
forall a b. (a -> b) -> [a] -> [b]
map Parser Text -> Parser Text
forall a. Parser a -> Parser a
lexeme
            [ Parser Text
"="
            , Parser Text
"<>"
            , Parser Text
"!="
            , Parser Text
"AND"
            , Parser Text
"OR"
            ]

parseOnDelete :: ParsecT Void Text Identity OnDelete
parseOnDelete = [ParsecT Void Text Identity OnDelete]
-> ParsecT Void Text Identity OnDelete
forall (f :: * -> *) (m :: * -> *) a.
(Foldable f, Alternative m) =>
f (m a) -> m a
choice
        [ (Parser Text -> Parser Text
forall a. Parser a -> Parser a
lexeme Parser Text
"NO" Parser Text -> Parser Text -> Parser Text
forall a b.
ParsecT Void Text Identity a
-> ParsecT Void Text Identity b -> ParsecT Void Text Identity b
forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> Parser Text -> Parser Text
forall a. Parser a -> Parser a
lexeme Parser Text
"ACTION") Parser Text
-> ParsecT Void Text Identity OnDelete
-> ParsecT Void Text Identity OnDelete
forall a b.
ParsecT Void Text Identity a
-> ParsecT Void Text Identity b -> ParsecT Void Text Identity b
forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> OnDelete -> ParsecT Void Text Identity OnDelete
forall a. a -> ParsecT Void Text Identity a
forall (f :: * -> *) a. Applicative f => a -> f a
pure OnDelete
NoAction
        , (Parser Text -> Parser Text
forall a. Parser a -> Parser a
lexeme Parser Text
"RESTRICT" Parser Text
-> ParsecT Void Text Identity OnDelete
-> ParsecT Void Text Identity OnDelete
forall a b.
ParsecT Void Text Identity a
-> ParsecT Void Text Identity b -> ParsecT Void Text Identity b
forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> OnDelete -> ParsecT Void Text Identity OnDelete
forall a. a -> ParsecT Void Text Identity a
forall (f :: * -> *) a. Applicative f => a -> f a
pure OnDelete
Restrict)
        , (Parser Text -> Parser Text
forall a. Parser a -> Parser a
lexeme Parser Text
"SET" Parser Text
-> ParsecT Void Text Identity OnDelete
-> ParsecT Void Text Identity OnDelete
forall a b.
ParsecT Void Text Identity a
-> ParsecT Void Text Identity b -> ParsecT Void Text Identity b
forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> ((Parser Text -> Parser Text
forall a. Parser a -> Parser a
lexeme Parser Text
"NULL" Parser Text
-> ParsecT Void Text Identity OnDelete
-> ParsecT Void Text Identity OnDelete
forall a b.
ParsecT Void Text Identity a
-> ParsecT Void Text Identity b -> ParsecT Void Text Identity b
forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> OnDelete -> ParsecT Void Text Identity OnDelete
forall a. a -> ParsecT Void Text Identity a
forall (f :: * -> *) a. Applicative f => a -> f a
pure OnDelete
SetNull) ParsecT Void Text Identity OnDelete
-> ParsecT Void Text Identity OnDelete
-> ParsecT Void Text Identity OnDelete
forall a.
ParsecT Void Text Identity a
-> ParsecT Void Text Identity a -> ParsecT Void Text Identity a
forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
<|> (Parser Text -> Parser Text
forall a. Parser a -> Parser a
lexeme Parser Text
"DEFAULT" Parser Text
-> ParsecT Void Text Identity OnDelete
-> ParsecT Void Text Identity OnDelete
forall a b.
ParsecT Void Text Identity a
-> ParsecT Void Text Identity b -> ParsecT Void Text Identity b
forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> OnDelete -> ParsecT Void Text Identity OnDelete
forall a. a -> ParsecT Void Text Identity a
forall (f :: * -> *) a. Applicative f => a -> f a
pure OnDelete
SetDefault)))
        , (Parser Text -> Parser Text
forall a. Parser a -> Parser a
lexeme Parser Text
"CASCADE" Parser Text
-> ParsecT Void Text Identity OnDelete
-> ParsecT Void Text Identity OnDelete
forall a b.
ParsecT Void Text Identity a
-> ParsecT Void Text Identity b -> ParsecT Void Text Identity b
forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> OnDelete -> ParsecT Void Text Identity OnDelete
forall a. a -> ParsecT Void Text Identity a
forall (f :: * -> *) a. Applicative f => a -> f a
pure OnDelete
Cascade)
        ]

parseColumn :: Parser (Bool, Column)
parseColumn :: ParsecT Void Text Identity (Bool, Column)
parseColumn = do
    Text
name <- Parser Text
identifier
    PostgresType
columnType <- Parser PostgresType
sqlType
    Parser ()
forall e s (m :: * -> *).
(MonadParsec e s m, Token s ~ Char) =>
m ()
space
    Maybe Expression
defaultValue <- ParsecT Void Text Identity Expression
-> ParsecT Void Text Identity (Maybe Expression)
forall (f :: * -> *) a. Alternative f => f a -> f (Maybe a)
optional do
        Parser Text -> Parser Text
forall a. Parser a -> Parser a
lexeme Parser Text
"DEFAULT"
        ParsecT Void Text Identity Expression
expression
    Maybe ColumnGenerator
generator <- ParsecT Void Text Identity ColumnGenerator
-> ParsecT Void Text Identity (Maybe ColumnGenerator)
forall (f :: * -> *) a. Alternative f => f a -> f (Maybe a)
optional do
        Parser Text -> Parser Text
forall a. Parser a -> Parser a
lexeme Parser Text
"GENERATED"
        Parser Text -> Parser Text
forall a. Parser a -> Parser a
lexeme Parser Text
"ALWAYS"
        Parser Text -> Parser Text
forall a. Parser a -> Parser a
lexeme Parser Text
"AS"
        Expression
generate <- ParsecT Void Text Identity Expression
expression
        Bool
stored <- Maybe Text -> Bool
forall a. Maybe a -> Bool
isJust (Maybe Text -> Bool)
-> ParsecT Void Text Identity (Maybe Text)
-> ParsecT Void Text Identity Bool
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Parser Text -> ParsecT Void Text Identity (Maybe Text)
forall (f :: * -> *) a. Alternative f => f a -> f (Maybe a)
optional (Parser Text -> Parser Text
forall a. Parser a -> Parser a
lexeme Parser Text
"STORED")
        ColumnGenerator -> ParsecT Void Text Identity ColumnGenerator
forall a. a -> ParsecT Void Text Identity a
forall (f :: * -> *) a. Applicative f => a -> f a
pure ColumnGenerator { Expression
generate :: Expression
$sel:generate:ColumnGenerator :: Expression
generate, Bool
stored :: Bool
$sel:stored:ColumnGenerator :: Bool
stored }
    Bool
primaryKey <- Maybe Text -> Bool
forall a. Maybe a -> Bool
isJust (Maybe Text -> Bool)
-> ParsecT Void Text Identity (Maybe Text)
-> ParsecT Void Text Identity Bool
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Parser Text -> ParsecT Void Text Identity (Maybe Text)
forall (f :: * -> *) a. Alternative f => f a -> f (Maybe a)
optional (Parser Text -> Parser Text
forall a. Parser a -> Parser a
lexeme Parser Text
"PRIMARY" Parser Text -> Parser Text -> Parser Text
forall a b.
ParsecT Void Text Identity a
-> ParsecT Void Text Identity b -> ParsecT Void Text Identity b
forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> Parser Text -> Parser Text
forall a. Parser a -> Parser a
lexeme Parser Text
"KEY")
    Bool
notNull <- Maybe Text -> Bool
forall a. Maybe a -> Bool
isJust (Maybe Text -> Bool)
-> ParsecT Void Text Identity (Maybe Text)
-> ParsecT Void Text Identity Bool
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Parser Text -> ParsecT Void Text Identity (Maybe Text)
forall (f :: * -> *) a. Alternative f => f a -> f (Maybe a)
optional (Parser Text -> Parser Text
forall a. Parser a -> Parser a
lexeme Parser Text
"NOT" Parser Text -> Parser Text -> Parser Text
forall a b.
ParsecT Void Text Identity a
-> ParsecT Void Text Identity b -> ParsecT Void Text Identity b
forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> Parser Text -> Parser Text
forall a. Parser a -> Parser a
lexeme Parser Text
"NULL")
    Bool
isUnique <- Maybe Text -> Bool
forall a. Maybe a -> Bool
isJust (Maybe Text -> Bool)
-> ParsecT Void Text Identity (Maybe Text)
-> ParsecT Void Text Identity Bool
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Parser Text -> ParsecT Void Text Identity (Maybe Text)
forall (f :: * -> *) a. Alternative f => f a -> f (Maybe a)
optional (Parser Text -> Parser Text
forall a. Parser a -> Parser a
lexeme Parser Text
"UNIQUE")
    (Bool, Column) -> ParsecT Void Text Identity (Bool, Column)
forall a. a -> ParsecT Void Text Identity a
forall (f :: * -> *) a. Applicative f => a -> f a
pure (Bool
primaryKey, Column { Text
$sel:name:Column :: Text
name :: Text
name, PostgresType
columnType :: PostgresType
$sel:columnType:Column :: PostgresType
columnType, Maybe Expression
defaultValue :: Maybe Expression
$sel:defaultValue:Column :: Maybe Expression
defaultValue, Bool
notNull :: Bool
$sel:notNull:Column :: Bool
notNull, Bool
isUnique :: Bool
$sel:isUnique:Column :: Bool
isUnique, Maybe ColumnGenerator
generator :: Maybe ColumnGenerator
$sel:generator:Column :: Maybe ColumnGenerator
generator })

sqlType :: Parser PostgresType
sqlType :: Parser PostgresType
sqlType = [Parser PostgresType] -> Parser PostgresType
forall (f :: * -> *) (m :: * -> *) a.
(Foldable f, Alternative m) =>
f (m a) -> m a
choice ([Parser PostgresType] -> Parser PostgresType)
-> [Parser PostgresType] -> Parser PostgresType
forall a b. (a -> b) -> a -> b
$ (Parser PostgresType -> Parser PostgresType)
-> [Parser PostgresType] -> [Parser PostgresType]
forall a b. (a -> b) -> [a] -> [b]
map Parser PostgresType -> Parser PostgresType
optionalArray
        [ Parser PostgresType
uuid
        , Parser PostgresType
text
        , Parser PostgresType
interval --Needs higher precedence otherwise parsed as int
        , Parser PostgresType
bigint
        , Parser PostgresType
smallint
        , Parser PostgresType
int   -- order int after smallint/bigint because symbol INT is prefix of INT2, INT8
        , Parser PostgresType
bool
        , Parser PostgresType
timestamp
        , Parser PostgresType
timestampZ
        , Parser PostgresType
timestampZ'
        , Parser PostgresType
timestamp'
        , Parser PostgresType
real
        , Parser PostgresType
double
        , Parser PostgresType
point
        , Parser PostgresType
polygon
        , Parser PostgresType
date
        , Parser PostgresType
binary
        , Parser PostgresType
time
        , Parser PostgresType
numericPS
        , Parser PostgresType
numeric
        , Parser PostgresType
character
        , Parser PostgresType
varchar
        , Parser PostgresType
serial
        , Parser PostgresType
bigserial
        , Parser PostgresType
jsonb
        , Parser PostgresType
inet
        , Parser PostgresType
tsvector
        , Parser PostgresType
trigger
        , Parser PostgresType
singleChar
        , Parser PostgresType
customType
        ]
            where
                timestamp :: Parser PostgresType
timestamp = do
                    Parser Text -> Parser Text
forall a. Parser a -> Parser a
forall e s (m :: * -> *) a. MonadParsec e s m => m a -> m a
try (Text -> Parser Text
symbol' Text
"TIMESTAMP" Parser Text -> Parser Text -> Parser Text
forall a b.
ParsecT Void Text Identity a
-> ParsecT Void Text Identity b -> ParsecT Void Text Identity b
forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> Text -> Parser Text
symbol' Text
"WITHOUT" Parser Text -> Parser Text -> Parser Text
forall a b.
ParsecT Void Text Identity a
-> ParsecT Void Text Identity b -> ParsecT Void Text Identity b
forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> Text -> Parser Text
symbol' Text
"TIME" Parser Text -> Parser Text -> Parser Text
forall a b.
ParsecT Void Text Identity a
-> ParsecT Void Text Identity b -> ParsecT Void Text Identity b
forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> Text -> Parser Text
symbol' Text
"ZONE")
                    PostgresType -> Parser PostgresType
forall a. a -> ParsecT Void Text Identity a
forall (f :: * -> *) a. Applicative f => a -> f a
pure PostgresType
PTimestamp

                timestampZ :: Parser PostgresType
timestampZ = do
                    Parser Text -> Parser Text
forall a. Parser a -> Parser a
forall e s (m :: * -> *) a. MonadParsec e s m => m a -> m a
try (Text -> Parser Text
symbol' Text
"TIMESTAMP" Parser Text -> Parser Text -> Parser Text
forall a b.
ParsecT Void Text Identity a
-> ParsecT Void Text Identity b -> ParsecT Void Text Identity b
forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> Text -> Parser Text
symbol' Text
"WITH" Parser Text -> Parser Text -> Parser Text
forall a b.
ParsecT Void Text Identity a
-> ParsecT Void Text Identity b -> ParsecT Void Text Identity b
forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> Text -> Parser Text
symbol' Text
"TIME" Parser Text -> Parser Text -> Parser Text
forall a b.
ParsecT Void Text Identity a
-> ParsecT Void Text Identity b -> ParsecT Void Text Identity b
forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> Text -> Parser Text
symbol' Text
"ZONE")
                    PostgresType -> Parser PostgresType
forall a. a -> ParsecT Void Text Identity a
forall (f :: * -> *) a. Applicative f => a -> f a
pure PostgresType
PTimestampWithTimezone

                timestampZ' :: Parser PostgresType
timestampZ' = do
                    Parser Text -> Parser Text
forall a. Parser a -> Parser a
forall e s (m :: * -> *) a. MonadParsec e s m => m a -> m a
try (Text -> Parser Text
symbol' Text
"TIMESTAMPZ")
                    PostgresType -> Parser PostgresType
forall a. a -> ParsecT Void Text Identity a
forall (f :: * -> *) a. Applicative f => a -> f a
pure PostgresType
PTimestampWithTimezone

                timestamp' :: Parser PostgresType
timestamp' = do
                    Parser Text -> Parser Text
forall a. Parser a -> Parser a
forall e s (m :: * -> *) a. MonadParsec e s m => m a -> m a
try (Text -> Parser Text
symbol' Text
"TIMESTAMP")
                    PostgresType -> Parser PostgresType
forall a. a -> ParsecT Void Text Identity a
forall (f :: * -> *) a. Applicative f => a -> f a
pure PostgresType
PTimestamp

                uuid :: Parser PostgresType
uuid = do
                    Parser Text -> Parser Text
forall a. Parser a -> Parser a
forall e s (m :: * -> *) a. MonadParsec e s m => m a -> m a
try (Text -> Parser Text
symbol' Text
"UUID")
                    PostgresType -> Parser PostgresType
forall a. a -> ParsecT Void Text Identity a
forall (f :: * -> *) a. Applicative f => a -> f a
pure PostgresType
PUUID

                text :: Parser PostgresType
text = do
                    Parser Text -> Parser Text
forall a. Parser a -> Parser a
forall e s (m :: * -> *) a. MonadParsec e s m => m a -> m a
try (Text -> Parser Text
symbol' Text
"TEXT")
                    PostgresType -> Parser PostgresType
forall a. a -> ParsecT Void Text Identity a
forall (f :: * -> *) a. Applicative f => a -> f a
pure PostgresType
PText

                bigint :: Parser PostgresType
bigint = do
                    Parser Text -> Parser Text
forall a. Parser a -> Parser a
forall e s (m :: * -> *) a. MonadParsec e s m => m a -> m a
try (Text -> Parser Text
symbol' Text
"BIGINT") Parser Text -> Parser Text -> Parser Text
forall a.
ParsecT Void Text Identity a
-> ParsecT Void Text Identity a -> ParsecT Void Text Identity a
forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
<|> Parser Text -> Parser Text
forall a. Parser a -> Parser a
forall e s (m :: * -> *) a. MonadParsec e s m => m a -> m a
try (Text -> Parser Text
symbol' Text
"INT8")
                    PostgresType -> Parser PostgresType
forall a. a -> ParsecT Void Text Identity a
forall (f :: * -> *) a. Applicative f => a -> f a
pure PostgresType
PBigInt

                smallint :: Parser PostgresType
smallint = do
                    Parser Text -> Parser Text
forall a. Parser a -> Parser a
forall e s (m :: * -> *) a. MonadParsec e s m => m a -> m a
try (Text -> Parser Text
symbol' Text
"SMALLINT") Parser Text -> Parser Text -> Parser Text
forall a.
ParsecT Void Text Identity a
-> ParsecT Void Text Identity a -> ParsecT Void Text Identity a
forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
<|> Parser Text -> Parser Text
forall a. Parser a -> Parser a
forall e s (m :: * -> *) a. MonadParsec e s m => m a -> m a
try (Text -> Parser Text
symbol' Text
"INT2")
                    PostgresType -> Parser PostgresType
forall a. a -> ParsecT Void Text Identity a
forall (f :: * -> *) a. Applicative f => a -> f a
pure PostgresType
PSmallInt

                int :: Parser PostgresType
int = do
                    Parser Text -> Parser Text
forall a. Parser a -> Parser a
forall e s (m :: * -> *) a. MonadParsec e s m => m a -> m a
try (Text -> Parser Text
symbol' Text
"INTEGER") Parser Text -> Parser Text -> Parser Text
forall a.
ParsecT Void Text Identity a
-> ParsecT Void Text Identity a -> ParsecT Void Text Identity a
forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
<|> Parser Text -> Parser Text
forall a. Parser a -> Parser a
forall e s (m :: * -> *) a. MonadParsec e s m => m a -> m a
try (Text -> Parser Text
symbol' Text
"INT4") Parser Text -> Parser Text -> Parser Text
forall a.
ParsecT Void Text Identity a
-> ParsecT Void Text Identity a -> ParsecT Void Text Identity a
forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
<|> Parser Text -> Parser Text
forall a. Parser a -> Parser a
forall e s (m :: * -> *) a. MonadParsec e s m => m a -> m a
try (Text -> Parser Text
symbol' Text
"INT")
                    PostgresType -> Parser PostgresType
forall a. a -> ParsecT Void Text Identity a
forall (f :: * -> *) a. Applicative f => a -> f a
pure PostgresType
PInt

                bool :: Parser PostgresType
bool = do
                    Parser Text -> Parser Text
forall a. Parser a -> Parser a
forall e s (m :: * -> *) a. MonadParsec e s m => m a -> m a
try (Text -> Parser Text
symbol' Text
"BOOLEAN") Parser Text -> Parser Text -> Parser Text
forall a.
ParsecT Void Text Identity a
-> ParsecT Void Text Identity a -> ParsecT Void Text Identity a
forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
<|> Parser Text -> Parser Text
forall a. Parser a -> Parser a
forall e s (m :: * -> *) a. MonadParsec e s m => m a -> m a
try (Text -> Parser Text
symbol' Text
"BOOL")
                    PostgresType -> Parser PostgresType
forall a. a -> ParsecT Void Text Identity a
forall (f :: * -> *) a. Applicative f => a -> f a
pure PostgresType
PBoolean

                real :: Parser PostgresType
real = do
                    Parser Text -> Parser Text
forall a. Parser a -> Parser a
forall e s (m :: * -> *) a. MonadParsec e s m => m a -> m a
try (Text -> Parser Text
symbol' Text
"REAL") Parser Text -> Parser Text -> Parser Text
forall a.
ParsecT Void Text Identity a
-> ParsecT Void Text Identity a -> ParsecT Void Text Identity a
forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
<|> Parser Text -> Parser Text
forall a. Parser a -> Parser a
forall e s (m :: * -> *) a. MonadParsec e s m => m a -> m a
try (Text -> Parser Text
symbol' Text
"FLOAT4")
                    PostgresType -> Parser PostgresType
forall a. a -> ParsecT Void Text Identity a
forall (f :: * -> *) a. Applicative f => a -> f a
pure PostgresType
PReal

                double :: Parser PostgresType
double = do
                    Parser Text -> Parser Text
forall a. Parser a -> Parser a
forall e s (m :: * -> *) a. MonadParsec e s m => m a -> m a
try (Text -> Parser Text
symbol' Text
"DOUBLE PRECISION") Parser Text -> Parser Text -> Parser Text
forall a.
ParsecT Void Text Identity a
-> ParsecT Void Text Identity a -> ParsecT Void Text Identity a
forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
<|> Parser Text -> Parser Text
forall a. Parser a -> Parser a
forall e s (m :: * -> *) a. MonadParsec e s m => m a -> m a
try (Text -> Parser Text
symbol' Text
"FLOAT8")
                    PostgresType -> Parser PostgresType
forall a. a -> ParsecT Void Text Identity a
forall (f :: * -> *) a. Applicative f => a -> f a
pure PostgresType
PDouble

                point :: Parser PostgresType
point = do
                    Parser Text -> Parser Text
forall a. Parser a -> Parser a
forall e s (m :: * -> *) a. MonadParsec e s m => m a -> m a
try (Text -> Parser Text
symbol' Text
"POINT")
                    PostgresType -> Parser PostgresType
forall a. a -> ParsecT Void Text Identity a
forall (f :: * -> *) a. Applicative f => a -> f a
pure PostgresType
PPoint

                polygon :: Parser PostgresType
polygon = do
                    Parser Text -> Parser Text
forall a. Parser a -> Parser a
forall e s (m :: * -> *) a. MonadParsec e s m => m a -> m a
try (Text -> Parser Text
symbol' Text
"POLYGON")
                    PostgresType -> Parser PostgresType
forall a. a -> ParsecT Void Text Identity a
forall (f :: * -> *) a. Applicative f => a -> f a
pure PostgresType
PPolygon

                date :: Parser PostgresType
date = do
                    Parser Text -> Parser Text
forall a. Parser a -> Parser a
forall e s (m :: * -> *) a. MonadParsec e s m => m a -> m a
try (Text -> Parser Text
symbol' Text
"DATE")
                    PostgresType -> Parser PostgresType
forall a. a -> ParsecT Void Text Identity a
forall (f :: * -> *) a. Applicative f => a -> f a
pure PostgresType
PDate

                binary :: Parser PostgresType
binary = do
                    Parser Text -> Parser Text
forall a. Parser a -> Parser a
forall e s (m :: * -> *) a. MonadParsec e s m => m a -> m a
try (Text -> Parser Text
symbol' Text
"BYTEA")
                    PostgresType -> Parser PostgresType
forall a. a -> ParsecT Void Text Identity a
forall (f :: * -> *) a. Applicative f => a -> f a
pure PostgresType
PBinary

                time :: Parser PostgresType
time = do
                    Parser Text -> Parser Text
forall a. Parser a -> Parser a
forall e s (m :: * -> *) a. MonadParsec e s m => m a -> m a
try (Text -> Parser Text
symbol' Text
"TIME")
                    Parser Text -> ParsecT Void Text Identity (Maybe Text)
forall (f :: * -> *) a. Alternative f => f a -> f (Maybe a)
optional do
                        Text -> Parser Text
symbol' Text
"WITHOUT"
                        Text -> Parser Text
symbol' Text
"TIME"
                        Text -> Parser Text
symbol' Text
"ZONE"
                    PostgresType -> Parser PostgresType
forall a. a -> ParsecT Void Text Identity a
forall (f :: * -> *) a. Applicative f => a -> f a
pure PostgresType
PTime

                interval :: Parser PostgresType
interval = do
                    Parser Text -> Parser Text
forall a. Parser a -> Parser a
forall e s (m :: * -> *) a. MonadParsec e s m => m a -> m a
try (Text -> Parser Text
symbol' Text
"INTERVAL")
                    Maybe Text
fields <- Parser Text -> ParsecT Void Text Identity (Maybe Text)
forall (f :: * -> *) a. Alternative f => f a -> f (Maybe a)
optional do
                        [Parser Text] -> Parser Text
forall (f :: * -> *) (m :: * -> *) a.
(Foldable f, Alternative m) =>
f (m a) -> m a
choice ([Parser Text] -> Parser Text) -> [Parser Text] -> Parser Text
forall a b. (a -> b) -> a -> b
$ (Text -> Parser Text) -> [Text] -> [Parser Text]
forall a b. (a -> b) -> [a] -> [b]
map Text -> Parser Text
symbol' [Text]
intervalFields
                    PostgresType -> Parser PostgresType
forall a. a -> ParsecT Void Text Identity a
forall (f :: * -> *) a. Applicative f => a -> f a
pure (Maybe Text -> PostgresType
PInterval Maybe Text
fields)

                numericPS :: Parser PostgresType
numericPS = do
                    Parser Text -> Parser Text
forall a. Parser a -> Parser a
forall e s (m :: * -> *) a. MonadParsec e s m => m a -> m a
try (Text -> Parser Text
symbol' Text
"NUMERIC(")
                    [Expression]
values <- Parser ()
-> Parser ()
-> ParsecT Void Text Identity [Expression]
-> ParsecT Void Text Identity [Expression]
forall (m :: * -> *) open close a.
Applicative m =>
m open -> m close -> m a -> m a
between (Parser ()
forall e s (m :: * -> *).
(MonadParsec e s m, Token s ~ Char) =>
m ()
space) (Token Text -> ParsecT Void Text Identity (Token Text)
forall e s (m :: * -> *).
(MonadParsec e s m, Token s ~ Char) =>
Token s -> m (Token s)
char Char
Token Text
')' ParsecT Void Text Identity Char -> Parser () -> Parser ()
forall a b.
ParsecT Void Text Identity a
-> ParsecT Void Text Identity b -> ParsecT Void Text Identity b
forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> Parser ()
forall e s (m :: * -> *).
(MonadParsec e s m, Token s ~ Char) =>
m ()
space) (ParsecT Void Text Identity Expression
varExpr ParsecT Void Text Identity Expression
-> Parser () -> ParsecT Void Text Identity [Expression]
forall (m :: * -> *) a end. MonadPlus m => m a -> m end -> m [a]
`sepBy` (Token Text -> ParsecT Void Text Identity (Token Text)
forall e s (m :: * -> *).
(MonadParsec e s m, Token s ~ Char) =>
Token s -> m (Token s)
char Char
Token Text
',' ParsecT Void Text Identity Char -> Parser () -> Parser ()
forall a b.
ParsecT Void Text Identity a
-> ParsecT Void Text Identity b -> ParsecT Void Text Identity b
forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> Parser ()
forall e s (m :: * -> *).
(MonadParsec e s m, Token s ~ Char) =>
m ()
space))
                    case [Expression]
values of
                        [VarExpression Text
precision, VarExpression Text
scale] -> do
                            let p :: Maybe Int
p = Text -> Maybe Int
textToInt Text
precision
                            let s :: Maybe Int
s = Text -> Maybe Int
textToInt Text
scale
                            Bool -> Parser () -> Parser ()
forall (f :: * -> *). Applicative f => Bool -> f () -> f ()
when ([Bool] -> Bool
forall (t :: * -> *). Foldable t => t Bool -> Bool
or [Maybe Int -> Bool
forall a. Maybe a -> Bool
isNothing Maybe Int
p, Maybe Int -> Bool
forall a. Maybe a -> Bool
isNothing Maybe Int
s]) do
                                String -> Parser ()
forall a. String -> ParsecT Void Text Identity a
forall (m :: * -> *) a. MonadFail m => String -> m a
Prelude.fail String
"Failed to parse NUMERIC(..) expression"
                            PostgresType -> Parser PostgresType
forall a. a -> ParsecT Void Text Identity a
forall (f :: * -> *) a. Applicative f => a -> f a
pure (Maybe Int -> Maybe Int -> PostgresType
PNumeric Maybe Int
p Maybe Int
s)
                        [VarExpression Text
precision] -> do
                            let p :: Maybe Int
p = Text -> Maybe Int
textToInt Text
precision
                            Bool -> Parser () -> Parser ()
forall (f :: * -> *). Applicative f => Bool -> f () -> f ()
when (Maybe Int -> Bool
forall a. Maybe a -> Bool
isNothing Maybe Int
p) do
                                String -> Parser ()
forall a. String -> ParsecT Void Text Identity a
forall (m :: * -> *) a. MonadFail m => String -> m a
Prelude.fail String
"Failed to parse NUMERIC(..) expression"
                            PostgresType -> Parser PostgresType
forall a. a -> ParsecT Void Text Identity a
forall (f :: * -> *) a. Applicative f => a -> f a
pure (Maybe Int -> Maybe Int -> PostgresType
PNumeric Maybe Int
p Maybe Int
forall a. Maybe a
Nothing)
                        [Expression]
_ -> String -> Parser PostgresType
forall a. String -> ParsecT Void Text Identity a
forall (m :: * -> *) a. MonadFail m => String -> m a
Prelude.fail String
"Failed to parse NUMERIC(..) expression"

                numeric :: Parser PostgresType
numeric = do
                    Parser Text -> Parser Text
forall a. Parser a -> Parser a
forall e s (m :: * -> *) a. MonadParsec e s m => m a -> m a
try (Text -> Parser Text
symbol' Text
"NUMERIC")
                    PostgresType -> Parser PostgresType
forall a. a -> ParsecT Void Text Identity a
forall (f :: * -> *) a. Applicative f => a -> f a
pure (Maybe Int -> Maybe Int -> PostgresType
PNumeric Maybe Int
forall a. Maybe a
Nothing Maybe Int
forall a. Maybe a
Nothing)

                varchar :: Parser PostgresType
varchar = do
                    Parser Text -> Parser Text
forall a. Parser a -> Parser a
forall e s (m :: * -> *) a. MonadParsec e s m => m a -> m a
try (Text -> Parser Text
symbol' Text
"CHARACTER VARYING") Parser Text -> Parser Text -> Parser Text
forall a.
ParsecT Void Text Identity a
-> ParsecT Void Text Identity a -> ParsecT Void Text Identity a
forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
<|> Parser Text -> Parser Text
forall a. Parser a -> Parser a
forall e s (m :: * -> *) a. MonadParsec e s m => m a -> m a
try (Text -> Parser Text
symbol' Text
"VARCHAR")
                    Maybe Expression
value <- ParsecT Void Text Identity Expression
-> ParsecT Void Text Identity (Maybe Expression)
forall (f :: * -> *) a. Alternative f => f a -> f (Maybe a)
optional (ParsecT Void Text Identity Expression
 -> ParsecT Void Text Identity (Maybe Expression))
-> ParsecT Void Text Identity Expression
-> ParsecT Void Text Identity (Maybe Expression)
forall a b. (a -> b) -> a -> b
$ Parser ()
-> Parser ()
-> ParsecT Void Text Identity Expression
-> ParsecT Void Text Identity Expression
forall (m :: * -> *) open close a.
Applicative m =>
m open -> m close -> m a -> m a
between (Token Text -> ParsecT Void Text Identity (Token Text)
forall e s (m :: * -> *).
(MonadParsec e s m, Token s ~ Char) =>
Token s -> m (Token s)
char Char
Token Text
'(' ParsecT Void Text Identity Char -> Parser () -> Parser ()
forall a b.
ParsecT Void Text Identity a
-> ParsecT Void Text Identity b -> ParsecT Void Text Identity b
forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> Parser ()
forall e s (m :: * -> *).
(MonadParsec e s m, Token s ~ Char) =>
m ()
space) (Token Text -> ParsecT Void Text Identity (Token Text)
forall e s (m :: * -> *).
(MonadParsec e s m, Token s ~ Char) =>
Token s -> m (Token s)
char Char
Token Text
')' ParsecT Void Text Identity Char -> Parser () -> Parser ()
forall a b.
ParsecT Void Text Identity a
-> ParsecT Void Text Identity b -> ParsecT Void Text Identity b
forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> Parser ()
forall e s (m :: * -> *).
(MonadParsec e s m, Token s ~ Char) =>
m ()
space) (ParsecT Void Text Identity Expression
varExpr)
                    case Maybe Expression
value of
                        Just (VarExpression Text
limit) -> do
                            let l :: Maybe Int
l = Text -> Maybe Int
textToInt Text
limit
                            case Maybe Int
l of
                                Maybe Int
Nothing -> String -> Parser PostgresType
forall a. String -> ParsecT Void Text Identity a
forall (m :: * -> *) a. MonadFail m => String -> m a
Prelude.fail String
"Failed to parse CHARACTER VARYING(..) expression"
                                Just Int
l -> PostgresType -> Parser PostgresType
forall a. a -> ParsecT Void Text Identity a
forall (f :: * -> *) a. Applicative f => a -> f a
pure (Maybe Int -> PostgresType
PVaryingN (Int -> Maybe Int
forall a. a -> Maybe a
Just Int
l))
                        Maybe Expression
Nothing -> PostgresType -> Parser PostgresType
forall a. a -> ParsecT Void Text Identity a
forall (f :: * -> *) a. Applicative f => a -> f a
pure (Maybe Int -> PostgresType
PVaryingN Maybe Int
forall a. Maybe a
Nothing)
                        Maybe Expression
_ -> String -> Parser PostgresType
forall a. String -> ParsecT Void Text Identity a
forall (m :: * -> *) a. MonadFail m => String -> m a
Prelude.fail String
"Failed to parse CHARACTER VARYING(..) expression"

                character :: Parser PostgresType
character = do
                    Parser Text -> Parser Text
forall a. Parser a -> Parser a
forall e s (m :: * -> *) a. MonadParsec e s m => m a -> m a
try (Text -> Parser Text
symbol' Text
"CHAR(") Parser Text -> Parser Text -> Parser Text
forall a.
ParsecT Void Text Identity a
-> ParsecT Void Text Identity a -> ParsecT Void Text Identity a
forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
<|> Parser Text -> Parser Text
forall a. Parser a -> Parser a
forall e s (m :: * -> *) a. MonadParsec e s m => m a -> m a
try (Text -> Parser Text
symbol' Text
"CHARACTER(")
                    Expression
value <- Parser ()
-> Parser ()
-> ParsecT Void Text Identity Expression
-> ParsecT Void Text Identity Expression
forall (m :: * -> *) open close a.
Applicative m =>
m open -> m close -> m a -> m a
between (Parser ()
forall e s (m :: * -> *).
(MonadParsec e s m, Token s ~ Char) =>
m ()
space) (Token Text -> ParsecT Void Text Identity (Token Text)
forall e s (m :: * -> *).
(MonadParsec e s m, Token s ~ Char) =>
Token s -> m (Token s)
char Char
Token Text
')' ParsecT Void Text Identity Char -> Parser () -> Parser ()
forall a b.
ParsecT Void Text Identity a
-> ParsecT Void Text Identity b -> ParsecT Void Text Identity b
forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> Parser ()
forall e s (m :: * -> *).
(MonadParsec e s m, Token s ~ Char) =>
m ()
space) (ParsecT Void Text Identity Expression
varExpr)
                    case Expression
value of
                        VarExpression Text
length -> do
                            let l :: Maybe Int
l = Text -> Maybe Int
textToInt Text
length
                            case Maybe Int
l of
                                Maybe Int
Nothing -> String -> Parser PostgresType
forall a. String -> ParsecT Void Text Identity a
forall (m :: * -> *) a. MonadFail m => String -> m a
Prelude.fail String
"Failed to parse CHARACTER VARYING(..) expression"
                                Just Int
l -> PostgresType -> Parser PostgresType
forall a. a -> ParsecT Void Text Identity a
forall (f :: * -> *) a. Applicative f => a -> f a
pure (Int -> PostgresType
PCharacterN Int
l)
                        Expression
_ -> String -> Parser PostgresType
forall a. String -> ParsecT Void Text Identity a
forall (m :: * -> *) a. MonadFail m => String -> m a
Prelude.fail String
"Failed to parse CHARACTER VARYING(..) expression"

                singleChar :: Parser PostgresType
singleChar = do
                    Parser Text -> Parser Text
forall a. Parser a -> Parser a
forall e s (m :: * -> *) a. MonadParsec e s m => m a -> m a
try (Text -> Parser Text
symbol Text
"\"char\"")
                    PostgresType -> Parser PostgresType
forall a. a -> ParsecT Void Text Identity a
forall (f :: * -> *) a. Applicative f => a -> f a
pure PostgresType
PSingleChar

                serial :: Parser PostgresType
serial = do
                    Parser Text -> Parser Text
forall a. Parser a -> Parser a
forall e s (m :: * -> *) a. MonadParsec e s m => m a -> m a
try (Text -> Parser Text
symbol' Text
"SERIAL")
                    PostgresType -> Parser PostgresType
forall a. a -> ParsecT Void Text Identity a
forall (f :: * -> *) a. Applicative f => a -> f a
pure PostgresType
PSerial

                bigserial :: Parser PostgresType
bigserial = do
                    Parser Text -> Parser Text
forall a. Parser a -> Parser a
forall e s (m :: * -> *) a. MonadParsec e s m => m a -> m a
try (Text -> Parser Text
symbol' Text
"BIGSERIAL")
                    PostgresType -> Parser PostgresType
forall a. a -> ParsecT Void Text Identity a
forall (f :: * -> *) a. Applicative f => a -> f a
pure PostgresType
PBigserial

                jsonb :: Parser PostgresType
jsonb = do
                    Parser Text -> Parser Text
forall a. Parser a -> Parser a
forall e s (m :: * -> *) a. MonadParsec e s m => m a -> m a
try (Text -> Parser Text
symbol' Text
"JSONB")
                    PostgresType -> Parser PostgresType
forall a. a -> ParsecT Void Text Identity a
forall (f :: * -> *) a. Applicative f => a -> f a
pure PostgresType
PJSONB

                inet :: Parser PostgresType
inet = do
                    Parser Text -> Parser Text
forall a. Parser a -> Parser a
forall e s (m :: * -> *) a. MonadParsec e s m => m a -> m a
try (Text -> Parser Text
symbol' Text
"INET")
                    PostgresType -> Parser PostgresType
forall a. a -> ParsecT Void Text Identity a
forall (f :: * -> *) a. Applicative f => a -> f a
pure PostgresType
PInet

                tsvector :: Parser PostgresType
tsvector = do
                    Parser Text -> Parser Text
forall a. Parser a -> Parser a
forall e s (m :: * -> *) a. MonadParsec e s m => m a -> m a
try (Text -> Parser Text
symbol' Text
"TSVECTOR")
                    PostgresType -> Parser PostgresType
forall a. a -> ParsecT Void Text Identity a
forall (f :: * -> *) a. Applicative f => a -> f a
pure PostgresType
PTSVector

                optionalArray :: Parser PostgresType -> Parser PostgresType
optionalArray Parser PostgresType
typeParser= do
                    PostgresType
arrayType <- Parser PostgresType
typeParser;
                    (Parser PostgresType -> Parser PostgresType
forall a. Parser a -> Parser a
forall e s (m :: * -> *) a. MonadParsec e s m => m a -> m a
try do Text -> Parser Text
symbol' Text
"[]"; PostgresType -> Parser PostgresType
forall a. a -> ParsecT Void Text Identity a
forall (f :: * -> *) a. Applicative f => a -> f a
pure (PostgresType -> Parser PostgresType)
-> PostgresType -> Parser PostgresType
forall a b. (a -> b) -> a -> b
$ PostgresType -> PostgresType
PArray PostgresType
arrayType) Parser PostgresType -> Parser PostgresType -> Parser PostgresType
forall a.
ParsecT Void Text Identity a
-> ParsecT Void Text Identity a -> ParsecT Void Text Identity a
forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
<|> PostgresType -> Parser PostgresType
forall a. a -> ParsecT Void Text Identity a
forall (f :: * -> *) a. Applicative f => a -> f a
pure PostgresType
arrayType

                trigger :: Parser PostgresType
trigger = do
                    Parser Text -> Parser Text
forall a. Parser a -> Parser a
forall e s (m :: * -> *) a. MonadParsec e s m => m a -> m a
try (Text -> Parser Text
symbol' Text
"TRIGGER")
                    PostgresType -> Parser PostgresType
forall a. a -> ParsecT Void Text Identity a
forall (f :: * -> *) a. Applicative f => a -> f a
pure PostgresType
PTrigger

                customType :: Parser PostgresType
customType = do
                    ParsecT Void Text Identity Char
-> ParsecT Void Text Identity (Maybe Char)
forall (f :: * -> *) a. Alternative f => f a -> f (Maybe a)
optional do
                        Parser Text -> Parser Text
forall a. Parser a -> Parser a
lexeme Parser Text
"public"
                        Token Text -> ParsecT Void Text Identity (Token Text)
forall e s (m :: * -> *).
(MonadParsec e s m, Token s ~ Char) =>
Token s -> m (Token s)
char Char
Token Text
'.'
                    Text
theType <- Parser Text -> Parser Text
forall a. Parser a -> Parser a
forall e s (m :: * -> *) a. MonadParsec e s m => m a -> m a
try (Maybe String
-> (Token Text -> Bool) -> ParsecT Void Text Identity (Tokens Text)
forall e s (m :: * -> *).
MonadParsec e s m =>
Maybe String -> (Token s -> Bool) -> m (Tokens s)
takeWhile1P (String -> Maybe String
forall a. a -> Maybe a
Just String
"Custom type") (\Token Text
c -> Char -> Bool
isAlphaNum Char
Token Text
c Bool -> Bool -> Bool
|| Char
Token Text
c Char -> Char -> Bool
forall a. Eq a => a -> a -> Bool
== Char
'_'))
                    PostgresType -> Parser PostgresType
forall a. a -> ParsecT Void Text Identity a
forall (f :: * -> *) a. Applicative f => a -> f a
pure (Text -> PostgresType
PCustomType Text
theType)


intervalFields :: [Text]
intervalFields :: [Text]
intervalFields =  [ Text
"YEAR TO MONTH", Text
"DAY TO HOUR", Text
"DAY TO MINUTE", Text
"DAY TO SECOND"
                   , Text
"HOUR TO MINUTE", Text
"HOUR TO SECOND", Text
"MINUTE TO SECOND"
                   , Text
"YEAR",  Text
"MONTH", Text
"DAY", Text
"HOUR", Text
"MINUTE", Text
"SECOND"]


term :: ParsecT Void Text Identity Expression
term = ParsecT Void Text Identity Expression
-> ParsecT Void Text Identity Expression
forall {s} {m :: * -> *} {e} {a}.
(Token s ~ Char, MonadParsec e s m) =>
m a -> m a
parens ParsecT Void Text Identity Expression
expression ParsecT Void Text Identity Expression
-> ParsecT Void Text Identity Expression
-> ParsecT Void Text Identity Expression
forall a.
ParsecT Void Text Identity a
-> ParsecT Void Text Identity a -> ParsecT Void Text Identity a
forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
<|> ParsecT Void Text Identity Expression
-> ParsecT Void Text Identity Expression
forall a. Parser a -> Parser a
forall e s (m :: * -> *) a. MonadParsec e s m => m a -> m a
try ParsecT Void Text Identity Expression
callExpr ParsecT Void Text Identity Expression
-> ParsecT Void Text Identity Expression
-> ParsecT Void Text Identity Expression
forall a.
ParsecT Void Text Identity a
-> ParsecT Void Text Identity a -> ParsecT Void Text Identity a
forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
<|> ParsecT Void Text Identity Expression
-> ParsecT Void Text Identity Expression
forall a. Parser a -> Parser a
forall e s (m :: * -> *) a. MonadParsec e s m => m a -> m a
try ParsecT Void Text Identity Expression
doubleExpr ParsecT Void Text Identity Expression
-> ParsecT Void Text Identity Expression
-> ParsecT Void Text Identity Expression
forall a.
ParsecT Void Text Identity a
-> ParsecT Void Text Identity a -> ParsecT Void Text Identity a
forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
<|> ParsecT Void Text Identity Expression
-> ParsecT Void Text Identity Expression
forall a. Parser a -> Parser a
forall e s (m :: * -> *) a. MonadParsec e s m => m a -> m a
try ParsecT Void Text Identity Expression
intExpr ParsecT Void Text Identity Expression
-> ParsecT Void Text Identity Expression
-> ParsecT Void Text Identity Expression
forall a.
ParsecT Void Text Identity a
-> ParsecT Void Text Identity a -> ParsecT Void Text Identity a
forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
<|> ParsecT Void Text Identity Expression
selectExpr ParsecT Void Text Identity Expression
-> ParsecT Void Text Identity Expression
-> ParsecT Void Text Identity Expression
forall a.
ParsecT Void Text Identity a
-> ParsecT Void Text Identity a -> ParsecT Void Text Identity a
forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
<|> ParsecT Void Text Identity Expression
varExpr ParsecT Void Text Identity Expression
-> ParsecT Void Text Identity Expression
-> ParsecT Void Text Identity Expression
forall a.
ParsecT Void Text Identity a
-> ParsecT Void Text Identity a -> ParsecT Void Text Identity a
forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
<|> (ParsecT Void Text Identity Expression
textExpr ParsecT Void Text Identity Expression
-> ParsecT Void Text Identity (Maybe ())
-> ParsecT Void Text Identity Expression
forall a b.
ParsecT Void Text Identity a
-> ParsecT Void Text Identity b -> ParsecT Void Text Identity a
forall (f :: * -> *) a b. Applicative f => f a -> f b -> f a
<* Parser () -> ParsecT Void Text Identity (Maybe ())
forall (f :: * -> *) a. Alternative f => f a -> f (Maybe a)
optional Parser ()
forall e s (m :: * -> *).
(MonadParsec e s m, Token s ~ Char) =>
m ()
space)
    where
        parens :: m a -> m a
parens m a
f = m () -> m () -> m a -> m a
forall (m :: * -> *) open close a.
Applicative m =>
m open -> m close -> m a -> m a
between (Token s -> m (Token s)
forall e s (m :: * -> *).
(MonadParsec e s m, Token s ~ Char) =>
Token s -> m (Token s)
char Char
Token s
'(' m Char -> m () -> m ()
forall a b. m a -> m b -> m b
forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> m ()
forall e s (m :: * -> *).
(MonadParsec e s m, Token s ~ Char) =>
m ()
space) (Token s -> m (Token s)
forall e s (m :: * -> *).
(MonadParsec e s m, Token s ~ Char) =>
Token s -> m (Token s)
char Char
Token s
')' m Char -> m () -> m ()
forall a b. m a -> m b -> m b
forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> m ()
forall e s (m :: * -> *).
(MonadParsec e s m, Token s ~ Char) =>
m ()
space) m a
f

table :: [[Operator (ParsecT Void Text Identity) Expression]]
table = [
            [ Text
-> (Expression -> Expression -> Expression)
-> Operator (ParsecT Void Text Identity) Expression
forall {a}.
Text -> (a -> a -> a) -> Operator (ParsecT Void Text Identity) a
binary  Text
"<>"  Expression -> Expression -> Expression
NotEqExpression
            , Text
-> (Expression -> Expression -> Expression)
-> Operator (ParsecT Void Text Identity) Expression
forall {a}.
Text -> (a -> a -> a) -> Operator (ParsecT Void Text Identity) a
binary Text
"="  Expression -> Expression -> Expression
EqExpression

            , Text
-> (Expression -> Expression -> Expression)
-> Operator (ParsecT Void Text Identity) Expression
forall {a}.
Text -> (a -> a -> a) -> Operator (ParsecT Void Text Identity) a
binary Text
"<=" Expression -> Expression -> Expression
LessThanOrEqualToExpression
            , Text
-> (Expression -> Expression -> Expression)
-> Operator (ParsecT Void Text Identity) Expression
forall {a}.
Text -> (a -> a -> a) -> Operator (ParsecT Void Text Identity) a
binary Text
"<"  Expression -> Expression -> Expression
LessThanExpression
            , Text
-> (Expression -> Expression -> Expression)
-> Operator (ParsecT Void Text Identity) Expression
forall {a}.
Text -> (a -> a -> a) -> Operator (ParsecT Void Text Identity) a
binary Text
">="  Expression -> Expression -> Expression
GreaterThanOrEqualToExpression
            , Text
-> (Expression -> Expression -> Expression)
-> Operator (ParsecT Void Text Identity) Expression
forall {a}.
Text -> (a -> a -> a) -> Operator (ParsecT Void Text Identity) a
binary Text
">"  Expression -> Expression -> Expression
GreaterThanExpression
            , Text
-> (Expression -> Expression -> Expression)
-> Operator (ParsecT Void Text Identity) Expression
forall {a}.
Text -> (a -> a -> a) -> Operator (ParsecT Void Text Identity) a
binary Text
"||" Expression -> Expression -> Expression
ConcatenationExpression

            , Text
-> (Expression -> Expression -> Expression)
-> Operator (ParsecT Void Text Identity) Expression
forall {a}.
Text -> (a -> a -> a) -> Operator (ParsecT Void Text Identity) a
binary Text
"IS" Expression -> Expression -> Expression
IsExpression
            , Text
-> (Expression -> Expression -> Expression)
-> Operator (ParsecT Void Text Identity) Expression
forall {a}.
Text -> (a -> a -> a) -> Operator (ParsecT Void Text Identity) a
binary Text
"IN" Expression -> Expression -> Expression
InExpression
            , Text
-> (Expression -> Expression)
-> Operator (ParsecT Void Text Identity) Expression
forall {a}.
Text -> (a -> a) -> Operator (ParsecT Void Text Identity) a
prefix Text
"NOT" Expression -> Expression
NotExpression
            , Text
-> (Expression -> Expression)
-> Operator (ParsecT Void Text Identity) Expression
forall {a}.
Text -> (a -> a) -> Operator (ParsecT Void Text Identity) a
prefix Text
"EXISTS" Expression -> Expression
ExistsExpression
            , Operator (ParsecT Void Text Identity) Expression
typeCast
            , Operator (ParsecT Void Text Identity) Expression
dot
            ],
            [ Text
-> (Expression -> Expression -> Expression)
-> Operator (ParsecT Void Text Identity) Expression
forall {a}.
Text -> (a -> a -> a) -> Operator (ParsecT Void Text Identity) a
binary Text
"AND" Expression -> Expression -> Expression
AndExpression, Text
-> (Expression -> Expression -> Expression)
-> Operator (ParsecT Void Text Identity) Expression
forall {a}.
Text -> (a -> a -> a) -> Operator (ParsecT Void Text Identity) a
binary Text
"OR" Expression -> Expression -> Expression
OrExpression ]
        ]
    where
        binary :: Text -> (a -> a -> a) -> Operator (ParsecT Void Text Identity) a
binary  Text
name a -> a -> a
f = ParsecT Void Text Identity (a -> a -> a)
-> Operator (ParsecT Void Text Identity) a
forall (m :: * -> *) a. m (a -> a -> a) -> Operator m a
InfixL  (a -> a -> a
f (a -> a -> a)
-> Parser Text -> ParsecT Void Text Identity (a -> a -> a)
forall a b.
a -> ParsecT Void Text Identity b -> ParsecT Void Text Identity a
forall (f :: * -> *) a b. Functor f => a -> f b -> f a
<$ Parser Text -> Parser Text
forall a. Parser a -> Parser a
forall e s (m :: * -> *) a. MonadParsec e s m => m a -> m a
try (Text -> Parser Text
symbol Text
name))
        prefix :: Text -> (a -> a) -> Operator (ParsecT Void Text Identity) a
prefix  Text
name a -> a
f = ParsecT Void Text Identity (a -> a)
-> Operator (ParsecT Void Text Identity) a
forall (m :: * -> *) a. m (a -> a) -> Operator m a
Prefix  (a -> a
f (a -> a) -> Parser Text -> ParsecT Void Text Identity (a -> a)
forall a b.
a -> ParsecT Void Text Identity b -> ParsecT Void Text Identity a
forall (f :: * -> *) a b. Functor f => a -> f b -> f a
<$ Text -> Parser Text
symbol Text
name)
        postfix :: Text -> (a -> a) -> Operator (ParsecT Void Text Identity) a
postfix Text
name a -> a
f = ParsecT Void Text Identity (a -> a)
-> Operator (ParsecT Void Text Identity) a
forall (m :: * -> *) a. m (a -> a) -> Operator m a
Postfix (a -> a
f (a -> a) -> Parser Text -> ParsecT Void Text Identity (a -> a)
forall a b.
a -> ParsecT Void Text Identity b -> ParsecT Void Text Identity a
forall (f :: * -> *) a b. Functor f => a -> f b -> f a
<$ Text -> Parser Text
symbol Text
name)

        -- Cannot be implemented as a infix operator as that requires two expression operands,
        -- but the second is the type-cast type which is not an expression
        typeCast :: Operator (ParsecT Void Text Identity) Expression
typeCast = ParsecT Void Text Identity (Expression -> Expression)
-> Operator (ParsecT Void Text Identity) Expression
forall (m :: * -> *) a. m (a -> a) -> Operator m a
Postfix do
            Text -> Parser Text
symbol Text
"::"
            PostgresType
castType <- Parser PostgresType
sqlType
            (Expression -> Expression)
-> ParsecT Void Text Identity (Expression -> Expression)
forall a. a -> ParsecT Void Text Identity a
forall (f :: * -> *) a. Applicative f => a -> f a
pure ((Expression -> Expression)
 -> ParsecT Void Text Identity (Expression -> Expression))
-> (Expression -> Expression)
-> ParsecT Void Text Identity (Expression -> Expression)
forall a b. (a -> b) -> a -> b
$ \Expression
expr -> Expression -> PostgresType -> Expression
TypeCastExpression Expression
expr PostgresType
castType

        dot :: Operator (ParsecT Void Text Identity) Expression
dot = ParsecT Void Text Identity (Expression -> Expression)
-> Operator (ParsecT Void Text Identity) Expression
forall (m :: * -> *) a. m (a -> a) -> Operator m a
Postfix do
            Token Text -> ParsecT Void Text Identity (Token Text)
forall e s (m :: * -> *).
(MonadParsec e s m, Token s ~ Char) =>
Token s -> m (Token s)
char Char
Token Text
'.'
            Text
name <- Parser Text
identifier
            (Expression -> Expression)
-> ParsecT Void Text Identity (Expression -> Expression)
forall a. a -> ParsecT Void Text Identity a
forall (f :: * -> *) a. Applicative f => a -> f a
pure ((Expression -> Expression)
 -> ParsecT Void Text Identity (Expression -> Expression))
-> (Expression -> Expression)
-> ParsecT Void Text Identity (Expression -> Expression)
forall a b. (a -> b) -> a -> b
$ \Expression
expr -> Expression -> Text -> Expression
DotExpression Expression
expr Text
name

-- | Parses a SQL expression
--
-- This parser makes use of makeExprParser as described in https://hackage.haskell.org/package/parser-combinators-1.2.0/docs/Control-Monad-Combinators-Expr.html
expression :: Parser Expression
expression :: ParsecT Void Text Identity Expression
expression = do
    Expression
e <- ParsecT Void Text Identity Expression
-> [[Operator (ParsecT Void Text Identity) Expression]]
-> ParsecT Void Text Identity Expression
forall (m :: * -> *) a.
MonadPlus m =>
m a -> [[Operator m a]] -> m a
makeExprParser ParsecT Void Text Identity Expression
term [[Operator (ParsecT Void Text Identity) Expression]]
table ParsecT Void Text Identity Expression
-> String -> ParsecT Void Text Identity Expression
forall e s (m :: * -> *) a.
MonadParsec e s m =>
m a -> String -> m a
<?> String
"expression"
    Parser ()
forall e s (m :: * -> *).
(MonadParsec e s m, Token s ~ Char) =>
m ()
space
    Expression -> ParsecT Void Text Identity Expression
forall a. a -> ParsecT Void Text Identity a
forall (f :: * -> *) a. Applicative f => a -> f a
pure Expression
e

varExpr :: Parser Expression
varExpr :: ParsecT Void Text Identity Expression
varExpr = Text -> Expression
VarExpression (Text -> Expression)
-> Parser Text -> ParsecT Void Text Identity Expression
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Parser Text
identifier

doubleExpr :: Parser Expression
doubleExpr :: ParsecT Void Text Identity Expression
doubleExpr = Double -> Expression
DoubleExpression (Double -> Expression)
-> ParsecT Void Text Identity Double
-> ParsecT Void Text Identity Expression
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> (Parser ()
-> ParsecT Void Text Identity Double
-> ParsecT Void Text Identity Double
forall e s (m :: * -> *) a.
(MonadParsec e s m, Token s ~ Char, Num a) =>
m () -> m a -> m a
Lexer.signed Parser ()
spaceConsumer ParsecT Void Text Identity Double
forall e s (m :: * -> *) a.
(MonadParsec e s m, Token s ~ Char, RealFloat a) =>
m a
Lexer.float)

intExpr :: Parser Expression
intExpr :: ParsecT Void Text Identity Expression
intExpr = Int -> Expression
IntExpression (Int -> Expression)
-> ParsecT Void Text Identity Int
-> ParsecT Void Text Identity Expression
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> (Parser ()
-> ParsecT Void Text Identity Int -> ParsecT Void Text Identity Int
forall e s (m :: * -> *) a.
(MonadParsec e s m, Token s ~ Char, Num a) =>
m () -> m a -> m a
Lexer.signed Parser ()
spaceConsumer ParsecT Void Text Identity Int
forall e s (m :: * -> *) a.
(MonadParsec e s m, Token s ~ Char, Num a) =>
m a
Lexer.decimal)

callExpr :: Parser Expression
callExpr :: ParsecT Void Text Identity Expression
callExpr = do
    Text
func <- Parser Text
qualifiedIdentifier
    [Expression]
args <- ParsecT Void Text Identity Char
-> ParsecT Void Text Identity Char
-> ParsecT Void Text Identity [Expression]
-> ParsecT Void Text Identity [Expression]
forall (m :: * -> *) open close a.
Applicative m =>
m open -> m close -> m a -> m a
between (Token Text -> ParsecT Void Text Identity (Token Text)
forall e s (m :: * -> *).
(MonadParsec e s m, Token s ~ Char) =>
Token s -> m (Token s)
char Char
Token Text
'(') (Token Text -> ParsecT Void Text Identity (Token Text)
forall e s (m :: * -> *).
(MonadParsec e s m, Token s ~ Char) =>
Token s -> m (Token s)
char Char
Token Text
')') (ParsecT Void Text Identity Expression
expression ParsecT Void Text Identity Expression
-> Parser () -> ParsecT Void Text Identity [Expression]
forall (m :: * -> *) a end. MonadPlus m => m a -> m end -> m [a]
`sepBy` (Token Text -> ParsecT Void Text Identity (Token Text)
forall e s (m :: * -> *).
(MonadParsec e s m, Token s ~ Char) =>
Token s -> m (Token s)
char Char
Token Text
',' ParsecT Void Text Identity Char -> Parser () -> Parser ()
forall a b.
ParsecT Void Text Identity a
-> ParsecT Void Text Identity b -> ParsecT Void Text Identity b
forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> Parser ()
forall e s (m :: * -> *).
(MonadParsec e s m, Token s ~ Char) =>
m ()
space))
    Parser ()
forall e s (m :: * -> *).
(MonadParsec e s m, Token s ~ Char) =>
m ()
space
    Expression -> ParsecT Void Text Identity Expression
forall a. a -> ParsecT Void Text Identity a
forall (f :: * -> *) a. Applicative f => a -> f a
pure (Text -> [Expression] -> Expression
CallExpression Text
func [Expression]
args)

textExpr :: Parser Expression
textExpr :: ParsecT Void Text Identity Expression
textExpr = Text -> Expression
TextExpression (Text -> Expression)
-> Parser Text -> ParsecT Void Text Identity Expression
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Parser Text
textExpr'

textExpr' :: Parser Text
textExpr' :: Parser Text
textExpr' = String -> Text
forall a b. ConvertibleStrings a b => a -> b
cs (String -> Text) -> Parser String -> Parser Text
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> do
    let emptyByteString :: Parser String
emptyByteString = do
            Tokens Text -> ParsecT Void Text Identity (Tokens Text)
forall e s (m :: * -> *).
MonadParsec e s m =>
Tokens s -> m (Tokens s)
string Tokens Text
"'\\x'"
            String -> Parser String
forall a. a -> ParsecT Void Text Identity a
forall (f :: * -> *) a. Applicative f => a -> f a
pure String
""
    (Parser String -> Parser String
forall a. Parser a -> Parser a
forall e s (m :: * -> *) a. MonadParsec e s m => m a -> m a
try (Token Text -> ParsecT Void Text Identity (Token Text)
forall e s (m :: * -> *).
(MonadParsec e s m, Token s ~ Char) =>
Token s -> m (Token s)
char Char
Token Text
'\'' ParsecT Void Text Identity Char -> Parser String -> Parser String
forall a b.
ParsecT Void Text Identity a
-> ParsecT Void Text Identity b -> ParsecT Void Text Identity b
forall (f :: * -> *) a b. Applicative f => f a -> f b -> f b
*> ParsecT Void Text Identity Char
-> ParsecT Void Text Identity Char -> Parser String
forall (m :: * -> *) a end. MonadPlus m => m a -> m end -> m [a]
manyTill ParsecT Void Text Identity Char
forall e s (m :: * -> *).
(MonadParsec e s m, Token s ~ Char) =>
m Char
Lexer.charLiteral (Token Text -> ParsecT Void Text Identity (Token Text)
forall e s (m :: * -> *).
(MonadParsec e s m, Token s ~ Char) =>
Token s -> m (Token s)
char Char
Token Text
'\''))) Parser String -> Parser String -> Parser String
forall a.
ParsecT Void Text Identity a
-> ParsecT Void Text Identity a -> ParsecT Void Text Identity a
forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
<|> Parser String
emptyByteString

selectExpr :: Parser Expression
selectExpr :: ParsecT Void Text Identity Expression
selectExpr = do
    Text -> Parser Text
symbol' Text
"SELECT"
    [Expression]
columns <- ParsecT Void Text Identity Expression
expression ParsecT Void Text Identity Expression
-> Parser () -> ParsecT Void Text Identity [Expression]
forall (m :: * -> *) a end. MonadPlus m => m a -> m end -> m [a]
`sepBy` (Token Text -> ParsecT Void Text Identity (Token Text)
forall e s (m :: * -> *).
(MonadParsec e s m, Token s ~ Char) =>
Token s -> m (Token s)
char Char
Token Text
',' ParsecT Void Text Identity Char -> Parser () -> Parser ()
forall a b.
ParsecT Void Text Identity a
-> ParsecT Void Text Identity b -> ParsecT Void Text Identity b
forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> Parser ()
forall e s (m :: * -> *).
(MonadParsec e s m, Token s ~ Char) =>
m ()
space)
    Text -> Parser Text
symbol' Text
"FROM"
    Expression
from <- ParsecT Void Text Identity Expression
expression


    let whereClause :: Maybe Text -> ParsecT Void Text Identity Expression
whereClause Maybe Text
alias = do
            Text -> Parser Text
symbol' Text
"WHERE"
            Expression
whereClause <- ParsecT Void Text Identity Expression
expression
            Expression -> ParsecT Void Text Identity Expression
forall a. a -> ParsecT Void Text Identity a
forall (f :: * -> *) a. Applicative f => a -> f a
pure (Select -> Expression
SelectExpression Select { [Expression]
Maybe Text
Expression
columns :: [Expression]
from :: Expression
alias :: Maybe Text
whereClause :: Expression
$sel:columns:Select :: [Expression]
$sel:from:Select :: Expression
$sel:alias:Select :: Maybe Text
$sel:whereClause:Select :: Expression
.. })

    let explicitAs :: ParsecT Void Text Identity Expression
explicitAs = do
            Text -> Parser Text
symbol' Text
"AS"
            Text
alias <- Parser Text
identifier
            Maybe Text -> ParsecT Void Text Identity Expression
whereClause (Text -> Maybe Text
forall a. a -> Maybe a
Just Text
alias)

    let implicitAs :: ParsecT Void Text Identity Expression
implicitAs = do
            Text
alias <- Parser Text
identifier
            Maybe Text -> ParsecT Void Text Identity Expression
whereClause (Text -> Maybe Text
forall a. a -> Maybe a
Just Text
alias)

    Maybe Text -> ParsecT Void Text Identity Expression
whereClause Maybe Text
forall a. Maybe a
Nothing ParsecT Void Text Identity Expression
-> ParsecT Void Text Identity Expression
-> ParsecT Void Text Identity Expression
forall a.
ParsecT Void Text Identity a
-> ParsecT Void Text Identity a -> ParsecT Void Text Identity a
forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
<|> ParsecT Void Text Identity Expression
explicitAs ParsecT Void Text Identity Expression
-> ParsecT Void Text Identity Expression
-> ParsecT Void Text Identity Expression
forall a.
ParsecT Void Text Identity a
-> ParsecT Void Text Identity a -> ParsecT Void Text Identity a
forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
<|> ParsecT Void Text Identity Expression
implicitAs





identifier :: Parser Text
identifier :: Parser Text
identifier = do
    Text
i <- (ParsecT Void Text Identity Char
-> ParsecT Void Text Identity Char -> Parser Text -> Parser Text
forall (m :: * -> *) open close a.
Applicative m =>
m open -> m close -> m a -> m a
between (Token Text -> ParsecT Void Text Identity (Token Text)
forall e s (m :: * -> *).
(MonadParsec e s m, Token s ~ Char) =>
Token s -> m (Token s)
char Char
Token Text
'"') (Token Text -> ParsecT Void Text Identity (Token Text)
forall e s (m :: * -> *).
(MonadParsec e s m, Token s ~ Char) =>
Token s -> m (Token s)
char Char
Token Text
'"') (Maybe String
-> (Token Text -> Bool) -> ParsecT Void Text Identity (Tokens Text)
forall e s (m :: * -> *).
MonadParsec e s m =>
Maybe String -> (Token s -> Bool) -> m (Tokens s)
takeWhile1P Maybe String
forall a. Maybe a
Nothing (\Token Text
c -> Char
Token Text
c Char -> Char -> Bool
forall a. Eq a => a -> a -> Bool
/= Char
'"'))) Parser Text -> Parser Text -> Parser Text
forall a.
ParsecT Void Text Identity a
-> ParsecT Void Text Identity a -> ParsecT Void Text Identity a
forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
<|> Maybe String
-> (Token Text -> Bool) -> ParsecT Void Text Identity (Tokens Text)
forall e s (m :: * -> *).
MonadParsec e s m =>
Maybe String -> (Token s -> Bool) -> m (Tokens s)
takeWhile1P (String -> Maybe String
forall a. a -> Maybe a
Just String
"identifier") (\Token Text
c -> Char -> Bool
isAlphaNum Char
Token Text
c Bool -> Bool -> Bool
|| Char
Token Text
c Char -> Char -> Bool
forall a. Eq a => a -> a -> Bool
== Char
'_')
    Parser ()
forall e s (m :: * -> *).
(MonadParsec e s m, Token s ~ Char) =>
m ()
space
    Text -> Parser Text
forall a. a -> ParsecT Void Text Identity a
forall (f :: * -> *) a. Applicative f => a -> f a
pure Text
i

comment :: ParsecT Void Text Identity Statement
comment = do
    (Token Text -> ParsecT Void Text Identity (Token Text)
forall e s (m :: * -> *).
(MonadParsec e s m, Token s ~ Char) =>
Token s -> m (Token s)
char Char
Token Text
'-' ParsecT Void Text Identity Char
-> ParsecT Void Text Identity Char
-> ParsecT Void Text Identity Char
forall a b.
ParsecT Void Text Identity a
-> ParsecT Void Text Identity b -> ParsecT Void Text Identity b
forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> Token Text -> ParsecT Void Text Identity (Token Text)
forall e s (m :: * -> *).
(MonadParsec e s m, Token s ~ Char) =>
Token s -> m (Token s)
char Char
Token Text
'-') ParsecT Void Text Identity Char
-> String -> ParsecT Void Text Identity Char
forall e s (m :: * -> *) a.
MonadParsec e s m =>
m a -> String -> m a
<?> String
"Line comment"
    Text
content <- Maybe String
-> (Token Text -> Bool) -> ParsecT Void Text Identity (Tokens Text)
forall e s (m :: * -> *).
MonadParsec e s m =>
Maybe String -> (Token s -> Bool) -> m (Tokens s)
takeWhileP Maybe String
forall a. Maybe a
Nothing (Token Text -> Token Text -> Bool
forall a. Eq a => a -> a -> Bool
/= Char
Token Text
'\n')
    Statement -> ParsecT Void Text Identity Statement
forall a. a -> ParsecT Void Text Identity a
forall (f :: * -> *) a. Applicative f => a -> f a
pure Comment { Text
content :: Text
$sel:content:StatementCreateTable :: Text
content }

createIndex :: ParsecT Void Text Identity Statement
createIndex = do
    Parser Text -> Parser Text
forall a. Parser a -> Parser a
lexeme Parser Text
"CREATE"
    Bool
unique <- Maybe Text -> Bool
forall a. Maybe a -> Bool
isJust (Maybe Text -> Bool)
-> ParsecT Void Text Identity (Maybe Text)
-> ParsecT Void Text Identity Bool
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Parser Text -> ParsecT Void Text Identity (Maybe Text)
forall (f :: * -> *) a. Alternative f => f a -> f (Maybe a)
optional (Parser Text -> Parser Text
forall a. Parser a -> Parser a
lexeme Parser Text
"UNIQUE")
    Parser Text -> Parser Text
forall a. Parser a -> Parser a
lexeme Parser Text
"INDEX"
    Text
indexName <- Parser Text
identifier
    Parser Text -> Parser Text
forall a. Parser a -> Parser a
lexeme Parser Text
"ON"
    Text
tableName <- Parser Text
qualifiedIdentifier
    Maybe IndexType
indexType <- ParsecT Void Text Identity IndexType
-> ParsecT Void Text Identity (Maybe IndexType)
forall (f :: * -> *) a. Alternative f => f a -> f (Maybe a)
optional ParsecT Void Text Identity IndexType
parseIndexType
    [IndexColumn]
columns <- Parser ()
-> Parser ()
-> ParsecT Void Text Identity [IndexColumn]
-> ParsecT Void Text Identity [IndexColumn]
forall (m :: * -> *) open close a.
Applicative m =>
m open -> m close -> m a -> m a
between (Token Text -> ParsecT Void Text Identity (Token Text)
forall e s (m :: * -> *).
(MonadParsec e s m, Token s ~ Char) =>
Token s -> m (Token s)
char Char
Token Text
'(' ParsecT Void Text Identity Char -> Parser () -> Parser ()
forall a b.
ParsecT Void Text Identity a
-> ParsecT Void Text Identity b -> ParsecT Void Text Identity b
forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> Parser ()
forall e s (m :: * -> *).
(MonadParsec e s m, Token s ~ Char) =>
m ()
space) (Token Text -> ParsecT Void Text Identity (Token Text)
forall e s (m :: * -> *).
(MonadParsec e s m, Token s ~ Char) =>
Token s -> m (Token s)
char Char
Token Text
')' ParsecT Void Text Identity Char -> Parser () -> Parser ()
forall a b.
ParsecT Void Text Identity a
-> ParsecT Void Text Identity b -> ParsecT Void Text Identity b
forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> Parser ()
forall e s (m :: * -> *).
(MonadParsec e s m, Token s ~ Char) =>
m ()
space) ParsecT Void Text Identity [IndexColumn]
parseIndexColumns
    Maybe Expression
whereClause <- ParsecT Void Text Identity Expression
-> ParsecT Void Text Identity (Maybe Expression)
forall (f :: * -> *) a. Alternative f => f a -> f (Maybe a)
optional do
        Parser Text -> Parser Text
forall a. Parser a -> Parser a
lexeme Parser Text
"WHERE"
        ParsecT Void Text Identity Expression
expression
    Token Text -> ParsecT Void Text Identity (Token Text)
forall e s (m :: * -> *).
(MonadParsec e s m, Token s ~ Char) =>
Token s -> m (Token s)
char Char
Token Text
';'
    Statement -> ParsecT Void Text Identity Statement
forall a. a -> ParsecT Void Text Identity a
forall (f :: * -> *) a. Applicative f => a -> f a
pure CreateIndex { Text
indexName :: Text
$sel:indexName:StatementCreateTable :: Text
indexName, Bool
unique :: Bool
$sel:unique:StatementCreateTable :: Bool
unique, Text
$sel:tableName:StatementCreateTable :: Text
tableName :: Text
tableName, [IndexColumn]
columns :: [IndexColumn]
$sel:columns:StatementCreateTable :: [IndexColumn]
columns, Maybe Expression
whereClause :: Maybe Expression
$sel:whereClause:StatementCreateTable :: Maybe Expression
whereClause, Maybe IndexType
indexType :: Maybe IndexType
$sel:indexType:StatementCreateTable :: Maybe IndexType
indexType }

parseIndexColumns :: ParsecT Void Text Identity [IndexColumn]
parseIndexColumns = ParsecT Void Text Identity IndexColumn
parseIndexColumn ParsecT Void Text Identity IndexColumn
-> Parser () -> ParsecT Void Text Identity [IndexColumn]
forall (m :: * -> *) a end. MonadPlus m => m a -> m end -> m [a]
`sepBy` (Token Text -> ParsecT Void Text Identity (Token Text)
forall e s (m :: * -> *).
(MonadParsec e s m, Token s ~ Char) =>
Token s -> m (Token s)
char Char
Token Text
',' ParsecT Void Text Identity Char -> Parser () -> Parser ()
forall a b.
ParsecT Void Text Identity a
-> ParsecT Void Text Identity b -> ParsecT Void Text Identity b
forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> Parser ()
forall e s (m :: * -> *).
(MonadParsec e s m, Token s ~ Char) =>
m ()
space)

parseIndexColumn :: ParsecT Void Text Identity IndexColumn
parseIndexColumn = do
    Expression
column <- ParsecT Void Text Identity Expression
expression
    Maybe IndexColumnOrder
orderOption1 <- ParsecT Void Text Identity IndexColumnOrder
-> ParsecT Void Text Identity (Maybe IndexColumnOrder)
forall (f :: * -> *) a. Alternative f => f a -> f (Maybe a)
optional (ParsecT Void Text Identity IndexColumnOrder
 -> ParsecT Void Text Identity (Maybe IndexColumnOrder))
-> ParsecT Void Text Identity IndexColumnOrder
-> ParsecT Void Text Identity (Maybe IndexColumnOrder)
forall a b. (a -> b) -> a -> b
$ Parser ()
forall e s (m :: * -> *).
(MonadParsec e s m, Token s ~ Char) =>
m ()
space Parser () -> Parser Text -> Parser Text
forall a b.
ParsecT Void Text Identity a
-> ParsecT Void Text Identity b -> ParsecT Void Text Identity b
forall (f :: * -> *) a b. Applicative f => f a -> f b -> f b
*> Parser Text -> Parser Text
forall a. Parser a -> Parser a
lexeme Parser Text
"ASC" Parser Text
-> IndexColumnOrder -> ParsecT Void Text Identity IndexColumnOrder
forall (f :: * -> *) a b. Functor f => f a -> b -> f b
$> IndexColumnOrder
Asc ParsecT Void Text Identity IndexColumnOrder
-> ParsecT Void Text Identity IndexColumnOrder
-> ParsecT Void Text Identity IndexColumnOrder
forall a.
ParsecT Void Text Identity a
-> ParsecT Void Text Identity a -> ParsecT Void Text Identity a
forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
<|> Parser ()
forall e s (m :: * -> *).
(MonadParsec e s m, Token s ~ Char) =>
m ()
space Parser () -> Parser Text -> Parser Text
forall a b.
ParsecT Void Text Identity a
-> ParsecT Void Text Identity b -> ParsecT Void Text Identity b
forall (f :: * -> *) a b. Applicative f => f a -> f b -> f b
*> Parser Text -> Parser Text
forall a. Parser a -> Parser a
lexeme Parser Text
"DESC" Parser Text
-> IndexColumnOrder -> ParsecT Void Text Identity IndexColumnOrder
forall (f :: * -> *) a b. Functor f => f a -> b -> f b
$> IndexColumnOrder
Desc
    Maybe IndexColumnOrder
orderOption2 <- ParsecT Void Text Identity IndexColumnOrder
-> ParsecT Void Text Identity (Maybe IndexColumnOrder)
forall (f :: * -> *) a. Alternative f => f a -> f (Maybe a)
optional (ParsecT Void Text Identity IndexColumnOrder
 -> ParsecT Void Text Identity (Maybe IndexColumnOrder))
-> ParsecT Void Text Identity IndexColumnOrder
-> ParsecT Void Text Identity (Maybe IndexColumnOrder)
forall a b. (a -> b) -> a -> b
$ Parser ()
forall e s (m :: * -> *).
(MonadParsec e s m, Token s ~ Char) =>
m ()
space Parser () -> Parser Text -> Parser Text
forall a b.
ParsecT Void Text Identity a
-> ParsecT Void Text Identity b -> ParsecT Void Text Identity b
forall (f :: * -> *) a b. Applicative f => f a -> f b -> f b
*> Parser Text -> Parser Text
forall a. Parser a -> Parser a
lexeme Parser Text
"NULLS FIRST" Parser Text
-> IndexColumnOrder -> ParsecT Void Text Identity IndexColumnOrder
forall (f :: * -> *) a b. Functor f => f a -> b -> f b
$> IndexColumnOrder
NullsFirst ParsecT Void Text Identity IndexColumnOrder
-> ParsecT Void Text Identity IndexColumnOrder
-> ParsecT Void Text Identity IndexColumnOrder
forall a.
ParsecT Void Text Identity a
-> ParsecT Void Text Identity a -> ParsecT Void Text Identity a
forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
<|> Parser ()
forall e s (m :: * -> *).
(MonadParsec e s m, Token s ~ Char) =>
m ()
space Parser () -> Parser Text -> Parser Text
forall a b.
ParsecT Void Text Identity a
-> ParsecT Void Text Identity b -> ParsecT Void Text Identity b
forall (f :: * -> *) a b. Applicative f => f a -> f b -> f b
*> Parser Text -> Parser Text
forall a. Parser a -> Parser a
lexeme Parser Text
"NULLS LAST" Parser Text
-> IndexColumnOrder -> ParsecT Void Text Identity IndexColumnOrder
forall (f :: * -> *) a b. Functor f => f a -> b -> f b
$> IndexColumnOrder
NullsLast
    IndexColumn -> ParsecT Void Text Identity IndexColumn
forall a. a -> ParsecT Void Text Identity a
forall (f :: * -> *) a. Applicative f => a -> f a
pure IndexColumn { Expression
column :: Expression
$sel:column:IndexColumn :: Expression
column, $sel:columnOrder:IndexColumn :: [IndexColumnOrder]
columnOrder = [Maybe IndexColumnOrder] -> [IndexColumnOrder]
forall a. [Maybe a] -> [a]
catMaybes [Maybe IndexColumnOrder
orderOption1, Maybe IndexColumnOrder
orderOption2] }

parseIndexType :: ParsecT Void Text Identity IndexType
parseIndexType = do
    Parser Text -> Parser Text
forall a. Parser a -> Parser a
lexeme Parser Text
"USING"

    [ParsecT Void Text Identity IndexType]
-> ParsecT Void Text Identity IndexType
forall (f :: * -> *) (m :: * -> *) a.
(Foldable f, Alternative m) =>
f (m a) -> m a
choice ([ParsecT Void Text Identity IndexType]
 -> ParsecT Void Text Identity IndexType)
-> [ParsecT Void Text Identity IndexType]
-> ParsecT Void Text Identity IndexType
forall a b. (a -> b) -> a -> b
$ ((Text, IndexType) -> ParsecT Void Text Identity IndexType)
-> [(Text, IndexType)] -> [ParsecT Void Text Identity IndexType]
forall a b. (a -> b) -> [a] -> [b]
map (\(Text
s, IndexType
v) -> do Text -> Parser Text
symbol' Text
s; IndexType -> ParsecT Void Text Identity IndexType
forall a. a -> ParsecT Void Text Identity a
forall (f :: * -> *) a. Applicative f => a -> f a
pure IndexType
v)
        [ (Text
"btree", IndexType
Btree)
        , (Text
"gin", IndexType
Gin)
        , (Text
"gist", IndexType
Gist)
        ]

createFunction :: ParsecT Void Text Identity Statement
createFunction = do
    Parser Text -> Parser Text
forall a. Parser a -> Parser a
lexeme Parser Text
"CREATE"
    Bool
orReplace <- Maybe Text -> Bool
forall a. Maybe a -> Bool
isJust (Maybe Text -> Bool)
-> ParsecT Void Text Identity (Maybe Text)
-> ParsecT Void Text Identity Bool
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Parser Text -> ParsecT Void Text Identity (Maybe Text)
forall (f :: * -> *) a. Alternative f => f a -> f (Maybe a)
optional (Parser Text -> Parser Text
forall a. Parser a -> Parser a
lexeme Parser Text
"OR" Parser Text -> Parser Text -> Parser Text
forall a b.
ParsecT Void Text Identity a
-> ParsecT Void Text Identity b -> ParsecT Void Text Identity b
forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> Parser Text -> Parser Text
forall a. Parser a -> Parser a
lexeme Parser Text
"REPLACE")
    Parser Text -> Parser Text
forall a. Parser a -> Parser a
lexeme Parser Text
"FUNCTION"
    Text
functionName <- Parser Text
qualifiedIdentifier
    [(Text, PostgresType)]
functionArguments <- ParsecT Void Text Identity Char
-> ParsecT Void Text Identity Char
-> ParsecT Void Text Identity [(Text, PostgresType)]
-> ParsecT Void Text Identity [(Text, PostgresType)]
forall (m :: * -> *) open close a.
Applicative m =>
m open -> m close -> m a -> m a
between (Token Text -> ParsecT Void Text Identity (Token Text)
forall e s (m :: * -> *).
(MonadParsec e s m, Token s ~ Char) =>
Token s -> m (Token s)
char Char
Token Text
'(') (Token Text -> ParsecT Void Text Identity (Token Text)
forall e s (m :: * -> *).
(MonadParsec e s m, Token s ~ Char) =>
Token s -> m (Token s)
char Char
Token Text
')') (ParsecT Void Text Identity (Text, PostgresType)
functionArgument ParsecT Void Text Identity (Text, PostgresType)
-> Parser () -> ParsecT Void Text Identity [(Text, PostgresType)]
forall (m :: * -> *) a end. MonadPlus m => m a -> m end -> m [a]
`sepBy` (Token Text -> ParsecT Void Text Identity (Token Text)
forall e s (m :: * -> *).
(MonadParsec e s m, Token s ~ Char) =>
Token s -> m (Token s)
char Char
Token Text
',' ParsecT Void Text Identity Char -> Parser () -> Parser ()
forall a b.
ParsecT Void Text Identity a
-> ParsecT Void Text Identity b -> ParsecT Void Text Identity b
forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> Parser ()
forall e s (m :: * -> *).
(MonadParsec e s m, Token s ~ Char) =>
m ()
space))
    Parser ()
forall e s (m :: * -> *).
(MonadParsec e s m, Token s ~ Char) =>
m ()
space
    Parser Text -> Parser Text
forall a. Parser a -> Parser a
lexeme Parser Text
"RETURNS"
    PostgresType
returns <- Parser PostgresType
sqlType

    Maybe Text
language <- Parser Text -> ParsecT Void Text Identity (Maybe Text)
forall (f :: * -> *) a. Alternative f => f a -> f (Maybe a)
optional do
        Parser Text -> Parser Text
forall a. Parser a -> Parser a
lexeme Parser Text
"language" Parser Text -> Parser Text -> Parser Text
forall a.
ParsecT Void Text Identity a
-> ParsecT Void Text Identity a -> ParsecT Void Text Identity a
forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
<|> Parser Text -> Parser Text
forall a. Parser a -> Parser a
lexeme Parser Text
"LANGUAGE"
        Text -> Parser Text
symbol' Text
"plpgsql" Parser Text -> Parser Text -> Parser Text
forall a.
ParsecT Void Text Identity a
-> ParsecT Void Text Identity a -> ParsecT Void Text Identity a
forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
<|> Text -> Parser Text
symbol' Text
"SQL"

    Parser Text -> Parser Text
forall a. Parser a -> Parser a
lexeme Parser Text
"AS"
    Parser ()
forall e s (m :: * -> *).
(MonadParsec e s m, Token s ~ Char) =>
m ()
space
    Text
functionBody <- [Token Text] -> Text
forall a b. ConvertibleStrings a b => a -> b
cs ([Token Text] -> Text)
-> ParsecT Void Text Identity [Token Text] -> Parser Text
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> ParsecT Void Text Identity Char
-> ParsecT Void Text Identity Char
-> ParsecT Void Text Identity [Token Text]
-> ParsecT Void Text Identity [Token Text]
forall (m :: * -> *) open close a.
Applicative m =>
m open -> m close -> m a -> m a
between (Token Text -> ParsecT Void Text Identity (Token Text)
forall e s (m :: * -> *).
(MonadParsec e s m, Token s ~ Char) =>
Token s -> m (Token s)
char Char
Token Text
'$' ParsecT Void Text Identity Char
-> ParsecT Void Text Identity Char
-> ParsecT Void Text Identity Char
forall a b.
ParsecT Void Text Identity a
-> ParsecT Void Text Identity b -> ParsecT Void Text Identity b
forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> Token Text -> ParsecT Void Text Identity (Token Text)
forall e s (m :: * -> *).
(MonadParsec e s m, Token s ~ Char) =>
Token s -> m (Token s)
char Char
Token Text
'$') (Token Text -> ParsecT Void Text Identity (Token Text)
forall e s (m :: * -> *).
(MonadParsec e s m, Token s ~ Char) =>
Token s -> m (Token s)
char Char
Token Text
'$' ParsecT Void Text Identity Char
-> ParsecT Void Text Identity Char
-> ParsecT Void Text Identity Char
forall a b.
ParsecT Void Text Identity a
-> ParsecT Void Text Identity b -> ParsecT Void Text Identity b
forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> Token Text -> ParsecT Void Text Identity (Token Text)
forall e s (m :: * -> *).
(MonadParsec e s m, Token s ~ Char) =>
Token s -> m (Token s)
char Char
Token Text
'$') (ParsecT Void Text Identity (Token Text)
-> ParsecT Void Text Identity [Token Text]
forall (m :: * -> *) a. MonadPlus m => m a -> m [a]
many (Token Text -> ParsecT Void Text Identity (Token Text)
forall e s (m :: * -> *).
MonadParsec e s m =>
Token s -> m (Token s)
anySingleBut Char
Token Text
'$'))
    Parser ()
forall e s (m :: * -> *).
(MonadParsec e s m, Token s ~ Char) =>
m ()
space

    Text
language <- case Maybe Text
language of
        Just Text
language -> Text -> Parser Text
forall a. a -> ParsecT Void Text Identity a
forall (f :: * -> *) a. Applicative f => a -> f a
pure Text
language
        Maybe Text
Nothing -> do
            Parser Text -> Parser Text
forall a. Parser a -> Parser a
lexeme Parser Text
"language" Parser Text -> Parser Text -> Parser Text
forall a.
ParsecT Void Text Identity a
-> ParsecT Void Text Identity a -> ParsecT Void Text Identity a
forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
<|> Parser Text -> Parser Text
forall a. Parser a -> Parser a
lexeme Parser Text
"LANGUAGE"
            Text -> Parser Text
symbol' Text
"plpgsql" Parser Text -> Parser Text -> Parser Text
forall a.
ParsecT Void Text Identity a
-> ParsecT Void Text Identity a -> ParsecT Void Text Identity a
forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
<|> Text -> Parser Text
symbol' Text
"SQL"
    Token Text -> ParsecT Void Text Identity (Token Text)
forall e s (m :: * -> *).
(MonadParsec e s m, Token s ~ Char) =>
Token s -> m (Token s)
char Char
Token Text
';'
    Statement -> ParsecT Void Text Identity Statement
forall a. a -> ParsecT Void Text Identity a
forall (f :: * -> *) a. Applicative f => a -> f a
pure CreateFunction { Text
functionName :: Text
$sel:functionName:StatementCreateTable :: Text
functionName, [(Text, PostgresType)]
functionArguments :: [(Text, PostgresType)]
$sel:functionArguments:StatementCreateTable :: [(Text, PostgresType)]
functionArguments, Text
functionBody :: Text
$sel:functionBody:StatementCreateTable :: Text
functionBody, Bool
orReplace :: Bool
$sel:orReplace:StatementCreateTable :: Bool
orReplace, PostgresType
returns :: PostgresType
$sel:returns:StatementCreateTable :: PostgresType
returns, Text
language :: Text
$sel:language:StatementCreateTable :: Text
language }
    where
        functionArgument :: ParsecT Void Text Identity (Text, PostgresType)
functionArgument = do
            Text
argumentName <- Parser Text
qualifiedIdentifier
            Parser ()
forall e s (m :: * -> *).
(MonadParsec e s m, Token s ~ Char) =>
m ()
space
            PostgresType
argumentType <- Parser PostgresType
sqlType
            (Text, PostgresType)
-> ParsecT Void Text Identity (Text, PostgresType)
forall a. a -> ParsecT Void Text Identity a
forall (f :: * -> *) a. Applicative f => a -> f a
pure (Text
argumentName, PostgresType
argumentType)

createTrigger :: ParsecT Void Text Identity Statement
createTrigger = do
    Parser Text -> Parser Text
forall a. Parser a -> Parser a
lexeme Parser Text
"CREATE"
    Parser Text -> Parser Text
forall a. Parser a -> Parser a
lexeme Parser Text
"TRIGGER"

    Text
name <- Parser Text
qualifiedIdentifier
    TriggerEventWhen
eventWhen <- (Parser Text -> Parser Text
forall a. Parser a -> Parser a
lexeme Parser Text
"AFTER" Parser Text
-> ParsecT Void Text Identity TriggerEventWhen
-> ParsecT Void Text Identity TriggerEventWhen
forall a b.
ParsecT Void Text Identity a
-> ParsecT Void Text Identity b -> ParsecT Void Text Identity b
forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> TriggerEventWhen -> ParsecT Void Text Identity TriggerEventWhen
forall a. a -> ParsecT Void Text Identity a
forall (f :: * -> *) a. Applicative f => a -> f a
pure TriggerEventWhen
After) ParsecT Void Text Identity TriggerEventWhen
-> ParsecT Void Text Identity TriggerEventWhen
-> ParsecT Void Text Identity TriggerEventWhen
forall a.
ParsecT Void Text Identity a
-> ParsecT Void Text Identity a -> ParsecT Void Text Identity a
forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
<|> (Parser Text -> Parser Text
forall a. Parser a -> Parser a
lexeme Parser Text
"BEFORE" Parser Text
-> ParsecT Void Text Identity TriggerEventWhen
-> ParsecT Void Text Identity TriggerEventWhen
forall a b.
ParsecT Void Text Identity a
-> ParsecT Void Text Identity b -> ParsecT Void Text Identity b
forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> TriggerEventWhen -> ParsecT Void Text Identity TriggerEventWhen
forall a. a -> ParsecT Void Text Identity a
forall (f :: * -> *) a. Applicative f => a -> f a
pure TriggerEventWhen
Before) ParsecT Void Text Identity TriggerEventWhen
-> ParsecT Void Text Identity TriggerEventWhen
-> ParsecT Void Text Identity TriggerEventWhen
forall a.
ParsecT Void Text Identity a
-> ParsecT Void Text Identity a -> ParsecT Void Text Identity a
forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
<|> (Parser Text -> Parser Text
forall a. Parser a -> Parser a
lexeme Parser Text
"INSTEAD OF" Parser Text
-> ParsecT Void Text Identity TriggerEventWhen
-> ParsecT Void Text Identity TriggerEventWhen
forall a b.
ParsecT Void Text Identity a
-> ParsecT Void Text Identity b -> ParsecT Void Text Identity b
forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> TriggerEventWhen -> ParsecT Void Text Identity TriggerEventWhen
forall a. a -> ParsecT Void Text Identity a
forall (f :: * -> *) a. Applicative f => a -> f a
pure TriggerEventWhen
InsteadOf)
    TriggerEvent
event <- (Parser Text -> Parser Text
forall a. Parser a -> Parser a
lexeme Parser Text
"INSERT" Parser Text
-> ParsecT Void Text Identity TriggerEvent
-> ParsecT Void Text Identity TriggerEvent
forall a b.
ParsecT Void Text Identity a
-> ParsecT Void Text Identity b -> ParsecT Void Text Identity b
forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> TriggerEvent -> ParsecT Void Text Identity TriggerEvent
forall a. a -> ParsecT Void Text Identity a
forall (f :: * -> *) a. Applicative f => a -> f a
pure TriggerEvent
TriggerOnInsert) ParsecT Void Text Identity TriggerEvent
-> ParsecT Void Text Identity TriggerEvent
-> ParsecT Void Text Identity TriggerEvent
forall a.
ParsecT Void Text Identity a
-> ParsecT Void Text Identity a -> ParsecT Void Text Identity a
forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
<|> (Parser Text -> Parser Text
forall a. Parser a -> Parser a
lexeme Parser Text
"UPDATE" Parser Text
-> ParsecT Void Text Identity TriggerEvent
-> ParsecT Void Text Identity TriggerEvent
forall a b.
ParsecT Void Text Identity a
-> ParsecT Void Text Identity b -> ParsecT Void Text Identity b
forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> TriggerEvent -> ParsecT Void Text Identity TriggerEvent
forall a. a -> ParsecT Void Text Identity a
forall (f :: * -> *) a. Applicative f => a -> f a
pure TriggerEvent
TriggerOnUpdate) ParsecT Void Text Identity TriggerEvent
-> ParsecT Void Text Identity TriggerEvent
-> ParsecT Void Text Identity TriggerEvent
forall a.
ParsecT Void Text Identity a
-> ParsecT Void Text Identity a -> ParsecT Void Text Identity a
forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
<|> (Parser Text -> Parser Text
forall a. Parser a -> Parser a
lexeme Parser Text
"DELETE" Parser Text
-> ParsecT Void Text Identity TriggerEvent
-> ParsecT Void Text Identity TriggerEvent
forall a b.
ParsecT Void Text Identity a
-> ParsecT Void Text Identity b -> ParsecT Void Text Identity b
forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> TriggerEvent -> ParsecT Void Text Identity TriggerEvent
forall a. a -> ParsecT Void Text Identity a
forall (f :: * -> *) a. Applicative f => a -> f a
pure TriggerEvent
TriggerOnDelete) ParsecT Void Text Identity TriggerEvent
-> ParsecT Void Text Identity TriggerEvent
-> ParsecT Void Text Identity TriggerEvent
forall a.
ParsecT Void Text Identity a
-> ParsecT Void Text Identity a -> ParsecT Void Text Identity a
forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
<|> (Parser Text -> Parser Text
forall a. Parser a -> Parser a
lexeme Parser Text
"TRUNCATE" Parser Text
-> ParsecT Void Text Identity TriggerEvent
-> ParsecT Void Text Identity TriggerEvent
forall a b.
ParsecT Void Text Identity a
-> ParsecT Void Text Identity b -> ParsecT Void Text Identity b
forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> TriggerEvent -> ParsecT Void Text Identity TriggerEvent
forall a. a -> ParsecT Void Text Identity a
forall (f :: * -> *) a. Applicative f => a -> f a
pure TriggerEvent
TriggerOnTruncate)

    Parser Text -> Parser Text
forall a. Parser a -> Parser a
lexeme Parser Text
"ON"
    Text
tableName <- Parser Text
qualifiedIdentifier

    Parser Text -> Parser Text
forall a. Parser a -> Parser a
lexeme Parser Text
"FOR"
    Parser Text -> ParsecT Void Text Identity (Maybe Text)
forall (f :: * -> *) a. Alternative f => f a -> f (Maybe a)
optional (Parser Text -> Parser Text
forall a. Parser a -> Parser a
lexeme Parser Text
"EACH")

    TriggerFor
for <- (Parser Text -> Parser Text
forall a. Parser a -> Parser a
lexeme Parser Text
"ROW" Parser Text
-> ParsecT Void Text Identity TriggerFor
-> ParsecT Void Text Identity TriggerFor
forall a b.
ParsecT Void Text Identity a
-> ParsecT Void Text Identity b -> ParsecT Void Text Identity b
forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> TriggerFor -> ParsecT Void Text Identity TriggerFor
forall a. a -> ParsecT Void Text Identity a
forall (f :: * -> *) a. Applicative f => a -> f a
pure TriggerFor
ForEachRow) ParsecT Void Text Identity TriggerFor
-> ParsecT Void Text Identity TriggerFor
-> ParsecT Void Text Identity TriggerFor
forall a.
ParsecT Void Text Identity a
-> ParsecT Void Text Identity a -> ParsecT Void Text Identity a
forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
<|> (Parser Text -> Parser Text
forall a. Parser a -> Parser a
lexeme Parser Text
"STATEMENT" Parser Text
-> ParsecT Void Text Identity TriggerFor
-> ParsecT Void Text Identity TriggerFor
forall a b.
ParsecT Void Text Identity a
-> ParsecT Void Text Identity b -> ParsecT Void Text Identity b
forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> TriggerFor -> ParsecT Void Text Identity TriggerFor
forall a. a -> ParsecT Void Text Identity a
forall (f :: * -> *) a. Applicative f => a -> f a
pure TriggerFor
ForEachStatement)

    Maybe Expression
whenCondition <- ParsecT Void Text Identity Expression
-> ParsecT Void Text Identity (Maybe Expression)
forall (f :: * -> *) a. Alternative f => f a -> f (Maybe a)
optional do
        Parser Text -> Parser Text
forall a. Parser a -> Parser a
lexeme Parser Text
"WHEN"
        ParsecT Void Text Identity Expression
expression

    Parser Text -> Parser Text
forall a. Parser a -> Parser a
lexeme Parser Text
"EXECUTE"
    Parser Text -> ParsecT Void Text Identity (Maybe Text)
forall (f :: * -> *) a. Alternative f => f a -> f (Maybe a)
optional (Parser Text -> Parser Text
forall a. Parser a -> Parser a
lexeme Parser Text
"FUNCTION" Parser Text -> Parser Text -> Parser Text
forall a.
ParsecT Void Text Identity a
-> ParsecT Void Text Identity a -> ParsecT Void Text Identity a
forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
<|> Parser Text -> Parser Text
forall a. Parser a -> Parser a
lexeme Parser Text
"PROCEDURE")

    (CallExpression Text
functionName [Expression]
arguments) <- ParsecT Void Text Identity Expression
callExpr

    Token Text -> ParsecT Void Text Identity (Token Text)
forall e s (m :: * -> *).
(MonadParsec e s m, Token s ~ Char) =>
Token s -> m (Token s)
char Char
Token Text
';'

    Statement -> ParsecT Void Text Identity Statement
forall a. a -> ParsecT Void Text Identity a
forall (f :: * -> *) a. Applicative f => a -> f a
pure CreateTrigger
        { Text
$sel:name:StatementCreateTable :: Text
name :: Text
name
        , TriggerEventWhen
eventWhen :: TriggerEventWhen
$sel:eventWhen:StatementCreateTable :: TriggerEventWhen
eventWhen
        , TriggerEvent
event :: TriggerEvent
$sel:event:StatementCreateTable :: TriggerEvent
event
        , Text
$sel:tableName:StatementCreateTable :: Text
tableName :: Text
tableName
        , TriggerFor
for :: TriggerFor
$sel:for:StatementCreateTable :: TriggerFor
for
        , Maybe Expression
whenCondition :: Maybe Expression
$sel:whenCondition:StatementCreateTable :: Maybe Expression
whenCondition
        , Text
$sel:functionName:StatementCreateTable :: Text
functionName :: Text
functionName
        , [Expression]
arguments :: [Expression]
$sel:arguments:StatementCreateTable :: [Expression]
arguments
        }

alterTable :: ParsecT Void Text Identity Statement
alterTable = do
    Parser Text -> Parser Text
forall a. Parser a -> Parser a
lexeme Parser Text
"TABLE"
    Parser Text -> ParsecT Void Text Identity (Maybe Text)
forall (f :: * -> *) a. Alternative f => f a -> f (Maybe a)
optional (Parser Text -> Parser Text
forall a. Parser a -> Parser a
lexeme Parser Text
"ONLY")
    Text
tableName <- Parser Text
qualifiedIdentifier
    let add :: ParsecT Void Text Identity Statement
add = do
            Parser Text -> Parser Text
forall a. Parser a -> Parser a
lexeme Parser Text
"ADD"
            let addUnique :: ParsecT Void Text Identity Statement
addUnique = do
                    Constraint
unique <- Maybe Text -> ParsecT Void Text Identity Constraint
parseUniqueConstraint Maybe Text
forall a. Maybe a
Nothing
                    Maybe Bool
deferrable <- ParsecT Void Text Identity Bool
-> ParsecT Void Text Identity (Maybe Bool)
forall (f :: * -> *) a. Alternative f => f a -> f (Maybe a)
optional ParsecT Void Text Identity Bool
parseDeferrable
                    Maybe DeferrableType
deferrableType <- ParsecT Void Text Identity DeferrableType
-> ParsecT Void Text Identity (Maybe DeferrableType)
forall (f :: * -> *) a. Alternative f => f a -> f (Maybe a)
optional ParsecT Void Text Identity DeferrableType
parseDeferrableType
                    Token Text -> ParsecT Void Text Identity (Token Text)
forall e s (m :: * -> *).
(MonadParsec e s m, Token s ~ Char) =>
Token s -> m (Token s)
char Char
Token Text
';'
                    Statement -> ParsecT Void Text Identity Statement
forall a. a -> ParsecT Void Text Identity a
forall (f :: * -> *) a. Applicative f => a -> f a
pure (Text
-> Constraint -> Maybe Bool -> Maybe DeferrableType -> Statement
AddConstraint Text
tableName Constraint
unique Maybe Bool
deferrable Maybe DeferrableType
deferrableType)
            Text -> ParsecT Void Text Identity Statement
addConstraint Text
tableName ParsecT Void Text Identity Statement
-> ParsecT Void Text Identity Statement
-> ParsecT Void Text Identity Statement
forall a.
ParsecT Void Text Identity a
-> ParsecT Void Text Identity a -> ParsecT Void Text Identity a
forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
<|> Text -> ParsecT Void Text Identity Statement
addColumn Text
tableName ParsecT Void Text Identity Statement
-> ParsecT Void Text Identity Statement
-> ParsecT Void Text Identity Statement
forall a.
ParsecT Void Text Identity a
-> ParsecT Void Text Identity a -> ParsecT Void Text Identity a
forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
<|> ParsecT Void Text Identity Statement
addUnique
    let drop :: ParsecT Void Text Identity Statement
drop = do
            Parser Text -> Parser Text
forall a. Parser a -> Parser a
lexeme Parser Text
"DROP"
            Text -> ParsecT Void Text Identity Statement
dropColumn Text
tableName ParsecT Void Text Identity Statement
-> ParsecT Void Text Identity Statement
-> ParsecT Void Text Identity Statement
forall a.
ParsecT Void Text Identity a
-> ParsecT Void Text Identity a -> ParsecT Void Text Identity a
forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
<|> Text -> ParsecT Void Text Identity Statement
dropConstraint Text
tableName
    let rename :: ParsecT Void Text Identity Statement
rename = do
            Parser Text -> Parser Text
forall a. Parser a -> Parser a
lexeme Parser Text
"RENAME"
            Text -> ParsecT Void Text Identity Statement
renameColumn Text
tableName ParsecT Void Text Identity Statement
-> ParsecT Void Text Identity Statement
-> ParsecT Void Text Identity Statement
forall a.
ParsecT Void Text Identity a
-> ParsecT Void Text Identity a -> ParsecT Void Text Identity a
forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
<|> Text -> ParsecT Void Text Identity Statement
renameTable Text
tableName
    let alter :: ParsecT Void Text Identity Statement
alter = do
            Parser Text -> Parser Text
forall a. Parser a -> Parser a
lexeme Parser Text
"ALTER"
            Text -> ParsecT Void Text Identity Statement
alterColumn Text
tableName
    Text -> ParsecT Void Text Identity Statement
enableRowLevelSecurity Text
tableName ParsecT Void Text Identity Statement
-> ParsecT Void Text Identity Statement
-> ParsecT Void Text Identity Statement
forall a.
ParsecT Void Text Identity a
-> ParsecT Void Text Identity a -> ParsecT Void Text Identity a
forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
<|> ParsecT Void Text Identity Statement
add ParsecT Void Text Identity Statement
-> ParsecT Void Text Identity Statement
-> ParsecT Void Text Identity Statement
forall a.
ParsecT Void Text Identity a
-> ParsecT Void Text Identity a -> ParsecT Void Text Identity a
forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
<|> ParsecT Void Text Identity Statement
drop ParsecT Void Text Identity Statement
-> ParsecT Void Text Identity Statement
-> ParsecT Void Text Identity Statement
forall a.
ParsecT Void Text Identity a
-> ParsecT Void Text Identity a -> ParsecT Void Text Identity a
forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
<|> ParsecT Void Text Identity Statement
rename ParsecT Void Text Identity Statement
-> ParsecT Void Text Identity Statement
-> ParsecT Void Text Identity Statement
forall a.
ParsecT Void Text Identity a
-> ParsecT Void Text Identity a -> ParsecT Void Text Identity a
forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
<|> ParsecT Void Text Identity Statement
alter

alterType :: ParsecT Void Text Identity Statement
alterType = do
    Parser Text -> Parser Text
forall a. Parser a -> Parser a
lexeme Parser Text
"TYPE"
    Text
typeName <- Parser Text
qualifiedIdentifier
    Text -> ParsecT Void Text Identity Statement
addValue Text
typeName

alterSequence :: ParsecT Void Text Identity Statement
alterSequence = do
    Parser Text -> Parser Text
forall a. Parser a -> Parser a
lexeme Parser Text
"SEQUENCE"
    Text
raw <- [Token Text] -> Text
forall a b. ConvertibleStrings a b => a -> b
cs ([Token Text] -> Text)
-> ParsecT Void Text Identity [Token Text] -> Parser Text
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> ParsecT Void Text Identity (Token Text)
-> ParsecT Void Text Identity Char
-> ParsecT Void Text Identity [Token Text]
forall (m :: * -> *) a end. MonadPlus m => m a -> m end -> m [a]
someTill (ParsecT Void Text Identity (Token Text)
forall e s (m :: * -> *). MonadParsec e s m => m (Token s)
anySingle) (Token Text -> ParsecT Void Text Identity (Token Text)
forall e s (m :: * -> *).
(MonadParsec e s m, Token s ~ Char) =>
Token s -> m (Token s)
char Char
Token Text
';')
    Statement -> ParsecT Void Text Identity Statement
forall a. a -> ParsecT Void Text Identity a
forall (f :: * -> *) a. Applicative f => a -> f a
pure UnknownStatement { $sel:raw:StatementCreateTable :: Text
raw = Text
"ALTER SEQUENCE " Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
raw };

-- | ALTER TABLE users ALTER COLUMN email DROP NOT NULL;
--  ALTER TABLE users ALTER COLUMN email SET NOT NULL;
--  ALTER TABLE users ALTER COLUMN email SET DEFAULT 'value';
--  ALTER TABLE users ALTER COLUMN email DROP DEFAULT;
alterColumn :: Text -> ParsecT Void Text Identity Statement
alterColumn Text
tableName = do
    Parser Text -> Parser Text
forall a. Parser a -> Parser a
lexeme Parser Text
"COLUMN"
    Text
columnName <- Parser Text
identifier

    let drop :: ParsecT Void Text Identity Statement
drop = do
            Parser Text -> Parser Text
forall a. Parser a -> Parser a
lexeme Parser Text
"DROP"
            let notNull :: ParsecT Void Text Identity Statement
notNull = do
                    Parser Text -> Parser Text
forall a. Parser a -> Parser a
lexeme Parser Text
"NOT"
                    Parser Text -> Parser Text
forall a. Parser a -> Parser a
lexeme Parser Text
"NULL"
                    Token Text -> ParsecT Void Text Identity (Token Text)
forall e s (m :: * -> *).
(MonadParsec e s m, Token s ~ Char) =>
Token s -> m (Token s)
char Char
Token Text
';'
                    Statement -> ParsecT Void Text Identity Statement
forall a. a -> ParsecT Void Text Identity a
forall (f :: * -> *) a. Applicative f => a -> f a
pure DropNotNull { Text
$sel:tableName:StatementCreateTable :: Text
tableName :: Text
tableName, Text
columnName :: Text
$sel:columnName:StatementCreateTable :: Text
columnName }
            let defaultValue :: ParsecT Void Text Identity Statement
defaultValue = do
                    Parser Text -> Parser Text
forall a. Parser a -> Parser a
lexeme Parser Text
"DEFAULT"
                    Token Text -> ParsecT Void Text Identity (Token Text)
forall e s (m :: * -> *).
(MonadParsec e s m, Token s ~ Char) =>
Token s -> m (Token s)
char Char
Token Text
';'
                    Statement -> ParsecT Void Text Identity Statement
forall a. a -> ParsecT Void Text Identity a
forall (f :: * -> *) a. Applicative f => a -> f a
pure DropDefaultValue { Text
$sel:tableName:StatementCreateTable :: Text
tableName :: Text
tableName, Text
columnName :: Text
$sel:columnName:StatementCreateTable :: Text
columnName }
            ParsecT Void Text Identity Statement
notNull ParsecT Void Text Identity Statement
-> ParsecT Void Text Identity Statement
-> ParsecT Void Text Identity Statement
forall a.
ParsecT Void Text Identity a
-> ParsecT Void Text Identity a -> ParsecT Void Text Identity a
forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
<|> ParsecT Void Text Identity Statement
defaultValue

    let set :: ParsecT Void Text Identity Statement
set = do
            Parser Text -> Parser Text
forall a. Parser a -> Parser a
lexeme Parser Text
"SET"
            let notNull :: ParsecT Void Text Identity Statement
notNull = do
                    Parser Text -> Parser Text
forall a. Parser a -> Parser a
lexeme Parser Text
"NOT"
                    Parser Text -> Parser Text
forall a. Parser a -> Parser a
lexeme Parser Text
"NULL"
                    Token Text -> ParsecT Void Text Identity (Token Text)
forall e s (m :: * -> *).
(MonadParsec e s m, Token s ~ Char) =>
Token s -> m (Token s)
char Char
Token Text
';'
                    Statement -> ParsecT Void Text Identity Statement
forall a. a -> ParsecT Void Text Identity a
forall (f :: * -> *) a. Applicative f => a -> f a
pure SetNotNull { Text
$sel:tableName:StatementCreateTable :: Text
tableName :: Text
tableName, Text
columnName :: Text
$sel:columnName:StatementCreateTable :: Text
columnName }
            let defaultValue :: ParsecT Void Text Identity Statement
defaultValue = do
                    Parser Text -> Parser Text
forall a. Parser a -> Parser a
lexeme Parser Text
"DEFAULT"
                    Expression
value <- ParsecT Void Text Identity Expression
expression
                    Token Text -> ParsecT Void Text Identity (Token Text)
forall e s (m :: * -> *).
(MonadParsec e s m, Token s ~ Char) =>
Token s -> m (Token s)
char Char
Token Text
';'
                    Statement -> ParsecT Void Text Identity Statement
forall a. a -> ParsecT Void Text Identity a
forall (f :: * -> *) a. Applicative f => a -> f a
pure SetDefaultValue { Text
$sel:tableName:StatementCreateTable :: Text
tableName :: Text
tableName, Text
columnName :: Text
$sel:columnName:StatementCreateTable :: Text
columnName, Expression
value :: Expression
value :: Expression
value }
            ParsecT Void Text Identity Statement
notNull ParsecT Void Text Identity Statement
-> ParsecT Void Text Identity Statement
-> ParsecT Void Text Identity Statement
forall a.
ParsecT Void Text Identity a
-> ParsecT Void Text Identity a -> ParsecT Void Text Identity a
forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
<|> ParsecT Void Text Identity Statement
defaultValue

    ParsecT Void Text Identity Statement
drop ParsecT Void Text Identity Statement
-> ParsecT Void Text Identity Statement
-> ParsecT Void Text Identity Statement
forall a.
ParsecT Void Text Identity a
-> ParsecT Void Text Identity a -> ParsecT Void Text Identity a
forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
<|> ParsecT Void Text Identity Statement
set




enableRowLevelSecurity :: Text -> ParsecT Void Text Identity Statement
enableRowLevelSecurity Text
tableName = do
    Parser Text -> Parser Text
forall a. Parser a -> Parser a
lexeme Parser Text
"ENABLE"
    Parser Text -> Parser Text
forall a. Parser a -> Parser a
lexeme Parser Text
"ROW"
    Parser Text -> Parser Text
forall a. Parser a -> Parser a
lexeme Parser Text
"LEVEL"
    Parser Text -> Parser Text
forall a. Parser a -> Parser a
lexeme Parser Text
"SECURITY"
    Token Text -> ParsecT Void Text Identity (Token Text)
forall e s (m :: * -> *).
(MonadParsec e s m, Token s ~ Char) =>
Token s -> m (Token s)
char Char
Token Text
';'
    Statement -> ParsecT Void Text Identity Statement
forall a. a -> ParsecT Void Text Identity a
forall (f :: * -> *) a. Applicative f => a -> f a
pure EnableRowLevelSecurity { Text
$sel:tableName:StatementCreateTable :: Text
tableName :: Text
tableName }

createPolicy :: ParsecT Void Text Identity Statement
createPolicy = do
    Parser Text -> Parser Text
forall a. Parser a -> Parser a
lexeme Parser Text
"CREATE"
    Parser Text -> Parser Text
forall a. Parser a -> Parser a
lexeme Parser Text
"POLICY"
    Text
name <- Parser Text
identifier
    Parser Text -> Parser Text
forall a. Parser a -> Parser a
lexeme Parser Text
"ON"
    Text
tableName <- Parser Text
qualifiedIdentifier

    Maybe PolicyAction
action <- ParsecT Void Text Identity PolicyAction
-> ParsecT Void Text Identity (Maybe PolicyAction)
forall (f :: * -> *) a. Alternative f => f a -> f (Maybe a)
optional (Parser Text -> Parser Text
forall a. Parser a -> Parser a
lexeme Parser Text
"FOR" Parser Text
-> ParsecT Void Text Identity PolicyAction
-> ParsecT Void Text Identity PolicyAction
forall a b.
ParsecT Void Text Identity a
-> ParsecT Void Text Identity b -> ParsecT Void Text Identity b
forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> ParsecT Void Text Identity PolicyAction
policyAction)

    Maybe Expression
using <- ParsecT Void Text Identity Expression
-> ParsecT Void Text Identity (Maybe Expression)
forall (f :: * -> *) a. Alternative f => f a -> f (Maybe a)
optional do
        Parser Text -> Parser Text
forall a. Parser a -> Parser a
lexeme Parser Text
"USING"
        ParsecT Void Text Identity Expression
expression

    Maybe Expression
check <- ParsecT Void Text Identity Expression
-> ParsecT Void Text Identity (Maybe Expression)
forall (f :: * -> *) a. Alternative f => f a -> f (Maybe a)
optional do
        Parser Text -> Parser Text
forall a. Parser a -> Parser a
lexeme Parser Text
"WITH"
        Parser Text -> Parser Text
forall a. Parser a -> Parser a
lexeme Parser Text
"CHECK"
        ParsecT Void Text Identity Expression
expression

    Token Text -> ParsecT Void Text Identity (Token Text)
forall e s (m :: * -> *).
(MonadParsec e s m, Token s ~ Char) =>
Token s -> m (Token s)
char Char
Token Text
';'

    Statement -> ParsecT Void Text Identity Statement
forall a. a -> ParsecT Void Text Identity a
forall (f :: * -> *) a. Applicative f => a -> f a
pure CreatePolicy { Text
$sel:name:StatementCreateTable :: Text
name :: Text
name, Maybe PolicyAction
action :: Maybe PolicyAction
$sel:action:StatementCreateTable :: Maybe PolicyAction
action, Text
$sel:tableName:StatementCreateTable :: Text
tableName :: Text
tableName, Maybe Expression
using :: Maybe Expression
$sel:using:StatementCreateTable :: Maybe Expression
using, Maybe Expression
check :: Maybe Expression
$sel:check:StatementCreateTable :: Maybe Expression
check }

policyAction :: ParsecT Void Text Identity PolicyAction
policyAction =
    (Parser Text -> Parser Text
forall a. Parser a -> Parser a
lexeme Parser Text
"ALL" Parser Text
-> ParsecT Void Text Identity PolicyAction
-> ParsecT Void Text Identity PolicyAction
forall a b.
ParsecT Void Text Identity a
-> ParsecT Void Text Identity b -> ParsecT Void Text Identity b
forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> PolicyAction -> ParsecT Void Text Identity PolicyAction
forall a. a -> ParsecT Void Text Identity a
forall (f :: * -> *) a. Applicative f => a -> f a
pure PolicyAction
PolicyForAll)
    ParsecT Void Text Identity PolicyAction
-> ParsecT Void Text Identity PolicyAction
-> ParsecT Void Text Identity PolicyAction
forall a.
ParsecT Void Text Identity a
-> ParsecT Void Text Identity a -> ParsecT Void Text Identity a
forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
<|> (Parser Text -> Parser Text
forall a. Parser a -> Parser a
lexeme Parser Text
"SELECT" Parser Text
-> ParsecT Void Text Identity PolicyAction
-> ParsecT Void Text Identity PolicyAction
forall a b.
ParsecT Void Text Identity a
-> ParsecT Void Text Identity b -> ParsecT Void Text Identity b
forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> PolicyAction -> ParsecT Void Text Identity PolicyAction
forall a. a -> ParsecT Void Text Identity a
forall (f :: * -> *) a. Applicative f => a -> f a
pure PolicyAction
PolicyForSelect)
    ParsecT Void Text Identity PolicyAction
-> ParsecT Void Text Identity PolicyAction
-> ParsecT Void Text Identity PolicyAction
forall a.
ParsecT Void Text Identity a
-> ParsecT Void Text Identity a -> ParsecT Void Text Identity a
forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
<|> (Parser Text -> Parser Text
forall a. Parser a -> Parser a
lexeme Parser Text
"INSERT" Parser Text
-> ParsecT Void Text Identity PolicyAction
-> ParsecT Void Text Identity PolicyAction
forall a b.
ParsecT Void Text Identity a
-> ParsecT Void Text Identity b -> ParsecT Void Text Identity b
forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> PolicyAction -> ParsecT Void Text Identity PolicyAction
forall a. a -> ParsecT Void Text Identity a
forall (f :: * -> *) a. Applicative f => a -> f a
pure PolicyAction
PolicyForInsert)
    ParsecT Void Text Identity PolicyAction
-> ParsecT Void Text Identity PolicyAction
-> ParsecT Void Text Identity PolicyAction
forall a.
ParsecT Void Text Identity a
-> ParsecT Void Text Identity a -> ParsecT Void Text Identity a
forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
<|> (Parser Text -> Parser Text
forall a. Parser a -> Parser a
lexeme Parser Text
"UPDATE" Parser Text
-> ParsecT Void Text Identity PolicyAction
-> ParsecT Void Text Identity PolicyAction
forall a b.
ParsecT Void Text Identity a
-> ParsecT Void Text Identity b -> ParsecT Void Text Identity b
forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> PolicyAction -> ParsecT Void Text Identity PolicyAction
forall a. a -> ParsecT Void Text Identity a
forall (f :: * -> *) a. Applicative f => a -> f a
pure PolicyAction
PolicyForUpdate)
    ParsecT Void Text Identity PolicyAction
-> ParsecT Void Text Identity PolicyAction
-> ParsecT Void Text Identity PolicyAction
forall a.
ParsecT Void Text Identity a
-> ParsecT Void Text Identity a -> ParsecT Void Text Identity a
forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
<|> (Parser Text -> Parser Text
forall a. Parser a -> Parser a
lexeme Parser Text
"DELETE" Parser Text
-> ParsecT Void Text Identity PolicyAction
-> ParsecT Void Text Identity PolicyAction
forall a b.
ParsecT Void Text Identity a
-> ParsecT Void Text Identity b -> ParsecT Void Text Identity b
forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> PolicyAction -> ParsecT Void Text Identity PolicyAction
forall a. a -> ParsecT Void Text Identity a
forall (f :: * -> *) a. Applicative f => a -> f a
pure PolicyAction
PolicyForDelete)

setStatement :: ParsecT Void Text Identity Statement
setStatement = do
    Parser Text -> Parser Text
forall a. Parser a -> Parser a
lexeme Parser Text
"SET"
    Text
name <- Parser Text
identifier
    Parser Text -> Parser Text
forall a. Parser a -> Parser a
lexeme Parser Text
"="
    Expression
value <- ParsecT Void Text Identity Expression
expression
    Token Text -> ParsecT Void Text Identity (Token Text)
forall e s (m :: * -> *).
(MonadParsec e s m, Token s ~ Char) =>
Token s -> m (Token s)
char Char
Token Text
';'
    Statement -> ParsecT Void Text Identity Statement
forall a. a -> ParsecT Void Text Identity a
forall (f :: * -> *) a. Applicative f => a -> f a
pure Set { Text
$sel:name:StatementCreateTable :: Text
name :: Text
name, Expression
value :: Expression
value :: Expression
value }

selectStatement :: ParsecT Void Text Identity Statement
selectStatement = do
    Parser Text -> Parser Text
forall a. Parser a -> Parser a
lexeme Parser Text
"SELECT"
    Text
query <- Maybe String
-> (Token Text -> Bool) -> ParsecT Void Text Identity (Tokens Text)
forall e s (m :: * -> *).
MonadParsec e s m =>
Maybe String -> (Token s -> Bool) -> m (Tokens s)
takeWhile1P (String -> Maybe String
forall a. a -> Maybe a
Just String
"SQL Query") (\Token Text
c -> Char
Token Text
c Char -> Char -> Bool
forall a. Eq a => a -> a -> Bool
/= Char
';')
    Token Text -> ParsecT Void Text Identity (Token Text)
forall e s (m :: * -> *).
(MonadParsec e s m, Token s ~ Char) =>
Token s -> m (Token s)
char Char
Token Text
';'
    Statement -> ParsecT Void Text Identity Statement
forall a. a -> ParsecT Void Text Identity a
forall (f :: * -> *) a. Applicative f => a -> f a
pure SelectStatement { Text
query :: Text
$sel:query:StatementCreateTable :: Text
query }


commentStatement :: ParsecT Void Text Identity Statement
commentStatement = do
    Parser Text -> Parser Text
forall a. Parser a -> Parser a
lexeme Parser Text
"COMMENT"
    Text
content <- Maybe String
-> (Token Text -> Bool) -> ParsecT Void Text Identity (Tokens Text)
forall e s (m :: * -> *).
MonadParsec e s m =>
Maybe String -> (Token s -> Bool) -> m (Tokens s)
takeWhile1P (String -> Maybe String
forall a. a -> Maybe a
Just String
"SQL Query") (\Token Text
c -> Char
Token Text
c Char -> Char -> Bool
forall a. Eq a => a -> a -> Bool
/= Char
';')
    Token Text -> ParsecT Void Text Identity (Token Text)
forall e s (m :: * -> *).
(MonadParsec e s m, Token s ~ Char) =>
Token s -> m (Token s)
char Char
Token Text
';'
    Statement -> ParsecT Void Text Identity Statement
forall a. a -> ParsecT Void Text Identity a
forall (f :: * -> *) a. Applicative f => a -> f a
pure Comment { Text
$sel:content:StatementCreateTable :: Text
content :: Text
content }

qualifiedIdentifier :: Parser Text
qualifiedIdentifier = do
    ParsecT Void Text Identity Char
-> ParsecT Void Text Identity (Maybe Char)
forall (f :: * -> *) a. Alternative f => f a -> f (Maybe a)
optional (ParsecT Void Text Identity Char
 -> ParsecT Void Text Identity (Maybe Char))
-> ParsecT Void Text Identity Char
-> ParsecT Void Text Identity (Maybe Char)
forall a b. (a -> b) -> a -> b
$ ParsecT Void Text Identity Char -> ParsecT Void Text Identity Char
forall a. Parser a -> Parser a
forall e s (m :: * -> *) a. MonadParsec e s m => m a -> m a
try do
        Parser Text -> Parser Text
forall a. Parser a -> Parser a
lexeme Parser Text
"public"
        Token Text -> ParsecT Void Text Identity (Token Text)
forall e s (m :: * -> *).
(MonadParsec e s m, Token s ~ Char) =>
Token s -> m (Token s)
char Char
Token Text
'.'
    Parser Text
identifier

addColumn :: Text -> ParsecT Void Text Identity Statement
addColumn Text
tableName = do
    Parser Text -> Parser Text
forall a. Parser a -> Parser a
lexeme Parser Text
"COLUMN"
    (Bool
_, Column
column) <- ParsecT Void Text Identity (Bool, Column)
parseColumn
    Token Text -> ParsecT Void Text Identity (Token Text)
forall e s (m :: * -> *).
(MonadParsec e s m, Token s ~ Char) =>
Token s -> m (Token s)
char Char
Token Text
';'
    Statement -> ParsecT Void Text Identity Statement
forall a. a -> ParsecT Void Text Identity a
forall (f :: * -> *) a. Applicative f => a -> f a
pure AddColumn { Text
$sel:tableName:StatementCreateTable :: Text
tableName :: Text
tableName, Column
column :: Column
$sel:column:StatementCreateTable :: Column
column }

dropColumn :: Text -> ParsecT Void Text Identity Statement
dropColumn Text
tableName = do
    Parser Text -> Parser Text
forall a. Parser a -> Parser a
lexeme Parser Text
"COLUMN"
    Text
columnName <- Parser Text
identifier
    Token Text -> ParsecT Void Text Identity (Token Text)
forall e s (m :: * -> *).
(MonadParsec e s m, Token s ~ Char) =>
Token s -> m (Token s)
char Char
Token Text
';'
    Statement -> ParsecT Void Text Identity Statement
forall a. a -> ParsecT Void Text Identity a
forall (f :: * -> *) a. Applicative f => a -> f a
pure DropColumn { Text
$sel:tableName:StatementCreateTable :: Text
tableName :: Text
tableName, Text
$sel:columnName:StatementCreateTable :: Text
columnName :: Text
columnName }

dropConstraint :: Text -> ParsecT Void Text Identity Statement
dropConstraint Text
tableName = do
    Parser Text -> Parser Text
forall a. Parser a -> Parser a
lexeme Parser Text
"CONSTRAINT"
    Text
constraintName <- Parser Text
identifier
    Token Text -> ParsecT Void Text Identity (Token Text)
forall e s (m :: * -> *).
(MonadParsec e s m, Token s ~ Char) =>
Token s -> m (Token s)
char Char
Token Text
';'
    Statement -> ParsecT Void Text Identity Statement
forall a. a -> ParsecT Void Text Identity a
forall (f :: * -> *) a. Applicative f => a -> f a
pure DropConstraint { Text
$sel:tableName:StatementCreateTable :: Text
tableName :: Text
tableName, Text
constraintName :: Text
$sel:constraintName:StatementCreateTable :: Text
constraintName }

renameColumn :: Text -> ParsecT Void Text Identity Statement
renameColumn Text
tableName = do
    Parser Text -> Parser Text
forall a. Parser a -> Parser a
lexeme Parser Text
"COLUMN"
    Text
from <- Parser Text
identifier
    Parser Text -> Parser Text
forall a. Parser a -> Parser a
lexeme Parser Text
"TO"
    Text
to <- Parser Text
identifier
    Token Text -> ParsecT Void Text Identity (Token Text)
forall e s (m :: * -> *).
(MonadParsec e s m, Token s ~ Char) =>
Token s -> m (Token s)
char Char
Token Text
';'
    Statement -> ParsecT Void Text Identity Statement
forall a. a -> ParsecT Void Text Identity a
forall (f :: * -> *) a. Applicative f => a -> f a
pure RenameColumn { Text
$sel:tableName:StatementCreateTable :: Text
tableName :: Text
tableName, Text
from :: Text
$sel:from:StatementCreateTable :: Text
from, Text
to :: Text
$sel:to:StatementCreateTable :: Text
to }

renameTable :: Text -> ParsecT Void Text Identity Statement
renameTable Text
tableName = do
    Parser Text -> Parser Text
forall a. Parser a -> Parser a
lexeme Parser Text
"TO"
    Text
to <- Parser Text
identifier
    Token Text -> ParsecT Void Text Identity (Token Text)
forall e s (m :: * -> *).
(MonadParsec e s m, Token s ~ Char) =>
Token s -> m (Token s)
char Char
Token Text
';'
    Statement -> ParsecT Void Text Identity Statement
forall a. a -> ParsecT Void Text Identity a
forall (f :: * -> *) a. Applicative f => a -> f a
pure RenameTable { $sel:from:StatementCreateTable :: Text
from = Text
tableName, Text
$sel:to:StatementCreateTable :: Text
to :: Text
to }

dropTable :: ParsecT Void Text Identity Statement
dropTable = do
    Parser Text -> Parser Text
forall a. Parser a -> Parser a
lexeme Parser Text
"DROP"
    Parser Text -> Parser Text
forall a. Parser a -> Parser a
lexeme Parser Text
"TABLE"
    Text
tableName <- Parser Text
identifier
    Token Text -> ParsecT Void Text Identity (Token Text)
forall e s (m :: * -> *).
(MonadParsec e s m, Token s ~ Char) =>
Token s -> m (Token s)
char Char
Token Text
';'
    Statement -> ParsecT Void Text Identity Statement
forall a. a -> ParsecT Void Text Identity a
forall (f :: * -> *) a. Applicative f => a -> f a
pure DropTable { Text
$sel:tableName:StatementCreateTable :: Text
tableName :: Text
tableName }

dropType :: ParsecT Void Text Identity Statement
dropType = do
    Parser Text -> Parser Text
forall a. Parser a -> Parser a
lexeme Parser Text
"DROP"
    Parser Text -> Parser Text
forall a. Parser a -> Parser a
lexeme Parser Text
"TYPE"
    Text
name <- Parser Text
qualifiedIdentifier
    Token Text -> ParsecT Void Text Identity (Token Text)
forall e s (m :: * -> *).
(MonadParsec e s m, Token s ~ Char) =>
Token s -> m (Token s)
char Char
Token Text
';'
    Statement -> ParsecT Void Text Identity Statement
forall a. a -> ParsecT Void Text Identity a
forall (f :: * -> *) a. Applicative f => a -> f a
pure DropEnumType { Text
$sel:name:StatementCreateTable :: Text
name :: Text
name }

dropFunction :: ParsecT Void Text Identity Statement
dropFunction = do
    Parser Text -> Parser Text
forall a. Parser a -> Parser a
lexeme Parser Text
"DROP"
    Parser Text -> Parser Text
forall a. Parser a -> Parser a
lexeme Parser Text
"FUNCTION"
    Text
functionName <- Parser Text
qualifiedIdentifier
    Token Text -> ParsecT Void Text Identity (Token Text)
forall e s (m :: * -> *).
(MonadParsec e s m, Token s ~ Char) =>
Token s -> m (Token s)
char Char
Token Text
';'
    Statement -> ParsecT Void Text Identity Statement
forall a. a -> ParsecT Void Text Identity a
forall (f :: * -> *) a. Applicative f => a -> f a
pure DropFunction { Text
$sel:functionName:StatementCreateTable :: Text
functionName :: Text
functionName }

dropIndex :: ParsecT Void Text Identity Statement
dropIndex = do
    Parser Text -> Parser Text
forall a. Parser a -> Parser a
lexeme Parser Text
"DROP"
    Parser Text -> Parser Text
forall a. Parser a -> Parser a
lexeme Parser Text
"INDEX"
    Text
indexName <- Parser Text
qualifiedIdentifier
    Token Text -> ParsecT Void Text Identity (Token Text)
forall e s (m :: * -> *).
(MonadParsec e s m, Token s ~ Char) =>
Token s -> m (Token s)
char Char
Token Text
';'
    Statement -> ParsecT Void Text Identity Statement
forall a. a -> ParsecT Void Text Identity a
forall (f :: * -> *) a. Applicative f => a -> f a
pure DropIndex { Text
$sel:indexName:StatementCreateTable :: Text
indexName :: Text
indexName }

dropPolicy :: ParsecT Void Text Identity Statement
dropPolicy = do
    Parser Text -> Parser Text
forall a. Parser a -> Parser a
lexeme Parser Text
"DROP"
    Parser Text -> Parser Text
forall a. Parser a -> Parser a
lexeme Parser Text
"POLICY"
    Text
policyName <- Parser Text
qualifiedIdentifier
    Parser Text -> Parser Text
forall a. Parser a -> Parser a
lexeme Parser Text
"ON"
    Text
tableName <- Parser Text
qualifiedIdentifier
    Token Text -> ParsecT Void Text Identity (Token Text)
forall e s (m :: * -> *).
(MonadParsec e s m, Token s ~ Char) =>
Token s -> m (Token s)
char Char
Token Text
';'
    Statement -> ParsecT Void Text Identity Statement
forall a. a -> ParsecT Void Text Identity a
forall (f :: * -> *) a. Applicative f => a -> f a
pure DropPolicy { Text
$sel:tableName:StatementCreateTable :: Text
tableName :: Text
tableName, Text
policyName :: Text
$sel:policyName:StatementCreateTable :: Text
policyName }

dropTrigger :: ParsecT Void Text Identity Statement
dropTrigger = do
    Parser Text -> Parser Text
forall a. Parser a -> Parser a
lexeme Parser Text
"DROP"
    Parser Text -> Parser Text
forall a. Parser a -> Parser a
lexeme Parser Text
"TRIGGER"
    Text
name <- Parser Text
qualifiedIdentifier
    Parser Text -> Parser Text
forall a. Parser a -> Parser a
lexeme Parser Text
"ON"
    Text
tableName <- Parser Text
qualifiedIdentifier
    Token Text -> ParsecT Void Text Identity (Token Text)
forall e s (m :: * -> *).
(MonadParsec e s m, Token s ~ Char) =>
Token s -> m (Token s)
char Char
Token Text
';'
    Statement -> ParsecT Void Text Identity Statement
forall a. a -> ParsecT Void Text Identity a
forall (f :: * -> *) a. Applicative f => a -> f a
pure DropTrigger { Text
$sel:name:StatementCreateTable :: Text
name :: Text
name, Text
$sel:tableName:StatementCreateTable :: Text
tableName :: Text
tableName }

createSequence :: ParsecT Void Text Identity Statement
createSequence = do
    Parser Text -> Parser Text
forall a. Parser a -> Parser a
lexeme Parser Text
"CREATE"
    Parser Text -> Parser Text
forall a. Parser a -> Parser a
lexeme Parser Text
"SEQUENCE"
    Text
name <- Parser Text
qualifiedIdentifier

    -- We accept all the following SEQUENCE attributes, but don't save them
    -- This is mostly to void issues in migrations when parsing the pg_dump output
    Parser PostgresType
-> ParsecT Void Text Identity (Maybe PostgresType)
forall (f :: * -> *) a. Alternative f => f a -> f (Maybe a)
optional do
        Parser Text -> Parser Text
forall a. Parser a -> Parser a
lexeme Parser Text
"AS"
        Parser PostgresType
sqlType

    ParsecT Void Text Identity Expression
-> ParsecT Void Text Identity (Maybe Expression)
forall (f :: * -> *) a. Alternative f => f a -> f (Maybe a)
optional do
        Parser Text -> Parser Text
forall a. Parser a -> Parser a
lexeme Parser Text
"START"
        Parser Text -> Parser Text
forall a. Parser a -> Parser a
lexeme Parser Text
"WITH"
        ParsecT Void Text Identity Expression
expression

    ParsecT Void Text Identity Expression
-> ParsecT Void Text Identity (Maybe Expression)
forall (f :: * -> *) a. Alternative f => f a -> f (Maybe a)
optional do
        Parser Text -> Parser Text
forall a. Parser a -> Parser a
lexeme Parser Text
"INCREMENT"
        Parser Text -> Parser Text
forall a. Parser a -> Parser a
lexeme Parser Text
"BY"
        ParsecT Void Text Identity Expression
expression

    Parser Text -> ParsecT Void Text Identity (Maybe Text)
forall (f :: * -> *) a. Alternative f => f a -> f (Maybe a)
optional do
        Parser Text -> Parser Text
forall a. Parser a -> Parser a
lexeme Parser Text
"NO"
        Parser Text -> Parser Text
forall a. Parser a -> Parser a
lexeme Parser Text
"MINVALUE"

    Parser Text -> ParsecT Void Text Identity (Maybe Text)
forall (f :: * -> *) a. Alternative f => f a -> f (Maybe a)
optional do
        Parser Text -> Parser Text
forall a. Parser a -> Parser a
lexeme Parser Text
"NO"
        Parser Text -> Parser Text
forall a. Parser a -> Parser a
lexeme Parser Text
"MAXVALUE"

    ParsecT Void Text Identity Expression
-> ParsecT Void Text Identity (Maybe Expression)
forall (f :: * -> *) a. Alternative f => f a -> f (Maybe a)
optional do
        Parser Text -> Parser Text
forall a. Parser a -> Parser a
lexeme Parser Text
"CACHE"
        ParsecT Void Text Identity Expression
expression

    Token Text -> ParsecT Void Text Identity (Token Text)
forall e s (m :: * -> *).
(MonadParsec e s m, Token s ~ Char) =>
Token s -> m (Token s)
char Char
Token Text
';'
    Statement -> ParsecT Void Text Identity Statement
forall a. a -> ParsecT Void Text Identity a
forall (f :: * -> *) a. Applicative f => a -> f a
pure CreateSequence { Text
$sel:name:StatementCreateTable :: Text
name :: Text
name }

addValue :: Text -> ParsecT Void Text Identity Statement
addValue Text
typeName = do
    Parser Text -> Parser Text
forall a. Parser a -> Parser a
lexeme Parser Text
"ADD"
    Parser Text -> Parser Text
forall a. Parser a -> Parser a
lexeme Parser Text
"VALUE"
    Bool
ifNotExists <- Maybe Text -> Bool
forall a. Maybe a -> Bool
isJust (Maybe Text -> Bool)
-> ParsecT Void Text Identity (Maybe Text)
-> ParsecT Void Text Identity Bool
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Parser Text -> ParsecT Void Text Identity (Maybe Text)
forall (f :: * -> *) a. Alternative f => f a -> f (Maybe a)
optional do
            Parser Text -> Parser Text
forall a. Parser a -> Parser a
lexeme Parser Text
"IF"
            Parser Text -> Parser Text
forall a. Parser a -> Parser a
lexeme Parser Text
"NOT"
            Parser Text -> Parser Text
forall a. Parser a -> Parser a
lexeme Parser Text
"EXISTS"
    Text
newValue <- Parser Text
textExpr'
    Token Text -> ParsecT Void Text Identity (Token Text)
forall e s (m :: * -> *).
(MonadParsec e s m, Token s ~ Char) =>
Token s -> m (Token s)
char Char
Token Text
';'
    Statement -> ParsecT Void Text Identity Statement
forall a. a -> ParsecT Void Text Identity a
forall (f :: * -> *) a. Applicative f => a -> f a
pure AddValueToEnumType { $sel:enumName:StatementCreateTable :: Text
enumName = Text
typeName, Text
newValue :: Text
$sel:newValue:StatementCreateTable :: Text
newValue, Bool
$sel:ifNotExists:StatementCreateTable :: Bool
ifNotExists :: Bool
ifNotExists }

begin :: ParsecT Void Text Identity Statement
begin = do
    Parser Text -> Parser Text
forall a. Parser a -> Parser a
lexeme Parser Text
"BEGIN"
    Token Text -> ParsecT Void Text Identity (Token Text)
forall e s (m :: * -> *).
(MonadParsec e s m, Token s ~ Char) =>
Token s -> m (Token s)
char Char
Token Text
';'
    Statement -> ParsecT Void Text Identity Statement
forall a. a -> ParsecT Void Text Identity a
forall (f :: * -> *) a. Applicative f => a -> f a
pure Statement
Begin

commit :: ParsecT Void Text Identity Statement
commit = do
    Parser Text -> Parser Text
forall a. Parser a -> Parser a
lexeme Parser Text
"COMMIT"
    Token Text -> ParsecT Void Text Identity (Token Text)
forall e s (m :: * -> *).
(MonadParsec e s m, Token s ~ Char) =>
Token s -> m (Token s)
char Char
Token Text
';'
    Statement -> ParsecT Void Text Identity Statement
forall a. a -> ParsecT Void Text Identity a
forall (f :: * -> *) a. Applicative f => a -> f a
pure Statement
Commit

-- | Turns sql like '1::double precision' into just '1'
removeTypeCasts :: Expression -> Expression
removeTypeCasts :: Expression -> Expression
removeTypeCasts (TypeCastExpression Expression
value PostgresType
_) = Expression
value
removeTypeCasts Expression
otherwise = Expression
otherwise