diff --git a/src/backend/optimizer/plan/setrefs.c b/src/backend/optimizer/plan/setrefs.c index e5786455704..86d29ecede3 100644 --- a/src/backend/optimizer/plan/setrefs.c +++ b/src/backend/optimizer/plan/setrefs.c @@ -438,6 +438,15 @@ add_rte_to_flat_rtable(PlannerGlobal *glob, RangeTblEntry *rte) newrte->colcollations = NIL; newrte->securityQuals = NIL; + /* + * Also, if it's a subquery RTE, lose the relid that may have been kept to + * signal that it had been a view. We don't want that to escape the + * planner, mainly because doing so breaks -DWRITE_READ_PARSE_PLAN_TREES + * testing thanks to outfuncs/readfuncs not preserving it. + */ + if (newrte->rtekind == RTE_SUBQUERY) + newrte->relid = InvalidOid; + glob->finalrtable = lappend(glob->finalrtable, newrte); /* diff --git a/src/backend/rewrite/rewriteHandler.c b/src/backend/rewrite/rewriteHandler.c index 95c62a1e8cf..028b37e63fd 100644 --- a/src/backend/rewrite/rewriteHandler.c +++ b/src/backend/rewrite/rewriteHandler.c @@ -1828,8 +1828,8 @@ ApplyRetrieveRule(Query *parsetree, /* * Clear fields that should not be set in a subquery RTE. However, we - * retain the relid to support correct operation of makeWholeRowVar during - * planning. + * retain the relid for now, to support correct operation of + * makeWholeRowVar during planning. */ rte->relkind = 0; rte->rellockmode = 0; diff --git a/src/backend/tcop/postgres.c b/src/backend/tcop/postgres.c index 8c624ee6699..bc8dd553a49 100644 --- a/src/backend/tcop/postgres.c +++ b/src/backend/tcop/postgres.c @@ -803,45 +803,10 @@ pg_rewrite_query(Query *query) } #endif -#ifdef WRITE_READ_PARSE_PLAN_TREES - /* Optional debugging check: pass querytree through outfuncs/readfuncs */ - { - List *new_list = NIL; - ListCell *lc; - - /* - * We currently lack outfuncs/readfuncs support for most utility - * statement types, so only attempt to write/read non-utility queries. - */ - foreach(lc, querytree_list) - { - Query *query = castNode(Query, lfirst(lc)); - - if (query->commandType != CMD_UTILITY) - { - char *str = nodeToString(query); - Query *new_query = stringToNodeWithLocations(str); - - /* - * queryId is not saved in stored rules, but we must preserve - * it here to avoid breaking pg_stat_statements. - */ - new_query->queryId = query->queryId; - - new_list = lappend(new_list, new_query); - pfree(str); - } - else - new_list = lappend(new_list, query); - } - - /* This checks both outfuncs/readfuncs and the equal() routines... */ - if (!equal(new_list, querytree_list)) - elog(WARNING, "outfuncs/readfuncs failed to produce equal parse tree"); - else - querytree_list = new_list; - } -#endif + /* + * We don't apply WRITE_READ_PARSE_PLAN_TREES to rewritten query trees, + * because it breaks the hack of preserving relid for rewritten views. + */ if (Debug_print_rewritten) elog_node_display(LOG, "rewritten parse tree", querytree_list, diff --git a/src/include/nodes/parsenodes.h b/src/include/nodes/parsenodes.h index af828b84459..4f4612fa39f 100644 --- a/src/include/nodes/parsenodes.h +++ b/src/include/nodes/parsenodes.h @@ -985,8 +985,8 @@ typedef struct RangeTblEntry * As a special case, relid can also be set in RTE_SUBQUERY RTEs. This * happens when an RTE_RELATION RTE for a view is transformed to an * RTE_SUBQUERY during rewriting. We keep the relid because it is useful - * during planning, cf makeWholeRowVar. (It cannot be relied on during - * execution, because it will not propagate to parallel workers.) + * during planning, cf makeWholeRowVar. (It will not be passed on to the + * executor, however.) * * As a special case, RTE_NAMEDTUPLESTORE can also set relid to indicate * that the tuple format of the tuplestore is the same as the referenced