Commit 64919aaab made pull_up_simple_subquery set rte->subquery = NULL after doing the deed, so that we don't waste cycles copying a now-useless subquery tree around. I discovered today while working on another patch that if you invoke query_tree_mutator or range_table_mutator on the whole Query after that point, range_table_mutator dumps core, because it's expecting subquery links to never be NULL. There's apparently noplace in our core code that does that today, but I'm a bit surprised we've not heard complaints from anyone else. I propose to do this to harden it:
diff --git a/src/backend/nodes/nodeFuncs.c b/src/backend/nodes/nodeFuncs.c index 876f84dd39..8d58265010 100644 --- a/src/backend/nodes/nodeFuncs.c +++ b/src/backend/nodes/nodeFuncs.c @@ -3788,7 +3788,9 @@ range_table_mutator(List *rtable, /* we don't bother to copy eref, aliases, etc; OK? */ break; case RTE_SUBQUERY: - if (!(flags & QTW_IGNORE_RT_SUBQUERIES)) + /* In the planner, subquery is null if it's been flattened */ + if (!(flags & QTW_IGNORE_RT_SUBQUERIES) && + rte->subquery != NULL) { CHECKFLATCOPY(newrte->subquery, rte->subquery, Query); MUTATE(newrte->subquery, newrte->subquery, Query *); regards, tom lane