duckdb / duckdb-rs

Ergonomic bindings to duckdb for Rust
MIT License
511 stars 113 forks source link

Bug in code that reads Enums #380

Open thumbert opened 2 months ago

thumbert commented 2 months ago

It's a coincidence that the current enum tests in test_all_types.rs pass. Here's a simple example that shows a bug due to incorrect array indexing.

use duckdb::{Connection, Result};

#[derive(Debug)]
struct Person { id: i32, name: String, }

fn main() -> Result<()> {
    let conn = Connection::open_in_memory()?;
    conn.execute_batch(r#"
CREATE TABLE enum_test (
    id INTEGER,
    name ENUM('AA', 'BB', 'CC')
);
INSERT INTO enum_test VALUES (0, 'BB');
INSERT INTO enum_test VALUES (1, 'AA');
INSERT INTO enum_test VALUES (2, 'CC');
INSERT INTO enum_test VALUES (3, 'BB');
    "#)?;
    let mut stmt = conn.prepare("SELECT id, name FROM enum_test")?;
    let person_iter = stmt.query_map([], |row| {
        Ok(Person{
            id: row.get(0)?,
            name: match row.get_ref_unwrap(1).to_owned() {
                duckdb::types::Value::Enum(e) => e,
                _ => panic!("Oops")
            },
        })
    })?;

    for person in person_iter {
        println!("Found person {:?}", person.unwrap());
    }
    Ok(())
}

Here is the error

Found person Person { id: 0, name: "AA" }
Found person Person { id: 1, name: "BB" }
Found person Person { id: 2, name: "CC" }
thread 'main' panicked at /home/adrian/.cargo/registry/src/index.crates.io-6f17d22bba15001f/arrow-array-52.1.0/src/array/byte_array.rs:305:9:
Trying to access an element at index 3 from a StringArray of length 3
stack backtrace: [...]

It looks like the indexing loops over the enum values instead of the actual row values. This is related to the #365 issue I reported on 29Jul. I am quite sure now it's a bug in the Rust DuckDb driver.

Best regards, Tony