Tokio_postgres: Dynamically iterating over column values

Rust newbie here.

Using tokio_postgres, I want to dynamically process database query results by iterating over rows and then iterating over each field in a row.

I'm expecting I should be able to do something like this:

    let rows = client.query("select * from category", &[]).await?;
    if rows.len() > 0 {
        let columns = rows[0].columns();
        for row in &rows {
            for col in columns {
                match row.get(col.name()) { // <-- Error: "type annotations needed"
                    // What do I do here?
                }
            }
        }
    }

But, as indicated, the compiler has a problem with me wanting to match on the result of the get function.

One option I have considered is to call get with a different type annotation, depending on the type inferred from the column, but not sure if this is a good option. In the end, the value itself will probably have to go into an Enum that can cater for all the database types.

What I ultimately want to do, is expose a function to Rhai that can call a SELECT query, then process the results dynamically. But I am stuck on how I would handle the values of different types.

Perhaps I have gone too far down a path and need to backtrack to see things in context.

On the Rust side, you can't escape the type system, which won't let you have Schrödinger-typed values that only fully materialize when used in an expression. This leaves you with serializing everything into a string, or using an enum. I've never used Rhai, but I suspect that any support for dynamically-typed values must use one of those strategies behind the scenes.

2 Likes

Gotta love that! :grin:

I'm facing a similar issue; one way to solve this is to match against *row.columns()[0].type_(), then deal with different Postgres types in each arm, e.g., Type::TEXT. A full list of Postgres types can be found at Type in tokio_postgres::types - Rust. Hope this helps.

1 Like

This topic was automatically closed 90 days after the last reply. We invite you to open a new topic if you have further questions or comments.