1
0
mirror of https://github.com/postgres/postgres.git synced 2025-06-29 10:41:53 +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:
Tom Lane
2013-11-23 20:03:56 -05:00
parent f145454d57
commit 45e02e3232
3 changed files with 20 additions and 3 deletions

View File

@ -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