diff --git a/TODO b/TODO
index dd1fb8b..cf6af47 100644
--- a/TODO
+++ b/TODO
@@ -34,7 +34,7 @@ keyword tree support prefix mode so can start from already parsed
do the final big left factor: typenames, interval lits, iden +
suffixes
-left factor/try removal summary (needs updating):
+left factor/try removal summary (this list needs updating):
identifier starts:
interval literal
@@ -61,19 +61,24 @@ rules for changing the multi keyword parsing:
if the keyword is optionally followed by another, e.g. with
recursive, then don't do this.
+change join defaults to be defaults
rough SQL 2011 todo, including tests to write:
review the commented out reserved keyword entries and work out how to
fix
+test case insensitvity and case preservation
+
big areas:
window functions
nested window functions
case
-table ref
-joined table
-group by
+
+table ref: tablesample, time period spec, only, unnest, table, lateral
+ bug
+joined table: partitioned joins
+group by: set quantifier
window clause
other areas:
@@ -113,11 +118,15 @@ member
submultiset
period
-create list of unsupported syntax: xml, ref, subtypes, modules?
+alias for * in select list
+create list of unsupported syntax: xml, ref, subtypes, modules?
+only
---
+
+
after next release
review areas where this parser is too permissive, e.g. value
diff --git a/tools/Language/SQL/SimpleSQL/SQL2011.lhs b/tools/Language/SQL/SimpleSQL/SQL2011.lhs
index d88ea48..0df8588 100644
--- a/tools/Language/SQL/SimpleSQL/SQL2011.lhs
+++ b/tools/Language/SQL/SimpleSQL/SQL2011.lhs
@@ -2501,10 +2501,12 @@ Specify construction of a multiset.
> [rowValueConstructor
> ,rowValueExpression
> ,tableValueConstructor
+> ,fromClause
> ,tableReference
> ,joinedTable
> ,whereClause
> ,groupByClause
+> ,havingClause
> ,windowClause
> ,querySpecification
> ,withQueryExpression
@@ -2635,11 +2637,26 @@ Specify a table derived from one or more tables.
::=
[ { }... ]
+> fromClause :: TestItem
+> fromClause = Group "fromClause"
+> $ map (uncurry TestQueryExpr)
+> [("select * from tbl1,tbl2"
+> ,makeSelect
+> {qeSelectList = [(Star, Nothing)]
+> ,qeFrom = [TRSimple [Name "tbl1"], TRSimple [Name "tbl2"]]
+> })]
+
+
== 7.6
Function
Reference a table.
+> tableReference :: TestItem
+> tableReference = Group "table reference"
+> $ map (uncurry TestQueryExpr)
+> [("select * from t", sel)
+
::= |
::= [ ]
@@ -2657,7 +2674,7 @@ Reference a table.
::=
::=
- [ ]
+ [ ]
[ [ AS ]
[ ] ]
| [ AS ]
@@ -2680,6 +2697,8 @@ Reference a table.
AND
| FOR SYSTEM_TIME FROM TO
+TODO: query system time period spec
+
::=
::=
@@ -2688,6 +2707,8 @@ Reference a table.
::= ONLY
+TODO: only
+
::= LATERAL
::=
@@ -2721,10 +2742,53 @@ Reference a table.
|
-> tableReference :: TestItem
-> tableReference = Group "table reference"
-> [-- todo: table reference
+
+> -- table or query name
+> ,("select * from t u", a sel)
+> ,("select * from t as u", a sel)
+> ,("select * from t u(a,b)", sel1 )
+> ,("select * from t as u(a,b)", sel1)
+> -- derived table TODO: realistic example
+> ,("select * from (select * from t) u"
+> ,a $ sel {qeFrom = [TRQueryExpr sel]})
+> -- lateral TODO: realistic example
+> ,("select * from lateral t"
+> ,af TRLateral sel)
+> -- TODO: bug, lateral should bind more tightly than the alias
+> --,("select * from lateral t u"
+> -- ,a $ af sel TRLateral)
+> -- collection TODO: realistic example
+> -- TODO: make it work
+> --,("select * from unnest(a)", undefined)
+> --,("select * from unnest(a,b)", undefined)
+> --,("select * from unnest(a,b) with ordinality", undefined)
+> --,("select * from unnest(a,b) with ordinality u", undefined)
+> --,("select * from unnest(a,b) with ordinality as u", undefined)
+> -- table fn TODO: realistic example
+> -- TODO: make it work
+> --,("select * from table(a)", undefined)
+> -- parens
+> ,("select * from (a join b)", jsel)
+> ,("select * from (a join b) u", a jsel)
+> ,("select * from ((a join b)) u", a $ af TRParens jsel)
+> ,("select * from ((a join b) u) u", a $ af TRParens $ a jsel)
> ]
+> where
+> sel = makeSelect
+> {qeSelectList = [(Star, Nothing)]
+> ,qeFrom = [TRSimple [Name "t"]]}
+> af f s = s {qeFrom = map f (qeFrom s)}
+> a s = af (\x -> TRAlias x $ Alias (Name "u") Nothing) s
+> sel1 = makeSelect
+> {qeSelectList = [(Star, Nothing)]
+> ,qeFrom = [TRAlias (TRSimple [Name "t"])
+> $ Alias (Name "u") $ Just [Name "a", Name "b"]]}
+> jsel = sel {qeFrom =
+> [TRParens $ TRJoin (TRSimple [Name "a"])
+> False
+> JInner
+> (TRSimple [Name "b"])
+> Nothing]}
== 7.7
@@ -2771,8 +2835,51 @@ Specify a table derived from a Cartesian product, inner join, or outer join.
> joinedTable :: TestItem
> joinedTable = Group "joined table"
-> [-- todo: joined table
+> $ map (uncurry TestQueryExpr)
+> [("select * from a cross join b"
+> ,sel $ TRJoin a False JCross b Nothing)
+> ,("select * from a join b on true"
+> ,sel $ TRJoin a False JInner b
+> (Just $ JoinOn $ Iden [Name "true"]))
+> ,("select * from a join b using (c)"
+> ,sel $ TRJoin a False JInner b
+> (Just $ JoinUsing [Name "c"]))
+> ,("select * from a inner join b on true"
+> ,sel $ TRJoin a False JInner b
+> (Just $ JoinOn $ Iden [Name "true"]))
+> ,("select * from a left join b on true"
+> ,sel $ TRJoin a False JLeft b
+> (Just $ JoinOn $ Iden [Name "true"]))
+> ,("select * from a left outer join b on true"
+> ,sel $ TRJoin a False JLeft b
+> (Just $ JoinOn $ Iden [Name "true"]))
+> ,("select * from a right join b on true"
+> ,sel $ TRJoin a False JRight b
+> (Just $ JoinOn $ Iden [Name "true"]))
+> ,("select * from a full join b on true"
+> ,sel $ TRJoin a False JFull b
+> (Just $ JoinOn $ Iden [Name "true"]))
+> ,("select * from a natural join b"
+> ,sel $ TRJoin a True JInner b Nothing)
+> ,("select * from a natural inner join b"
+> ,sel $ TRJoin a True JInner b Nothing)
+> ,("select * from a natural left join b"
+> ,sel $ TRJoin a True JLeft b Nothing)
+> ,("select * from a natural left outer join b"
+> ,sel $ TRJoin a True JLeft b Nothing)
+> ,("select * from a natural right join b"
+> ,sel $ TRJoin a True JRight b Nothing)
+> ,("select * from a natural full join b"
+> ,sel $ TRJoin a True JFull b Nothing)
> ]
+> where
+> sel t = makeSelect
+> {qeSelectList = [(Star, Nothing)]
+> ,qeFrom = [t]}
+> a = TRSimple [Name "a"]
+> b = TRSimple [Name "b"]
+
+TODO: partitioned joins
== 7.8
@@ -2842,6 +2949,46 @@ clause> to the result of the previously specified clause.
::=
+
+> groupByClause :: TestItem
+> groupByClause = Group "group by clause"
+> $ map (uncurry TestQueryExpr)
+> [("select a,sum(x) from t group by a"
+> ,qe [SimpleGroup $ Iden [Name "a"]])
+> ,("select a,sum(x) from t group by a collate c"
+> ,qe [SimpleGroup $ Collate (Iden [Name "a"]) [Name "c"]])
+> ,("select a,b,sum(x) from t group by a,b"
+> ,qex [SimpleGroup $ Iden [Name "a"]
+> ,SimpleGroup $ Iden [Name "b"]])
+> -- todo: group by set quantifier
+> --,("select a,sum(x) from t group by distinct a"
+> --,undefined)
+> --,("select a,sum(x) from t group by all a"
+> -- ,undefined)
+> ,("select a,b,sum(x) from t group by rollup(a,b)"
+> ,qex [Rollup [SimpleGroup $ Iden [Name "a"]
+> ,SimpleGroup $ Iden [Name "b"]]])
+> ,("select a,b,sum(x) from t group by cube(a,b)"
+> ,qex [Cube [SimpleGroup $ Iden [Name "a"]
+> ,SimpleGroup $ Iden [Name "b"]]])
+> ,("select a,b,sum(x) from t group by grouping sets((),(a,b))"
+> ,qex [GroupingSets [GroupingParens []
+> ,GroupingParens [SimpleGroup $ Iden [Name "a"]
+> ,SimpleGroup $ Iden [Name "b"]]]])
+> ,("select sum(x) from t group by ()"
+> ,let x = qe [GroupingParens []]
+> in x {qeSelectList = tail $ qeSelectList x})
+> ]
+> where
+> qe g = makeSelect
+> {qeSelectList = [(Iden [Name "a"], Nothing)
+> ,(App [Name "sum"] [Iden [Name "x"]], Nothing)]
+> ,qeFrom = [TRSimple [Name "t"]]
+> ,qeGroupBy = g}
+> qex g = let x = qe g
+> in x {qeSelectList = let [a,b] = qeSelectList x
+> in [a,(Iden [Name "b"],Nothing),b]}
+
== 7.10
Function
@@ -2851,9 +2998,18 @@ not satisfy a .
::= HAVING
-> groupByClause :: TestItem
-> groupByClause = Group "group by clause"
-> [-- todo: group by clause
+> havingClause :: TestItem
+> havingClause = Group "having clause"
+> $ map (uncurry TestQueryExpr)
+> [("select a,sum(x) from t group by a having sum(x) > 1000"
+> ,makeSelect
+> {qeSelectList = [(Iden [Name "a"], Nothing)
+> ,(App [Name "sum"] [Iden [Name "x"]], Nothing)]
+> ,qeFrom = [TRSimple [Name "t"]]
+> ,qeGroupBy = [SimpleGroup $ Iden [Name "a"]]
+> ,qeHaving = Just $ BinOp (App [Name "sum"] [Iden [Name "x"]])
+> [Name ">"]
+> (NumLit "1000")})
> ]
== 7.11