changeset 1192:9c82548c97e9

Subquery FROM items
author Adam Chlipala <adamc@hcoop.net>
date Thu, 25 Mar 2010 16:06:04 -0400
parents 61c3139eab12
children 1da49fd79e20
files lib/ur/basis.urs src/monoize.sml src/urweb.grm tests/subquery.ur
diffstat 4 files changed, 37 insertions(+), 4 deletions(-) [+]
line wrap: on
line diff
--- a/lib/ur/basis.urs	Thu Mar 25 15:44:24 2010 -0400
+++ b/lib/ur/basis.urs	Thu Mar 25 16:06:04 2010 -0400
@@ -295,6 +295,9 @@
 val sql_from_table : free ::: {{Type}} -> t ::: Type -> fs ::: {Type}
                      -> fieldsOf t fs -> name :: Name
                      -> t -> sql_from_items free [name = fs]
+val sql_from_query : free ::: {{Type}} -> fs ::: {Type} -> name :: Name
+                     -> sql_query free [] fs
+                     -> sql_from_items free [name = fs]
 val sql_from_comma : free ::: {{Type}} -> tabs1 ::: {{Type}} -> tabs2 ::: {{Type}}
                      -> [tabs1 ~ tabs2]
     => sql_from_items free tabs1 -> sql_from_items free tabs2
--- a/src/monoize.sml	Thu Mar 25 15:44:24 2010 -0400
+++ b/src/monoize.sml	Thu Mar 25 16:06:04 2010 -0400
@@ -1882,7 +1882,7 @@
                                            strcatComma (map (fn (x, t) =>
                                                                 strcat [
                                                                 (L'.EField (gf "SelectExps", x), loc),
-                                                                sc (" AS _" ^ x)
+                                                                sc (" AS uw_" ^ x)
                                                             ]) sexps
                                                         @ map (fn (x, xts) =>
                                                                   strcatComma
@@ -2059,6 +2059,19 @@
                                    (L'.EPrim (Prim.String (" AS T_" ^ name)), loc)]), loc),
                  fm)
             end
+          | L.ECApp ((L.ECApp ((L.ECApp ((L.EFfi ("Basis", "sql_from_query"), _), _),
+                                          _), _), _),
+                     (L.CName name, _)) =>
+            let
+                val s = (L'.TFfi ("Basis", "string"), loc)
+                fun sc s = (L'.EPrim (Prim.String s), loc)
+            in
+                ((L'.EAbs ("q", s, s,
+                           strcat [sc "(",
+                                   (L'.ERel 0, loc),
+                                   sc (") AS T_" ^ name)]), loc),
+                 fm)
+            end
           | L.ECApp ((L.ECApp ((L.ECApp ((L.EFfi ("Basis", "sql_from_comma"), _), _), _), _), _), _) =>
             let
                 val s = (L'.TFfi ("Basis", "string"), loc)
@@ -2317,7 +2330,7 @@
                _), _),
               _), _),
              _), _),
-            (L.CName nm, _)) => ((L'.EPrim (Prim.String ("_" ^ lowercaseFirst nm)), loc), fm)
+            (L.CName nm, _)) => ((L'.EPrim (Prim.String ("uw_" ^ lowercaseFirst nm)), loc), fm)
 
           | L.ECApp (
             (L.ECApp (
--- a/src/urweb.grm	Thu Mar 25 15:44:24 2010 -0400
+++ b/src/urweb.grm	Thu Mar 25 16:06:04 2010 -0400
@@ -1629,6 +1629,14 @@
                                              (#1 fitem1 @ #1 fitem2,
                                               (EApp (e, sqlexp), loc))
                                          end)
+       | LPAREN query RPAREN AS tname   (let
+                                             val loc = s (LPARENleft, RPARENright)
+                                                       
+                                             val e = (EVar (["Basis"], "sql_from_query", Infer), loc)
+                                             val e = (ECApp (e, tname), loc)
+                                         in
+                                             ([tname], (EApp (e, query), loc))
+                                         end)
 
 tname  : CSYMBOL                        (CName CSYMBOL, s (CSYMBOLleft, CSYMBOLright))
        | LBRACE cexp RBRACE             (cexp)
--- a/tests/subquery.ur	Thu Mar 25 15:44:24 2010 -0400
+++ b/tests/subquery.ur	Thu Mar 25 16:06:04 2010 -0400
@@ -6,5 +6,14 @@
                   WHERE t.B = (SELECT MAX(U.B) AS M
                                FROM t AS U
                                WHERE U.A = t.A))
-         (fn r => <xml>{[r.A]},{[r.C]};</xml>);
-    return <xml>{v}</xml>
+                 (fn r => <xml>{[r.A]},{[r.C]};</xml>);
+    v' <- queryX1 (SELECT t.A, t.C
+                   FROM (SELECT t.A AS A, MAX(t.B) AS B
+                         FROM t
+                         GROUP BY t.A) AS Maxes
+                   JOIN t ON t.A = Maxes.A AND t.B = Maxes.B)
+                  (fn r => <xml>{[r.A]},{[r.C]};</xml>);
+    return <xml><body>
+      {v}<br/>
+      {v'}
+    </body></xml>