1

For two postgresql tables, a and b with non-null columns

struct MyStruct {
  id: i32,
  name: String,
}

sqlx::query_as!(MyStruct, r"
  SELECT a.id, b.name
  FROM a
  INNER JOIN b on a.id = b.a
")

results in errors like the following

mismatched types
expected type i32
   found enum std::option::Option<i32> rustcE0308
macros.rs(552, 9): Actual error occurred here
macros.rs(552, 9): Error originated from macro call here

I can force sqlx to mark the columns as non-null via the foo as "foo!" syntax, but I'd rather not.

sqlx::query_as!(MyStruct, r#"
  SELECT a.id as "id!", b.name as "name!"
  FROM a
  INNER JOIN b on a.id = b.a
"#)

In the sqlx documentation it says

In most cases, the database engine can tell us whether or not a column may be NULL, and the query!() macro adjusts the field types of the returned struct accordingly.

For Postgres, this only works for columns which come directly from actual tables, as the implementation will need to query the table metadata to find if a given column has a NOT NULL constraint. Columns that do not have a NOT NULL constraint or are the result of an expression are assumed to be nullable and so Option is used instead of T.

Does a JOIN count as an expression that would prevent the database engine from inferring non-nullability? Am I missing something about sqlx that would enable it to correctly infer that those columns cannot be null?

Cypress Frankenfeld
  • 2,317
  • 2
  • 28
  • 40

0 Answers0