duckdb-ffi-1.5.3.0: src/Database/DuckDB/FFI/Arrow.hs
{- | Arrow C Data Interface conversion and callbacks.
The @mkArrow...@ functions invoke existing callback pointers. The
@wrapArrow...@ functions allocate callback pointers for Haskell functions.
Keep each allocated pointer alive while native code can call it. Free it with
@freeHaskellFunPtr@ after its last use. Catch all callback exceptions before
they can return to C.
-}
module Database.DuckDB.FFI.Arrow (
c_duckdb_to_arrow_schema,
c_duckdb_data_chunk_to_arrow,
c_duckdb_schema_from_arrow,
c_duckdb_data_chunk_from_arrow,
c_duckdb_destroy_arrow_converted_schema,
mkArrowSchemaRelease,
mkArrowArrayRelease,
mkArrowStreamGetSchema,
mkArrowStreamGetNext,
mkArrowStreamGetLastError,
mkArrowStreamRelease,
wrapArrowSchemaRelease,
wrapArrowArrayRelease,
wrapArrowStreamGetSchema,
wrapArrowStreamGetNext,
wrapArrowStreamGetLastError,
wrapArrowStreamRelease,
releaseArrowSchema,
releaseArrowArray,
releaseArrowStream,
) where
import Control.Exception (mask_)
import Control.Monad (when)
import Database.DuckDB.FFI.Types
import Foreign.C.String (CString)
import Foreign.C.Types (CInt (..))
import Foreign.Ptr (FunPtr, Ptr, nullFunPtr)
import Foreign.Storable (peek)
{- | Transforms a DuckDB Schema into an Arrow Schema
Parameters:
* @arrow_options@: The Arrow settings used to produce arrow.
* @types@: The DuckDB logical types for each column in the schema.
* @names@: The names for each column in the schema.
* @column_count@: The number of columns that exist in the schema.
* @out_schema@: The resulting arrow schema. Must be destroyed with
@out_schema->release(out_schema)@.
Returns The error data. Must be destroyed with @duckdb_destroy_error_data@.
-}
foreign import ccall safe "duckdb_to_arrow_schema"
c_duckdb_to_arrow_schema :: DuckDBArrowOptions -> Ptr DuckDBLogicalType -> Ptr CString -> DuckDBIdx -> Ptr ArrowSchema -> IO DuckDBErrorData
{- | Transforms a DuckDB data chunk into an Arrow array.
Parameters:
* @arrow_options@: The Arrow settings used to produce arrow.
* @chunk@: The DuckDB data chunk to convert.
* @out_arrow_array@: The output Arrow structure that will hold the converted
data. Must be released with @out_arrow_array->release(out_arrow_array)@
Returns The error data. Must be destroyed with @duckdb_destroy_error_data@.
-}
foreign import ccall safe "duckdb_data_chunk_to_arrow"
c_duckdb_data_chunk_to_arrow :: DuckDBArrowOptions -> DuckDBDataChunk -> Ptr ArrowArray -> IO DuckDBErrorData
{- | Transforms an Arrow Schema into a DuckDB Schema.
Parameters:
* @connection@: The connection to get the transformation settings from.
* @schema@: The input Arrow schema. Must be released with
@schema->release(schema)@.
* @out_types@: The Arrow converted schema with extra information about the
arrow types. Must be destroyed with @duckdb_destroy_arrow_converted_schema@.
Returns The error data. Must be destroyed with @duckdb_destroy_error_data@.
-}
foreign import ccall safe "duckdb_schema_from_arrow"
c_duckdb_schema_from_arrow :: DuckDBConnection -> Ptr ArrowSchema -> Ptr DuckDBArrowConvertedSchema -> IO DuckDBErrorData
{- | Transforms an Arrow array into a DuckDB data chunk. The data chunk will retain
ownership of the underlying Arrow data.
Parameters:
* @connection@: The connection to get the transformation settings from.
* @arrow_array@: The input Arrow array. Data ownership is passed on to
DuckDB's DataChunk, the underlying object does not need to be released and
won't have ownership of the data.
* @converted_schema@: The Arrow converted schema with extra information about
the arrow types.
* @out_chunk@: The resulting DuckDB data chunk. Must be destroyed by
duckdb_destroy_data_chunk.
Returns The error data. Must be destroyed with @duckdb_destroy_error_data@.
-}
foreign import ccall safe "duckdb_data_chunk_from_arrow"
c_duckdb_data_chunk_from_arrow :: DuckDBConnection -> Ptr ArrowArray -> DuckDBArrowConvertedSchema -> Ptr DuckDBDataChunk -> IO DuckDBErrorData
{- | Destroys the arrow converted schema and de-allocates all memory allocated for
that arrow converted schema.
Parameters:
* @arrow_converted_schema@: The arrow converted schema to destroy.
-}
foreign import ccall safe "duckdb_destroy_arrow_converted_schema"
c_duckdb_destroy_arrow_converted_schema :: Ptr DuckDBArrowConvertedSchema -> IO ()
-- | Invoke a non-null Arrow schema release callback.
foreign import ccall safe "dynamic"
mkArrowSchemaRelease :: FunPtr (Ptr ArrowSchema -> IO ()) -> Ptr ArrowSchema -> IO ()
-- | Invoke a non-null Arrow array release callback.
foreign import ccall safe "dynamic"
mkArrowArrayRelease :: FunPtr (Ptr ArrowArray -> IO ()) -> Ptr ArrowArray -> IO ()
-- | Invoke the schema callback of an unreleased Arrow stream.
foreign import ccall safe "dynamic"
mkArrowStreamGetSchema :: FunPtr (Ptr ArrowArrayStream -> Ptr ArrowSchema -> IO CInt) -> Ptr ArrowArrayStream -> Ptr ArrowSchema -> IO CInt
-- | Invoke the next-array callback of an unreleased Arrow stream.
foreign import ccall safe "dynamic"
mkArrowStreamGetNext :: FunPtr (Ptr ArrowArrayStream -> Ptr ArrowArray -> IO CInt) -> Ptr ArrowArrayStream -> Ptr ArrowArray -> IO CInt
-- | Read a stream error after a failed callback. Copy it before the next callback.
foreign import ccall safe "dynamic"
mkArrowStreamGetLastError :: FunPtr (Ptr ArrowArrayStream -> IO CString) -> Ptr ArrowArrayStream -> IO CString
-- | Invoke a non-null Arrow stream release callback.
foreign import ccall safe "dynamic"
mkArrowStreamRelease :: FunPtr (Ptr ArrowArrayStream -> IO ()) -> Ptr ArrowArrayStream -> IO ()
-- | Allocate a C-callable Arrow schema release callback.
foreign import ccall "wrapper"
wrapArrowSchemaRelease :: (Ptr ArrowSchema -> IO ()) -> IO (FunPtr (Ptr ArrowSchema -> IO ()))
-- | Allocate a C-callable Arrow array release callback.
foreign import ccall "wrapper"
wrapArrowArrayRelease :: (Ptr ArrowArray -> IO ()) -> IO (FunPtr (Ptr ArrowArray -> IO ()))
-- | Allocate a C-callable Arrow stream schema callback.
foreign import ccall "wrapper"
wrapArrowStreamGetSchema :: (Ptr ArrowArrayStream -> Ptr ArrowSchema -> IO CInt) -> IO (FunPtr (Ptr ArrowArrayStream -> Ptr ArrowSchema -> IO CInt))
-- | Allocate a C-callable Arrow stream next-array callback.
foreign import ccall "wrapper"
wrapArrowStreamGetNext :: (Ptr ArrowArrayStream -> Ptr ArrowArray -> IO CInt) -> IO (FunPtr (Ptr ArrowArrayStream -> Ptr ArrowArray -> IO CInt))
-- | Allocate a C-callable Arrow stream last-error callback.
foreign import ccall "wrapper"
wrapArrowStreamGetLastError :: (Ptr ArrowArrayStream -> IO CString) -> IO (FunPtr (Ptr ArrowArrayStream -> IO CString))
-- | Allocate a C-callable Arrow stream release callback.
foreign import ccall "wrapper"
wrapArrowStreamRelease :: (Ptr ArrowArrayStream -> IO ()) -> IO (FunPtr (Ptr ArrowArrayStream -> IO ()))
{- | Release an Arrow schema unless its release callback is null.
The pointer must address an initialized structure. The structure itself stays
allocated. Asynchronous exceptions are masked during release.
-}
releaseArrowSchema :: Ptr ArrowSchema -> IO ()
releaseArrowSchema ptr = mask_ $ do
schema <- peek ptr
when (arrowSchemaRelease schema /= nullFunPtr) $
mkArrowSchemaRelease (arrowSchemaRelease schema) ptr
{- | Release an Arrow array unless its release callback is null.
The pointer must address an initialized structure. The structure itself stays
allocated. Asynchronous exceptions are masked during release.
-}
releaseArrowArray :: Ptr ArrowArray -> IO ()
releaseArrowArray ptr = mask_ $ do
array <- peek ptr
when (arrowArrayRelease array /= nullFunPtr) $
mkArrowArrayRelease (arrowArrayRelease array) ptr
{- | Release an Arrow stream unless its release callback is null.
The pointer must address an initialized structure. The structure itself stays
allocated. Asynchronous exceptions are masked during release.
-}
releaseArrowStream :: Ptr ArrowArrayStream -> IO ()
releaseArrowStream ptr = mask_ $ do
stream <- peek ptr
when (arrowStreamRelease stream /= nullFunPtr) $
mkArrowStreamRelease (arrowStreamRelease stream) ptr