Skip to main content

chdb_rust/
arrow_stream.rs

1//! Arrow streaming support for chDB.
2//!
3//! This module provides types and functions for registering Arrow streams and arrays
4//! as table functions in chDB, enabling efficient data transfer between Arrow
5//! and ClickHouse formats.
6//!
7//! # Overview
8//!
9//! Arrow streaming allows you to:
10//! - Register Arrow streams as virtual tables that can be queried with SQL
11//! - Register Arrow arrays as virtual tables
12//! - Unregister tables when done
13//!
14//! # Examples
15//!
16//! ```no_run
17//! use chdb_rust::connection::Connection;
18//! use chdb_rust::arrow_stream::{ArrowStream, ArrowSchema, ArrowArray};
19//!
20//! // Create a connection
21//! let conn = Connection::open_in_memory()?;
22//!
23//! // Register an Arrow stream as a table (assuming you have an Arrow stream handle)
24//! // let arrow_stream = ArrowStream::from_raw(stream_ptr);
25//! // conn.register_arrow_stream("my_table", &arrow_stream)?;
26//!
27//! // Query the registered table
28//! // let result = conn.query("SELECT * FROM my_table", OutputFormat::JSONEachRow)?;
29//!
30//! // Unregister when done
31//! // conn.unregister_arrow_table("my_table")?;
32//! # Ok::<(), chdb_rust::error::Error>(())
33//! ```
34
35use crate::bindings;
36
37/// A handle to an Arrow stream.
38///
39/// This is a wrapper around the opaque `chdb_arrow_stream` pointer type.
40/// Arrow streams are typically created from Arrow C++ or other Arrow implementations.
41///
42/// # Safety
43///
44/// The underlying pointer must be valid and must remain valid for the lifetime
45/// of this handle. The handle does not take ownership of the Arrow stream.
46#[derive(Debug, Clone, Copy)]
47pub struct ArrowStream {
48    inner: bindings::chdb_arrow_stream,
49}
50
51unsafe impl Send for ArrowStream {}
52
53impl ArrowStream {
54    /// Create an `ArrowStream` from a raw `chdb_arrow_stream` pointer.
55    ///
56    /// # Safety
57    ///
58    /// The pointer must be valid and point to a valid Arrow stream handle.
59    /// The caller is responsible for ensuring the stream remains valid for
60    /// the lifetime of this handle.
61    ///
62    /// # Arguments
63    ///
64    /// * `stream` - A raw pointer to a `chdb_arrow_stream`
65    ///
66    /// # Examples
67    ///
68    /// ```no_run
69    /// use chdb_rust::arrow_stream::ArrowStream;
70    ///
71    /// // Assuming you have a valid Arrow stream pointer from Arrow C++
72    /// // let stream_ptr: *mut chdb_arrow_stream_ = ...;
73    /// // let arrow_stream = unsafe { ArrowStream::from_raw(stream_ptr) };
74    /// ```
75    pub unsafe fn from_raw(stream: bindings::chdb_arrow_stream) -> Self {
76        Self { inner: stream }
77    }
78
79    /// Get the raw pointer to the underlying Arrow stream handle.
80    ///
81    /// # Returns
82    ///
83    /// Returns the raw `chdb_arrow_stream` pointer.
84    pub fn as_raw(&self) -> bindings::chdb_arrow_stream {
85        self.inner
86    }
87}
88
89/// A handle to an Arrow schema.
90///
91/// This is a wrapper around the opaque `chdb_arrow_schema` pointer type.
92/// Arrow schemas define the structure of Arrow data.
93///
94/// # Safety
95///
96/// The underlying pointer must be valid and must remain valid for the lifetime
97/// of this handle. The handle does not take ownership of the Arrow schema.
98#[derive(Debug, Clone, Copy)]
99pub struct ArrowSchema {
100    inner: bindings::chdb_arrow_schema,
101}
102
103unsafe impl Send for ArrowSchema {}
104
105impl ArrowSchema {
106    /// Create an `ArrowSchema` from a raw `chdb_arrow_schema` pointer.
107    ///
108    /// # Safety
109    ///
110    /// The pointer must be valid and point to a valid Arrow schema handle.
111    /// The caller is responsible for ensuring the schema remains valid for
112    /// the lifetime of this handle.
113    ///
114    /// # Arguments
115    ///
116    /// * `schema` - A raw pointer to a `chdb_arrow_schema`
117    ///
118    /// # Examples
119    ///
120    /// ```no_run
121    /// use chdb_rust::arrow_stream::ArrowSchema;
122    ///
123    /// // Assuming you have a valid Arrow schema pointer from Arrow C++
124    /// // let schema_ptr: *mut chdb_arrow_schema_ = ...;
125    /// // let arrow_schema = unsafe { ArrowSchema::from_raw(schema_ptr) };
126    /// ```
127    pub unsafe fn from_raw(schema: bindings::chdb_arrow_schema) -> Self {
128        Self { inner: schema }
129    }
130
131    /// Get the raw pointer to the underlying Arrow schema handle.
132    ///
133    /// # Returns
134    ///
135    /// Returns the raw `chdb_arrow_schema` pointer.
136    pub fn as_raw(&self) -> bindings::chdb_arrow_schema {
137        self.inner
138    }
139}
140
141/// A handle to an Arrow array.
142///
143/// This is a wrapper around the opaque `chdb_arrow_array` pointer type.
144/// Arrow arrays contain the actual data in Arrow format.
145///
146/// # Safety
147///
148/// The underlying pointer must be valid and must remain valid for the lifetime
149/// of this handle. The handle does not take ownership of the Arrow array.
150#[derive(Debug, Clone, Copy)]
151pub struct ArrowArray {
152    inner: bindings::chdb_arrow_array,
153}
154
155unsafe impl Send for ArrowArray {}
156
157impl ArrowArray {
158    /// Create an `ArrowArray` from a raw `chdb_arrow_array` pointer.
159    ///
160    /// # Safety
161    ///
162    /// The pointer must be valid and point to a valid Arrow array handle.
163    /// The caller is responsible for ensuring the array remains valid for
164    /// the lifetime of this handle.
165    ///
166    /// # Arguments
167    ///
168    /// * `array` - A raw pointer to a `chdb_arrow_array`
169    ///
170    /// # Examples
171    ///
172    /// ```no_run
173    /// use chdb_rust::arrow_stream::ArrowArray;
174    ///
175    /// // Assuming you have a valid Arrow array pointer from Arrow C++
176    /// // let array_ptr: *mut chdb_arrow_array_ = ...;
177    /// // let arrow_array = unsafe { ArrowArray::from_raw(array_ptr) };
178    /// ```
179    pub unsafe fn from_raw(array: bindings::chdb_arrow_array) -> Self {
180        Self { inner: array }
181    }
182
183    /// Get the raw pointer to the underlying Arrow array handle.
184    ///
185    /// # Returns
186    ///
187    /// Returns the raw `chdb_arrow_array` pointer.
188    pub fn as_raw(&self) -> bindings::chdb_arrow_array {
189        self.inner
190    }
191}
192
193#[cfg(test)]
194mod tests {
195    use super::*;
196
197    #[test]
198    fn test_arrow_stream_from_raw() {
199        // Test that we can create an ArrowStream from a null pointer
200        // (this is just testing the API, not actual functionality)
201        let null_ptr = std::ptr::null_mut();
202        let stream = unsafe { ArrowStream::from_raw(null_ptr) };
203        assert!(stream.as_raw().is_null());
204    }
205
206    #[test]
207    fn test_arrow_schema_from_raw() {
208        let null_ptr = std::ptr::null_mut();
209        let schema = unsafe { ArrowSchema::from_raw(null_ptr) };
210        assert!(schema.as_raw().is_null());
211    }
212
213    #[test]
214    fn test_arrow_array_from_raw() {
215        let null_ptr = std::ptr::null_mut();
216        let array = unsafe { ArrowArray::from_raw(null_ptr) };
217        assert!(array.as_raw().is_null());
218    }
219}