mirror of
				https://github.com/postgres/postgres.git
				synced 2025-10-29 22:49:41 +03:00 
			
		
		
		
	Ensure pg_dump_sort.c sorts null vs non-null namespace consistently.
The original coding here (which is, I believe, my fault) supposed that it didn't need to concern itself with the possibility that one object of a given type-priority has a namespace while another doesn't. But that's not reliably true anymore, if it ever was; and if it does happen then it's possible that DOTypeNameCompare returns self-inconsistent comparison results. That leads to unspecified behavior in qsort() and a resultant weird output order from pg_dump. This should end up being only a cosmetic problem, because any ordering constraints that actually matter should be enforced by the later dependency-based sort. Still, it's a bug, so back-patch. Report and fix by Jacob Champion, though I editorialized on his patch to the extent of making NULL sort after non-NULL, for consistency with our usual sorting definitions. Discussion: https://postgr.es/m/CABAq_6Hw+V-Kj7PNfD5tgOaWT_-qaYkc+SRmJkPLeUjYXLdxwQ@mail.gmail.com
This commit is contained in:
		| @@ -257,7 +257,7 @@ DOTypeNameCompare(const void *p1, const void *p2) | |||||||
| 	DumpableObject *obj2 = *(DumpableObject *const *) p2; | 	DumpableObject *obj2 = *(DumpableObject *const *) p2; | ||||||
| 	int			cmpval; | 	int			cmpval; | ||||||
|  |  | ||||||
| 	/* Sort by type */ | 	/* Sort by type's priority */ | ||||||
| 	cmpval = newObjectTypePriority[obj1->objType] - | 	cmpval = newObjectTypePriority[obj1->objType] - | ||||||
| 		newObjectTypePriority[obj2->objType]; | 		newObjectTypePriority[obj2->objType]; | ||||||
|  |  | ||||||
| @@ -265,17 +265,24 @@ DOTypeNameCompare(const void *p1, const void *p2) | |||||||
| 		return cmpval; | 		return cmpval; | ||||||
|  |  | ||||||
| 	/* | 	/* | ||||||
| 	 * Sort by namespace.  Note that all objects of the same type should | 	 * Sort by namespace.  Typically, all objects of the same priority would | ||||||
| 	 * either have or not have a namespace link, so we needn't be fancy about | 	 * either have or not have a namespace link, but there are exceptions. | ||||||
| 	 * cases where one link is null and the other not. | 	 * Sort NULL namespace after non-NULL in such cases. | ||||||
| 	 */ | 	 */ | ||||||
| 	if (obj1->namespace && obj2->namespace) | 	if (obj1->namespace) | ||||||
| 	{ | 	{ | ||||||
| 		cmpval = strcmp(obj1->namespace->dobj.name, | 		if (obj2->namespace) | ||||||
| 						obj2->namespace->dobj.name); | 		{ | ||||||
| 		if (cmpval != 0) | 			cmpval = strcmp(obj1->namespace->dobj.name, | ||||||
| 			return cmpval; | 							obj2->namespace->dobj.name); | ||||||
|  | 			if (cmpval != 0) | ||||||
|  | 				return cmpval; | ||||||
|  | 		} | ||||||
|  | 		else | ||||||
|  | 			return -1; | ||||||
| 	} | 	} | ||||||
|  | 	else if (obj2->namespace) | ||||||
|  | 		return 1; | ||||||
|  |  | ||||||
| 	/* Sort by name */ | 	/* Sort by name */ | ||||||
| 	cmpval = strcmp(obj1->name, obj2->name); | 	cmpval = strcmp(obj1->name, obj2->name); | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user