Propagate CTE property flags when copying a CTE list into a rule.
authorTom Lane <[email protected]>
Sun, 7 Feb 2021 00:28:39 +0000 (19:28 -0500)
committerTom Lane <[email protected]>
Sun, 7 Feb 2021 00:28:39 +0000 (19:28 -0500)
rewriteRuleAction() neglected this step, although it was careful to
propagate other similar flags such as hasSubLinks or hasRowSecurity.
Omitting to transfer hasRecursive is just cosmetic at the moment,
but omitting hasModifyingCTE is a live bug, since the executor
certainly looks at that.

The proposed test case only fails back to v10, but since the executor
examines hasModifyingCTE in 9.x as well, I suspect that a test case
could be devised that fails in older branches.  Given the nearness
of the release deadline, though, I'm not going to spend time looking
for a better test.

Report and patch by Greg Nancarrow, cosmetic changes by me

Discussion: https://postgr.es/m/CAJcOf-fAdj=nDKMsRhQzndm-O13NY4dL6xGcEvdX5Xvbbi0V7g@mail.gmail.com

src/backend/rewrite/rewriteHandler.c

index fd63dd7a3bdc728e8213b0c4dd804d53ba431a68..f91d16aa3989fcf8cb95edfbf7be3516fdf2e39e 100644 (file)
@@ -511,6 +511,9 @@ rewriteRuleAction(Query *parsetree,
         *
         * This could possibly be fixed by using some sort of internally
         * generated ID, instead of names, to link CTE RTEs to their CTEs.
+        * However, decompiling the results would be quite confusing; note the
+        * merge of hasRecursive flags below, which could change the apparent
+        * semantics of such redundantly-named CTEs.
         */
        foreach(lc, parsetree->cteList)
        {
@@ -532,6 +535,9 @@ rewriteRuleAction(Query *parsetree,
        /* OK, it's safe to combine the CTE lists */
        sub_action->cteList = list_concat(sub_action->cteList,
                                          copyObject(parsetree->cteList));
+       /* ... and don't forget about the associated flags */
+       sub_action->hasRecursive |= parsetree->hasRecursive;
+       sub_action->hasModifyingCTE |= parsetree->hasModifyingCTE;
    }
 
    /*