changeset 1194:601a77af0477

'AS' clauses for expression columns may be omitted
author Adam Chlipala <adamc@hcoop.net>
date Thu, 25 Mar 2010 16:41:51 -0400
parents 1da49fd79e20
children aff5e661b5f8
files doc/manual.tex src/urweb.grm tests/agg.ur
diffstat 3 files changed, 22 insertions(+), 15 deletions(-) [+]
line wrap: on
line diff
--- a/doc/manual.tex	Thu Mar 25 16:27:10 2010 -0400
+++ b/doc/manual.tex	Thu Mar 25 16:41:51 2010 -0400
@@ -1959,6 +1959,7 @@
   &&& p,^+ & \textrm{particular columns} \\
   \textrm{Pre-projections} & p &::=& t.f & \textrm{one column from a table} \\
   &&& t.\{\{c\}\} & \textrm{a record of columns from a table (of kind $\{\mt{Type}\}$)} \\
+  &&& E \; [\mt{AS} \; f] & \textrm{expression column} \\
   \textrm{Table names} & t &::=& x & \textrm{constant table name (automatically capitalized)} \\
   &&& X & \textrm{constant table name} \\
   &&& \{\{c\}\} & \textrm{computed table name (of kind $\mt{Name}$)} \\
@@ -1997,6 +1998,8 @@
 
 Additionally, an SQL expression may be inserted into normal Ur code with the syntax $(\mt{SQL} \; E)$ or $(\mt{WHERE} \; E)$.  Similar shorthands exist for other nonterminals, with the prefix $\mt{FROM}$ for $\mt{FROM}$ items and $\mt{SELECT1}$ for pre-queries.
 
+Unnamed expression columns in $\mt{SELECT}$ clauses are assigned consecutive natural numbers, starting with 1.
+
 \subsubsection{DML}
 
 DML commands $D$ are added to the rules for expressions $e$.
--- a/src/urweb.grm	Thu Mar 25 16:27:10 2010 -0400
+++ b/src/urweb.grm	Thu Mar 25 16:41:51 2010 -0400
@@ -42,7 +42,7 @@
 
 datatype select_item =
          Field of con * con
-       | Exp of con * exp
+       | Exp of con option * exp
        | Fields of con * con
 
 datatype select =
@@ -58,7 +58,7 @@
       | (CName x1, CName x2) => x1 = x2
       | _ => false
 
-fun amend_select loc (si, (tabs, exps)) =
+fun amend_select loc (si, (count, tabs, exps)) =
     case si of
         Field (tx, fx) =>
         let
@@ -76,7 +76,7 @@
             else
                 ErrorMsg.errorAt loc "Select of field from unbound table";
             
-            (tabs, exps)
+            (count, tabs, exps)
         end
       | Fields (tx, fs) =>
         let
@@ -92,9 +92,10 @@
             else
                 ErrorMsg.errorAt loc "Select of field from unbound table";
             
-            (tabs, exps)
+            (count, tabs, exps)
         end
-      | Exp (c, e) => (tabs, (c, e) :: exps)
+      | Exp (SOME c, e) => (count, tabs, (c, e) :: exps)
+      | Exp (NONE, e) => (count+1, tabs, ((CName (Int.toString count), loc), e) :: exps)
 
 fun amend_group loc (gi, tabs) =
     let
@@ -1460,7 +1461,8 @@
                                                    | Items sis =>
                                                      let
                                                          val tabs = map (fn nm => (nm, (CRecord [], loc))) (#1 tables)
-                                                         val (tabs, exps) = foldl (amend_select loc) (tabs, []) sis
+                                                         val (_, tabs, exps) = foldl (amend_select loc)
+                                                                                     (1, tabs, []) sis
                                                          val empties = List.mapPartial (fn (nm, (CRecord [], _)) =>
                                                                                            SOME nm
                                                                                          | _ => NONE) tabs
@@ -1662,7 +1664,8 @@
        | LBRACE cexp RBRACE             (cexp)
 
 seli   : tident DOT fident              (Field (tident, fident))
-       | sqlexp AS fident               (Exp (fident, sqlexp))
+       | sqlexp                         (Exp (NONE, sqlexp))
+       | sqlexp AS fident               (Exp (SOME fident, sqlexp))
        | tident DOT LBRACE LBRACE cexp RBRACE RBRACE (Fields (tident, cexp))
 
 selis  : seli                           ([seli])
--- a/tests/agg.ur	Thu Mar 25 16:27:10 2010 -0400
+++ b/tests/agg.ur	Thu Mar 25 16:41:51 2010 -0400
@@ -1,13 +1,14 @@
 table t1 : {A : int, B : string, C : float}
 table t2 : {A : float, D : int, E : option string}
 
-val q1 = (SELECT COUNT( * ) AS X FROM t1)
-val q2 = (SELECT AVG(t1.A) AS X FROM t1)
-val q3 = (SELECT SUM(t1.C) AS X FROM t1)
-val q4 = (SELECT MIN(t1.B) AS X, MAX(t1.A) AS Y FROM t1)
-val q5 = (SELECT SUM(t1.A) AS X FROM t1 GROUP BY t1.B)
-val q6 = (SELECT COUNT(t2.E) AS N FROM t2 GROUP BY t2.D)
+val q1 : sql_query [] _ _ = (SELECT COUNT( * ) FROM t1)
+val q2 : sql_query [] _ _ = (SELECT AVG(t1.A) FROM t1)
+val q3 : sql_query [] _ _ = (SELECT SUM(t1.C) FROM t1)
+val q4 : sql_query [] _ _ = (SELECT MIN(t1.B), MAX(t1.A) FROM t1)
+val q5 : sql_query [] _ _ = (SELECT SUM(t1.A) FROM t1 GROUP BY t1.B)
+val q6 = (SELECT COUNT(t2.E) FROM t2 GROUP BY t2.D)
 
 fun main () : transaction page =
-    xml <- queryX q6 (fn r => <xml>{[r.N]};</xml>);
-    return <xml><body>{xml}</body></xml>
+    xml <- queryX q6 (fn r => <xml>{[r.1]};</xml>);
+    xml2 <- queryX q4 (fn r => <xml>{[r.1]}, {[r.2]};</xml>);
+    return <xml><body>{xml}<br/>{xml2}</body></xml>