Skip to main content
execute returns a better_duck_core::DuckResult — it owns the DuckDB result handle, is a lazy Iterator<Item = Result<DuckRow>>, and carries the result’s metadata. Rows come out as better_duck_core::DuckRow.

Iterating

Plain forward iteration decodes each row once and caches nothing:

Row-oriented helpers

The Iterator method — pulls and decodes the next row.
Re-reads the row at the current cursor position.
Peeks whether at least one more row exists without consuming it — a later next() still yields that row. Idempotent.
Consumes the result and tallies remaining rows without materializing each DuckRow (skips per-column conversion). Spans internal chunks correctly.
Consumes the result into an owned, thread-safe ResultSet.

Replaying with rewind

Rewind is opt-in because the default path never clones rows:
enable_rewind() makes every row pulled from that point on clone into a cache; rewind() then replays it. Rows consumed before enable_rewind() cannot be recovered, and without enable_rewind() a rewind() is a no-op.
Row vs chunk — do not mix. A DuckResult is consumed either row-by-row (next / exists / count / materialize) or chunk-by-chunk (fetch_chunk, feature columnar), never both — they share one cursor. The first mode used wins; the other then yields Error::MixedIterationMode. See columnar access.

DuckRow access

A DuckRow is one row’s values plus its (Arc-shared) column names.
  • get(name: &str) -> Option<&DuckValue> — by column name, case-sensitive, matched by string (first match if names repeat).
  • get_idx(idx: usize) -> Option<&DuckValue> — by zero-based index.
  • column_count() -> u64.
See values overview for the full DuckValue model.

Result & column metadata

Available on DuckResult before consuming any rows:
  • changes() -> u64 — affected rows for DML; 0 for SELECT.
  • column_count() -> u64.
  • column_name(idx) -> Result<&str>, column_names() -> &[Box<str>], column_idx(name) -> Option<usize>.
  • column_type(idx) -> Result<DUCKDB_TYPE> — the coarse DuckDB type id (kept for migration).
  • column_logical_type(idx) -> Result<&TypeInfo> / column_schema() -> &[TypeInfo] — the lossless descriptor (DECIMAL width/scale, nested LIST/STRUCT/MAP shapes, ENUM labels). See TypeInfo.
  • statement_type() -> StatementType, result_type() -> ResultType.
An out-of-range index yields Error::InvalidColumnIndex.

ResultType

result_type() returns better_duck_core::ResultType, which is #[non_exhaustive] — match with a _ arm: statement_type() returns StatementType.

TableDescription

Read a catalog table’s columns without a query — better_duck_core::TableDescription, from a Connection (&self):
A missing table or an interior NUL in a name is an error at creation. Indexed accessors return None out of range, except column_has_default, which errors.

See also