Open
Description
Bug Description
Double left join leads to faulty Option / nullability inference. I have provided a minimal repro.
There are two nullability inference issues:
- LEFT JOIN-ed table columns are inferred as not Optional
- The FROM table columns are inferred as Optional
Minimal Reproduction
https://github.com/Palmik/sqlx-issue-repro
The schema:
CREATE TABLE foo (
id BIGINT PRIMARY KEY,
name TEXT NOT NULL
);
CREATE TABLE baz (
id BIGINT PRIMARY KEY,
name TEXT NOT NULL
);
CREATE TABLE bar (
id BIGINT PRIMARY KEY,
foo_id BIGINT NOT NULL REFERENCES foo(id),
baz_id BIGINT REFERENCES baz(id),
name TEXT NOT NULL
);
The sql query:
SELECT
foo.id,
foo.name,
bar.id AS "bar_id",
bar.name AS "bar_name",
baz.id AS "baz_id",
baz.name AS "baz_name"
FROM foo
LEFT JOIN bar ON bar.foo_id = foo.id
LEFT JOIN baz ON baz.id = bar.baz_id
You would expect foo.id
and foo.name
to not be optional, and the other columns to be optional. SQLx infers foo.*
and baz.*
as optional, and bar.*
as not optional. One can circumvent the issue by using the AS "bar_id?"
syntax to mark the columns as optional manually.
Running the code produces:
thread 'main' panicked at 'called `Result::unwrap()` on an `Err` value: ColumnDecode { index: "2", source: UnexpectedNullError }', src/main.rs:77:6
If you make sure that all rows exist, e.g. commenting out line 27
, you get:
Record { id: Some(1), name: Some("foo1"), bar_id: 1, bar_name: "bar1", baz_id: Some(1), baz_name: Some("baz1") }
Record { id: Some(2), name: Some("foo2"), bar_id: 2, bar_name: "bar2", baz_id: Some(2), baz_name: Some("baz2") }
Record { id: Some(1), name: Some("foo1"), bar_id: 3, bar_name: "bar3", baz_id: None, baz_name: None }
Record { id: Some(2), name: Some("foo2"), bar_id: 4, bar_name: "bar4", baz_id: None, baz_name: None }
Info
- SQLx version:
0.7.2
- SQLx features enabled:
sqlx = { version = "0.7.2", features = ["postgres", "uuid", "runtime-tokio-native-tls"] }
- Database server and version: PostgreSQL 16, but also reproducible on 15.2
- Operating system: linux
rustc --version
:rustc 1.71.1 (eb26296b5 2023-08-03)