Skip to content

Comments

Eliminate case expression if all branches are the same either way#360

Open
duairc wants to merge 1 commit intotomjaguarpaw:masterfrom
duairc:casefix
Open

Eliminate case expression if all branches are the same either way#360
duairc wants to merge 1 commit intotomjaguarpaw:masterfrom
duairc:casefix

Conversation

@duairc
Copy link
Contributor

@duairc duairc commented Dec 26, 2017

Okay, so this is a fairly simple fix, but I'm not sure it's the right place to fix this issue. I've attached a .zip file with a bunch of files that show an example of when this is an issue.

Basically, since PostgreSQL 9.0, PostgreSQL has the ability to optimise away outer joins in certain cases if none of the columns in the outer join are actually used in the end.

The problem is that when you use Opaleye.FunctionalJoin, it generates a CASE expression against every such column, even if the result is the same regardless. From the PostgreSQL's point of view, the value of the column is "needed" then, so it can't optimise away the JOIN.

This commit just makes Opaleye not generate the CASE expressions in the first place if every branch has the same result either way, which means PostgresSQL doesn't do the JOINs.

The .zip file I've attached contains a simple test case schema, a file with the appropriate Opaleye boilerplate for that schema, and the result of doing EXPLAIN on respective:

  1. Hand-crafted SQL queries
  2. Opaleye-generated SQL queries without this fix
  3. Opaleye-generated SQL queries with this fix

These show that the JOIN is optimised away in the first and third cases.

@tomjaguarpaw
Copy link
Owner

Hello. Thanks for this. I'm sorry I haven't responded. It must have got lost because it was Christmas time.

This sounds like a very nice idea. I'd probably prefer that the optimization was done on the PrimQuery rather than the SQL types, though. It should probably live in Optimize.hs.

@tomjaguarpaw
Copy link
Owner

The offending line seems to be an ifThenElseMany. I imagine you get this behaviour when fR rr == f lr rr. Is that right?

@tomjaguarpaw
Copy link
Owner

I imagine you get this behaviour when fR rr == f lr rr. Is that right?

I've checked, and yes, that's the issue.

I'm a bit surprised that Postgres itself doesn't do this. Anyway, I'm happy to add the optimization but it should be done on the PrimQuery.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants