77 *
88 *
99 * IDENTIFICATION
10- * $Header: /cvsroot/pgsql/src/backend/rewrite/rewriteManip.c,v 1.79 2003/09/25 06:58:01 petere Exp $
10+ * $Header: /cvsroot/pgsql/src/backend/rewrite/rewriteManip.c,v 1.80 2003/10/20 20:01:59 tgl Exp $
1111 *
1212 *-------------------------------------------------------------------------
1313 */
9999checkExprHasSubLink (Node * node )
100100{
101101/*
102- * If a Query is passed, examine it --- but wewill not recurse into
102+ * If a Query is passed, examine it --- but weneed not recurse into
103103 * sub-Queries.
104104 */
105105return query_or_expression_tree_walker (node ,
@@ -755,10 +755,12 @@ AddQual(Query *parsetree, Node *qual)
755755/*
756756 * Make sure query is marked correctly if added qual has sublinks or
757757 * aggregates (not sure it can ever have aggs, but sublinks
758- * definitely).
758+ * definitely). Need not search qual when query is already marked.
759759 */
760- parsetree -> hasAggs |=checkExprHasAggs (copy );
761- parsetree -> hasSubLinks |=checkExprHasSubLink (copy );
760+ if (!parsetree -> hasAggs )
761+ parsetree -> hasAggs = checkExprHasAggs (copy );
762+ if (!parsetree -> hasSubLinks )
763+ parsetree -> hasSubLinks = checkExprHasSubLink (copy );
762764}
763765
764766/*
@@ -809,10 +811,12 @@ AddHavingQual(Query *parsetree, Node *havingQual)
809811/*
810812 * Make sure query is marked correctly if added qual has sublinks or
811813 * aggregates (not sure it can ever have aggs, but sublinks
812- * definitely).
814+ * definitely). Need not search qual when query is already marked.
813815 */
814- parsetree -> hasAggs |=checkExprHasAggs (copy );
815- parsetree -> hasSubLinks |=checkExprHasSubLink (copy );
816+ if (!parsetree -> hasAggs )
817+ parsetree -> hasAggs = checkExprHasAggs (copy );
818+ if (!parsetree -> hasSubLinks )
819+ parsetree -> hasSubLinks = checkExprHasSubLink (copy );
816820}
817821
818822
@@ -845,6 +849,12 @@ AddInvertedQual(Query *parsetree, Node *qual)
845849 * entry with matching resno from targetlist, if there is one.
846850 * If not, we either change the unmatched Var's varno to update_varno
847851 * (when event == CMD_UPDATE) or replace it with a constant NULL.
852+ *
853+ * Note: the business with inserted_sublink is needed to update hasSubLinks
854+ * in subqueries when the replacement adds a subquery inside a subquery.
855+ * Messy, isn't it? We do not need to do similar pushups for hasAggs,
856+ * because it isn't possible for this transformation to insert a level-zero
857+ * aggregate reference into a subquery --- it could only insert outer aggs.
848858 */
849859
850860typedef struct
@@ -854,6 +864,7 @@ typedef struct
854864List * targetlist ;
855865int event ;
856866int update_varno ;
867+ bool inserted_sublink ;
857868}ResolveNew_context ;
858869
859870static Node *
@@ -904,6 +915,9 @@ ResolveNew_mutator(Node *node, ResolveNew_context *context)
904915/* Adjust varlevelsup if tlist item is from higher query */
905916if (this_varlevelsup > 0 )
906917IncrementVarSublevelsUp (n ,this_varlevelsup ,0 );
918+ /* Report it if we are adding a sublink to query */
919+ if (!context -> inserted_sublink )
920+ context -> inserted_sublink = checkExprHasSubLink (n );
907921return n ;
908922}
909923}
@@ -914,12 +928,17 @@ ResolveNew_mutator(Node *node, ResolveNew_context *context)
914928{
915929/* Recurse into RTE subquery or not-yet-planned sublink subquery */
916930Query * newnode ;
931+ bool save_inserted_sublink ;
917932
918933context -> sublevels_up ++ ;
934+ save_inserted_sublink = context -> inserted_sublink ;
935+ context -> inserted_sublink = false;
919936newnode = query_tree_mutator ((Query * )node ,
920937ResolveNew_mutator ,
921938 (void * )context ,
9229390 );
940+ newnode -> hasSubLinks |=context -> inserted_sublink ;
941+ context -> inserted_sublink = save_inserted_sublink ;
923942context -> sublevels_up -- ;
924943return (Node * )newnode ;
925944}
@@ -938,6 +957,7 @@ ResolveNew(Node *node, int target_varno, int sublevels_up,
938957context .targetlist = targetlist ;
939958context .event = event ;
940959context .update_varno = update_varno ;
960+ context .inserted_sublink = false;
941961
942962/*
943963 * Must be prepared to start with a Query or a bare expression tree;