@@ -128,7 +128,7 @@ static bool find_dependent_phvs_in_jointree(PlannerInfo *root,
128
128
Node * node , int varno );
129
129
static void substitute_phv_relids (Node * node ,
130
130
int varno , Relids subrelids );
131
- static void fix_append_rel_relids (List * append_rel_list , int varno ,
131
+ static void fix_append_rel_relids (PlannerInfo * root , int varno ,
132
132
Relids subrelids );
133
133
static Node * find_jointree_node_for_rel (Node * jtnode , int relid );
134
134
@@ -1232,14 +1232,14 @@ pull_up_simple_subquery(PlannerInfo *root, Node *jtnode, RangeTblEntry *rte,
1232
1232
* already checked that this won't require introducing multiple subrelids
1233
1233
* into the single-slot AppendRelInfo structs.
1234
1234
*/
1235
- if (parse -> hasSubLinks || root -> glob -> lastPHId != 0 ||
1236
- root -> append_rel_list )
1235
+ if (root -> glob -> lastPHId != 0 || root -> append_rel_list )
1237
1236
{
1238
1237
Relids subrelids ;
1239
1238
1240
1239
subrelids = get_relids_in_jointree ((Node * ) subquery -> jointree , false);
1241
- substitute_phv_relids ((Node * ) parse , varno , subrelids );
1242
- fix_append_rel_relids (root -> append_rel_list , varno , subrelids );
1240
+ if (root -> glob -> lastPHId != 0 )
1241
+ substitute_phv_relids ((Node * ) parse , varno , subrelids );
1242
+ fix_append_rel_relids (root , varno , subrelids );
1243
1243
}
1244
1244
1245
1245
/*
@@ -1418,7 +1418,10 @@ pull_up_union_leaf_queries(Node *setOp, PlannerInfo *root, int parentRTindex,
1418
1418
1419
1419
/*
1420
1420
* Recursively apply pull_up_subqueries to the new child RTE. (We
1421
- * must build the AppendRelInfo first, because this will modify it.)
1421
+ * must build the AppendRelInfo first, because this will modify it;
1422
+ * indeed, that's the only part of the upper query where Vars
1423
+ * referencing childRTindex can exist at this point.)
1424
+ *
1422
1425
* Note that we can pass NULL for containing-join info even if we're
1423
1426
* actually under an outer join, because the child's expressions
1424
1427
* aren't going to propagate up to the join. Also, we ignore the
@@ -2119,6 +2122,25 @@ perform_pullup_replace_vars(PlannerInfo *root,
2119
2122
Query * parse = root -> parse ;
2120
2123
ListCell * lc ;
2121
2124
2125
+ /*
2126
+ * If we are considering an appendrel child subquery (that is, a UNION ALL
2127
+ * member query that we're pulling up), then the only part of the upper
2128
+ * query that could reference the child yet is the translated_vars list of
2129
+ * the associated AppendRelInfo. Furthermore, we do not need to insert
2130
+ * PHVs in the AppendRelInfo --- there isn't any outer join between.
2131
+ */
2132
+ if (containing_appendrel )
2133
+ {
2134
+ bool save_need_phvs = rvcontext -> need_phvs ;
2135
+
2136
+ rvcontext -> need_phvs = false;
2137
+ containing_appendrel -> translated_vars = (List * )
2138
+ pullup_replace_vars ((Node * ) containing_appendrel -> translated_vars ,
2139
+ rvcontext );
2140
+ rvcontext -> need_phvs = save_need_phvs ;
2141
+ return ;
2142
+ }
2143
+
2122
2144
/*
2123
2145
* Replace all of the top query's references to the subquery's outputs
2124
2146
* with copies of the adjusted subtlist items, being careful not to
@@ -2172,22 +2194,14 @@ perform_pullup_replace_vars(PlannerInfo *root,
2172
2194
parse -> havingQual = pullup_replace_vars (parse -> havingQual , rvcontext );
2173
2195
2174
2196
/*
2175
- * Replace references in the translated_vars lists of appendrels. When
2176
- * pulling up an appendrel member, we do not need PHVs in the list of the
2177
- * parent appendrel --- there isn't any outer join between. Elsewhere,
2178
- * use PHVs for safety. (This analysis could be made tighter but it seems
2179
- * unlikely to be worth much trouble.)
2197
+ * Replace references in the translated_vars lists of appendrels.
2180
2198
*/
2181
2199
foreach (lc , root -> append_rel_list )
2182
2200
{
2183
2201
AppendRelInfo * appinfo = (AppendRelInfo * ) lfirst (lc );
2184
- bool save_need_phvs = rvcontext -> need_phvs ;
2185
2202
2186
- if (appinfo == containing_appendrel )
2187
- rvcontext -> need_phvs = false;
2188
2203
appinfo -> translated_vars = (List * )
2189
2204
pullup_replace_vars ((Node * ) appinfo -> translated_vars , rvcontext );
2190
- rvcontext -> need_phvs = save_need_phvs ;
2191
2205
}
2192
2206
2193
2207
/*
@@ -3358,7 +3372,7 @@ remove_result_refs(PlannerInfo *root, int varno, Node *newjtloc)
3358
3372
subrelids = get_relids_in_jointree (newjtloc , false);
3359
3373
Assert (!bms_is_empty (subrelids ));
3360
3374
substitute_phv_relids ((Node * ) root -> parse , varno , subrelids );
3361
- fix_append_rel_relids (root -> append_rel_list , varno , subrelids );
3375
+ fix_append_rel_relids (root , varno , subrelids );
3362
3376
}
3363
3377
3364
3378
/*
@@ -3577,7 +3591,7 @@ substitute_phv_relids(Node *node, int varno, Relids subrelids)
3577
3591
* We assume we may modify the AppendRelInfo nodes in-place.
3578
3592
*/
3579
3593
static void
3580
- fix_append_rel_relids (List * append_rel_list , int varno , Relids subrelids )
3594
+ fix_append_rel_relids (PlannerInfo * root , int varno , Relids subrelids )
3581
3595
{
3582
3596
ListCell * l ;
3583
3597
int subvarno = -1 ;
@@ -3588,7 +3602,7 @@ fix_append_rel_relids(List *append_rel_list, int varno, Relids subrelids)
3588
3602
* AppendRelInfo nodes refer to it. So compute it on first use. Note that
3589
3603
* bms_singleton_member will complain if set is not singleton.
3590
3604
*/
3591
- foreach (l , append_rel_list )
3605
+ foreach (l , root -> append_rel_list )
3592
3606
{
3593
3607
AppendRelInfo * appinfo = (AppendRelInfo * ) lfirst (l );
3594
3608
@@ -3603,8 +3617,9 @@ fix_append_rel_relids(List *append_rel_list, int varno, Relids subrelids)
3603
3617
}
3604
3618
3605
3619
/* Also fix up any PHVs in its translated vars */
3606
- substitute_phv_relids ((Node * ) appinfo -> translated_vars ,
3607
- varno , subrelids );
3620
+ if (root -> glob -> lastPHId != 0 )
3621
+ substitute_phv_relids ((Node * ) appinfo -> translated_vars ,
3622
+ varno , subrelids );
3608
3623
}
3609
3624
}
3610
3625
0 commit comments