diff options
Diffstat (limited to 'lib/configuration/read_conf.ml')
-rw-r--r-- | lib/configuration/read_conf.ml | 69 |
1 files changed, 39 insertions, 30 deletions
diff --git a/lib/configuration/read_conf.ml b/lib/configuration/read_conf.ml index 69240c1..11f6726 100644 --- a/lib/configuration/read_conf.ml +++ b/lib/configuration/read_conf.ml @@ -126,44 +126,51 @@ end = struct let column = Expression_parser.Incremental.column_expr end +exception Divergent (** Ensure the group criteria in window functions match the global group by - criteria. + criteria. *) - Traverse the configuration tree until finding a group window. *) +exception NestedGroup +(** Raised when a group contains another one *) + +(** Traverse the configuration tree until finding a group window. *) let matchWindowGroup : eq:('a -> 'a -> bool) -> subset:'a ImportExpression.T.t list -> 'a ImportExpression.T.t -> - bool = + unit = fun ~eq ~subset expression -> - let exception Divergent in let open ImportExpression.T in - let rec f = function + let rec f isIngroup = function | Empty | Literal _ | Integer _ | Path _ -> () - | Expr e -> f e + | Expr e -> f isIngroup e | Concat pp | Function' (_, pp) | Function (_, pp) | Nvl pp | Join (_, pp) - -> List.iter ~f pp - | Window (_, pp1, _) -> - if List.equal ~eq:(ImportExpression.T.equal eq) subset pp1 then () - else raise_notrace Divergent + -> List.iter ~f:(f isIngroup) pp + | Window (expr, pp1, pp2) -> + let () = + if List.equal ~eq:(ImportExpression.T.equal eq) subset pp1 then () + else + match subset with + | [] -> () + | _ -> raise_notrace Divergent + in + let () = + match isIngroup with + | true -> raise NestedGroup + | false -> () + in + + ignore @@ ImportExpression.T.map_window ~f:(f true) expr; + List.iter ~f:(f true) pp1; + List.iter ~f:(f true) pp2 | BOperator (_, arg1, arg2) -> - f arg1; - f arg2 + f isIngroup arg1; + f isIngroup arg2 | GEquality (_, arg1, args) -> - f arg1; - List.iter ~f args + f isIngroup arg1; + List.iter ~f:(f isIngroup) args in - match subset with - | [] -> - (* Do not bother traversing the tree if there is no group by, just - return Ok *) - true - | _ -> ( - try - f expression; - true - with - | Divergent -> false) + f false expression module Make (S : Decoders.Decode.S) = struct let ( let* ) = S.( let* ) @@ -185,13 +192,15 @@ module Make (S : Decoders.Decode.S) = struct | Error e -> S.fail_with Decoders.Error.(make e) | Ok expr -> ( (* Now check that every window function include at least the uniq list *) - let valid_subset = matchWindowGroup ~eq ~subset:groups expr in - match valid_subset with - | true -> S.succeed expr - | false -> + match matchWindowGroup ~eq ~subset:groups expr with + | () -> S.succeed expr + | exception Divergent -> S.fail "The group function shall match the same arguments as the \ - \"uniq\" parameter") + \"uniq\" parameter" + | exception NestedGroup -> + S.fail + "A group function cannot contains another group function") method source = let* file = S.field "file" S.string |