# HG changeset patch # User Adam Chlipala # Date 1219942568 14400 # Node ID f5732dc1316cfdc63cd3f9298d30966c7506f229 # Parent 0608a0cfd32a5a840719df18306cbe977ae32525 More aggregate functions diff -r 0608a0cfd32a -r f5732dc1316c lib/basis.lig --- 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 *) diff -r 0608a0cfd32a -r f5732dc1316c src/lacweb.grm --- 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") diff -r 0608a0cfd32a -r f5732dc1316c src/lacweb.lex --- 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 @@ "NOT" => (Tokens.NOT (pos yypos, pos yypos + size yytext)); "COUNT" => (Tokens.COUNT (pos yypos, pos yypos + size yytext)); + "AVG" => (Tokens.AVG (pos yypos, pos yypos + size yytext)); + "SUM" => (Tokens.SUM (pos yypos, pos yypos + size yytext)); + "MIN" => (Tokens.MIN (pos yypos, pos yypos + size yytext)); + "MAX" => (Tokens.MAX (pos yypos, pos yypos + size yytext)); {id} => (Tokens.SYMBOL (yytext, pos yypos, pos yypos + size yytext)); {cid} => (Tokens.CSYMBOL (yytext, pos yypos, pos yypos + size yytext)); diff -r 0608a0cfd32a -r f5732dc1316c tests/agg.lac --- 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)