summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGravatar Adam Chlipala <adamc@hcoop.net>2008-08-28 12:56:08 -0400
committerGravatar Adam Chlipala <adamc@hcoop.net>2008-08-28 12:56:08 -0400
commit86b1f463ce9af2ddfcd86bb75279b9809b22db6a (patch)
treeb356ee03cb6af9e37de926271f5cc02376641fc9
parentfe8bd11ade81a5835d72c498a763c13c17fddd25 (diff)
More aggregate functions
-rw-r--r--lib/basis.lig19
-rw-r--r--src/lacweb.grm19
-rw-r--r--src/lacweb.lex4
-rw-r--r--tests/agg.lac5
4 files changed, 43 insertions, 4 deletions
diff --git a/lib/basis.lig b/lib/basis.lig
index 0b685301..f14a9233 100644
--- a/lib/basis.lig
+++ b/lib/basis.lig
@@ -121,13 +121,30 @@ val sql_gt : sql_comparison
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 *)
diff --git a/src/lacweb.grm b/src/lacweb.grm
index e230d91e..df01558e 100644
--- a/src/lacweb.grm
+++ b/src/lacweb.grm
@@ -110,7 +110,6 @@ fun sql_compare (oper, sqlexp1, sqlexp2, loc) =
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 @@ fun sql_relop (oper, sqlexp1, sqlexp2, loc) =
| 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 @@ fun sql_relop (oper, sqlexp1, sqlexp2, loc) =
| lopt of exp
| ofopt of exp
| sqlint of exp
+ | sqlagg of string
%verbose (* print summary of errors *)
@@ -831,6 +831,16 @@ sqlexp : TRUE (sql_inject (EVar (["Basis"], "True"),
(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 @@ ofopt : (EVar (["Basis"], "sql_no_offset"), dum
sqlint : INT (EPrim (Prim.Int INT), s (INTleft, INTright))
| LBRACE eexp RBRACE (eexp)
+
+sqlagg : AVG ("avg")
+ | SUM ("sum")
+ | MIN ("min")
+ | MAX ("max")
diff --git a/src/lacweb.lex b/src/lacweb.lex
index 08e39c81..5ba2f5c8 100644
--- a/src/lacweb.lex
+++ b/src/lacweb.lex
@@ -324,6 +324,10 @@ notags = [^<{\n]+;
<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));
diff --git a/tests/agg.lac b/tests/agg.lac
index 7061612b..f9b744e9 100644
--- a/tests/agg.lac
+++ b/tests/agg.lac
@@ -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)