aboutsummaryrefslogtreecommitdiff
path: root/src/backend/parser/parse_node.c
diff options
context:
space:
mode:
authorTom Lane <tgl@sss.pgh.pa.us>2013-11-23 20:03:56 -0500
committerTom Lane <tgl@sss.pgh.pa.us>2013-11-23 20:03:56 -0500
commit45e02e3232ac7cc5ffe36f7986159b5e0b1f6fdc (patch)
treebb69dba6e6a73d92b137588928df2204f7c150b6 /src/backend/parser/parse_node.c
parentf145454d57bc9dfd105f7236a03a00dd25395dd2 (diff)
downloadpostgresql-45e02e3232ac7cc5ffe36f7986159b5e0b1f6fdc.tar.gz
postgresql-45e02e3232ac7cc5ffe36f7986159b5e0b1f6fdc.zip
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.
Diffstat (limited to 'src/backend/parser/parse_node.c')
-rw-r--r--src/backend/parser/parse_node.c13
1 files changed, 13 insertions, 0 deletions
diff --git a/src/backend/parser/parse_node.c b/src/backend/parser/parse_node.c
index 6ffbd767275..e0ea43a8104 100644
--- a/src/backend/parser/parse_node.c
+++ b/src/backend/parser/parse_node.c
@@ -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