Closed rmunn closed 4 years ago
I just found the !!
operator in the documentation, which does what I actually want here (a left outer join). And adding the !!
operator produces a SELECT statement with names like SELECT user.login
instead of SELECT users.login
, and that ends up returning the results correctly (the username, first & last name, etc, are not blank). Which goes some way to confirm that the root cause of the issue is the SELECT statement being produced with field names users.login
, users.firstname
, etc., but the results being parsed expecting field names user.login
, user.firstname
, etc. (singular vs plural).
So although I'm no longer blocked by this issue, I'll leave it open as I do think I've discovered an actual bug.
Another data point: the order of the where
and join
clauses in my query expression makes a difference to the names chosen in the resulting SQL. My original query looked like:
query {
for user in ctx.Testquery.Users do
where (user.Login = username)
join mail in !! ctx.Testquery.EmailAddresses on (user.Id = mail.UserId)
select (user, mail)
}
That produces SELECT users.login AS 'users.login', ...
(plural users
), and I get blank data for the fields in the users
table. But if I swap the order of the join
and where
clauses:
query {
for user in ctx.Testquery.Users do
join mail in !! ctx.Testquery.EmailAddresses on (user.Id = mail.UserId)
where (user.Login = username)
select (user, mail)
}
Then this produces SELECT user.login AS 'user.login', ...
(singular user
), and I get the correct (non-blank) data out of the users
table.
So it wasn't actually the presence of the !!
operator that was fixing it for me, it was the ordering of the join
clauses vs the where
clauses! Weird.
Thanks for reporting this, it seems like the recent alias changes broke the where-before-join case and our unit-test assertions were not good enough to catch this. I'll fix...
Try the NuGet version 1.1.74 please.
Looks like 1.1.74 fixed it. Thanks!
Description
A simple query joining two tables produces empty results for the left side of the join, even though running the generated SQL works correctly at the MySQL command prompt.
Repro steps
I've trimmed this down as much as I can, but it's still going to be a bit long since there's quite a bit of information to include. Sorry about the length; it's as short as I can make it.
The data structure is a table of users, each of which can have multiple email addresses; one email address is set as the "default" address. Relevant subset of my test data (produced by
mysqldump
and trimmed down to as small as I can make it):I use SqlProvider as follows:
Here's the query that's failing:
While this one succeeds:
I added
FSharp.Data.Sql.Common.QueryEvents.SqlQueryEvent |> Event.add (printfn "Executing SQL: %O")
to my initialization code so I could inspect the SQL being generated by SqlProvider. I noticed a difference between the two queries generated:First, failing, query (including the join):
This one ends up printing the following out of my
for
loop:Second, successful, query (without any join):
This one prints the following out of my
for
loop (of course, only one email address is found since I didn't do a join):Note the difference between the names used in the SELECT statement. With the join, the statement is:
and the name is
users.login
(with some extra backtick characters). But when I do a query without the join, the statement is:and here the name of the column is just
login
, notusers.login
. I suspect that the different column names being selected by the generated SQL are responsible for whether or not SqlProvider succeeds in finding and extracting the data once the query returns.Note that when I run the generated SQL query in MySQL, it works:
So the data is getting out of MySQL, it's just not making it all the way back to my F# code. Somewhere inside SqlProvider, the user data gets lost and only the emails make it out intact.
Expected behavior
Joining two tables returns data from both tables.
Actual behavior
Joining the
users
table to theemail_addresses
table ends up returning blank data from theusers
table, though the emails get returned correctly.Known workarounds
I expect (though I haven't yet tried this) that I can work around this bug by doing two queries and avoiding
join
, which is rather inefficient. Thankfully my database is pretty small and my user base is limited, so the inefficiency won't kill me.Related information