mirror of
				https://github.com/postgres/postgres.git
				synced 2025-10-25 00:03:23 -04:00 
			
		
		
		
	Fix more problems with rewriter failing to set Query.hasSubLinks when inserting
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.
This commit is contained in:
		
							parent
							
								
									93eab311e4
								
							
						
					
					
						commit
						96a25d393c
					
				| @ -7,7 +7,7 @@ | ||||
|  * Portions Copyright (c) 1994, Regents of the University of California | ||||
|  * | ||||
|  * IDENTIFICATION | ||||
|  *	  $PostgreSQL: pgsql/src/backend/rewrite/rewriteHandler.c,v 1.179 2008/08/28 23:09:48 tgl Exp $ | ||||
|  *	  $PostgreSQL: pgsql/src/backend/rewrite/rewriteHandler.c,v 1.180 2008/09/24 16:52:46 tgl Exp $ | ||||
|  * | ||||
|  *------------------------------------------------------------------------- | ||||
|  */ | ||||
| @ -346,6 +346,37 @@ 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; | ||||
| 				case RTE_VALUES: | ||||
| 					sub_action->hasSubLinks = | ||||
| 						checkExprHasSubLink((Node *) rte->values_lists); | ||||
| 					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 | ||||
| @ -455,6 +486,14 @@ rewriteRuleAction(Query *parsetree, | ||||
| 					   rule_action->returningList, | ||||
| 					   CMD_SELECT, | ||||
| 					   0); | ||||
| 
 | ||||
| 		/*
 | ||||
| 		 * There could have been some SubLinks in parsetree's returningList, | ||||
| 		 * in which case we'd better mark the rule_action correctly. | ||||
| 		 */ | ||||
| 		if (parsetree->hasSubLinks && !rule_action->hasSubLinks) | ||||
| 			rule_action->hasSubLinks = | ||||
| 					checkExprHasSubLink((Node *) rule_action->returningList); | ||||
| 	} | ||||
| 
 | ||||
| 	return rule_action; | ||||
|  | ||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user