Fix PlaceHolderVar mechanism's interaction with outer joins.
Tom Lane <tgl@sss.pgh.pa.us>
Fix PlaceHolderVar mechanism's interaction with outer joins. The point of a PlaceHolderVar is to allow a non-strict expression to be evaluated below an outer join, after which its value bubbles up like a Var and can be forced to NULL when the outer join's semantics require that. However, there was a serious design oversight in that, namely that we didn't ensure that there was actually a correct place in the plan tree to evaluate the placeholder :-(. It may be necessary to delay evaluation of an outer join to ensure that a placeholder that should be evaluated below the join can be evaluated there. Per recent bug report from Kirill Simonov. Back-patch to 8.4 where the PlaceHolderVar mechanism was introduced.
Files
| Path | Change | +/− |
|---|---|---|
| src/backend/nodes/copyfuncs.c | modified | +1 −0 |
| src/backend/nodes/equalfuncs.c | modified | +1 −0 |
| src/backend/nodes/outfuncs.c | modified | +1 −0 |
| src/backend/optimizer/plan/initsplan.c | modified | +37 −0 |
| src/backend/optimizer/plan/planmain.c | modified | +13 −8 |
| src/backend/optimizer/util/placeholder.c | modified | +211 −23 |
| src/include/nodes/relation.h | modified | +16 −1 |
| src/include/optimizer/placeholder.h | modified | +4 −1 |
| src/test/regress/expected/join.out | modified | +45 −0 |
| src/test/regress/sql/join.sql | modified | +40 −0 |