From 0aa28ff96a7c68b397be95e102a451860565de91 Mon Sep 17 00:00:00 2001 From: Ignat Insarov Date: Sun, 20 Dec 2020 20:03:15 +0500 Subject: [PATCH] Fix handling of empty statements. --- Language/SQL/SimpleSQL/Parse.lhs | 15 +++++++-------- Language/SQL/SimpleSQL/Pretty.lhs | 13 +++++++++++-- Language/SQL/SimpleSQL/Syntax.lhs | 1 + simple-sql-parser.cabal | 3 ++- .../Language/SQL/SimpleSQL/EmptyStatement.lhs | 18 ++++++++++++++++++ tools/Language/SQL/SimpleSQL/Tests.lhs | 2 ++ 6 files changed, 41 insertions(+), 11 deletions(-) create mode 100644 tools/Language/SQL/SimpleSQL/EmptyStatement.lhs diff --git a/Language/SQL/SimpleSQL/Parse.lhs b/Language/SQL/SimpleSQL/Parse.lhs index ba5f684..e65b8ff 100644 --- a/Language/SQL/SimpleSQL/Parse.lhs +++ b/Language/SQL/SimpleSQL/Parse.lhs @@ -1450,14 +1450,14 @@ TODO: change style > topLevelQueryExpr = queryExpr (id <$ semi) > topLevelStatement :: Parser Statement -> topLevelStatement = statement (id <$ semi) +> topLevelStatement = statement ------------------------- = Statements -> statement :: Parser Statement -> statement = choice +> statementWithoutSemicolon :: Parser Statement +> statementWithoutSemicolon = choice > [keyword_ "create" *> choice [createSchema > ,createTable > ,createView @@ -1488,6 +1488,9 @@ TODO: change style > ,revoke > ,SelectStatement <$> queryExpr > ] +> +> statement :: Parser Statement +> statement = statementWithoutSemicolon <* optional semi <|> semi *> pure EmptyStatement > createSchema :: Parser Statement > createSchema = keyword_ "schema" >> @@ -1895,12 +1898,8 @@ 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 - > statements :: Parser [Statement] -> statements = (:[]) <$> statement -> >>= optionSuffix ((semi *>) . pure) -> >>= optionSuffix (\p -> (p++) <$> statements) +> statements = many statement ---------------------------------------------- diff --git a/Language/SQL/SimpleSQL/Pretty.lhs b/Language/SQL/SimpleSQL/Pretty.lhs index c5894dd..f611cb4 100644 --- a/Language/SQL/SimpleSQL/Pretty.lhs +++ b/Language/SQL/SimpleSQL/Pretty.lhs @@ -35,14 +35,22 @@ Try to do this when this code is ported to a modern pretty printing lib. > prettyScalarExpr :: Dialect -> ScalarExpr -> String > prettyScalarExpr d = render . scalarExpr d +> -- | A terminating semicolon. +> terminator :: Doc +> terminator = text ";\n" + > -- | Convert a statement ast to concrete syntax. > prettyStatement :: Dialect -> Statement -> String -> prettyStatement d = render . statement d +> prettyStatement _ EmptyStatement = render terminator +> prettyStatement d s = render (statement d s) > -- | Convert a list of statements to concrete syntax. A semicolon > -- is inserted after each statement. > prettyStatements :: Dialect -> [Statement] -> String -> prettyStatements d = render . vcat . map ((<> text ";\n") . statement d) +> prettyStatements d = render . vcat . map prettyStatementWithSemicolon +> where +> prettyStatementWithSemicolon :: Statement -> Doc +> prettyStatementWithSemicolon s = statement d s <> terminator = scalar expressions @@ -641,6 +649,7 @@ Try to do this when this code is ported to a modern pretty printing lib. > statement _ (StatementComment cs) = vcat $ map comment cs +> statement _ EmptyStatement = empty == sessions diff --git a/Language/SQL/SimpleSQL/Syntax.lhs b/Language/SQL/SimpleSQL/Syntax.lhs index 22d61c8..2253dcd 100644 --- a/Language/SQL/SimpleSQL/Syntax.lhs +++ b/Language/SQL/SimpleSQL/Syntax.lhs @@ -530,6 +530,7 @@ I'm not sure if this is valid syntax or not. > | SetTransform > | SetCollation -} > | StatementComment [Comment] +> | EmptyStatement > deriving (Eq,Show,Read,Data,Typeable) > data DropBehaviour = diff --git a/simple-sql-parser.cabal b/simple-sql-parser.cabal index 3536053..343f322 100644 --- a/simple-sql-parser.cabal +++ b/simple-sql-parser.cabal @@ -85,7 +85,8 @@ Test-Suite Tests Language.SQL.SimpleSQL.Tpch, Language.SQL.SimpleSQL.ScalarExprs, Language.SQL.SimpleSQL.LexerTests, - Language.SQL.SimpleSQL.CustomDialect + Language.SQL.SimpleSQL.CustomDialect, + Language.SQL.SimpleSQL.EmptyStatement ghc-options: -threaded executable SimpleSqlParserTool diff --git a/tools/Language/SQL/SimpleSQL/EmptyStatement.lhs b/tools/Language/SQL/SimpleSQL/EmptyStatement.lhs new file mode 100644 index 0000000..3ba0e0a --- /dev/null +++ b/tools/Language/SQL/SimpleSQL/EmptyStatement.lhs @@ -0,0 +1,18 @@ +> module Language.SQL.SimpleSQL.EmptyStatement where +> +> import Language.SQL.SimpleSQL.Syntax +> import Language.SQL.SimpleSQL.TestTypes +> +> emptyStatementTests :: TestItem +> emptyStatementTests = Group "empty statement" +> [ TestStatement ansi2011 ";" EmptyStatement +> , TestStatements ansi2011 ";" [EmptyStatement] +> , TestStatements ansi2011 ";;" [EmptyStatement, EmptyStatement] +> , TestStatements ansi2011 ";;;" [EmptyStatement, EmptyStatement, EmptyStatement] +> , TestStatement ansi2011 "/* comment */ ;" EmptyStatement +> , TestStatements ansi2011 "/* comment */ ;" [EmptyStatement] +> , TestStatements ansi2011 "/* comment */ ; /* comment */ ;" +> [EmptyStatement, EmptyStatement] +> , TestStatements ansi2011 "/* comment */ ; /* comment */ ; /* comment */ ;" +> [EmptyStatement, EmptyStatement, EmptyStatement] +> ] diff --git a/tools/Language/SQL/SimpleSQL/Tests.lhs b/tools/Language/SQL/SimpleSQL/Tests.lhs index 0c0c3ca..44c0a89 100644 --- a/tools/Language/SQL/SimpleSQL/Tests.lhs +++ b/tools/Language/SQL/SimpleSQL/Tests.lhs @@ -29,6 +29,7 @@ test data to the Test.Framework tests. > import Language.SQL.SimpleSQL.Odbc > import Language.SQL.SimpleSQL.Tpch > import Language.SQL.SimpleSQL.LexerTests +> import Language.SQL.SimpleSQL.EmptyStatement > import Language.SQL.SimpleSQL.SQL2011Queries > import Language.SQL.SimpleSQL.SQL2011AccessControl @@ -64,6 +65,7 @@ order on the generated documentation. > ,mySQLTests > ,oracleTests > ,customDialectTests +> ,emptyStatementTests > ] > tests :: T.TestTree