mirror of
				https://github.com/postgres/postgres.git
				synced 2025-10-31 10:30:33 +03:00 
			
		
		
		
	Fix array slicing of int2vector and oidvector values.
The previous coding labeled expressions such as pg_index.indkey[1:3] as being of int2vector type; which is not right because the subscript bounds of such a result don't, in general, satisfy the restrictions of int2vector. To fix, implicitly promote the result of slicing int2vector to int2[], or oidvector to oid[]. This is similar to what we've done with domains over arrays, which is a good analogy because these types are very much like restricted domains of the corresponding regular-array types. A side-effect is that we now also forbid array-element updates on such columns, eg while "update pg_index set indkey[4] = 42" would have worked before if you were superuser (and corrupted your catalogs irretrievably, no doubt) it's now disallowed. This seems like a good thing since, again, some choices of subscripting would've led to results not satisfying the restrictions of int2vector. The case of an array-slice update was rejected before, though with a different error message than you get now. We could make these cases work in future if we added a cast from int2[] to int2vector (with a cast function checking the subscript restrictions) but it seems unlikely that there's any value in that. Per report from Ronan Dunklau. Back-patch to all supported branches because of the crash risks involved.
This commit is contained in:
		| @@ -226,6 +226,18 @@ transformArrayType(Oid *arrayType, int32 *arrayTypmod) | ||||
| 	 */ | ||||
| 	*arrayType = getBaseTypeAndTypmod(*arrayType, arrayTypmod); | ||||
|  | ||||
| 	/* | ||||
| 	 * We treat int2vector and oidvector as though they were domains over | ||||
| 	 * int2[] and oid[].  This is needed because array slicing could create an | ||||
| 	 * array that doesn't satisfy the dimensionality constraints of the | ||||
| 	 * xxxvector type; so we want the result of a slice operation to be | ||||
| 	 * considered to be of the more general type. | ||||
| 	 */ | ||||
| 	if (*arrayType == INT2VECTOROID) | ||||
| 		*arrayType = INT2ARRAYOID; | ||||
| 	else if (*arrayType == OIDVECTOROID) | ||||
| 		*arrayType = OIDARRAYOID; | ||||
|  | ||||
| 	/* Get the type tuple for the array */ | ||||
| 	type_tuple_array = SearchSysCache1(TYPEOID, ObjectIdGetDatum(*arrayType)); | ||||
| 	if (!HeapTupleIsValid(type_tuple_array)) | ||||
| @@ -263,6 +275,7 @@ transformArrayType(Oid *arrayType, int32 *arrayTypmod) | ||||
|  * For both cases, if the source array is of a domain-over-array type, | ||||
|  * the result is of the base array type or its element type; essentially, | ||||
|  * we must fold a domain to its base type before applying subscripting. | ||||
|  * (Note that int2vector and oidvector are treated as domains here.) | ||||
|  * | ||||
|  * pstate		Parse state | ||||
|  * arrayBase	Already-transformed expression for the array as a whole | ||||
|   | ||||
		Reference in New Issue
	
	Block a user