From 939189a04f2ffc61eca8260b4abd0b3fd1eb303f Mon Sep 17 00:00:00 2001 From: Jake Wheat Date: Tue, 17 Dec 2013 12:45:32 +0200 Subject: [PATCH] partial support for lateral --- Language/SQL/SimpleSQL/Parser.lhs | 3 ++- Language/SQL/SimpleSQL/Pretty.lhs | 1 + Language/SQL/SimpleSQL/Syntax.lhs | 2 ++ tools/Language/SQL/SimpleSQL/Postgres.lhs | 14 ++++++------- tools/Language/SQL/SimpleSQL/TableRefs.lhs | 24 ++++++++++++++++++++++ 5 files changed, 36 insertions(+), 8 deletions(-) diff --git a/Language/SQL/SimpleSQL/Parser.lhs b/Language/SQL/SimpleSQL/Parser.lhs index 690fab7..e00e888 100644 --- a/Language/SQL/SimpleSQL/Parser.lhs +++ b/Language/SQL/SimpleSQL/Parser.lhs @@ -505,6 +505,7 @@ tref > tref = nonJoinTref >>= optionSuffix joinTrefSuffix > nonJoinTref = choice [try (TRQueryExpr <$> parens queryExpr) > ,TRParens <$> parens tref +> ,TRLateral <$> (try (keyword_ "lateral") *> tref) > ,try (TRFunction <$> identifierString > <*> parens (commaSep scalarExpr)) > ,TRSimple <$> identifierString] @@ -690,7 +691,7 @@ keyword parser also > ["select", "as", "from", "where", "having", "group", "order" > ,"limit", "offset" > ,"inner", "left", "right", "full", "natural", "join" -> ,"cross", "on", "using" +> ,"cross", "on", "using", "lateral" > ,"when", "then", "case", "end", "in" > ,"except", "intersect", "union"] diff --git a/Language/SQL/SimpleSQL/Pretty.lhs b/Language/SQL/SimpleSQL/Pretty.lhs index f7c1f0e..62de7e5 100644 --- a/Language/SQL/SimpleSQL/Pretty.lhs +++ b/Language/SQL/SimpleSQL/Pretty.lhs @@ -182,6 +182,7 @@ > ,nest 5 $ vcat $ punctuate comma $ map tr ts] > where > tr (TRSimple t) = text t +> tr (TRLateral t) = text "lateral" <+> tr t > tr (TRFunction f as) = > text f <> parens (commaSep $ map scalarExpr as) > tr (TRAlias t a cs) = diff --git a/Language/SQL/SimpleSQL/Syntax.lhs b/Language/SQL/SimpleSQL/Syntax.lhs index 9cfc630..43f5fcd 100644 --- a/Language/SQL/SimpleSQL/Syntax.lhs +++ b/Language/SQL/SimpleSQL/Syntax.lhs @@ -197,6 +197,8 @@ I'm not sure if this is valid syntax or not. > | TRQueryExpr QueryExpr > -- | from function(args) > | TRFunction String [ScalarExpr] +> -- | from lateral t +> | TRLateral TableRef > deriving (Eq,Show,Read) TODO: add function table ref diff --git a/tools/Language/SQL/SimpleSQL/Postgres.lhs b/tools/Language/SQL/SimpleSQL/Postgres.lhs index 5d6cd32..39b6a61 100644 --- a/tools/Language/SQL/SimpleSQL/Postgres.lhs +++ b/tools/Language/SQL/SimpleSQL/Postgres.lhs @@ -51,7 +51,7 @@ queries section > ,"SELECT * FROM people AS mother JOIN people AS child ON mother.id = child.mother_id;" > ,"SELECT * FROM my_table AS a CROSS JOIN my_table AS b;" > ,"SELECT * FROM (my_table AS a CROSS JOIN my_table) AS b;" -> ,"SELECT * FROM getfoo(1) AS t1;" -- function tableref +> ,"SELECT * FROM getfoo(1) AS t1;" > ,"SELECT * FROM foo\n\ > \ WHERE foosubid IN (\n\ > \ SELECT foosubid\n\ @@ -63,23 +63,23 @@ queries section > \ AS t1(proname name, prosrc text)\n\ > \ WHERE proname LIKE 'bytea%';"-} -- types in the alias?? -> --,"SELECT * FROM foo, LATERAL (SELECT * FROM bar WHERE bar.id = foo.bar_id) ss;" -- lateral +> ,"SELECT * FROM foo, LATERAL (SELECT * FROM bar WHERE bar.id = foo.bar_id) ss;" -- lateral > ,"SELECT * FROM foo, bar WHERE bar.id = foo.bar_id;" > {-,"SELECT p1.id, p2.id, v1, v2\n\ > \FROM polygons p1, polygons p2,\n\ > \ LATERAL vertices(p1.poly) v1,\n\ > \ LATERAL vertices(p2.poly) v2\n\ -> \WHERE (v1 <-> v2) < 10 AND p1.id != p2.id;"-} -- <-> operator?, lateral +> \WHERE (v1 <-> v2) < 10 AND p1.id != p2.id;"-} -- <-> operator? > {-,"SELECT p1.id, p2.id, v1, v2\n\ > \FROM polygons p1 CROSS JOIN LATERAL vertices(p1.poly) v1,\n\ > \ polygons p2 CROSS JOIN LATERAL vertices(p2.poly) v2\n\ > \WHERE (v1 <-> v2) < 10 AND p1.id != p2.id;"-} -> {-,"SELECT m.name\n\ +> ,"SELECT m.name\n\ > \FROM manufacturers m LEFT JOIN LATERAL get_product_names(m.id) pname ON true\n\ -> \WHERE pname IS NULL;"-} -- lateral, function ref +> \WHERE pname IS NULL;" > ,"SELECT * FROM fdt WHERE c1 > 5" @@ -253,11 +253,11 @@ select page reference > \ )\n\ > \SELECT distance, employee_name FROM employee_recursive;"-} -- with recursive, full cte alias -> {-,"SELECT m.name AS mname, pname\n\ +> ,"SELECT m.name AS mname, pname\n\ > \FROM manufacturers m, LATERAL get_product_names(m.id) pname;" > ,"SELECT m.name AS mname, pname\n\ -> \FROM manufacturers m LEFT JOIN LATERAL get_product_names(m.id) pname ON true;"-} -- lateral +> \FROM manufacturers m LEFT JOIN LATERAL get_product_names(m.id) pname ON true;" > ,"SELECT 2+2;" diff --git a/tools/Language/SQL/SimpleSQL/TableRefs.lhs b/tools/Language/SQL/SimpleSQL/TableRefs.lhs index e00e74c..17884c0 100644 --- a/tools/Language/SQL/SimpleSQL/TableRefs.lhs +++ b/tools/Language/SQL/SimpleSQL/TableRefs.lhs @@ -19,6 +19,30 @@ expression > ,("select a from t,u" > ,ms [TRSimple "t", TRSimple "u"]) +these lateral queries make no sense but the syntax is valid + +> ,("select a from lateral a" +> ,ms [TRLateral $ TRSimple "a"]) + +> ,("select a from lateral a,b" +> ,ms [TRLateral $ TRSimple "a", TRSimple "b"]) + +> -- not sure what the problem is +> --,("select from a, lateral b" +> -- ,ms [TRSimple "a", TRLateral $ TRSimple "b"]) + +> ,("select a from a natural join lateral b" +> ,ms [TRJoin (TRSimple "a") JInner +> (TRLateral $ TRSimple "b") +> (Just JoinNatural)]) + +> -- the lateral binds on the outside of the join which is incorrect +> --,("select a from lateral a natural join lateral b" +> -- ,ms [TRJoin (TRLateral $ TRSimple "a") JInner +> -- (TRLateral $ TRSimple "b") +> -- (Just JoinNatural)]) + + > ,("select a from t inner join u on expr" > ,ms [TRJoin (TRSimple "t") JInner (TRSimple "u") > (Just $ JoinOn $ Iden "expr")])