]> git.ipfire.org Git - thirdparty/postgresql.git/commitdiff
Fix array slicing of int2vector and oidvector values.
authorTom Lane <tgl@sss.pgh.pa.us>
Sun, 24 Nov 2013 01:04:13 +0000 (20:04 -0500)
committerTom Lane <tgl@sss.pgh.pa.us>
Sun, 24 Nov 2013 01:04:13 +0000 (20:04 -0500)
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.

src/backend/parser/parse_node.c
src/include/catalog/pg_type.h

index f775850e049cd22d6e130bf827ae995dce222806..093b789d23fbd81649725149d171b4d0784ae596 100644 (file)
@@ -267,6 +267,18 @@ transformArraySubscripts(ParseState *pstate,
        if (!OidIsValid(elementType))
                elementType = transformArrayType(arrayType);
 
+       /*
+        * 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;
+
        /*
         * A list containing only single subscripts refers to a single array
         * element.  If any of the items are double subscripts (lower:upper), then
index d687d74b7bfacbe75341726bc799f4f7784fd049..e6bbd68bd2284b010dfde3f6c55e0e7fddbf1e69 100644 (file)
@@ -430,6 +430,7 @@ DATA(insert OID = 1001 (  _bytea     PGNSP PGUID -1 f b A f t \054 0        17 0 array_in
 DATA(insert OID = 1002 (  _char                 PGNSP PGUID -1 f b A f t \054 0        18 0 array_in array_out array_recv array_send - - - i x f 0 -1 0 _null_ _null_ ));
 DATA(insert OID = 1003 (  _name                 PGNSP PGUID -1 f b A f t \054 0        19 0 array_in array_out array_recv array_send - - - i x f 0 -1 0 _null_ _null_ ));
 DATA(insert OID = 1005 (  _int2                 PGNSP PGUID -1 f b A f t \054 0        21 0 array_in array_out array_recv array_send - - - i x f 0 -1 0 _null_ _null_ ));
+#define INT2ARRAYOID           1005
 DATA(insert OID = 1006 (  _int2vector PGNSP PGUID -1 f b A f t \054 0  22 0 array_in array_out array_recv array_send - - - i x f 0 -1 0 _null_ _null_ ));
 DATA(insert OID = 1007 (  _int4                 PGNSP PGUID -1 f b A f t \054 0        23 0 array_in array_out array_recv array_send - - - i x f 0 -1 0 _null_ _null_ ));
 #define INT4ARRAYOID           1007
@@ -437,6 +438,7 @@ DATA(insert OID = 1008 (  _regproc   PGNSP PGUID -1 f b A f t \054 0        24 0 array_i
 DATA(insert OID = 1009 (  _text                 PGNSP PGUID -1 f b A f t \054 0        25 0 array_in array_out array_recv array_send - - - i x f 0 -1 0 _null_ _null_ ));
 #define TEXTARRAYOID           1009
 DATA(insert OID = 1028 (  _oid          PGNSP PGUID -1 f b A f t \054 0        26 0 array_in array_out array_recv array_send - - - i x f 0 -1 0 _null_ _null_ ));
+#define OIDARRAYOID                    1028
 DATA(insert OID = 1010 (  _tid          PGNSP PGUID -1 f b A f t \054 0        27 0 array_in array_out array_recv array_send - - - i x f 0 -1 0 _null_ _null_ ));
 DATA(insert OID = 1011 (  _xid          PGNSP PGUID -1 f b A f t \054 0        28 0 array_in array_out array_recv array_send - - - i x f 0 -1 0 _null_ _null_ ));
 DATA(insert OID = 1012 (  _cid          PGNSP PGUID -1 f b A f t \054 0        29 0 array_in array_out array_recv array_send - - - i x f 0 -1 0 _null_ _null_ ));