Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 12 additions & 1 deletion rust/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,18 @@ mod error;
use scanner::LanceStream;
use error::{clear_last_error, set_last_error, ErrorCode};

// FFI ownership contract (Arrow C Data Interface):
// - All `*_open/create/get` functions return opaque handles owned by the caller,
// which must be released exactly once via the matching `*_close/free` call.
// - `lance_schema_to_arrow` transfers ownership of the populated ArrowSchema to
// the caller. The caller must call `release` exactly once on success.
// - `lance_batch_to_arrow` transfers ownership of the populated ArrowArray and
// ArrowSchema to the caller. The caller must call `release` exactly once on
// each on success.
// - On error (non-zero return), output ArrowSchema/ArrowArray are left
// untouched and must not be released unless the caller initialized them to a
// valid value before calling into this library.

// Dataset operations - just holds the dataset
struct DatasetHandle {
dataset: Arc<Dataset>,
Expand Down Expand Up @@ -246,7 +258,6 @@ pub unsafe extern "C" fn lance_create_fragment_stream(
}
}
}

scan.scan_in_order(false);

match LanceStream::from_scanner(scan) {
Expand Down
18 changes: 18 additions & 0 deletions src/lance_scan.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,21 @@
#include <cstdint>
#include <cstring>

// FFI ownership contract (Arrow C Data Interface):
// `lance_get_schema` returns an opaque schema handle; caller frees it via
// `lance_free_schema` exactly once.
// `lance_schema_to_arrow` populates `out_schema` on success (return 0) and
// transfers ownership of the ArrowSchema to the caller, who must call
// `out_schema->release(out_schema)` exactly once (or wrap it in RAII).
// `lance_create_stream` and `lance_create_fragment_stream` return opaque stream
// handles; caller closes them via `lance_close_stream` exactly once.
// `lance_stream_next` returns an opaque RecordBatch handle; caller frees it via
// `lance_free_batch` exactly once after use.
// `lance_batch_to_arrow` populates `out_array` and `out_schema` on success
// (return 0) and transfers ownership of both to the caller, who must call
// `release` exactly once on each.
// On error, the callee leaves output `ArrowSchema` / `ArrowArray` untouched; do
// not call `release` unless the caller initialized them to a valid value.
extern "C" {
void *lance_open_dataset(const char *path);
void lance_close_dataset(void *dataset);
Expand Down Expand Up @@ -524,6 +539,8 @@ static unique_ptr<FunctionData> LanceScanBind(ClientContext &context,
result->file_path + LanceFormatErrorSuffix());
}

memset(&result->schema_root.arrow_schema, 0,
sizeof(result->schema_root.arrow_schema));
if (lance_schema_to_arrow(schema_handle, &result->schema_root.arrow_schema) !=
0) {
lance_free_schema(schema_handle);
Expand Down Expand Up @@ -676,6 +693,7 @@ static bool LanceScanLoadNextBatch(LanceScanLocalState &local_state) {
}

auto new_chunk = make_shared_ptr<ArrowArrayWrapper>();
memset(&new_chunk->arrow_array, 0, sizeof(new_chunk->arrow_array));
ArrowSchema tmp_schema;
memset(&tmp_schema, 0, sizeof(tmp_schema));

Expand Down