Skip to content

Allow reading composite values into a Row-like struct #366

Open
@kostrowski

Description

@kostrowski

It would be useful to be able to treat the value of a composite-value column as a Row. Presently, to read composite values you need to use postgres-derive or handle the raw bytes returned by Row::get_bytes(...). In certain situations neither option is attractive. Using postgres-derive requires one to define a struct matching the fields of the composite value and results in parsing based on name matching, which could be a performance issue. Manually handling the raw bytes returned by Row::get_bytes(...) could avoid the performance issue, but that would mean duplicating a fair amount of code that is already in postgres-protocol in the form of message::DataRowBody and message::DataRowRanges.

I'm not entirely certain of the best approach within the library (a simple hack is to make DataRowBody and DataRowRanges externally constructible and feed the field's raw bytes into them).

An example use case would be in working with class-table inheritance, where you might want to query the concrete type variants as composites:

let sql = "\
    SELECT widget.type, widget.name, machine, toy \
    FROM widget LEFT JOIN machine USING (id) LEFT JOIN toy USING (id) \
";

for row in &conn.query(sql, &[]).unwrap() {
    let ty = str::from_utf8(row.get_bytes(0).unwrap()).unwrap();
    let name = row.get(1);
    let kind = match ty {
        "machine" => {
            let row: Composite = row.get(2);
            WidgetKind::Machine {
                gears: row.get(0),
                operator: row.get(1),
            }
        },
        "toy" => {
            let row: Composite = row.get(3);
            WidgetKind::Toy {
                minimum_age: row.get(0),
            }
        },
    };
    let widget = Widget { name, kind };
    println!("{:?}", widget);
}

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions