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)
Bug Description
Double left join leads to faulty Option / nullability inference. I have provided a minimal repro.
There are two nullability inference issues:
Minimal Reproduction
https://github.com/Palmik/sqlx-issue-repro
The schema:
The sql query:
You would expect
foo.idandfoo.nameto not be optional, and the other columns to be optional. SQLx infersfoo.*andbaz.*as optional, andbar.*as not optional. One can circumvent the issue by using theAS "bar_id?"syntax to mark the columns as optional manually.Running the code produces:
If you make sure that all rows exist, e.g. commenting out line
27, you get:Info
0.7.2sqlx = { version = "0.7.2", features = ["postgres", "uuid", "runtime-tokio-native-tls"] }rustc --version:rustc 1.71.1 (eb26296b5 2023-08-03)