open Utilities.Result module Error = struct open Condition let unqualified_name name = condition "unqualified-name" "A relation must be named as multigroup:relation" ("name" |=| Value.String name) end let page_limit = 16 let relation_path branch name = match String.index_opt name ':' with | Some i when i > 0 && i < String.length name - 1 -> Ok (String.concat "\\" [ branch; "multigroup"; String.sub name 0 i; "relation"; String.sub name (i + 1) (String.length name - i - 1) ] ) | _ -> Error (Error.unqualified_name name) let rec compile branch = function | Ast.Base name -> relation_path branch name |> Result.map (fun path -> RNT.Base path) | Ast.Project (attributes, query) -> compile branch query |> Result.map (fun plan -> RNT.Project (plan, attributes)) let execute (ctx : Sublanguage_context.t) query = let* plan = compile (ctx.session#path ^ "\\branch") query in let* relation = RNT.execute ctx.kernel plan in Fun.protect ~finally:(fun () -> RNT.release relation) (fun () -> let* cursor = RNT.enumerate relation in Fun.protect ~finally:(fun () -> RNT.release cursor) (fun () -> let* {RNT.tuples; exhausted} = RNT.fetch cursor page_limit in Ok (Sublanguage_types.Cursor {rows= tuples; has_more= not exhausted}) ) )