Skip to main content

Output

Derive Macro Output 

Source
#[derive(Output)]
{
    // Attributes available to this derive:
    #[sql]
}
Expand description

Defines a SQL output mapping.

Implements Output for the struct, enabling type-safe selection and decoding of rows in query! and query_lazy!. Column names are validated at compile time against the table or joined tables.

§Basic usage

#[derive(Output)]
#[sql(table = ExampleTable)]
struct BasicOutput {
    int_field: i32,
    str_field: String,
}

let value = 42;
let row: BasicOutput = query!(&mut conn,
    SELECT BasicOutput FROM ExampleTable WHERE ExampleTable.int_field = {value}
)
.await?;

§Custom select expressions

Use #[sql(select = ...)] to map a field to a SQL expression. The expression is emitted into the SELECT list with an alias matching the field name.

#[derive(Output)]
#[sql(table = ExampleTable)]
struct CustomSelectOutput {
    int_field: i32,
    #[sql(select = int_field + 1)]
    int_plus_one: i32,
}

let row: CustomSelectOutput = query!(&mut conn,
    SELECT CustomSelectOutput FROM ExampleTable WHERE ExampleTable.int_field = 42
)
.await?;

§Custom select arguments

Use {arg0}, {arg1}, … inside #[sql(select = ...)] and pass arguments in the query as SELECT OutputType(arg0, arg1) ... or RETURNING OutputType(arg0, arg1).

#[derive(Output)]
#[sql(table = ExampleTable)]
struct CustomSelectArgsOutput {
    #[sql(select = str_field || {arg0})]
    labeled: String,
}

let suffix = "!";
let row: CustomSelectArgsOutput = query!(&mut conn,
    SELECT CustomSelectArgsOutput({suffix}) FROM ExampleTable WHERE ExampleTable.int_field = 7
)
.await?;

§Joined output fields

For table_join! results, map fields to joined columns with #[sql(field = Table.column)] or #[sql(select = ...)].

table_join!(ExampleJoin | ExampleTable INNER JOIN RelatedTable ON ExampleTable.id = RelatedTable.parent_id);

#[derive(Output)]
#[sql(table = ExampleJoin)]
struct JoinedOutput {
    #[sql(field = ExampleTable.str_field)]
    parent_name: String,
    #[sql(select = RelatedTable.data || "_child")]
    child_data: String,
}

let parent_id = 1;
let rows: Vec<JoinedOutput> = query!(&mut conn,
    SELECT Vec<JoinedOutput> FROM ExampleJoin WHERE RelatedTable.parent_id = {parent_id}
)
.await?;

§Field attributes

  • #[sql(select = ...)] maps the field to a custom SQL expression.
  • #[sql(field = Table.column)] maps the field to a joined table column.
  • #[sql(bytes)] decodes the field from binary data (matches table field settings).

§Table attributes

  • #[sql(table = TableStruct)] is required and sets the base table for validation.

§Notes

  • Output structs represent a single row; wrap in Vec<T> or Option<T> for multiple or optional rows.
  • With use_output_columns, you can reference OutputType.column (or bare columns) in query! expressions.
  • Custom select arguments must be sequential (arg0, arg1, …).