diff --git a/Language/SQL/SimpleSQL/Parser.lhs b/Language/SQL/SimpleSQL/Parser.lhs
index b631cca..3321087 100644
--- a/Language/SQL/SimpleSQL/Parser.lhs
+++ b/Language/SQL/SimpleSQL/Parser.lhs
@@ -161,6 +161,19 @@ to be.
 >               return $ App i es
 >           _ -> return $ AggregateApp i d es (fromMaybe [] od)
 
+> windowSuffix :: ScalarExpr -> P ScalarExpr
+> windowSuffix e@(App f es) =
+>     choice [try (keyword_ "over")
+>             *> parens (WindowApp f es
+>                        <$> option [] partitionBy
+>                        <*> option [] orderBy)
+>            ,return e]
+>   where
+>     partitionBy = try (keyword_ "partition") >>
+>         keyword_ "by" >>
+>         commaSep1 scalarExpr'
+
+> windowSuffix e = return e
 
 > scase :: P ScalarExpr
 > scase =
@@ -308,7 +321,7 @@ postgresql handles this
 >                     ,extract
 >                     ,subquery
 >                     ,prefixUnaryOp
->                     ,try app
+>                     ,(try app) >>= windowSuffix
 >                     ,try dottedIden
 >                     ,identifier
 >                     ,sparens]
diff --git a/Language/SQL/SimpleSQL/Pretty.lhs b/Language/SQL/SimpleSQL/Pretty.lhs
index 8488d7b..8199e54 100644
--- a/Language/SQL/SimpleSQL/Pretty.lhs
+++ b/Language/SQL/SimpleSQL/Pretty.lhs
@@ -39,6 +39,15 @@ back into SQL source text. It attempts to format the output nicely.
 >                <+> commaSep (map scalarExpr es)
 >                <+> orderBy od)
 
+> scalarExpr (WindowApp f es pb od) =
+>     text f <> parens (commaSep $ map scalarExpr es)
+>     <+> text "over"
+>     <+> parens ((case pb of
+>                     [] -> empty
+>                     _ -> text "partition by"
+>                           <+> nest 4 (commaSep $ map scalarExpr pb))
+>                 <+> 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 0b9aaa2..c0cc67c 100644
--- a/Language/SQL/SimpleSQL/Syntax.lhs
+++ b/Language/SQL/SimpleSQL/Syntax.lhs
@@ -24,6 +24,7 @@
 >                 | AggregateApp String (Maybe Duplicates)
 >                                [ScalarExpr]
 >                                [(ScalarExpr,Direction)]
+>                 | WindowApp String [ScalarExpr] [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 2459177..0a78233 100644
--- a/Tests.lhs
+++ b/Tests.lhs
@@ -184,14 +184,20 @@
 
 > windowFunctions :: TestItem
 > windowFunctions = Group "windowFunctions" $ map (uncurry TestScalarExpr)
->     [{-("max(a) over ()", NumLit "1")
->     ,("count(*) over ()", NumLit "1")
->     ,("max(a) over (partition by b)", NumLit "1")
->     ,("sum(a) over (order by b)", NumLit "1")
->     ,("sum(a) over (partition by b order by c)", NumLit "1")
->     ,("sum(a) over (partition by b order by c)", NumLit "1")
+>     [("max(a) over ()", WindowApp "max" [Iden "a"] [] [])
+>     ,("count(*) over ()", WindowApp "count" [Star] [] [])
+>     ,("max(a) over (partition by b)"
+>      ,WindowApp "max" [Iden "a"] [Iden "b"] [])
+>     ,("max(a) over (partition by b,c)"
+>      ,WindowApp "max" [Iden "a"] [Iden "b",Iden "c"] [])
+>     ,("sum(a) over (order by b)"
+>      ,WindowApp "sum" [Iden "a"] [] [(Iden "b", Asc)])
+>     ,("sum(a) over (order by b desc,c)"
+>      ,WindowApp "sum" [Iden "a"] [] [(Iden "b", Desc)
+>                                     ,(Iden "c", Asc)])
+>     ,("sum(a) over (partition by b order by c)"
+>      ,WindowApp "sum" [Iden "a"] [Iden "b"] [(Iden "c", Asc)])
 >      -- todo: check order by options, add frames
->      -}
 >     ]
 
 > parens :: TestItem