1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
|
open StdLabels
module Path = ImportDataTypes.Path
module Expression = ImportExpression.T
type t = {
filters : Path.t Expression.t list;
group : Path.t Expression.t option;
}
(** Ensure the group criteria in window functions match the global group by
criteria.
Traverse the configuration tree until finding a group window. *)
(** Check if the expression contains a group function *)
let matchWindowGroup : 'a ImportExpression.T.t -> bool =
fun expression ->
let exception Found in
let open ImportExpression.T in
let rec f = function
| Empty | Literal _ | Integer _ | Path _ -> ()
| Expr e -> f e
| Concat pp | Function' (_, pp) | Function (_, pp) | Nvl pp | Join (_, pp)
-> List.iter ~f pp
| Window (_, _, _) -> raise Found
| BOperator (_, arg1, arg2) ->
f arg1;
f arg2
| GEquality (_, arg1, args) ->
f arg1;
List.iter ~f args
in
try
f expression;
false
with
| Found -> true
(** Transform a list of expression into a list of CTE to evaluate. *)
let of_filters : Path.t Expression.t list -> t list =
fun filters ->
let last_group, prev =
List.fold_left filters
~init:({ filters = []; group = None }, [])
~f:(fun (cte, acc) expr ->
begin
if matchWindowGroup expr then
( { filters = []; group = None },
{ cte with group = Some expr } :: acc )
else ({ cte with filters = expr :: cte.filters }, acc)
end)
in
List.rev (last_group :: prev)
|