-
Notifications
You must be signed in to change notification settings - Fork 1.3k
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
Left joins in SQLite can break the query macros #1249
Comments
I have a similar case and the panic happens on this line:
(I manually called |
@ProjectMoon 's example query still fails when reduced to SELECT
user_state.active_room
FROM accounts
LEFT JOIN user_state ON accounts.user_id = user_state.user_id; The
Edit: note that it doens't happen if we select only
|
I haven't been able to reproduce the issue with I'm trying to understand the Adding a |
I'm running into this as well. Are there any workarounds? |
I think this might be related to SQLites query prover/planner, in specific: https://www.sqlite.org/optoverview.html#the_left_join_strength_reduction_optimization If either of these situations are hit, then sqlite will change the query and I think this is what breaking the macro. If I am understanding correctly, in the above provided example, it is hitting the second case of OMIT LEFT JOIN
as I think a successful test of the left join strength reduction also causing a problem is:
CREATE TABLE IF NOT EXISTS "accounts" (
"user_id" TEXT PRIMARY KEY NOT NULL UNIQUE,
"password" TEXT NULL
);
CREATE TABLE IF NOT EXISTS "user_state" (
"row_id" integer primary key autoincrement,
"user_id" TEXT NOT NULL,
"active_room" TEXT,
"account_status" CHECK(account_status IN ('not_registered', 'registered', 'awaiting_activation'))
);
INSERT INTO accounts (user_id, password) VALUES
('a', 'pass')
, ('b', 'pass')
;
INSERT INTO user_state (user_id, active_room, account_status) VALUES
('a', 'room', 'not_registered')
, ('a', 'place', 'not_registered')
, ('b', 'room', 'not_registered')
;
-- this breaks as it reduces to a JOIN in the query prover
SELECT
a.user_id as "username",
a.password,
s.active_room,
s.account_status
FROM accounts a
LEFT JOIN user_state s on a.user_id = s.user_id
WHERE a.user_id = 'a'
AND (s.active_room = 'room' OR s.active_room = 'place')
;
-- this breaks as it reduces to a JOIN in the query prover
SELECT
a.user_id as "username",
a.password,
s.active_room,
s.account_status
FROM accounts a
LEFT JOIN user_state s on a.user_id = s.user_id
WHERE a.user_id = 'a'
;
-- this works as it has different results from a JOIN
SELECT
a.user_id as "username",
a.password,
s.active_room,
s.account_status
FROM accounts a
LEFT JOIN user_state s on a.user_id = s.user_id
WHERE a.user_id = 'a'
AND s.active_room = 'room'
;
|
Currently unknown issue, may be related to[0] though likely something else entirely. Further testing to be done at a later date. [0] launchbadge/sqlx#1249
Downgrading to sqlx 0.4 lets me compile with left outer joins that are failing on 0.5 |
Reproduced with version 0.5.10 If you add this to #[sqlx_macros::test]
async fn it_left_join() -> anyhow::Result<()> {
let mut conn = new::<Sqlite>().await?;
let info = conn.describe("SELECT tweet.id, accounts.id FROM tweet LEFT JOIN accounts ON tweet.owner_id = accounts.id").await?;
Ok(())
} This is weird as, near the end of the file, there is this line, very close from the first one in let d = conn
.describe(
"select tweet.id, accounts.id from accounts left join tweet on owner_id = accounts.id",
)
.await?; And the _explain_s are really different. My addition :
And the one present in the source code :
|
@abonander any thoughts on this? |
As a work around, I remove OP_NULL_ROW support, open-trade@81392f0 |
After some debugging by myself and some people in the #rust:mozilla.org Matrix room, we've come to the conclusion that I've found a bug in SQLx.
If I have two tables like this:
This query will break the
query
andquery_as!
macros:The error message returned during compilation is
proc macro panicked
andhelp: message: no entry found for key
. The code is located atsrc/sqlite/connection/explain.rs:149:32
. This occurs on sqlx 0.5.x, including 0.5.5.It seems specifically related to the
LEFT JOIN
. A regularJOIN
will compile just fine.The text was updated successfully, but these errors were encountered: