1
0
mirror of https://github.com/postgres/postgres.git synced 2025-08-24 09:27:52 +03:00

In clause_is_computable_at(), test required_relids for clone clauses.

Use the clause's required_relids not clause_relids for testing
whether it is computable at the current join level, if it is a
clone clause generated by deconstruct_distribute_oj_quals().

Arguably, this is more correct and we should do it for all clauses;
that would at least remove the handwavy claim that we are doing
it to save cycles compared to inspecting Vars individually.
However, attempting to do that exposes that we are not being careful
to compute an accurate value for required_relids in all cases.
I'm unsure whether it's a good idea to attempt to do that for v16,
or leave it as future clean-up.  In the meantime, this quick hack
demonstrably fixes some cases, so let's squeeze it in for beta1.

Patch by me, but great thanks to Richard Guo for investigation
and testing.  The new test cases are all modeled on his examples.

Discussion: https://postgr.es/m/CAMbWs4-_vwkBij4XOQ5ukxUvLgwTm0kS5_DO9CicUeKbEfKjUw@mail.gmail.com
This commit is contained in:
Tom Lane
2023-05-21 15:25:43 -04:00
parent eabb22525e
commit b9c755a2f6
3 changed files with 100 additions and 1 deletions

View File

@@ -544,13 +544,24 @@ clause_is_computable_at(PlannerInfo *root,
RestrictInfo *rinfo,
Relids eval_relids)
{
Relids clause_relids = rinfo->clause_relids;
Relids clause_relids;
ListCell *lc;
/* Nothing to do if no outer joins have been performed yet. */
if (!bms_overlap(eval_relids, root->outer_join_rels))
return true;
/*
* For an ordinary qual clause, we consider the actual clause_relids as
* explained above. However, it's possible for multiple members of a
* group of clone quals to have the same clause_relids, so for clones use
* the required_relids instead to ensure we select just one of them.
*/
if (rinfo->has_clone || rinfo->is_clone)
clause_relids = rinfo->required_relids;
else
clause_relids = rinfo->clause_relids;
foreach(lc, root->join_info_list)
{
SpecialJoinInfo *sjinfo = (SpecialJoinInfo *) lfirst(lc);