@@ -6,6 +6,7 @@ use tokio_util::sync::CancellationToken;
66
77use crate :: { BytesData , Callback , ErrorCode , ErrorInfo , mappers, proto} ;
88
9+ #[ derive( Clone ) ]
910pub struct SessionContextWrapper {
1011 runtime : crate :: RuntimeHandle ,
1112 inner : Arc < datafusion:: prelude:: SessionContext > ,
@@ -22,28 +23,30 @@ impl SessionContextWrapper {
2223
2324/// Creates a new `SessionContext` bound to a runtime.
2425///
26+ /// This is a synchronous operation.
27+ ///
2528/// # Safety
2629/// - `runtime_ptr` must be a valid pointer returned by `datafusion_runtime_new`
27- /// - `context_ptr ` must be a valid, aligned, non-null pointer to writable memory
30+ /// - `context_out_ptr ` must be a valid, aligned, non-null pointer to writable memory
2831/// - Caller must call `datafusion_context_destroy` exactly once with the returned pointer
2932#[ unsafe( no_mangle) ]
3033pub unsafe extern "C" fn datafusion_context_new (
3134 runtime_ptr : * mut crate :: RuntimeHandle ,
32- context_ptr : * mut * mut SessionContextWrapper ,
35+ context_out_ptr : * mut * mut SessionContextWrapper ,
3336) -> ErrorCode {
34- if context_ptr . is_null ( ) {
37+ if context_out_ptr . is_null ( ) {
3538 return ErrorCode :: InvalidArgument ;
3639 }
3740
3841 let runtime_handle = ffi_ref ! ( runtime_ptr) ;
3942
4043 let context = Box :: new ( SessionContextWrapper :: new ( Arc :: clone ( runtime_handle) ) ) ;
41- let raw_ptr = Box :: into_raw ( context) ;
44+ let context_ptr = Box :: into_raw ( context) ;
4245 unsafe {
43- * context_ptr = raw_ptr ;
46+ * context_out_ptr = context_ptr ;
4447 }
4548
46- debug ! ( "Created session context {raw_ptr :p}" ) ;
49+ debug ! ( "Created session context {context_ptr :p}" ) ;
4750
4851 ErrorCode :: Ok
4952}
@@ -66,6 +69,37 @@ pub unsafe extern "C" fn datafusion_context_destroy(
6669 ErrorCode :: Ok
6770}
6871
72+ /// Clones a `SessionContext`, creating a new wrapper that shares the same underlying context.
73+ ///
74+ /// This is a synchronous operation.
75+ ///
76+ /// # Safety
77+ /// - `context_ptr` must be a valid pointer returned by `datafusion_context_new` or `datafusion_context_clone`
78+ /// - `context_out_ptr` must be a valid, aligned, non-null pointer to writable memory
79+ /// - Caller must call `datafusion_context_destroy` exactly once with the returned pointer
80+ #[ unsafe( no_mangle) ]
81+ pub unsafe extern "C" fn datafusion_context_clone (
82+ context_ptr : * mut SessionContextWrapper ,
83+ context_out_ptr : * mut * mut SessionContextWrapper ,
84+ ) -> ErrorCode {
85+ if context_out_ptr. is_null ( ) {
86+ return ErrorCode :: InvalidArgument ;
87+ }
88+
89+ let context = ffi_ref ! ( context_ptr) ;
90+
91+ let cloned_context = Box :: new ( context. clone ( ) ) ;
92+ let cloned_context_ptr = Box :: into_raw ( cloned_context) ;
93+
94+ unsafe {
95+ * context_out_ptr = cloned_context_ptr;
96+ }
97+
98+ debug ! ( "Cloned session context {context_ptr:p} -> {cloned_context_ptr:p}" ) ;
99+
100+ ErrorCode :: Ok
101+ }
102+
69103/// Registers a CSV file as a table in the `SessionContext`.
70104///
71105/// This is an async operation. The callback is invoked on completion with no result data.
0 commit comments