summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorGravatar Adam Chlipala <adam@chlipala.net>2012-06-03 11:29:31 -0400
committerGravatar Adam Chlipala <adam@chlipala.net>2012-06-03 11:29:31 -0400
commit797db05343b520b16ea4f8eeab5fea6255d3284d (patch)
treedeacf0a9ebedccbc3e22fdb143c51d3dcc153a5b /src
parent858481a426ea3873440c3bed30eb563f8cf3480e (diff)
Lighter-weight encoding of window function use
Diffstat (limited to 'src')
-rw-r--r--src/elab_err.sml6
-rw-r--r--src/monoize.sml280
-rw-r--r--src/settings.sml2
-rw-r--r--src/urweb.grm87
-rw-r--r--src/urweb.lex4
5 files changed, 190 insertions, 189 deletions
diff --git a/src/elab_err.sml b/src/elab_err.sml
index 0e04cf51..4754d4ce 100644
--- a/src/elab_err.sml
+++ b/src/elab_err.sml
@@ -242,7 +242,11 @@ fun expError env err =
eprefaces' ([("Class constraint", p_con env c)]
@ (case E.resolveFailureCause () of
NONE => []
- | SOME c' => [("Reduced to unresolvable", p_con env c')])))
+ | SOME c' => [("Reduced to unresolvable", p_con env c')]))(*;
+ app (fn (c, rs) => (eprefaces' [("CLASS", p_con env c)];
+ app (fn (c, e) => eprefaces' [("RULE", p_con env c),
+ ("IMPL", p_exp env e)]) rs))
+ (E.listClasses env)*))
| IllegalRec (x, e) =>
(ErrorMsg.errorAt (#2 e) "Illegal 'val rec' righthand side (must be a function abstraction)";
eprefaces' [("Variable", PD.string x),
diff --git a/src/monoize.sml b/src/monoize.sml
index 8224b26f..4985c932 100644
--- a/src/monoize.sml
+++ b/src/monoize.sml
@@ -249,7 +249,13 @@ fun monoType env =
(L'.TFfi ("Basis", "string"), loc)
| L.CApp ((L.CApp ((L.CFfi ("Basis", "sql_from_items"), _), _), _), _) =>
(L'.TFfi ("Basis", "string"), loc)
- | L.CApp ((L.CApp ((L.CApp ((L.CApp ((L.CApp ((L.CFfi ("Basis", "sql_exp"), _), _), _), _), _), _), _), _), _), _) =>
+ | L.CApp ((L.CApp ((L.CApp ((L.CApp ((L.CFfi ("Basis", "sql_exp"), _), _), _), _), _), _), _), _) =>
+ (L'.TFfi ("Basis", "string"), loc)
+ | L.CApp ((L.CApp ((L.CApp ((L.CApp ((L.CFfi ("Basis", "sql_expw"), _), _), _), _), _), _), _), _) =>
+ (L'.TFfi ("Basis", "string"), loc)
+ | L.CApp ((L.CFfi ("Basis", "sql_window"), _), _) =>
+ (L'.TRecord [], loc)
+ | L.CApp ((L.CApp ((L.CApp ((L.CApp ((L.CFfi ("Basis", "sql_window_function"), _), _), _), _), _), _), _), _) =>
(L'.TFfi ("Basis", "string"), loc)
| L.CApp ((L.CApp ((L.CFfi ("Basis", "primary_key"), _), _), _), _) =>
(L'.TFfi ("Basis", "string"), loc)
@@ -299,16 +305,16 @@ fun monoType env =
(L'.TRecord [], loc)
| L.CApp ((L.CFfi ("Basis", "sql_maxable"), _), _) =>
(L'.TRecord [], loc)
- | L.CApp ((L.CApp ((L.CApp ((L.CFfi ("Basis", "sql_partition"), _), _), _), _), _), _) =>
- (L'.TFfi ("Basis", "string"), loc)
- | L.CApp ((L.CApp ((L.CApp ((L.CApp ((L.CFfi ("Basis", "sql_window"), _), _), _), _), _), _), _), _) =>
- (L'.TFfi ("Basis", "string"), loc)
| L.CApp ((L.CFfi ("Basis", "sql_arith"), _), _) =>
(L'.TRecord [], loc)
| L.CApp ((L.CFfi ("Basis", "sql_nfunc"), _), _) =>
(L'.TFfi ("Basis", "string"), loc)
| L.CApp ((L.CApp ((L.CFfi ("Basis", "sql_ufunc"), _), _), _), _) =>
(L'.TFfi ("Basis", "string"), loc)
+ | L.CApp ((L.CApp ((L.CApp ((L.CFfi ("Basis", "sql_partition"), _), _), _), _), _), _) =>
+ (L'.TFfi ("Basis", "string"), loc)
+ | L.CApp ((L.CApp ((L.CApp ((L.CApp ((L.CFfi ("Basis", "sql_window"), _), _), _), _), _), _), _), _) =>
+ (L'.TFfi ("Basis", "string"), loc)
| L.CApp ((L.CFfi ("Basis", "channel"), _), _) =>
(L'.TFfi ("Basis", "channel"), loc)
@@ -2111,9 +2117,7 @@ fun monoExp (env, st, fm) (all as (e, loc)) =
(L.ECApp (
(L.ECApp (
(L.ECApp (
- (L.ECApp (
- (L.EFfi ("Basis", "sql_inject"), _),
- _), _),
+ (L.EFfi ("Basis", "sql_inject"), _),
_), _),
_), _),
_), _),
@@ -2426,7 +2430,9 @@ fun monoExp (env, st, fm) (all as (e, loc)) =
| L.ECApp (
(L.ECApp (
(L.ECApp (
- (L.EFfi ("Basis", "sql_order_by_Cons"), _),
+ (L.ECApp (
+ (L.EFfi ("Basis", "sql_order_by_Cons"), _),
+ _), _),
_), _),
_), _),
_) =>
@@ -2434,19 +2440,20 @@ fun monoExp (env, st, fm) (all as (e, loc)) =
val s = (L'.TFfi ("Basis", "string"), loc)
fun sc s = (L'.EPrim (Prim.String s), loc)
in
- ((L'.EAbs ("e1", s, (L'.TFun (s, (L'.TFun (s, s), loc)), loc),
- (L'.EAbs ("d", s, (L'.TFun (s, s), loc),
- (L'.EAbs ("e2", s, s,
- (L'.ECase ((L'.ERel 0, loc),
- [((L'.PPrim (Prim.String ""), loc),
- strcat [(L'.ERel 2, loc),
- (L'.ERel 1, loc)]),
- ((L'.PWild, loc),
- strcat [(L'.ERel 2, loc),
- (L'.ERel 1, loc),
- sc ", ",
- (L'.ERel 0, loc)])],
- {disc = s, result = s}), loc)), loc)), loc)), loc),
+ ((L'.EAbs ("_", (L'.TRecord [], loc), (L'.TFun (s, (L'.TFun (s, (L'.TFun (s, s), loc)), loc)), loc),
+ (L'.EAbs ("e1", s, (L'.TFun (s, (L'.TFun (s, s), loc)), loc),
+ (L'.EAbs ("d", s, (L'.TFun (s, s), loc),
+ (L'.EAbs ("e2", s, s,
+ (L'.ECase ((L'.ERel 0, loc),
+ [((L'.PPrim (Prim.String ""), loc),
+ strcat [(L'.ERel 2, loc),
+ (L'.ERel 1, loc)]),
+ ((L'.PWild, loc),
+ strcat [(L'.ERel 2, loc),
+ (L'.ERel 1, loc),
+ sc ", ",
+ (L'.ERel 0, loc)])],
+ {disc = s, result = s}), loc)), loc)), loc)), loc)), loc),
fm)
end
@@ -2512,10 +2519,8 @@ fun monoExp (env, st, fm) (all as (e, loc)) =
(L.ECApp (
(L.ECApp (
(L.ECApp (
- (L.ECApp (
(L.EFfi ("Basis", "sql_unary"), _),
_), _),
- _), _),
_), _),
_), _),
_), _),
@@ -2544,9 +2549,7 @@ fun monoExp (env, st, fm) (all as (e, loc)) =
(L.ECApp (
(L.ECApp (
(L.ECApp (
- (L.ECApp (
- (L.EFfi ("Basis", "sql_binary"), _),
- _), _),
+ (L.EFfi ("Basis", "sql_binary"), _),
_), _),
_), _),
_), _),
@@ -2579,9 +2582,7 @@ fun monoExp (env, st, fm) (all as (e, loc)) =
(L.ECApp (
(L.ECApp (
(L.ECApp (
- (L.ECApp (
- (L.EFfi ("Basis", "sql_field"), _),
- _), _),
+ (L.EFfi ("Basis", "sql_field"), _),
_), _),
_), _),
_), _),
@@ -2595,9 +2596,7 @@ fun monoExp (env, st, fm) (all as (e, loc)) =
(L.ECApp (
(L.ECApp (
(L.ECApp (
- (L.ECApp (
- (L.EFfi ("Basis", "sql_exp"), _),
- _), _),
+ (L.EFfi ("Basis", "sql_exp"), _),
_), _),
_), _),
_), _),
@@ -2701,9 +2700,7 @@ fun monoExp (env, st, fm) (all as (e, loc)) =
| L.ECApp (
(L.ECApp (
(L.ECApp (
- (L.ECApp (
- (L.EFfi ("Basis", "sql_count"), _),
- _), _),
+ (L.EFfi ("Basis", "sql_count"), _),
_), _),
_), _),
_) => ((L'.EPrim (Prim.String "COUNT(*)"), loc),
@@ -2714,9 +2711,7 @@ fun monoExp (env, st, fm) (all as (e, loc)) =
(L.ECApp (
(L.ECApp (
(L.ECApp (
- (L.ECApp (
- (L.EFfi ("Basis", "sql_aggregate"), _),
- _), _),
+ (L.EFfi ("Basis", "sql_aggregate"), _),
_), _),
_), _),
_), _),
@@ -2732,7 +2727,7 @@ fun monoExp (env, st, fm) (all as (e, loc)) =
sc ")"]
in
((L'.EAbs ("c", s, (L'.TFun (s, (L'.TFun (s, s), loc)), loc),
- (L'.EAbs ("e1", s, s, main), loc)), loc),
+ (L'.EAbs ("e1", s, (L'.TFun (s, s), loc), main), loc)), loc),
fm)
end
@@ -2781,73 +2776,33 @@ fun monoExp (env, st, fm) (all as (e, loc)) =
(L'.EPrim (Prim.String "MIN"), loc)), loc)), loc),
fm)
- | L.ECApp (
- (L.ECApp (
- (L.ECApp (
- (L.EFfi ("Basis", "sql_no_partition"), _),
- _), _),
- _), _),
- _) => ((L'.EPrim (Prim.String ""), loc), fm)
- | L.ECApp (
- (L.ECApp (
- (L.ECApp (
- (L.ECApp (
- (L.EFfi ("Basis", "sql_partition"), _),
- _), _),
- _), _),
- _), _),
- _) =>
- let
- val s = (L'.TFfi ("Basis", "string"), loc)
- in
- ((L'.EAbs ("e", s, s, strcat [(L'.EPrim (Prim.String "PARTITION BY "), loc), (L'.ERel 0, loc)]), loc),
- fm)
- end
-
+ | L.EFfi ("Basis", "sql_asc") => ((L'.EPrim (Prim.String ""), loc), fm)
+ | L.EFfi ("Basis", "sql_desc") => ((L'.EPrim (Prim.String " DESC"), loc), fm)
| L.ECApp (
(L.ECApp (
(L.ECApp (
(L.ECApp (
- (L.EFfi ("Basis", "sql_window"), _),
+ (L.EFfi ("Basis", "sql_nfunc"), _),
_), _),
_), _),
_), _),
- _) =>
+ _) =>
let
- val () = if #windowFunctions (Settings.currentDbms ()) then
- ()
- else
- ErrorMsg.errorAt loc "The DBMS you've selected doesn't support window functions."
-
val s = (L'.TFfi ("Basis", "string"), loc)
fun sc s = (L'.EPrim (Prim.String s), loc)
-
- val main = strcat [(L'.ERel 2, loc),
- sc " OVER (",
- (L'.ERel 1, loc),
- (L'.ECase ((L'.ERel 0, loc),
- [((L'.PPrim (Prim.String ""), loc),
- sc ""),
- ((L'.PWild, loc),
- strcat [sc " ORDER BY ",
- (L'.ERel 0, loc)])],
- {disc = s,
- result = s}), loc),
- sc ")"]
in
- ((L'.EAbs ("w", s, (L'.TFun (s, (L'.TFun (s, s), loc)), loc),
- (L'.EAbs ("p", s, (L'.TFun (s, s), loc),
- (L'.EAbs ("o", s, s,
- main), loc)), loc)), loc),
+ ((L'.EAbs ("s", s, s, (L'.ERel 0, loc)), loc),
fm)
end
+ | L.EFfi ("Basis", "sql_window_normal") => ((L'.ERecord [], loc), fm)
+ | L.EFfi ("Basis", "sql_window_fancy") => ((L'.ERecord [], loc), fm)
| L.ECApp (
(L.ECApp (
(L.ECApp (
(L.ECApp (
(L.ECApp (
- (L.EFfi ("Basis", "sql_window_aggregate"), _),
+ (L.EFfi ("Basis", "sql_window"), _),
_), _),
_), _),
_), _),
@@ -2855,43 +2810,13 @@ fun monoExp (env, st, fm) (all as (e, loc)) =
_) =>
let
val s = (L'.TFfi ("Basis", "string"), loc)
- fun sc s = (L'.EPrim (Prim.String s), loc)
-
- val main = strcat [(L'.ERel 1, loc),
- sc "(",
- (L'.ERel 0, loc),
- sc ")"]
in
- ((L'.EAbs ("c", s, (L'.TFun (s, (L'.TFun (s, s), loc)), loc),
- (L'.EAbs ("e1", s, s, main), loc)), loc),
+ ((L'.EAbs ("_", (L'.TRecord [], loc), (L'.TFun (s, s), loc),
+ (L'.EAbs ("e", s, s,
+ (L'.ERel 0, loc)), loc)), loc),
fm)
end
- | L.ECApp ((L.ECApp ((L.ECApp ((L.EFfi ("Basis", "sql_window_count"), _), _), _), _), _), _) =>
- ((L'.EPrim (Prim.String "COUNT(*)"), loc), fm)
- | L.ECApp ((L.ECApp ((L.ECApp ((L.EFfi ("Basis", "sql_window_rank"), _), _), _), _), _), _) =>
- ((L'.EPrim (Prim.String "RANK()"), loc), fm)
-
- | L.EFfi ("Basis", "sql_asc") => ((L'.EPrim (Prim.String ""), loc), fm)
- | L.EFfi ("Basis", "sql_desc") => ((L'.EPrim (Prim.String " DESC"), loc), fm)
- | L.ECApp (
- (L.ECApp (
- (L.ECApp (
- (L.ECApp (
- (L.ECApp (
- (L.EFfi ("Basis", "sql_nfunc"), _),
- _), _),
- _), _),
- _), _),
- _), _),
- _) =>
- let
- val s = (L'.TFfi ("Basis", "string"), loc)
- fun sc s = (L'.EPrim (Prim.String s), loc)
- in
- ((L'.EAbs ("s", s, s, (L'.ERel 0, loc)), loc),
- fm)
- end
| L.EFfi ("Basis", "sql_current_timestamp") => ((L'.EPrim (Prim.String "CURRENT_TIMESTAMP"), loc), fm)
| L.ECApp (
@@ -2899,9 +2824,7 @@ fun monoExp (env, st, fm) (all as (e, loc)) =
(L.ECApp (
(L.ECApp (
(L.ECApp (
- (L.ECApp (
- (L.EFfi ("Basis", "sql_ufunc"), _),
- _), _),
+ (L.EFfi ("Basis", "sql_ufunc"), _),
_), _),
_), _),
_), _),
@@ -2935,9 +2858,7 @@ fun monoExp (env, st, fm) (all as (e, loc)) =
(L.ECApp (
(L.ECApp (
(L.ECApp (
- (L.ECApp (
- (L.EFfi ("Basis", "sql_is_null"), _), _),
- _), _),
+ (L.EFfi ("Basis", "sql_is_null"), _), _),
_), _),
_), _),
_), _)) =>
@@ -2978,11 +2899,7 @@ fun monoExp (env, st, fm) (all as (e, loc)) =
(L.ECApp (
(L.ECApp (
(L.ECApp (
- (L.ECApp (
- (L.ECApp (
- (L.EFfi ("Basis", "sql_if_then_else"), _), _),
- _), _),
- _), _),
+ (L.EFfi ("Basis", "sql_if_then_else"), _), _),
_), _),
_), _),
_), _)) =>
@@ -3007,9 +2924,7 @@ fun monoExp (env, st, fm) (all as (e, loc)) =
(L.ECApp (
(L.ECApp (
(L.ECApp (
- (L.ECApp (
- (L.EFfi ("Basis", "sql_nullable"), _),
- _), _),
+ (L.EFfi ("Basis", "sql_nullable"), _),
_), _),
_), _),
_), _),
@@ -3030,9 +2945,7 @@ fun monoExp (env, st, fm) (all as (e, loc)) =
(L.ECApp (
(L.ECApp (
(L.ECApp (
- (L.ECApp (
- (L.EFfi ("Basis", "sql_subquery"), _),
- _), _),
+ (L.EFfi ("Basis", "sql_subquery"), _),
_), _),
_), _),
_), _),
@@ -3051,6 +2964,97 @@ fun monoExp (env, st, fm) (all as (e, loc)) =
fm)
end
+ | L.ECApp (
+ (L.ECApp (
+ (L.ECApp (
+ (L.EFfi ("Basis", "sql_no_partition"), _),
+ _), _),
+ _), _),
+ _) => ((L'.EPrim (Prim.String ""), loc), fm)
+ | L.ECApp (
+ (L.ECApp (
+ (L.ECApp (
+ (L.ECApp (
+ (L.EFfi ("Basis", "sql_partition"), _),
+ _), _),
+ _), _),
+ _), _),
+ _) =>
+ let
+ val s = (L'.TFfi ("Basis", "string"), loc)
+ in
+ ((L'.EAbs ("e", s, s, strcat [(L'.EPrim (Prim.String "PARTITION BY "), loc), (L'.ERel 0, loc)]), loc),
+ fm)
+ end
+
+ | L.ECApp (
+ (L.ECApp (
+ (L.ECApp (
+ (L.ECApp (
+ (L.EFfi ("Basis", "sql_window_function"), _),
+ _), _),
+ _), _),
+ _), _),
+ _) =>
+ let
+ val () = if #windowFunctions (Settings.currentDbms ()) then
+ ()
+ else
+ ErrorMsg.errorAt loc "The DBMS you've selected doesn't support window functions."
+
+ val s = (L'.TFfi ("Basis", "string"), loc)
+ fun sc s = (L'.EPrim (Prim.String s), loc)
+
+ val main = strcat [(L'.ERel 2, loc),
+ sc " OVER (",
+ (L'.ERel 1, loc),
+ (L'.ECase ((L'.ERel 0, loc),
+ [((L'.PPrim (Prim.String ""), loc),
+ sc ""),
+ ((L'.PWild, loc),
+ strcat [sc " ORDER BY ",
+ (L'.ERel 0, loc)])],
+ {disc = s,
+ result = s}), loc),
+ sc ")"]
+ in
+ ((L'.EAbs ("w", s, (L'.TFun (s, (L'.TFun (s, s), loc)), loc),
+ (L'.EAbs ("p", s, (L'.TFun (s, s), loc),
+ (L'.EAbs ("o", s, s,
+ main), loc)), loc)), loc),
+ fm)
+ end
+
+ | L.ECApp (
+ (L.ECApp (
+ (L.ECApp (
+ (L.ECApp (
+ (L.ECApp (
+ (L.EFfi ("Basis", "sql_window_aggregate"), _),
+ _), _),
+ _), _),
+ _), _),
+ _), _),
+ _) =>
+ let
+ val s = (L'.TFfi ("Basis", "string"), loc)
+ fun sc s = (L'.EPrim (Prim.String s), loc)
+
+ val main = strcat [(L'.ERel 1, loc),
+ sc "(",
+ (L'.ERel 0, loc),
+ sc ")"]
+ in
+ ((L'.EAbs ("c", s, (L'.TFun (s, (L'.TFun (s, s), loc)), loc),
+ (L'.EAbs ("e1", s, s, main), loc)), loc),
+ fm)
+ end
+
+ | L.ECApp ((L.ECApp ((L.ECApp ((L.EFfi ("Basis", "sql_window_count"), _), _), _), _), _), _) =>
+ ((L'.EPrim (Prim.String "COUNT(*)"), loc), fm)
+ | L.ECApp ((L.ECApp ((L.ECApp ((L.EFfi ("Basis", "sql_rank"), _), _), _), _), _), _) =>
+ ((L'.EPrim (Prim.String "RANK()"), loc), fm)
+
| L.EFfiApp ("Basis", "nextval", [(e, _)]) =>
let
val (e, fm) = monoExp (env, st, fm) e
diff --git a/src/settings.sml b/src/settings.sml
index 3b89ce46..28739d6a 100644
--- a/src/settings.sml
+++ b/src/settings.sml
@@ -538,7 +538,7 @@ type dbms = {
falseString : string,
onlyUnion : bool,
nestedRelops : bool,
- windowFunctions : bool
+ windowFunctions: bool
}
val dbmses = ref ([] : dbms list)
diff --git a/src/urweb.grm b/src/urweb.grm
index eec8f8c1..708e5fcd 100644
--- a/src/urweb.grm
+++ b/src/urweb.grm
@@ -309,7 +309,7 @@ fun applyWindow loc e window =
(ECApp ((EVar (["Basis"], "sql_order_by_Nil", Infer), dummy),
(CWild (KRecord (KType, dummy), dummy), dummy)),
dummy)))
- val e' = (EVar (["Basis"], "sql_window", Infer), loc)
+ val e' = (EVar (["Basis"], "sql_window_function", Infer), loc)
val e' = (EApp (e', e), loc)
val e' = (EApp (e', pb), loc)
in
@@ -345,7 +345,7 @@ fun applyWindow loc e window =
| UNION | INTERSECT | EXCEPT
| LIMIT | OFFSET | ALL
| TRUE | FALSE | CAND | OR | NOT
- | COUNT | AVG | SUM | MIN | MAX | RANK
+ | COUNT | AVG | SUM | MIN | MAX | RANK | PARTITION | OVER
| ASC | DESC | RANDOM
| INSERT | INTO | VALUES | UPDATE | SET | DELETE | NULL | IS | COALESCE | LIKE
| CURRENT_TIMESTAMP
@@ -353,7 +353,6 @@ fun applyWindow loc e window =
| CCONSTRAINT | UNIQUE | CHECK | PRIMARY | FOREIGN | KEY | ON | NO | ACTION | RESTRICT | CASCADE | REFERENCES
| JOIN | INNER | CROSS | OUTER | LEFT | RIGHT | FULL
| CIF | CTHEN | CELSE
- | OVER | PARTITION
%nonterm
file of decl list
@@ -1755,6 +1754,8 @@ query1 : SELECT dopt select FROM tables wopt gopt hopt
exps)
end
+ val exps = map (fn (c, e) => (c, (EApp ((EVar (["Basis"], "sql_window", Infer), loc), e), loc))) exps
+
val sel = (CRecord sel, loc)
val grp = case gopt of
@@ -2041,49 +2042,37 @@ sqlexp : TRUE (sql_inject (EVar (["Basis"], "True", In
| NULL (sql_inject ((EVar (["Basis"], "None", Infer),
s (NULLleft, NULLright))))
- | COUNT LPAREN STAR RPAREN window (let
- val loc = s (COUNTleft, windowright)
- in
- case window of
- NONE => (EVar (["Basis"], "sql_count", Infer), loc)
- | SOME _ =>
- let
- val e = (EVar (["Basis"], "sql_window_count", Infer), loc)
- in
- applyWindow loc e window
- end
- end)
- | RANK UNIT window (let
- val loc = s (RANKleft, windowright)
- val e = (EVar (["Basis"], "sql_window_rank", Infer), loc)
- in
- applyWindow loc e window
- end)
- | COUNT LPAREN sqlexp RPAREN window (let
- val loc = s (COUNTleft, windowright)
-
- val e = (EVar (["Basis"], "sql_count_col", Infer), loc)
- in
- case window of
- NONE =>
- let
- val e = (EApp ((EVar (["Basis"], "sql_aggregate", Infer), loc),
- e), loc)
- in
- (EApp (e, sqlexp), loc)
- end
- | SOME _ =>
- let
- val e = (EApp ((EVar (["Basis"], "sql_window_aggregate", Infer), loc),
- e), loc)
- val e = (EApp (e, sqlexp), loc)
- in
- applyWindow loc e window
- end
- end)
+ | COUNT LPAREN STAR RPAREN window(let
+ val loc = s (COUNTleft, windowright)
+ in
+ case window of
+ NONE => (EVar (["Basis"], "sql_count", Infer), loc)
+ | SOME _ => applyWindow loc (EVar (["Basis"], "sql_window_count", Infer), loc) window
+ end)
+ | COUNT LPAREN sqlexp RPAREN window(let
+ val loc = s (COUNTleft, RPARENright)
+ val e = (EVar (["Basis"], "sql_count_col", Infer), loc)
+ in
+ case window of
+ NONE =>
+ let
+ val e = (EApp ((EVar (["Basis"], "sql_aggregate", Infer), loc),
+ e), loc)
+ in
+ (EApp (e, sqlexp), loc)
+ end
+ | SOME _ =>
+ let
+ val e = (EVar (["Basis"], "sql_count_col", Infer), loc)
+ val e = (EApp ((EVar (["Basis"], "sql_window_aggregate", Infer), loc),
+ e), loc)
+ in
+ applyWindow loc (EApp (e, sqlexp), loc) window
+ end
+ end)
| sqlagg LPAREN sqlexp RPAREN window (let
- val loc = s (sqlaggleft, windowright)
-
+ val loc = s (sqlaggleft, RPARENright)
+
val e = (EVar (["Basis"], "sql_" ^ sqlagg, Infer), loc)
in
case window of
@@ -2098,11 +2087,15 @@ sqlexp : TRUE (sql_inject (EVar (["Basis"], "True", In
let
val e = (EApp ((EVar (["Basis"], "sql_window_aggregate", Infer), loc),
e), loc)
- val e = (EApp (e, sqlexp), loc)
in
- applyWindow loc e window
+ applyWindow loc (EApp (e, sqlexp), loc) window
end
end)
+ | RANK UNIT window (let
+ val loc = s (RANKleft, windowright)
+ in
+ applyWindow loc (EVar (["Basis"], "sql_rank", Infer), loc) window
+ end)
| COALESCE LPAREN sqlexp COMMA sqlexp RPAREN
(let
val loc = s (COALESCEright, sqlexp2right)
diff --git a/src/urweb.lex b/src/urweb.lex
index 272c5e65..0994ecec 100644
--- a/src/urweb.lex
+++ b/src/urweb.lex
@@ -463,8 +463,6 @@ xint = x[0-9a-fA-F][0-9a-fA-F];
<INITIAL> "OFFSET" => (Tokens.OFFSET (pos yypos, pos yypos + size yytext));
<INITIAL> "ALL" => (Tokens.ALL (pos yypos, pos yypos + size yytext));
<INITIAL> "SELECT1" => (Tokens.SELECT1 (pos yypos, pos yypos + size yytext));
-<INITIAL> "OVER" => (Tokens.OVER (pos yypos, pos yypos + size yytext));
-<INITIAL> "PARTITION" => (Tokens.PARTITION (pos yypos, pos yypos + size yytext));
<INITIAL> "JOIN" => (Tokens.JOIN (pos yypos, pos yypos + size yytext));
<INITIAL> "INNER" => (Tokens.INNER (pos yypos, pos yypos + size yytext));
@@ -490,6 +488,8 @@ xint = x[0-9a-fA-F][0-9a-fA-F];
<INITIAL> "MIN" => (Tokens.MIN (pos yypos, pos yypos + size yytext));
<INITIAL> "MAX" => (Tokens.MAX (pos yypos, pos yypos + size yytext));
<INITIAL> "RANK" => (Tokens.RANK (pos yypos, pos yypos + size yytext));
+<INITIAL> "PARTITION" => (Tokens.PARTITION (pos yypos, pos yypos + size yytext));
+<INITIAL> "OVER" => (Tokens.OVER (pos yypos, pos yypos + size yytext));
<INITIAL> "IF" => (Tokens.CIF (pos yypos, pos yypos + size yytext));
<INITIAL> "THEN" => (Tokens.CTHEN (pos yypos, pos yypos + size yytext));