-
Notifications
You must be signed in to change notification settings - Fork 115
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Example on how to read an ENUM from duckdb #365
Comments
Still stumped by this. I found Here's a complete program that highlights the error: use duckdb::{
params,
types::Value,
Connection, Result,
};
#[derive(Debug)]
enum State {
CA,
NY,
}
#[derive(Debug)]
struct Data {
state: State,
value: i32,
}
fn main() -> Result<()> {
let conn = Connection::open_in_memory().unwrap();
let _ = conn.execute(
r#"
CREATE TABLE stats (
name ENUM('CA', 'NY'),
value INTEGER,
);
"#,
[],
);
let _ = conn.execute("INSERT INTO stats VALUES (?, ?);", params!["CA", 10]);
let _ = conn.execute("INSERT INTO stats VALUES (?, ?);", params!["CA", 20]);
let _ = conn.execute("INSERT INTO stats VALUES (?, ?);", params!["NY", 4]);
let query = "SELECT * FROM stats;";
let mut stmt = conn.prepare(query).unwrap();
let res_iter = stmt.query_map([], |row| {
let state = match row.get_ref_unwrap(0).to_owned() {
Value::Enum(e) => match e.as_str() {
"CA" => State::CA,
"NY" => State::NY,
_ => panic!("Unknown state"),
},
_ => panic!("Oops, first column should be an enum"),
};
println!("{:?}", state);
Ok(Data {
state: State::CA,
value: row.get(1)?,
})
})?;
let vs: Vec<Data> = res_iter.map(|e| e.unwrap()).collect();
println!("\n\n\nDone");
println!("{:?}", vs);
Ok(())
} The error is:
I would have expected to see CA, CA, NY, not CA, NY. It looks like the code loops over the enum values instead of the column values. |
I made it to work but it isn't pretty, it definitely doesn't live up to the headline of "an ergonomic wrapper". let state = match row.get_ref_unwrap(0) {
ValueRef::Enum(e, idx) => match e {
UInt8(v) => v
.values()
.as_any()
.downcast_ref::<StringArray>()
.unwrap()
.value(v.key(idx).unwrap()),
_ => panic!("Unknown state"),
},
_ => panic!("Oops, first column should be an enum"),
};
Ok(Data {
state: match state {
"CA" => State::CA,
"NY" => State::NY,
_ => panic!("Unknown state"),
},
value: row.get(1)?,
}) I think the code that deals with duckdb enums is not working as intended. For example, I think the program below should not panic, but it does. use duckdb::{
params,
Connection, Result,
};
#[derive(Debug)]
enum State {
CA,
NY,
}
#[derive(Debug)]
struct Data {
state: State,
value: i32,
}
fn main() -> Result<()> {
let conn = Connection::open_in_memory().unwrap();
let _ = conn.execute(
r#"
CREATE TABLE stats (
name ENUM('CA', 'NY'),
value INTEGER,
);
"#,
[],
);
let _ = conn.execute("INSERT INTO stats VALUES (?, ?);", params!["CA", 10]);
let _ = conn.execute("INSERT INTO stats VALUES (?, ?);", params!["CA", 20]);
let _ = conn.execute("INSERT INTO stats VALUES (?, ?);", params!["NY", 4]);
let mut idx = -1;
let query = "SELECT * FROM stats;";
let mut stmt = conn.prepare(query).unwrap();
let res_iter = stmt.query_map([], |row| {
let value = row.get_ref_unwrap(0).to_owned();
println!("state: {:?}", value);
Ok(Data {
state: State::CA,
value: row.get(1)?,
})
})?;
let vs: Vec<Data> = res_iter.map(|e| e.unwrap()).collect();
println!("{:?}", vs);
Ok(())
} If I'm doing something wrong, please comment. Thank you, |
Hi,
I have not seen an example on how to do this in the docs or the tests. Given how pervasive enums are in Rust, maybe an explicit example will be useful.
For example given this table
How do I read it back into Rust?
where
In the error message, I see
which has what I want, but how to do it in the code?
Thank you for your help. Yes, I'm a beginner in Rust.
Tony
The text was updated successfully, but these errors were encountered: