diff options
author | Tom Lane <tgl@sss.pgh.pa.us> | 2013-11-23 20:03:56 -0500 |
---|---|---|
committer | Tom Lane <tgl@sss.pgh.pa.us> | 2013-11-23 20:03:56 -0500 |
commit | 45e02e3232ac7cc5ffe36f7986159b5e0b1f6fdc (patch) | |
tree | bb69dba6e6a73d92b137588928df2204f7c150b6 /src/backend/parser/parse_target.c | |
parent | f145454d57bc9dfd105f7236a03a00dd25395dd2 (diff) | |
download | postgresql-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_target.c')
-rw-r--r-- | src/backend/parser/parse_target.c | 8 |
1 files changed, 5 insertions, 3 deletions
diff --git a/src/backend/parser/parse_target.c b/src/backend/parser/parse_target.c index 9c6c202c8e6..d56e00ffde6 100644 --- a/src/backend/parser/parse_target.c +++ b/src/backend/parser/parse_target.c @@ -839,18 +839,20 @@ transformAssignmentSubscripts(ParseState *pstate, /* If target was a domain over array, need to coerce up to the domain */ if (arrayType != targetTypeId) { + Oid resulttype = exprType(result); + result = coerce_to_target_type(pstate, - result, exprType(result), + result, resulttype, targetTypeId, targetTypMod, COERCION_ASSIGNMENT, COERCE_IMPLICIT_CAST, -1); - /* probably shouldn't fail, but check */ + /* can fail if we had int2vector/oidvector, but not for true domains */ if (result == NULL) ereport(ERROR, (errcode(ERRCODE_CANNOT_COERCE), errmsg("cannot cast type %s to %s", - format_type_be(exprType(result)), + format_type_be(resulttype), format_type_be(targetTypeId)), parser_errposition(pstate, location))); } |