-
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
PostgreSQL deferred FK constraint violations are silently dropped #1370
Comments
It looks like the fix should be pretty simple, since we're setting the limit parameter to 1 in the However, if we do generate an error, what do we do with the row that we already got? Should we change the return type of pub type FetchResult<T> = Result<T, FetchError<T>>;
pub struct FetchError<T> {
pub error: sqlx_core::Error,
pub row: Option<T>
}
// should allow existing usages of `?` to continue working
impl From<T> From<FetchError<T>> for sqlx_core::Error {} |
As a workaround, you can use let mut stream = sqlx::query_as("insert into bar values ('foo') returning *").fetch(&pool);
let bar: Bar = stream.try_next().await?.ok_or(sqlx::Error::RowNotFound)?;
// check for deferred FK constraint error
stream.try_next().await?; |
fwiw, I can't personally think of a real use case where having the row that wasn't inserted is useful. Nor does psql display it:
I think the complexity of having a type that can represent success-but-also-failure would be complexity without material benefit, and I'd rather just get an error in this case. |
furthermore, if someone has an unusual use case where this information really is relevant, they can use |
I just ran into this issue. Is there a plan for fixing Created a reproduction repo here: |
committed to database because of deferred FK constraint launchbadge/sqlx#1370
sqlx 0.5.5
postgresql 11.6
sqlx reports no error when a deferred FK constraint is violated.
For example, create two tables with a FK constraint between them, and see that with psql, an error is reported:
Now, try performing this insert with sqlx:
I'd think this should panic because the constraint was violated, but it does not:
I'm guessing the problem is sqlx sees the data row, then ignores the error in the response from the server:
The above is from this pcap: sqlx.pcap.gz
The error is reported this way because the constraint is deferred, so the row can be inserted, but then on commit (which happens automatically) the constraint is violated and the transaction aborts. So I'd also wonder if there is a larger class of bugs where a statement succeeds but sqlx then misses errors from autocommitting the transaction.
The text was updated successfully, but these errors were encountered: