-
Notifications
You must be signed in to change notification settings - Fork 227
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
ExecuteUpdate/Delete produce invalid SQL when table is present both as the primary and in a join #3253
Comments
@roji Can give you a hand with this as well. It worked out of the box when I added that in a couple of months ago but probably because I had fixed it earlier as part of some other tests back in Nov 2023. Currently get the following SQL for that test
Take a look at CirrusRedOrg/EntityFrameworkCore.Jet@8723fe8 |
Note that this looks like a dup of dotnet/efcore#33947 for SQLite. |
@ChrisJollyAU that's odd, the table that needs to be updated in this test is OwnedCollection, not Owner (PG and SQLite have a different problem where the primary/target table (OwnedCollections) also appears in the JOIN). Do you have some custom logic transforming the query in some way so that it's trying to update Owner instead? |
I do have some custom stuff regarding tables (and also validity since I can't use things like TOP directly in a DELETE) Unlike SQL Server, Jet doesn't have the Think its fine (mostly/probably) as |
Yeah, neither do most databases (e.g. PG, Sqlite) - SQL Server is a bit special on this.
I'm not sure, but IIRC usually only the table immediately after UPDATE (so Owner in your case) can be updated... I'd be surprised if it's possible to update joined tables (can you check?). If so, is it even possible to update multiple tables with the same UPDATE statement? |
Just checked the docs and it looks like they both can do an UPDATE-FROM. In fact sqlite's doc says "The SQLite implementation strives to be compatible with PostgreSQL". I actually have a sqlite implementation now that passes that UPDATE test. Should be easy to implement then for efcore.pg
Might be possible. Would have to test |
That's different from the SQL Server syntax; in PG, the FROM indeed can be used to join additional tables (and the PG provider indeed translates to to it, code). But the target/primary table is distinct and must be specified directly after UPDATE; you cannot have it in a FROM and then reference only its alias after the UPDATE, like we do for SQL Server (I assume SQLite works the same way). That's basically the problem with this issue, and that's why SQL Server is the only provider where this test is passing. I'll have generally have to dig deeper into this issue to figure out the best way to fix it across all providers... |
Its' actually a simple fix - 1 line change for sqlite. Trying to see how it would work for efcore.pg now |
Okay so in the base
The It just needs the if statement changed to the following and sqlite automatically gets that and the test You can do the same in I did try to make your |
@ChrisJollyAU sounds great! We should in general no longer be doing reference equality checks in the expression tree - in EF 9.0 we've started moving away from reference identity altogether, which was the source of lots of referential integrity bugs, and makes it difficult to achieve full immutability in the tree. So this is probably a remnant from pre-8.0 days. |
Finally getting round to answer this question we had (mostly curiosity). I can't do this in EFCore (it throws the error quite deep in a place that isn't easily overridable). But manually creating a UPDATE query does work So on the Northwind database I can do the following in Jet
And yes, if you look at each table (Customers and Orders) correct values are all updated |
Test NonSharedModelBulkUpdatesTestBase.Replace_ColumnExpression_in_column_setter:
... causes the following SQL to get generated:
... which fails because OwnedCollection is present twice (duplicate alias o0).
The SQL Server SQL generation always includes the primary table in the FROM, and only ever outputs the alias for the primary table:
Ideally, the SQL wouldn't even reference the Owner table (dotnet/efcore#33946). But in the meantime, on the PG side the fix is most likely to have a step which checks if the primary table is present in a join, and to remove the join if so.
The text was updated successfully, but these errors were encountered: