Skip to content

Implement binding for List#757

Open
aljazerzen wants to merge 3 commits into
duckdb:mainfrom
aljazerzen:main
Open

Implement binding for List#757
aljazerzen wants to merge 3 commits into
duckdb:mainfrom
aljazerzen:main

Conversation

@aljazerzen

@aljazerzen aljazerzen commented May 11, 2026

Copy link
Copy Markdown

Resolves a part of #680
Susersedes #643

I recomment review commit-by-commit:

  • Add Type::name() and Value::data_type_name()
  • Add ToSqlOutput::BorrowedValue variant
  • Bind and append List values

Main problem

Value::List is not cheaply convertible into ValueRef::List.

Before this PR, binding (and appending) converted all values to ValueRef,
and then matched on the variant to call appropriate ffi::duckdb_bind_xxx.

For container types, we cannot cheaply convert between Value and ValueRef,
so I've added two binding paths: value_to_duckdb and value_ref_to_duckdb.

Both convert to ffi::duckdb_value, which is then passed to
ffi::duckdb_bind_value/ffi::duckdb_append_value.

These two helpers do also support converting all other types, but they always
use the faster path of calling specialized ffi functions.

Why add ToSqlOutput::BorrowedValue variant?

Because we need to call ToSql(Value) and return &Value, not ValueRef.

In essence, the problem is that there are two dimensions in which Value
and ValueRef differ:

  • owned / borrowed,
  • statically / dynamically typed.

For most types except container types, both of these distinctions are irrelevant.
But for container types (e.g List), there can be 4 possible representations:

  • owned dynamic: Vec<Value>, (this is Value)
  • owned static: arrow::ListArray,
  • borrowed dynamic: &[Value],
  • borrowed static: &arrow::ListArray.

When binding, ToSql needs a path from owned dynamic to borrowed dynamic.

PR #643 gets around this by adding a new variant to ListType, but I think that
is messy because it mixes static/dynamic distinction with arrow list type impls.

Refactor `Display for Type` into `name() -> &str`.
Add `Value::data_type_name()`, so it does not need to infer the type
recursively just to get its name.
See reasoing in PR description.

Also simplifies value_ref_from_value, so the caller can decide how to
handle unsupported types.
@aljazerzen

Copy link
Copy Markdown
Author

@mlafeldt What's happening here? This is blocking me and it seem a bit rude to ask for a PR and then not review it.

@nimdeveloper

Copy link
Copy Markdown

I've created a new crate, implemented almost many of types, you can check it here
https://github.com/nimdeveloper/better-duck
It may help

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants