Skip to content

Commit 45e02e3

Browse files
committed
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.
1 parent f145454 commit 45e02e3

File tree

3 files changed

+20
-3
lines changed

3 files changed

+20
-3
lines changed

src/backend/parser/parse_node.c

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -226,6 +226,18 @@ transformArrayType(Oid *arrayType, int32 *arrayTypmod)
226226
*/
227227
*arrayType = getBaseTypeAndTypmod(*arrayType, arrayTypmod);
228228

229+
/*
230+
* We treat int2vector and oidvector as though they were domains over
231+
* int2[] and oid[]. This is needed because array slicing could create an
232+
* array that doesn't satisfy the dimensionality constraints of the
233+
* xxxvector type; so we want the result of a slice operation to be
234+
* considered to be of the more general type.
235+
*/
236+
if (*arrayType == INT2VECTOROID)
237+
*arrayType = INT2ARRAYOID;
238+
else if (*arrayType == OIDVECTOROID)
239+
*arrayType = OIDARRAYOID;
240+
229241
/* Get the type tuple for the array */
230242
type_tuple_array = SearchSysCache1(TYPEOID, ObjectIdGetDatum(*arrayType));
231243
if (!HeapTupleIsValid(type_tuple_array))
@@ -263,6 +275,7 @@ transformArrayType(Oid *arrayType, int32 *arrayTypmod)
263275
* For both cases, if the source array is of a domain-over-array type,
264276
* the result is of the base array type or its element type; essentially,
265277
* we must fold a domain to its base type before applying subscripting.
278+
* (Note that int2vector and oidvector are treated as domains here.)
266279
*
267280
* pstate Parse state
268281
* arrayBase Already-transformed expression for the array as a whole

src/backend/parser/parse_target.c

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -839,18 +839,20 @@ transformAssignmentSubscripts(ParseState *pstate,
839839
/* If target was a domain over array, need to coerce up to the domain */
840840
if (arrayType != targetTypeId)
841841
{
842+
Oid resulttype = exprType(result);
843+
842844
result = coerce_to_target_type(pstate,
843-
result, exprType(result),
845+
result, resulttype,
844846
targetTypeId, targetTypMod,
845847
COERCION_ASSIGNMENT,
846848
COERCE_IMPLICIT_CAST,
847849
-1);
848-
/* probably shouldn't fail, but check */
850+
/* can fail if we had int2vector/oidvector, but not for true domains */
849851
if (result == NULL)
850852
ereport(ERROR,
851853
(errcode(ERRCODE_CANNOT_COERCE),
852854
errmsg("cannot cast type %s to %s",
853-
format_type_be(exprType(result)),
855+
format_type_be(resulttype),
854856
format_type_be(targetTypeId)),
855857
parser_errposition(pstate, location)));
856858
}

src/include/catalog/pg_type.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -446,13 +446,15 @@ DATA(insert OID = 1001 ( _bytea PGNSP PGUID -1 f b A f t \054 0 17 0 array_in
446446
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 - - array_typanalyze i x f 0 -1 0 0 _null_ _null_ _null_ ));
447447
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 - - array_typanalyze i x f 0 -1 0 0 _null_ _null_ _null_ ));
448448
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 - - array_typanalyze i x f 0 -1 0 0 _null_ _null_ _null_ ));
449+
#define INT2ARRAYOID 1005
449450
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 - - array_typanalyze i x f 0 -1 0 0 _null_ _null_ _null_ ));
450451
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 - - array_typanalyze i x f 0 -1 0 0 _null_ _null_ _null_ ));
451452
#define INT4ARRAYOID 1007
452453
DATA(insert OID = 1008 ( _regproc PGNSP PGUID -1 f b A f t \054 0 24 0 array_in array_out array_recv array_send - - array_typanalyze i x f 0 -1 0 0 _null_ _null_ _null_ ));
453454
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 - - array_typanalyze i x f 0 -1 0 100 _null_ _null_ _null_ ));
454455
#define TEXTARRAYOID 1009
455456
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 - - array_typanalyze i x f 0 -1 0 0 _null_ _null_ _null_ ));
457+
#define OIDARRAYOID 1028
456458
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 - - array_typanalyze i x f 0 -1 0 0 _null_ _null_ _null_ ));
457459
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 - - array_typanalyze i x f 0 -1 0 0 _null_ _null_ _null_ ));
458460
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 - - array_typanalyze i x f 0 -1 0 0 _null_ _null_ _null_ ));

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy