mirror of
				https://github.com/postgres/postgres.git
				synced 2025-10-31 00:03:57 -04:00 
			
		
		
		
	Fix corner-case bug introduced with HOT: if REINDEX TABLE pg_class (or a
REINDEX DATABASE including same) is done before a session has done any other update on pg_class, the pg_class relcache entry was left with an incorrect setting of rd_indexattr, because the indexed-attributes set would be first demanded at a time when we'd forced a partial list of indexes into the pg_class entry, and it would remain cached after that. This could result in incorrect decisions about HOT-update safety later in the same session. In practice, since only pg_class_relname_nsp_index would be missed out, only ALTER TABLE RENAME and ALTER TABLE SET SCHEMA could trigger a problem. Per report and test case from Ondrej Jirman.
This commit is contained in:
		
							parent
							
								
									30fd8ec799
								
							
						
					
					
						commit
						eca1388629
					
				| @ -8,7 +8,7 @@ | ||||
|  * | ||||
|  * | ||||
|  * IDENTIFICATION | ||||
|  *	  $PostgreSQL: pgsql/src/backend/catalog/index.c,v 1.300 2008/06/19 00:46:04 alvherre Exp $ | ||||
|  *	  $PostgreSQL: pgsql/src/backend/catalog/index.c,v 1.301 2008/08/10 19:02:33 tgl Exp $ | ||||
|  * | ||||
|  * | ||||
|  * INTERFACE ROUTINES | ||||
| @ -2380,9 +2380,13 @@ reindex_relation(Oid relid, bool toast_too) | ||||
| 	 * problem. | ||||
| 	 */ | ||||
| 	is_pg_class = (RelationGetRelid(rel) == RelationRelationId); | ||||
| 	doneIndexes = NIL; | ||||
| 
 | ||||
| 	/* Ensure rd_indexattr is valid; see comments for RelationSetIndexList */ | ||||
| 	if (is_pg_class) | ||||
| 		(void) RelationGetIndexAttrBitmap(rel); | ||||
| 
 | ||||
| 	/* Reindex all the indexes. */ | ||||
| 	doneIndexes = NIL; | ||||
| 	foreach(indexId, indexIds) | ||||
| 	{ | ||||
| 		Oid			indexOid = lfirst_oid(indexId); | ||||
|  | ||||
							
								
								
									
										10
									
								
								src/backend/utils/cache/relcache.c
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										10
									
								
								src/backend/utils/cache/relcache.c
									
									
									
									
										vendored
									
									
								
							| @ -8,7 +8,7 @@ | ||||
|  * | ||||
|  * | ||||
|  * IDENTIFICATION | ||||
|  *	  $PostgreSQL: pgsql/src/backend/utils/cache/relcache.c,v 1.272 2008/05/12 00:00:52 alvherre Exp $ | ||||
|  *	  $PostgreSQL: pgsql/src/backend/utils/cache/relcache.c,v 1.273 2008/08/10 19:02:33 tgl Exp $ | ||||
|  * | ||||
|  *------------------------------------------------------------------------- | ||||
|  */ | ||||
| @ -2986,6 +2986,13 @@ insert_ordered_oid(List *list, Oid datum) | ||||
|  * messages.  In practice it is only used on pg_class (see REINDEX). | ||||
|  * | ||||
|  * It is up to the caller to make sure the given list is correctly ordered. | ||||
|  * | ||||
|  * We deliberately do not change rd_indexattr here: even when operating | ||||
|  * with a temporary partial index list, HOT-update decisions must be made | ||||
|  * correctly with respect to the full index set.  It is up to the caller | ||||
|  * to ensure that a correct rd_indexattr set has been cached before first | ||||
|  * calling RelationSetIndexList; else a subsequent inquiry might cause a | ||||
|  * wrong rd_indexattr set to get computed and cached. | ||||
|  */ | ||||
| void | ||||
| RelationSetIndexList(Relation relation, List *indexIds, Oid oidIndex) | ||||
| @ -3004,7 +3011,6 @@ RelationSetIndexList(Relation relation, List *indexIds, Oid oidIndex) | ||||
| 	relation->rd_indexvalid = 2;	/* mark list as forced */ | ||||
| 	/* must flag that we have a forced index list */ | ||||
| 	need_eoxact_work = true; | ||||
| 	/* we deliberately do not change rd_indexattr */ | ||||
| } | ||||
| 
 | ||||
| /*
 | ||||
|  | ||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user