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

Question about `Queryable` docs regarding struct field order #1472

Closed
jonathanstrong opened this Issue Jan 10, 2018 · 3 comments

Comments

Projects
None yet
2 participants
@jonathanstrong

jonathanstrong commented Jan 10, 2018

I was hoping to clarify something from the documentation of Queryable regarding struct field order:

The docs say:

When this trait is derived, it will assume that the order of fields on your struct match the order of the fields in the query. This means that field order is significant if you are using #[derive(Queryable)]. Field name has no affect.

(Empahsis mine.)

Is Queryable assuming the order of the struct fields matches the order of the database columns?

Lets say for an example table:

example_db=# \d example_table
            Table "public.example_table"
  Column  |           Type           | Modifiers 
----------+--------------------------+-----------
 id       | integer                  | not null
 a        | smallint                 | not null
 b        | smallint                 | not null
 c        | smallint                 | not null
Indexes:
    "example_table_pkey" PRIMARY KEY, btree (id)

And the struct is:

#[derive(Queryable)]
#[table_name = "example_table"]
struct Example {
    pub id: i32,
    pub c: i16,
    pub b: i16,
    pub a: i16
}

My assumption had been that diesel was mapping the fields of the struct by name to the database columns. Are the docs saying that instead the struct field order is used to map to columns, such that in the example above database column "a" would map to struct field "c"?

If not, can you further explain what the docs are trying to convey?

@sgrif

This comment has been minimized.

Member

sgrif commented Jan 11, 2018

Is Queryable assuming the order of the struct fields matches the order of the database columns?

No. It is assuming it matches the order of the items in the select clause of the query being run. If you haven't specified a select clause, it will be all columns on the table, in the order they appear in the table! declaration. If you are using diesel print-schema or infer_schema!, then that will be the same as the order of your database columns.

My assumption had been that diesel was mapping the fields of the struct by name to the database columns. Are the docs saying that instead the struct field order is used to map to columns, such that in the example above database column "a" would map to struct field "c"?

Correct. If you are using diesel print-schema or diesel infer_schema, then the query examples::table would have the select clause (examples::id, examples::a, examples::b, examples::c), which would load into your struct with the value of examples::a in the field called c on your struct.

@sgrif sgrif closed this Jan 11, 2018

@jonathanstrong

This comment has been minimized.

jonathanstrong commented Jan 11, 2018

Wow, ok. Fwiw, as a user of diesel print-schema/infer_schema! this is a very sharp departure from how I expected it to work. I realize the docs of Queryable state it plainly but might be worth looking for other more visible places to note this. In many cases you'll end up triggering a type error but in the cases the misordered fields match up on type it could be pretty maddening to debug.

@sgrif

This comment has been minimized.

Member

sgrif commented Jan 12, 2018

If you have any concrete places that you think it should be mentioned, feel free to open a PR. We mention in as many places as we can.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment