mirror of
https://github.com/postgres/postgres.git
synced 2025-09-02 04:21:28 +03:00
Remove ph_may_need from PlaceHolderInfo, with attendant simplifications.
The planner logic that attempted to make a preliminary estimate of the ph_needed levels for PlaceHolderVars seems to be completely broken by lateral references. Fortunately, the potential join order optimization that this code supported seems to be of relatively little value in practice; so let's just get rid of it rather than trying to fix it. Getting rid of this allows fairly substantial simplifications in placeholder.c, too, so planning in such cases should be a bit faster. Issue noted while pursuing bugs reported by Jeremy Evans and Antonin Houska, though this doesn't in itself fix either of their reported cases. What this does do is prevent an Assert crash in the kind of query illustrated by the added regression test. (I'm not sure that the plan for that query is stable enough across platforms to be usable as a regression test output ... but we'll soon find out from the buildfarm.) Back-patch to 9.3. The problem case can't arise without LATERAL, so no need to touch older branches.
This commit is contained in:
@@ -1465,18 +1465,9 @@ typedef struct AppendRelInfo
|
||||
* then allow it to bubble up like a Var until the ph_needed join level.
|
||||
* ph_needed has the same definition as attr_needed for a regular Var.
|
||||
*
|
||||
* ph_may_need is an initial estimate of ph_needed, formed using the
|
||||
* syntactic locations of references to the PHV. We need this in order to
|
||||
* determine whether the PHV reference forces a join ordering constraint:
|
||||
* if the PHV has to be evaluated below the nullable side of an outer join,
|
||||
* and then used above that outer join, we must constrain join order to ensure
|
||||
* there's a valid place to evaluate the PHV below the join. The final
|
||||
* actual ph_needed level might be lower than ph_may_need, but we can't
|
||||
* determine that until later on. Fortunately this doesn't matter for what
|
||||
* we need ph_may_need for: if there's a PHV reference syntactically
|
||||
* above the outer join, it's not going to be allowed to drop below the outer
|
||||
* join, so we would come to the same conclusions about join order even if
|
||||
* we had the final ph_needed value to compare to.
|
||||
* Notice that when ph_eval_at is a join rather than a single baserel, the
|
||||
* PlaceHolderInfo may create constraints on join order: the ph_eval_at join
|
||||
* has to be formed below any outer joins that should null the PlaceHolderVar.
|
||||
*
|
||||
* We create a PlaceHolderInfo only after determining that the PlaceHolderVar
|
||||
* is actually referenced in the plan tree, so that unreferenced placeholders
|
||||
@@ -1491,7 +1482,6 @@ typedef struct PlaceHolderInfo
|
||||
PlaceHolderVar *ph_var; /* copy of PlaceHolderVar tree */
|
||||
Relids ph_eval_at; /* lowest level we can evaluate value at */
|
||||
Relids ph_needed; /* highest level the value is needed at */
|
||||
Relids ph_may_need; /* highest level it might be needed at */
|
||||
int32 ph_width; /* estimated attribute width */
|
||||
} PlaceHolderInfo;
|
||||
|
||||
|
@@ -22,8 +22,6 @@ extern PlaceHolderVar *make_placeholder_expr(PlannerInfo *root, Expr *expr,
|
||||
extern PlaceHolderInfo *find_placeholder_info(PlannerInfo *root,
|
||||
PlaceHolderVar *phv, bool create_new_ph);
|
||||
extern void find_placeholders_in_jointree(PlannerInfo *root);
|
||||
extern void mark_placeholder_maybe_needed(PlannerInfo *root,
|
||||
PlaceHolderInfo *phinfo, Relids relids);
|
||||
extern void update_placeholder_eval_levels(PlannerInfo *root,
|
||||
SpecialJoinInfo *new_sjinfo);
|
||||
extern void fix_placeholder_input_needed_levels(PlannerInfo *root);
|
||||
|
Reference in New Issue
Block a user