]> granicus.if.org Git - postgresql/commitdiff
Fix more problems with rewriter failing to set Query.hasSubLinks when inserting
authorTom Lane <tgl@sss.pgh.pa.us>
Wed, 24 Sep 2008 16:53:07 +0000 (16:53 +0000)
committerTom Lane <tgl@sss.pgh.pa.us>
Wed, 24 Sep 2008 16:53:07 +0000 (16:53 +0000)
a SubLink expression into a rule query.  We missed cases where the original
query contained a sub-SELECT in a function in FROM, a multi-row VALUES list,
or a RETURNING list.  Per bug #4434 from Dean Rasheed and subsequent
investigation.

Back-patch to 8.1; older releases don't have the issue because they didn't
try to be smart about setting hasSubLinks only when needed.

src/backend/rewrite/rewriteHandler.c

index bf244b7e63a4babf41005a3678e3fd4b02a5525a..377dffaf435b72bac093a594c9aea0bc87a670ca 100644 (file)
@@ -7,7 +7,7 @@
  * Portions Copyright (c) 1994, Regents of the University of California
  *
  * IDENTIFICATION
- *       $PostgreSQL: pgsql/src/backend/rewrite/rewriteHandler.c,v 1.158.2.3 2007/03/01 18:50:42 tgl Exp $
+ *       $PostgreSQL: pgsql/src/backend/rewrite/rewriteHandler.c,v 1.158.2.4 2008/09/24 16:53:07 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -334,6 +334,33 @@ rewriteRuleAction(Query *parsetree,
        sub_action->rtable = list_concat((List *) copyObject(parsetree->rtable),
                                                                         sub_action->rtable);
 
+       /*
+        * There could have been some SubLinks in parsetree's rtable, in which
+        * case we'd better mark the sub_action correctly.
+        */
+       if (parsetree->hasSubLinks && !sub_action->hasSubLinks)
+       {
+               ListCell   *lc;
+
+               foreach(lc, parsetree->rtable)
+               {
+                       RangeTblEntry *rte = (RangeTblEntry *) lfirst(lc);
+
+                       switch (rte->rtekind)
+                       {
+                               case RTE_FUNCTION:
+                                       sub_action->hasSubLinks =
+                                               checkExprHasSubLink(rte->funcexpr);
+                                       break;
+                               default:
+                                       /* other RTE types don't contain bare expressions */
+                                       break;
+                       }
+                       if (sub_action->hasSubLinks)
+                               break;          /* no need to keep scanning rtable */
+               }
+       }
+
        /*
         * Each rule action's jointree should be the main parsetree's jointree
         * plus that rule's jointree, but usually *without* the original rtindex