mirror of
				https://github.com/postgres/postgres.git
				synced 2025-11-03 09:13:20 +03:00 
			
		
		
		
	Fix performance problem in fireRIRonSubselect: with nested subqueries,
fireRIRonSubselect was invoked twice at each subselect, leading to an exponential amount of wasted effort.
This commit is contained in:
		@@ -7,7 +7,7 @@
 | 
				
			|||||||
 *
 | 
					 *
 | 
				
			||||||
 *
 | 
					 *
 | 
				
			||||||
 * IDENTIFICATION
 | 
					 * IDENTIFICATION
 | 
				
			||||||
 *	  $Header: /cvsroot/pgsql/src/backend/rewrite/rewriteHandler.c,v 1.67 2000/01/27 18:11:37 tgl Exp $
 | 
					 *	  $Header: /cvsroot/pgsql/src/backend/rewrite/rewriteHandler.c,v 1.68 2000/03/12 18:57:05 tgl Exp $
 | 
				
			||||||
 *
 | 
					 *
 | 
				
			||||||
 *-------------------------------------------------------------------------
 | 
					 *-------------------------------------------------------------------------
 | 
				
			||||||
 */
 | 
					 */
 | 
				
			||||||
@@ -958,10 +958,6 @@ fireRIRonSubselect(Node *node, void *context)
 | 
				
			|||||||
		return false;
 | 
							return false;
 | 
				
			||||||
	if (IsA(node, SubLink))
 | 
						if (IsA(node, SubLink))
 | 
				
			||||||
	{
 | 
						{
 | 
				
			||||||
		/*
 | 
					 | 
				
			||||||
		 * Standard expression_tree_walker will not recurse into subselect,
 | 
					 | 
				
			||||||
		 * but here we must do so.
 | 
					 | 
				
			||||||
		 */
 | 
					 | 
				
			||||||
		SubLink    *sub = (SubLink *) node;
 | 
							SubLink    *sub = (SubLink *) node;
 | 
				
			||||||
		Query	   *qry;
 | 
							Query	   *qry;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -971,14 +967,12 @@ fireRIRonSubselect(Node *node, void *context)
 | 
				
			|||||||
		/* Do what we came for */
 | 
							/* Do what we came for */
 | 
				
			||||||
		qry = fireRIRrules((Query *) (sub->subselect));
 | 
							qry = fireRIRrules((Query *) (sub->subselect));
 | 
				
			||||||
		sub->subselect = (Node *) qry;
 | 
							sub->subselect = (Node *) qry;
 | 
				
			||||||
		/* Must recurse to handle any sub-subselects! */
 | 
							/* Need not recurse into subselect, because fireRIRrules did it */
 | 
				
			||||||
		if (fireRIRonSubselect((Node *) qry, context))
 | 
					 | 
				
			||||||
			return true;
 | 
					 | 
				
			||||||
		return false;
 | 
							return false;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	if (IsA(node, Query))
 | 
						if (IsA(node, Query))
 | 
				
			||||||
	{
 | 
						{
 | 
				
			||||||
		/* Reach here after recursing down into subselect above... */
 | 
							/* Reach here when called from fireRIRrules */
 | 
				
			||||||
		Query	   *qry = (Query *) node;
 | 
							Query	   *qry = (Query *) node;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		if (fireRIRonSubselect((Node *) (qry->targetList), context))
 | 
							if (fireRIRonSubselect((Node *) (qry->targetList), context))
 | 
				
			||||||
@@ -1107,12 +1101,12 @@ fireRIRrules(Query *parsetree)
 | 
				
			|||||||
		heap_close(rel, AccessShareLock);
 | 
							heap_close(rel, AccessShareLock);
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (parsetree->hasSubLinks)
 | 
					 | 
				
			||||||
		fireRIRonSubselect((Node *) parsetree, NULL);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	if (parsetree->hasAggs)
 | 
						if (parsetree->hasAggs)
 | 
				
			||||||
		parsetree->qual = modifyAggrefQual(parsetree->qual, parsetree);
 | 
							parsetree->qual = modifyAggrefQual(parsetree->qual, parsetree);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (parsetree->hasSubLinks)
 | 
				
			||||||
 | 
							fireRIRonSubselect((Node *) parsetree, NULL);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	return parsetree;
 | 
						return parsetree;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user