mirror of
				https://github.com/postgres/postgres.git
				synced 2025-10-31 00:03:57 -04:00 
			
		
		
		
	Last week's patch for make_sort_from_pathkeys wasn't good enough: it has
to be able to discard top-level RelabelType nodes on *both* sides of the equivalence-class-to-target-list comparison, since make_pathkey_from_sortinfo might either add or remove a RelabelType. Also fix the latter to do the removal case cleanly. Per example from Peter.
This commit is contained in:
		
							parent
							
								
									f1528b5154
								
							
						
					
					
						commit
						1be0601681
					
				| @ -11,7 +11,7 @@ | ||||
|  * Portions Copyright (c) 1994, Regents of the University of California | ||||
|  * | ||||
|  * IDENTIFICATION | ||||
|  *	  $PostgreSQL: pgsql/src/backend/optimizer/path/pathkeys.c,v 1.87 2007/11/02 18:54:15 tgl Exp $ | ||||
|  *	  $PostgreSQL: pgsql/src/backend/optimizer/path/pathkeys.c,v 1.88 2007/11/08 19:25:37 tgl Exp $ | ||||
|  * | ||||
|  *------------------------------------------------------------------------- | ||||
|  */ | ||||
| @ -292,9 +292,10 @@ make_pathkey_from_sortinfo(PlannerInfo *root, | ||||
| 	if (exprType((Node *) expr) != opcintype && | ||||
| 		!IsPolymorphicType(opcintype)) | ||||
| 	{ | ||||
| 		/* Strip any existing RelabelType, and add a new one */ | ||||
| 		/* Strip any existing RelabelType, and add a new one if needed */ | ||||
| 		while (expr && IsA(expr, RelabelType)) | ||||
| 			expr = (Expr *) ((RelabelType *) expr)->arg; | ||||
| 		if (exprType((Node *) expr) != opcintype) | ||||
| 			expr = (Expr *) makeRelabelType(expr, | ||||
| 											opcintype, | ||||
| 											-1, | ||||
|  | ||||
| @ -10,7 +10,7 @@ | ||||
|  * | ||||
|  * | ||||
|  * IDENTIFICATION | ||||
|  *	  $PostgreSQL: pgsql/src/backend/optimizer/plan/createplan.c,v 1.232 2007/11/02 18:54:15 tgl Exp $ | ||||
|  *	  $PostgreSQL: pgsql/src/backend/optimizer/plan/createplan.c,v 1.233 2007/11/08 19:25:37 tgl Exp $ | ||||
|  * | ||||
|  *------------------------------------------------------------------------- | ||||
|  */ | ||||
| @ -2738,7 +2738,7 @@ make_sort_from_pathkeys(PlannerInfo *root, Plan *lefttree, List *pathkeys, | ||||
| 		/*
 | ||||
| 		 * We can sort by any non-constant expression listed in the pathkey's | ||||
| 		 * EquivalenceClass.  For now, we take the first one that corresponds | ||||
| 		 * to an available Var in the tlist. If there isn't any, use the first | ||||
| 		 * to an available item in the tlist. If there isn't any, use the first | ||||
| 		 * one that is an expression in the input's vars.  (The non-const | ||||
| 		 * restriction only matters if the EC is below_outer_join; but if it | ||||
| 		 * isn't, it won't contain consts anyway, else we'd have discarded | ||||
| @ -2766,24 +2766,21 @@ make_sort_from_pathkeys(PlannerInfo *root, Plan *lefttree, List *pathkeys, | ||||
| 
 | ||||
| 			/*
 | ||||
| 			 * We can also use it if the pathkey expression is a relabel | ||||
| 			 * of the tlist entry.  This is needed for binary-compatible | ||||
| 			 * cases (cf. make_pathkey_from_sortinfo). | ||||
| 			 * of the tlist entry, or vice versa.  This is needed for | ||||
| 			 * binary-compatible cases (cf. make_pathkey_from_sortinfo). | ||||
| 			 * We prefer an exact match, though, so we do the basic | ||||
| 			 * search first. | ||||
| 			 */ | ||||
| 			if (IsA(em->em_expr, RelabelType)) | ||||
| 			{ | ||||
| 				Expr	   *rtarg = ((RelabelType *) em->em_expr)->arg; | ||||
| 
 | ||||
| 				tle = tlist_member((Node *) rtarg, tlist); | ||||
| 			tle = tlist_member_ignore_relabel((Node *) em->em_expr, tlist); | ||||
| 			if (tle) | ||||
| 			{ | ||||
| 				pk_datatype = em->em_datatype; | ||||
| 				break;			/* found expr already in tlist */ | ||||
| 			} | ||||
| 		} | ||||
| 		} | ||||
| 		if (!tle) | ||||
| 		{ | ||||
| 			/* No matching Var; look for a computable expression */ | ||||
| 			/* No matching tlist item; look for a computable expression */ | ||||
| 			Expr   *sortexpr = NULL; | ||||
| 
 | ||||
| 			foreach(j, pathkey->pk_eclass->ec_members) | ||||
| @ -2798,7 +2795,7 @@ make_sort_from_pathkeys(PlannerInfo *root, Plan *lefttree, List *pathkeys, | ||||
| 				exprvars = pull_var_clause((Node *) sortexpr, false); | ||||
| 				foreach(k, exprvars) | ||||
| 				{ | ||||
| 					if (!tlist_member(lfirst(k), tlist)) | ||||
| 					if (!tlist_member_ignore_relabel(lfirst(k), tlist)) | ||||
| 						break; | ||||
| 				} | ||||
| 				list_free(exprvars); | ||||
|  | ||||
| @ -8,7 +8,7 @@ | ||||
|  * | ||||
|  * | ||||
|  * IDENTIFICATION | ||||
|  *	  $PostgreSQL: pgsql/src/backend/optimizer/util/tlist.c,v 1.74 2007/01/05 22:19:33 momjian Exp $ | ||||
|  *	  $PostgreSQL: pgsql/src/backend/optimizer/util/tlist.c,v 1.75 2007/11/08 19:25:37 tgl Exp $ | ||||
|  * | ||||
|  *------------------------------------------------------------------------- | ||||
|  */ | ||||
| @ -44,6 +44,34 @@ tlist_member(Node *node, List *targetlist) | ||||
| 	return NULL; | ||||
| } | ||||
| 
 | ||||
| /*
 | ||||
|  * tlist_member_ignore_relabel | ||||
|  *	  Same as above, except that we ignore top-level RelabelType nodes | ||||
|  *	  while checking for a match.  This is needed for some scenarios | ||||
|  *	  involving binary-compatible sort operations. | ||||
|  */ | ||||
| TargetEntry * | ||||
| tlist_member_ignore_relabel(Node *node, List *targetlist) | ||||
| { | ||||
| 	ListCell   *temp; | ||||
| 
 | ||||
| 	while (node && IsA(node, RelabelType)) | ||||
| 		node = (Node *) ((RelabelType *) node)->arg; | ||||
| 
 | ||||
| 	foreach(temp, targetlist) | ||||
| 	{ | ||||
| 		TargetEntry *tlentry = (TargetEntry *) lfirst(temp); | ||||
| 		Expr   *tlexpr = tlentry->expr; | ||||
| 
 | ||||
| 		while (tlexpr && IsA(tlexpr, RelabelType)) | ||||
| 			tlexpr = ((RelabelType *) tlexpr)->arg; | ||||
| 
 | ||||
| 		if (equal(node, tlexpr)) | ||||
| 			return tlentry; | ||||
| 	} | ||||
| 	return NULL; | ||||
| } | ||||
| 
 | ||||
| /*
 | ||||
|  * flatten_tlist | ||||
|  *	  Create a target list that only contains unique variables. | ||||
|  | ||||
| @ -7,7 +7,7 @@ | ||||
|  * Portions Copyright (c) 1996-2007, PostgreSQL Global Development Group | ||||
|  * Portions Copyright (c) 1994, Regents of the University of California | ||||
|  * | ||||
|  * $PostgreSQL: pgsql/src/include/optimizer/tlist.h,v 1.45 2007/01/05 22:19:56 momjian Exp $ | ||||
|  * $PostgreSQL: pgsql/src/include/optimizer/tlist.h,v 1.46 2007/11/08 19:25:37 tgl Exp $ | ||||
|  * | ||||
|  *------------------------------------------------------------------------- | ||||
|  */ | ||||
| @ -18,6 +18,7 @@ | ||||
| 
 | ||||
| 
 | ||||
| extern TargetEntry *tlist_member(Node *node, List *targetlist); | ||||
| extern TargetEntry *tlist_member_ignore_relabel(Node *node, List *targetlist); | ||||
| 
 | ||||
| extern List *flatten_tlist(List *tlist); | ||||
| extern List *add_to_flat_tlist(List *tlist, List *vars); | ||||
|  | ||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user