-
-
Notifications
You must be signed in to change notification settings - Fork 233
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
INSERT sometimes unexpectedly mutates input when Returning is not specified #1029
Comments
I don't think point 5 is entirely corret, but it's difficult to change it as this point. It will breaking api. |
My understanding of the issue has improved since I wrote the report above, so to clarify the exact bug here: By default (if As you note: Postgres only returns rows that were actually touched by the statement, meaning the returned rows do not necessarily match up with the sent rows. It seems that Bun's intended behaviour is to augment the given records with the generated values from the database, but this is where the bug lies: Bun makes a fundamental assumption that the rows will match up exactly, and does not attempt to identify which input record each output row refers to. This is fine (ish) if it's returning all columns (because the resulting records are still internally consistent, though the pointer issues can still apply). But it's a big problem when returning only some columns, because the records end up being a mix of two unrelated records. It seems the most direct fix would be for Bun to find the matching input record for each returned row to update when using The "best" non-breaking fix might be to change the default to return every column, and not attempt to augment the provided records but instead replace them entirely (i.e. truncate the list then add items as if we had performed a Scan). For most users this will be invisible (if slightly less efficient), while entirely avoiding this whole class of error. Users who want greater efficiency can specify the columns to return explicitly, and with knowledge of the potential risks. Though I do think a better default (albeit breaking) would be to return no columns unless the user has explicitly requested them. |
This issue has been automatically marked as stale because it has not had activity in the last 30 days. If there is no update within the next 7 days, this issue will be closed. |
Agreed with both points, but we probably can only do the non-breaking fix at this point. |
Bun version: 1.2.3
In some specific circumstances, an insert statement can mutate its input even though
Returning
was not specified. This can lead to surprising results:There are 2 issues revealed here. One is quite clear:
The default behaviour of an insert should be to leave the input unchanged, but in the example above, the input is partially mutated in a way which is not consistent with either
Returning("NULL")
norReturning("*")
. Specifically: the 2 entries which are unchanged are removed from the input, and the remaining entry is a combination of the first value's key and the updated value's data.Specifying
Returning("NULL")
explicitly fixes this, but should not be required.The second issue is that if the data returned by an
INSERT ... RETURNING
is not in the same order as the original data (which can happen due to rows being omitted, and also due to the order simply being different, as the order is not guaranteed to match), values are mutated to match the order of the output instead of being matched by their primary key before being mutated. This can lead to surprising results, especially if pointers are involved at any level of the input data (as they will be mutated despite the returned data appearing to be consistent with the sent data).The text was updated successfully, but these errors were encountered: