aboutsummaryrefslogtreecommitdiffstats
path: root/lib
diff options
context:
space:
mode:
authorEstevan Castilho <tevo@riajuu.net>2026-05-30 02:52:21 +0000
committerEstevan Castilho <tevo@riajuu.net>2026-05-30 02:52:21 +0000
commit00365c4a39826bf20d289af7daaa8a41c0aa6ca7 (patch)
tree94d81fc6e0b3704f92ac216b501b51edfddf5e60 /lib
parent91675d81b8899bbe65f399b71065773aab7f1d13 (diff)
downloadSakura-00365c4a39826bf20d289af7daaa8a41c0aa6ca7.tar.gz
Sakura-00365c4a39826bf20d289af7daaa8a41c0aa6ca7.zip
`Project` plan node
Diffstat (limited to 'lib')
-rw-r--r--lib/drl/executor.ml8
-rw-r--r--lib/nt.ml7
-rw-r--r--lib/nt_ffi.ml20
3 files changed, 33 insertions, 2 deletions
diff --git a/lib/drl/executor.ml b/lib/drl/executor.ml
index 5f820c8..34edc08 100644
--- a/lib/drl/executor.ml
+++ b/lib/drl/executor.ml
@@ -28,10 +28,14 @@ module Make (NT : Nt.S) = struct
Ok (Nt.Take { limit = n; source = p })
| Ast.Const _ ->
Error (Error.unsupported_operator
- "Const: literal relations not yet reachable by VM; use Base")
+ "Const: literal relations not yet reachable by VM; use Base")
+ | Ast.Project (attrs, query) ->
+ let* source = compile resolve query in
+ Ok (Nt.Project { attrs; source })
+ | Ast.Rename _ -> Error (Error.unsupported_operator "TODO")
| _ ->
Error (Error.unsupported_operator
- "Select/Project/Rename/Union/Diff/Cartesian require VM operators not yet implemented")
+ "Select/Union/Diff/Cartesian require VM operators not yet implemented")
let page_limit = 16
diff --git a/lib/nt.ml b/lib/nt.ml
index 3882288..41de1d0 100644
--- a/lib/nt.ml
+++ b/lib/nt.ml
@@ -33,6 +33,7 @@ type plan_node =
concrete join algorithm (e.g. HashJoin, NestedLoop, LeapFrog, &c) *)
| Join of { left : plan_node; right : plan_node; on_attrs : string list }
| Take of { limit : int; source : plan_node }
+ | Project of { source : plan_node; attrs : string list }
module Error = struct
open Condition
@@ -326,6 +327,12 @@ module Make (B : Backend) = struct
(match Nt_ffi.ptr_to_opt raw with
| None -> Error (Error.cursor_error "plan_take failed")
| Some p -> Ok p)
+ | Project { source; attrs } ->
+ Nt_ffi.with_strings_as_char_array attrs (fun attrs ->
+ let* sp = build_plan source in
+ let raw = Nt_ffi.rnt_plan_project (Nt_ffi.nint_to_ptr sp) attrs in
+ Nt_ffi.ptr_to_opt raw
+ |> Option.to_result ~none:(Error.cursor_error "plan_project failed"))
let execute_query (plan : plan_node) ~(rel_name : string) :
(tuple_stream, Condition.t) result =
diff --git a/lib/nt_ffi.ml b/lib/nt_ffi.ml
index 8b70150..250ad4a 100644
--- a/lib/nt_ffi.ml
+++ b/lib/nt_ffi.ml
@@ -92,6 +92,9 @@ let rnt_plan_join =
let rnt_plan_take =
fn "rnt_plan_take" (ptr void @-> size_t @-> returning (ptr void))
+let rnt_plan_project =
+ fn "rnt_plan_project" (ptr void @-> ptr (ptr char) @-> returning (ptr void))
+
let rnt_plan_free =
fn "rnt_plan_free" (ptr void @-> returning void)
@@ -133,6 +136,23 @@ let with_out_string (f : char ptr ptr -> int) : int * string option =
if is_null p then (rc, None)
else (rc, Some (consume_cstring p))
+let with_strings_as_char_array
+ (strings : string list)
+ (body : char ptr ptr -> 'a)
+ : 'a =
+ let arr =
+ CArray.make
+ ~initial:(from_voidp char null)
+ (ptr char)
+ (1 + List.length strings)
+ in
+ List.iteri
+ (fun i s -> CArray.set arr i (Ctypes_std_views.char_ptr_of_string s))
+ strings;
+ body (CArray.start arr)
+ (* let pp = allocate (ptr (ptr char)) (from_voidp (ptr char) null) in *)
+
+
(* Converts a void* (returned from open_handle / cursor_open) to nativeint.
Returns None when the pointer is NULL (failure). *)
let ptr_to_opt (p : unit ptr) : nativeint option =