changeset 236:f5732dc1316c

More aggregate functions
author Adam Chlipala <adamc@hcoop.net>
date Thu, 28 Aug 2008 12:56:08 -0400
parents 0608a0cfd32a
children 9182068c9d7c
files lib/basis.lig src/lacweb.grm src/lacweb.lex tests/agg.lac
diffstat 4 files changed, 43 insertions(+), 4 deletions(-) [+]
line wrap: on
line diff
--- a/lib/basis.lig	Thu Aug 28 11:59:46 2008 -0400
+++ b/lib/basis.lig	Thu Aug 28 12:56:08 2008 -0400
@@ -121,13 +121,30 @@
 val sql_ge : sql_comparison
 val sql_comparison : sql_comparison
         -> tables ::: {{Type}} -> agg ::: {{Type}} -> exps ::: {Type}
-        -> t ::: Type -> sql_injectable t
+        -> t ::: Type
         -> sql_exp tables agg exps t -> sql_exp tables agg exps t
         -> sql_exp tables agg exps bool
 
 val sql_count : tables ::: {{Type}} -> agg ::: {{Type}} -> exps ::: {Type}
         -> unit -> sql_exp tables agg exps int
 
+con sql_aggregate :: Type -> Type
+val sql_aggregate : tables ::: {{Type}} -> agg ::: {{Type}} -> exps ::: {Type} -> t ::: Type
+        -> sql_aggregate t -> sql_exp agg agg exps t -> sql_exp tables agg exps t
+
+class sql_summable
+val sql_summable_int : sql_summable int
+val sql_summable_float : sql_summable float
+val sql_avg : t ::: Type -> sql_summable t -> sql_aggregate t
+val sql_sum : t ::: Type -> sql_summable t -> sql_aggregate t
+
+class sql_maxable
+val sql_maxable_int : sql_maxable int
+val sql_maxable_float : sql_maxable float
+val sql_maxable_string : sql_maxable string
+val sql_max : t ::: Type -> sql_maxable t -> sql_aggregate t
+val sql_min : t ::: Type -> sql_maxable t -> sql_aggregate t
+
 
 (** XML *)
 
--- a/src/lacweb.grm	Thu Aug 28 11:59:46 2008 -0400
+++ b/src/lacweb.grm	Thu Aug 28 12:56:08 2008 -0400
@@ -110,7 +110,6 @@
     let
         val e = (EVar (["Basis"], "sql_comparison"), loc)
         val e = (EApp (e, (EVar (["Basis"], "sql_" ^ oper), loc)), loc)
-        val e = (EApp (e, (EWild, loc)), loc)
         val e = (EApp (e, sqlexp1), loc)
     in
         (EApp (e, sqlexp2), loc)
@@ -169,7 +168,7 @@
  | UNION | INTERSECT | EXCEPT
  | LIMIT | OFFSET | ALL
  | TRUE | FALSE | CAND | OR | NOT
- | COUNT
+ | COUNT | AVG | SUM | MIN | MAX
  | NE | LT | LE | GT | GE
 
 %nonterm
@@ -253,6 +252,7 @@
  | lopt of exp
  | ofopt of exp
  | sqlint of exp
+ | sqlagg of string
 
 
 %verbose                                (* print summary of errors *)
@@ -831,6 +831,16 @@
                                              (EApp ((EVar (["Basis"], "sql_count"), loc),
                                                     (ERecord [], loc)), loc)
                                          end)
+       | sqlagg LPAREN sqlexp RPAREN    (let
+                                             val loc = s (sqlaggleft, RPARENright)
+
+                                             val e = (EApp ((EVar (["Basis"], "sql_" ^ sqlagg), loc),
+                                                            (EWild, loc)), loc)
+                                             val e = (EApp ((EVar (["Basis"], "sql_aggregate"), loc),
+                                                            e), loc)
+                                         in
+                                             (EApp (e, sqlexp), loc)
+                                         end)
 
 wopt   :                                (sql_inject (EVar (["Basis"], "True"),
                                                      EVar (["Basis"], "sql_bool"),
@@ -892,3 +902,8 @@
 
 sqlint : INT                             (EPrim (Prim.Int INT), s (INTleft, INTright))
        | LBRACE eexp RBRACE              (eexp)
+
+sqlagg : AVG                             ("avg")
+       | SUM                             ("sum")
+       | MIN                             ("min")
+       | MAX                             ("max")
--- a/src/lacweb.lex	Thu Aug 28 11:59:46 2008 -0400
+++ b/src/lacweb.lex	Thu Aug 28 12:56:08 2008 -0400
@@ -324,6 +324,10 @@
 <INITIAL> "NOT"       => (Tokens.NOT (pos yypos, pos yypos + size yytext));
 
 <INITIAL> "COUNT"     => (Tokens.COUNT (pos yypos, pos yypos + size yytext));
+<INITIAL> "AVG"       => (Tokens.AVG (pos yypos, pos yypos + size yytext));
+<INITIAL> "SUM"       => (Tokens.SUM (pos yypos, pos yypos + size yytext));
+<INITIAL> "MIN"       => (Tokens.MIN (pos yypos, pos yypos + size yytext));
+<INITIAL> "MAX"       => (Tokens.MAX (pos yypos, pos yypos + size yytext));
 
 <INITIAL> {id}        => (Tokens.SYMBOL (yytext, pos yypos, pos yypos + size yytext));
 <INITIAL> {cid}       => (Tokens.CSYMBOL (yytext, pos yypos, pos yypos + size yytext));
--- a/tests/agg.lac	Thu Aug 28 11:59:46 2008 -0400
+++ b/tests/agg.lac	Thu Aug 28 12:56:08 2008 -0400
@@ -1,4 +1,7 @@
 table t1 : {A : int, B : string, C : float}
 table t2 : {A : float, D : int}
 
-val q1 = (SELECT COUNT( * ) AS N FROM t1)
+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)