1
Fork 0

start adding basic dml

parser and pretty printer for statements
add query statement
add support for
  insert
  update
  delete
  truncate
bonus ddl:
  limited create schema
  drop schema

add grammar notes to the new test files
This commit is contained in:
Jake Wheat 2015-08-01 20:26:00 +03:00
parent 6fc8869f73
commit dfa84072dc
13 changed files with 684 additions and 2238 deletions

View file

@ -179,7 +179,8 @@ fixing them in the syntax but leaving them till the semantic checking
> module Language.SQL.SimpleSQL.Parser
> (parseQueryExpr
> ,parseValueExpr
> ,parseQueryExprs
> ,parseStatement
> ,parseStatements
> ,ParseError(..)) where
> import Control.Monad.Identity (Identity)
@ -220,9 +221,23 @@ fixing them in the syntax but leaving them till the semantic checking
> -> Either ParseError QueryExpr
> parseQueryExpr = wrapParse topLevelQueryExpr
> -- | Parses a list of query expressions, with semi colons between
> -- | Parses a statement, trailing semicolon optional.
> parseStatement :: Dialect
> -- ^ dialect of SQL to use
> -> FilePath
> -- ^ filename to use in error messages
> -> Maybe (Int,Int)
> -- ^ line number and column number of the first character
> -- in the source to use in error messages
> -> String
> -- ^ the SQL source to parse
> -> Either ParseError Statement
> parseStatement = wrapParse statement
> -- | Parses a list of statements, with semi colons between
> -- them. The final semicolon is optional.
> parseQueryExprs :: Dialect
> parseStatements :: Dialect
> -- ^ dialect of SQL to use
> -> FilePath
> -- ^ filename to use in error messages
@ -231,8 +246,8 @@ fixing them in the syntax but leaving them till the semantic checking
> -- in the source to use in error messages
> -> String
> -- ^ the SQL source to parse
> -> Either ParseError [QueryExpr]
> parseQueryExprs = wrapParse queryExprs
> -> Either ParseError [Statement]
> parseStatements = wrapParse statements
> -- | Parses a value expression.
> parseValueExpr :: Dialect
@ -701,7 +716,15 @@ all the value expressions which start with an identifier
> idenExpr =
> -- todo: work out how to left factor this
> try (TypedLit <$> typeName <*> stringTokExtend)
> <|> multisetSetFunction
> <|> (names <**> option Iden app)
> where
> -- this is a special case because set is a reserved keyword
> -- and the names parser won't parse it
> multisetSetFunction =
> App [Name "set"] . (:[]) <$>
> (try (keyword_ "set" *> openParen)
> *> valueExpr <* closeParen)
=== special
@ -1409,16 +1432,93 @@ TODO: change style
> topLevelQueryExpr :: Parser QueryExpr
> topLevelQueryExpr = queryExpr <??> (id <$ semi)
wrapper to parse a series of query exprs from a single source. They
must be separated by semicolon, but for the last expression, the
trailing semicolon is optional.
-------------------------
= Statements
> statement :: Parser Statement
> statement = choice
> [keyword_ "create"
> *> choice
> [createSchema
> ]
> ,keyword_ "drop"
> *> choice
> [dropSchema
> ]
> ,delete
> ,truncateSt
> ,insert
> ,update
> ,SelectStatement <$> queryExpr
> ]
> createSchema :: Parser Statement
> createSchema = keyword_ "schema" >>
> CreateSchema <$> names
> dropSchema :: Parser Statement
> dropSchema = keyword_ "schema" >>
> DropSchema <$> names
> <*> dropBehaviour
> delete :: Parser Statement
> delete = keywords_ ["delete","from"] >>
> Delete
> <$> names
> <*> optionMaybe (optional (keyword_ "as") *> name)
> <*> optionMaybe (keyword_ "where" *> valueExpr)
> truncateSt :: Parser Statement
> truncateSt = keywords_ ["truncate", "table"] >>
> Truncate
> <$> names
> <*> option DefaultIdentityRestart
> (ContinueIdentity <$ keywords_ ["continue","identity"]
> <|> RestartIdentity <$ keywords_ ["restart","identity"])
> insert :: Parser Statement
> insert = keywords_ ["insert", "into"] >>
> Insert
> <$> names
> <*> optionMaybe (parens $ commaSep1 name)
> <*> (DefaultInsertValues <$ keywords_ ["default", "values"]
> <|> InsertQuery <$> queryExpr)
> update :: Parser Statement
> update = keywords_ ["update"] >>
> Update
> <$> names
> <*> optionMaybe (optional (keyword_ "as") *> name)
> <*> (keyword_ "set" *> commaSep1 setClause)
> <*> optionMaybe (keyword_ "where" *> valueExpr)
> where
> setClause = multipleSet <|> singleSet
> multipleSet = SetMultiple
> <$> parens (commaSep1 names)
> <*> (symbol "=" *> parens (commaSep1 valueExpr))
> singleSet = Set
> <$> names
> <*> (symbol "=" *> valueExpr)
> dropBehaviour :: Parser DropBehaviour
> dropBehaviour =
> option DefaultDropBehaviour
> (Restrict <$ keyword_ "restrict"
> <|> Cascade <$ keyword_ "cascade")
----------------------------
wrapper to parse a series of statements. They must be separated by
semicolon, but for the last statement, the trailing semicolon is
optional.
TODO: change style
> queryExprs :: Parser [QueryExpr]
> queryExprs = (:[]) <$> queryExpr
> statements :: Parser [Statement]
> statements = (:[]) <$> statement
> >>= optionSuffix ((semi *>) . pure)
> >>= optionSuffix (\p -> (p++) <$> queryExprs)
> >>= optionSuffix (\p -> (p++) <$> statements)
----------------------------------------------
@ -1884,7 +1984,7 @@ means).
> ,"select"
> ,"sensitive"
> --,"session_user"
> --,"set"
> ,"set"
> ,"similar"
> ,"smallint"
> --,"some"

View file

@ -5,7 +5,8 @@
> module Language.SQL.SimpleSQL.Pretty
> (prettyQueryExpr
> ,prettyValueExpr
> ,prettyQueryExprs
> ,prettyStatement
> ,prettyStatements
> ) where
TODO: there should be more comments in this file, especially the bits
@ -26,10 +27,14 @@ which have been changed to try to improve the layout of the output.
> prettyValueExpr :: Dialect -> ValueExpr -> String
> prettyValueExpr d = render . valueExpr d
> -- | Convert a list of query exprs to concrete syntax. A semi colon
> -- is inserted after each query expr.
> prettyQueryExprs :: Dialect -> [QueryExpr] -> String
> prettyQueryExprs d = render . vcat . map ((<> text ";\n") . queryExpr d)
> -- | Convert a statement ast to concrete syntax.
> prettyStatement :: Dialect -> Statement -> String
> prettyStatement d = render . statement d
> -- | Convert a list of statements to concrete syntax. A semi colon
> -- is inserted after each statement.
> prettyStatements :: Dialect -> [Statement] -> String
> prettyStatements d = render . vcat . map ((<> text ";\n") . statement d)
= value expressions
@ -438,6 +443,67 @@ which have been changed to try to improve the layout of the output.
> NullsFirst -> text "nulls" <+> text "first"
> NullsLast -> text "nulls" <+> text "last")
= statements
> statement :: Dialect -> Statement -> Doc
== ddl
> statement _ (CreateSchema nm) =
> text "create" <+> text "schema" <+> names nm
> statement _ (DropSchema nm db) =
> text "drop" <+> text "schema" <+> names nm <+> dropBehav db
== dml
> statement d (SelectStatement q) = queryExpr d q
> statement d (Delete t a w) =
> text "delete" <+> text "from"
> <+> names t <+> maybe empty (\x -> text "as" <+> name x) a
> <+> maybeValueExpr d "where" w
> statement _ (Truncate t ir) =
> text "truncate" <+> text "table" <+> names t
> <+> case ir of
> DefaultIdentityRestart -> empty
> ContinueIdentity -> text "continue" <+> text "identity"
> RestartIdentity -> text "restart" <+> text "identity"
> statement d (Insert t cs s) =
> text "insert" <+> text "into" <+> names t
> <+> maybe empty (\cs' -> parens (commaSep $ map name cs')) cs
> <+> case s of
> DefaultInsertValues -> text "default" <+> text "values"
> InsertQuery q -> queryExpr d q
> statement d (Update t a sts whr) =
> text "update" <+> names t
> <+> maybe empty (\x -> text "as" <+> name x) a
> <+> text "set" <+> commaSep (map sc sts)
> <+> maybeValueExpr d "where" whr
> where
> sc (Set tg v) = names tg <+> text "=" <+> valueExpr d v
> sc (SetMultiple ts vs) = parens (commaSep $ map names ts) <+> text "="
> <+> parens (commaSep $ map (valueExpr d) vs)
== access control
== transactions
== sessions
== extras
> dropBehav :: DropBehaviour -> Doc
> dropBehav DefaultDropBehaviour = empty
> dropBehav Cascade = text "cascade"
> dropBehav Restrict = text "restrict"
= utils
> commaSep :: [Doc] -> Doc

View file

@ -30,9 +30,15 @@
> ,TableRef(..)
> ,JoinType(..)
> ,JoinCondition(..)
> -- * dialect
> -- * Statements
> ,Statement(..)
> ,DropBehaviour(..)
> ,IdentityRestart(..)
> ,InsertSource(..)
> ,SetClause(..)
> -- * Dialect
> ,Dialect(..)
> -- * comment
> -- * Comment
> ,Comment(..)
> ) where
@ -380,6 +386,107 @@ I'm not sure if this is valid syntax or not.
> | JoinUsing [Name] -- ^ using (column list)
> deriving (Eq,Show,Read,Data,Typeable)
---------------------------
> data Statement =
> -- ddl
> CreateSchema [Name] -- XXX
> | DropSchema [Name] DropBehaviour -- XXX
> {- | CreateTable -- XXX
> | AlterTable -- XXX
> | DropTable -- XXX
> | CreateView -- XXX
> | DropView -- XXX
> | CreateDomain -- XXX
> | AlterDomain
> | DropDomain -- XXX
> | CreateCharacterSet
> | DropCharacterSet
> | CreateCollation
> | DropCollation
> | CreateTranslation
> | DropTranslation
> | CreateAssertion
> | DropAssertion
> | CreateTrigger
> | DropTrigger
> | CreateType
> | AlterType
> | DropType
> -- routine stuff?
> | CreateCast
> | DropCast
> | CreateOrdering
> | DropOrdering
> -- transforms
> | CreateSequence -- XXX
> | AlterSequence -- XXX
> | DropSequence -- XXX -}
> -- dml
> | SelectStatement QueryExpr
> {- | DeclareCursor
> | OpenCursor
> | FetchCursor
> | CloseCursor
> | SelectInto -}
> -- | DeletePositioned
> | Delete [Name] (Maybe Name) (Maybe ValueExpr)
> | Truncate [Name] IdentityRestart
> | Insert [Name] (Maybe [Name]) InsertSource
> -- | Merge
> | Update [Name] (Maybe Name) [SetClause] (Maybe ValueExpr)
> {- | TemporaryTable
> | FreeLocator
> | HoldLocator -}
> -- access control
> {- | GrantPrivilege
> | GrantRole
> | CreateRole
> | DropRole
> | RevokePrivilege
> | RevokeRole -}
> -- transaction management
> {- | StartTransaction
> | SetTransaction
> | SetContraints
> | SavePoint
> | ReleaseSavePoint
> | Rollback -}
> -- session
> {- | SetSessionCharacteristics
> | SetSessionAuthorization
> | SetRole
> | SetTimeZone
> | SetCatalog
> | SetSchema
> | SetNames
> | SetTransform
> | SetCollation -}
> deriving (Eq,Show,Read,Data,Typeable)
> data DropBehaviour =
> Restrict
> | Cascade
> | DefaultDropBehaviour
> deriving (Eq,Show,Read,Data,Typeable)
> data IdentityRestart =
> ContinueIdentity
> | RestartIdentity
> | DefaultIdentityRestart
> deriving (Eq,Show,Read,Data,Typeable)
> data InsertSource =
> InsertQuery QueryExpr
> | DefaultInsertValues
> deriving (Eq,Show,Read,Data,Typeable)
> data SetClause =
> Set [Name] ValueExpr
> | SetMultiple [[Name]] [ValueExpr]
> deriving (Eq,Show,Read,Data,Typeable)
--------------------------
> -- | Used to set the dialect used for parsing and pretty printing,
> -- very unfinished at the moment.
@ -388,7 +495,8 @@ I'm not sure if this is valid syntax or not.
> deriving (Eq,Show,Read,Data,Typeable)
> -- | Comment. Useful when generating SQL code programmatically.
> -- | Comment. Useful when generating SQL code programmatically. The
> -- parser doesn't produce these.
> data Comment = BlockComment String
> deriving (Eq,Show,Read,Data,Typeable)

View file

@ -4,9 +4,8 @@ synopsis: A parser for SQL.
description: A parser for SQL. Parses most SQL:2011
queries, DML, schema/DDL, transaction control,
session and connection management, access
control. Please see the homepage for more
information
session and access control. Please see the
homepage for more information
<http://jakewheat.github.io/simple-sql-parser/>.
homepage: http://jakewheat.github.io/simple-sql-parser/

View file

@ -8,11 +8,11 @@ query expressions from one string.
> import Language.SQL.SimpleSQL.Syntax
> queryExprsTests :: TestItem
> queryExprsTests = Group "query exprs" $ map (uncurry (TestQueryExprs SQL2011))
> queryExprsTests = Group "query exprs" $ map (uncurry (TestStatements SQL2011))
> [("select 1",[ms])
> ,("select 1;",[ms])
> ,("select 1;select 1",[ms,ms])
> ,(" select 1;select 1; ",[ms,ms])
> ]
> where
> ms = makeSelect {qeSelectList = [(NumLit "1",Nothing)]}
> ms = SelectStatement $ makeSelect {qeSelectList = [(NumLit "1",Nothing)]}

View file

@ -10,3 +10,110 @@ grant, etc
> sql2011AccessControlTests :: TestItem
> sql2011AccessControlTests = Group "sql 2011 access control tests" []
12 Access control
12.1 <grant statement>
<grant statement> ::=
<grant privilege statement>
| <grant role statement>
12.2 <grant privilege statement>
<grant privilege statement> ::=
GRANT <privileges> TO <grantee> [ { <comma> <grantee> }... ]
[ WITH HIERARCHY OPTION ]
[ WITH GRANT OPTION ]
[ GRANTED BY <grantor> ]
12.3 <privileges>
<privileges> ::=
<object privileges> ON <object name>
<object name> ::=
[ TABLE ] <table name>
| DOMAIN <domain name>
| COLLATION <collation name>
| CHARACTER SET <character set name>
| TRANSLATION <transliteration name>
| TYPE <schema-resolved user-defined type name>
| SEQUENCE <sequence generator name>
| <specific routine designator>
<object privileges> ::=
ALL PRIVILEGES
| <action> [ { <comma> <action> }... ]
<action> ::=
SELECT
| SELECT <left paren> <privilege column list> <right paren>
| SELECT <left paren> <privilege method list> <right paren>
| DELETE
| INSERT [ <left paren> <privilege column list> <right paren> ]
| UPDATE [ <left paren> <privilege column list> <right paren> ]
| REFERENCES [ <left paren> <privilege column list> <right paren> ]
| USAGE
| TRIGGER
| UNDER
| EXECUTE
<privilege method list> ::=
<specific routine designator> [ { <comma> <specific routine designator> }... ]
<privilege column list> ::=
<column name list>
<grantee> ::=
PUBLIC
| <authorization identifier>
<grantor> ::=
CURRENT_USER
| CURRENT_ROLE
12.4 <role definition>
<role definition> ::=
CREATE ROLE <role name> [ WITH ADMIN <grantor> ]
12.5 <grant role statement>
<grant role statement> ::=
GRANT <role granted> [ { <comma> <role granted> }... ]
TO <grantee> [ { <comma> <grantee> }... ]
[ WITH ADMIN OPTION ]
[ GRANTED BY <grantor> ]
<role granted> ::=
<role name>
12.6 <drop role statement>
<drop role statement> ::=
DROP ROLE <role name>
12.7 <revoke statement>
<revoke statement> ::=
<revoke privilege statement>
| <revoke role statement>
<revoke privilege statement> ::=
REVOKE [ <revoke option extension> ] <privileges>
FROM <grantee> [ { <comma> <grantee> }... ]
[ GRANTED BY <grantor> ]
<drop behavior>
<revoke option extension> ::=
GRANT OPTION FOR
| HIERARCHY OPTION FOR
<revoke role statement> ::=
REVOKE [ ADMIN OPTION FOR ] <role revoked> [ { <comma> <role revoked> }... ]
FROM <grantee> [ { <comma> <grantee> }... ]
[ GRANTED BY <grantor> ]
<drop behavior>
<role revoked> ::=
<role name>

View file

@ -1,9 +1,8 @@
Sections 16, 17, 18 and 19 in Foundation
Sections 17 and 19 in Foundation
This module covers the tests for control statements (call and return),
transaction management (begin, commit, savepoint, etc.), connection
management, and session management (set).
This module covers the tests for transaction management (begin,
commit, savepoint, etc.), and session management (set).
> module Language.SQL.SimpleSQL.SQL2011Bits (sql2011BitsTests) where
@ -13,3 +12,170 @@ management, and session management (set).
> sql2011BitsTests :: TestItem
> sql2011BitsTests = Group "sql 2011 bits tests" []
17 Transaction management
17.1 <start transaction statement>
<start transaction statement> ::=
START TRANSACTION [ <transaction characteristics> ]
BEGIN is not in the standard!
17.2 <set transaction statement>
<set transaction statement> ::=
SET [ LOCAL ] TRANSACTION <transaction characteristics>
17.3 <transaction characteristics>
<transaction characteristics> ::=
[ <transaction mode> [ { <comma> <transaction mode> }... ] ]
<transaction mode> ::=
<isolation level>
| <transaction access mode>
| <diagnostics size>
<transaction access mode> ::=
READ ONLY
| READ WRITE
<isolation level> ::=
ISOLATION LEVEL <level of isolation>
<level of isolation> ::=
READ UNCOMMITTED
| READ COMMITTED
| REPEATABLE READ
| SERIALIZABLE
<diagnostics size> ::=
DIAGNOSTICS SIZE <number of conditions>
<number of conditions> ::=
<simple value specification>
17.4 <set constraints mode statement>
<set constraints mode statement> ::=
SET CONSTRAINTS <constraint name list> { DEFERRED | IMMEDIATE }
<constraint name list> ::=
ALL
| <constraint name> [ { <comma> <constraint name> }... ]
17.5 <savepoint statement>
<savepoint statement> ::=
SAVEPOINT <savepoint specifier>
<savepoint specifier> ::=
<savepoint name>
17.6 <release savepoint statement>
<release savepoint statement> ::=
RELEASE SAVEPOINT <savepoint specifier>
17.7 <commit statement>
<commit statement> ::=
COMMIT [ WORK ] [ AND [ NO ] CHAIN ]
17.8 <rollback statement>
<rollback statement> ::=
ROLLBACK [ WORK ] [ AND [ NO ] CHAIN ] [ <savepoint clause> ]
<savepoint clause> ::=
TO SAVEPOINT <savepoint specifier>
19 Session management
19.1 <set session characteristics statement>
<set session characteristics statement> ::=
SET SESSION CHARACTERISTICS AS <session characteristic list>
<session characteristic list> ::=
<session characteristic> [ { <comma> <session characteristic> }... ]
<session characteristic> ::=
<session transaction characteristics>
<session transaction characteristics> ::=
TRANSACTION <transaction mode> [ { <comma> <transaction mode> }... ]
19.2 <set session user identifier statement>
<set session user identifier statement> ::=
SET SESSION AUTHORIZATION <value specification>
19.3 <set role statement>
<set role statement> ::=
SET ROLE <role specification>
<role specification> ::=
<value specification>
| NONE
19.4 <set local time zone statement>
<set local time zone statement> ::=
SET TIME ZONE <set time zone value>
<set time zone value> ::=
<interval value expression>
| LOCAL
19.5 <set catalog statement>
<set catalog statement> ::=
SET <catalog name characteristic>
<catalog name characteristic> ::=
CATALOG <value specification>
19.6 <set schema statement>
<set schema statement> ::=
SET <schema name characteristic>
<schema name characteristic> ::=
SCHEMA <value specification>
19.7 <set names statement>
<set names statement> ::=
SET <character set name characteristic>
<character set name characteristic> ::=
NAMES <value specification>
19.8 <set path statement>
<set path statement> ::=
SET <SQL-path characteristic>
<SQL-path characteristic> ::=
PATH <value specification>
19.9 <set transform group statement>
<set transform group statement> ::=
SET <transform group characteristic>
<transform group characteristic> ::=
DEFAULT TRANSFORM GROUP <value specification>
| TRANSFORM GROUP FOR TYPE <path-resolved user-defined type name> <value specification>
19.10 <set session collation statement>
<set session collation statement> ::=
SET COLLATION <collation specification> [ FOR <character set specification list> ]
| SET NO COLLATION [ FOR <character set specification list> ]
<collation specification> ::=
<value specification>

File diff suppressed because it is too large Load diff

View file

@ -2476,6 +2476,9 @@ Specify a function yielding a value of a multiset type.
<multiset set function> ::=
SET <left paren> <multiset value expression> <right paren>
TODO: set is now a reserved keyword. Fix the set parsing with a
special case term.
> multisetValueFunction :: TestItem
> multisetValueFunction = Group "multiset value function"
> $ map (uncurry (TestValueExpr SQL2011))

View file

@ -6,9 +6,11 @@ This module covers the tests for parsing schema and DDL statements.
> module Language.SQL.SimpleSQL.SQL2011Schema (sql2011SchemaTests) where
> import Language.SQL.SimpleSQL.TestTypes
> import Language.SQL.SimpleSQL.Syntax
> sql2011SchemaTests :: TestItem
> sql2011SchemaTests = Group "sql 2011 schema tests" []
> sql2011SchemaTests = Group "sql 2011 schema tests"
> [
11.1 <schema definition>
@ -18,6 +20,12 @@ This module covers the tests for parsing schema and DDL statements.
[ <schema character set or path> ]
[ <schema element>... ]
> (TestStatement SQL2011 "create schema my_schema"
> $ CreateSchema [Name "my_schema"])
todo: schema name can have .
schema name can be quoted iden or unicode quoted iden
<schema character set or path> ::=
<schema character set specification>
| <schema path specification>
@ -66,6 +74,14 @@ This module covers the tests for parsing schema and DDL statements.
CASCADE
| RESTRICT
> ,(TestStatement SQL2011 "drop schema my_schema"
> $ DropSchema [Name "my_schema"] DefaultDropBehaviour)
> ,(TestStatement SQL2011 "drop schema my_schema cascade"
> $ DropSchema [Name "my_schema"] Cascade)
> ,(TestStatement SQL2011 "drop schema my_schema restrict"
> $ DropSchema [Name "my_schema"] Restrict)
11.3 <table definition>
@ -74,6 +90,9 @@ This module covers the tests for parsing schema and DDL statements.
[ WITH <system versioning clause> ]
[ ON COMMIT <table commit action> ROWS ]
,(TestStatement SQL2011 "create table ( a int )"
<table contents source> ::=
<table element list>
| <typed table clause>
@ -1310,3 +1329,5 @@ This module covers the tests for parsing schema and DDL statements.
<drop sequence generator statement> ::=
DROP SEQUENCE <sequence generator name> <drop behavior>
> ]

View file

@ -17,7 +17,8 @@ to lots of tricky exceptions/variationsx.
> data TestItem = Group String [TestItem]
> | TestValueExpr Dialect String ValueExpr
> | TestQueryExpr Dialect String QueryExpr
> | TestQueryExprs Dialect String [QueryExpr]
> | TestStatement Dialect String Statement
> | TestStatements Dialect String [Statement]
this just checks the sql parses without error, mostly just a
intermediate when I'm too lazy to write out the parsed AST. These

View file

@ -73,8 +73,10 @@ order on the generated documentation.
> toTest parseValueExpr prettyValueExpr d str expected
> itemToTest (TestQueryExpr d str expected) =
> toTest parseQueryExpr prettyQueryExpr d str expected
> itemToTest (TestQueryExprs d str expected) =
> toTest parseQueryExprs prettyQueryExprs d str expected
> itemToTest (TestStatement d str expected) =
> toTest parseStatement prettyStatement d str expected
> itemToTest (TestStatements d str expected) =
> toTest parseStatements prettyStatements d str expected
> itemToTest (ParseQueryExpr d str) =
> toPTest parseQueryExpr prettyQueryExpr d str

View file

@ -67,7 +67,7 @@ indent: parse then pretty print sql
> (f,src) <- getInput args
> either (error . peFormattedError)
> (putStrLn . ppShow)
> $ parseQueryExprs SQL2011 f Nothing src
> $ parseStatements SQL2011 f Nothing src
> )
> lexCommand :: (String,[String] -> IO ())
@ -87,7 +87,7 @@ indent: parse then pretty print sql
> ,\args -> do
> (f,src) <- getInput args
> either (error . peFormattedError)
> (putStrLn . prettyQueryExprs SQL2011)
> $ parseQueryExprs SQL2011 f Nothing src
> (putStrLn . prettyStatements SQL2011)
> $ parseStatements SQL2011 f Nothing src
> )