diff options
Diffstat (limited to 'src/backend/parser')
-rw-r--r-- | src/backend/parser/parse_node.c | 13 | ||||
-rw-r--r-- | src/backend/parser/parse_target.c | 8 |
2 files changed, 18 insertions, 3 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 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))); } |