diff --git a/Language/SQL/SimpleSQL/Parser.lhs b/Language/SQL/SimpleSQL/Parser.lhs index 1ce6f41..b631cca 100644 --- a/Language/SQL/SimpleSQL/Parser.lhs +++ b/Language/SQL/SimpleSQL/Parser.lhs @@ -148,10 +148,19 @@ to be. > app :: P ScalarExpr -> app = App <$> identifierString -> -- support for count(*) -> <*> parens (choice[(:[]) <$> try star -> ,commaSep scalarExpr']) +> app = do +> i <- identifierString +> _ <- symbol "(" +> d <- try duplicates +> es <- choice [(:[]) <$> try star +> ,commaSep scalarExpr'] +> od <- try $ optionMaybe orderBy +> _ <- symbol ")" +> case (d,od) of +> (Nothing,Nothing) -> +> return $ App i es +> _ -> return $ AggregateApp i d es (fromMaybe [] od) + > scase :: P ScalarExpr > scase = @@ -406,9 +415,10 @@ attempt to fix the precedence and associativity. Doesn't work = query expressions -> duplicates :: P Duplicates -> duplicates = option All $ try $ choice [All <$ keyword_ "all" -> ,Distinct <$ keyword "distinct"] +> duplicates :: P (Maybe Duplicates) +> duplicates = optionMaybe $ try $ +> choice [All <$ keyword_ "all" +> ,Distinct <$ keyword "distinct"] > selectItem :: P (Maybe String, ScalarExpr) > selectItem = flip (,) <$> scalarExpr <*> optionMaybe (try alias) @@ -472,9 +482,9 @@ attempt to fix the precedence and associativity. Doesn't work > having = optionalScalarExpr "having" > orderBy :: P [(ScalarExpr,Direction)] -> orderBy = option [] (try (keyword_ "order") -> *> keyword_ "by" -> *> commaSep1 ob) +> orderBy = try (keyword_ "order") +> *> keyword_ "by" +> *> commaSep1 ob > where > ob = (,) <$> scalarExpr > <*> option Asc (choice [Asc <$ keyword_ "asc" @@ -491,13 +501,13 @@ attempt to fix the precedence and associativity. Doesn't work > queryExpr = > try (keyword_ "select") >> > Select -> <$> duplicates +> <$> (fromMaybe All <$> duplicates) > <*> selectList > <*> from > <*> swhere > <*> sgroupBy > <*> having -> <*> orderBy +> <*> option [] orderBy > <*> limit > <*> offset diff --git a/Language/SQL/SimpleSQL/Pretty.lhs b/Language/SQL/SimpleSQL/Pretty.lhs index 333494c..8488d7b 100644 --- a/Language/SQL/SimpleSQL/Pretty.lhs +++ b/Language/SQL/SimpleSQL/Pretty.lhs @@ -30,6 +30,15 @@ back into SQL source text. It attempts to format the output nicely. > scalarExpr (App f es) = text f <> parens (commaSep (map scalarExpr es)) +> scalarExpr (AggregateApp f d es od) = +> text f +> <> parens ((case d of +> Just Distinct -> text "distinct" +> Just All -> text "all" +> Nothing -> empty) +> <+> commaSep (map scalarExpr es) +> <+> orderBy od) + > scalarExpr (SpecialOp nm [a,b,c]) | nm `elem` ["between", "not between"] = > sep [scalarExpr a > ,text nm <+> scalarExpr b diff --git a/Language/SQL/SimpleSQL/Syntax.lhs b/Language/SQL/SimpleSQL/Syntax.lhs index 4708ccd..0b9aaa2 100644 --- a/Language/SQL/SimpleSQL/Syntax.lhs +++ b/Language/SQL/SimpleSQL/Syntax.lhs @@ -21,6 +21,9 @@ > | Star > | Star2 String > | App String [ScalarExpr] +> | AggregateApp String (Maybe Duplicates) +> [ScalarExpr] +> [(ScalarExpr,Direction)] > -- the binop, prefixop and postfix op > -- are used for symbol and keyword operators > -- these are used even for the multiple keyword diff --git a/Tests.lhs b/Tests.lhs index d6b7e61..2459177 100644 --- a/Tests.lhs +++ b/Tests.lhs @@ -173,10 +173,13 @@ > aggregates :: TestItem > aggregates = Group "aggregates" $ map (uncurry TestScalarExpr) -> [{-("count(*)",NumLit "1") -> ,("sum(a order by a)",NumLit "1") -> ,("sum(all a)",NumLit "1") -> ,("count(distinct a)",NumLit "1")-} +> [("count(*)",App "count" [Star]) +> ,("sum(a order by a)" +> ,AggregateApp "sum" Nothing [Iden "a"] [(Iden "a", Asc)]) +> ,("sum(all a)" +> ,AggregateApp "sum" (Just All) [Iden "a"] []) +> ,("count(distinct a)" +> ,AggregateApp "count" (Just Distinct) [Iden "a"] []) > ] > windowFunctions :: TestItem