diff options
Diffstat (limited to 'src/backend/parser/parse_target.c')
-rw-r--r-- | src/backend/parser/parse_target.c | 31 |
1 files changed, 27 insertions, 4 deletions
diff --git a/src/backend/parser/parse_target.c b/src/backend/parser/parse_target.c index 8e92b99b5b2..d53d1d9f008 100644 --- a/src/backend/parser/parse_target.c +++ b/src/backend/parser/parse_target.c @@ -40,6 +40,7 @@ static Node *transformAssignmentIndirection(ParseState *pstate, bool targetIsArray, Oid targetTypeId, int32 targetTypMod, + Oid targetCollation, ListCell *indirection, Node *rhs, int location); @@ -48,6 +49,7 @@ static Node *transformAssignmentSubscripts(ParseState *pstate, const char *targetName, Oid targetTypeId, int32 targetTypMod, + Oid targetCollation, List *subscripts, bool isSlice, ListCell *next_indirection, @@ -455,6 +457,7 @@ transformAssignedExpr(ParseState *pstate, false, attrtype, attrtypmod, + attrcollation, list_head(indirection), (Node *) expr, location); @@ -548,8 +551,9 @@ updateTargetListEntry(ParseState *pstate, * targetIsArray is true if we're subscripting it. These are just for * error reporting. * - * targetTypeId and targetTypMod indicate the datatype of the object to - * be assigned to (initially the target column, later some subobject). + * targetTypeId, targetTypMod, targetCollation indicate the datatype and + * collation of the object to be assigned to (initially the target column, + * later some subobject). * * indirection is the sublist remaining to process. When it's NULL, we're * done recursing and can just coerce and return the RHS. @@ -569,6 +573,7 @@ transformAssignmentIndirection(ParseState *pstate, bool targetIsArray, Oid targetTypeId, int32 targetTypMod, + Oid targetCollation, ListCell *indirection, Node *rhs, int location) @@ -585,6 +590,7 @@ transformAssignmentIndirection(ParseState *pstate, ctest->typeId = targetTypeId; ctest->typeMod = targetTypMod; + ctest->collation = targetCollation; basenode = (Node *) ctest; } @@ -617,6 +623,7 @@ transformAssignmentIndirection(ParseState *pstate, AttrNumber attnum; Oid fieldTypeId; int32 fieldTypMod; + Oid fieldCollation; Assert(IsA(n, String)); @@ -629,6 +636,7 @@ transformAssignmentIndirection(ParseState *pstate, targetName, targetTypeId, targetTypMod, + targetCollation, subscripts, isSlice, i, @@ -662,8 +670,8 @@ transformAssignmentIndirection(ParseState *pstate, strVal(n)), parser_errposition(pstate, location))); - get_atttypetypmod(typrelid, attnum, - &fieldTypeId, &fieldTypMod); + get_atttypetypmodcoll(typrelid, attnum, + &fieldTypeId, &fieldTypMod, &fieldCollation); /* recurse to create appropriate RHS for field assign */ rhs = transformAssignmentIndirection(pstate, @@ -672,6 +680,7 @@ transformAssignmentIndirection(ParseState *pstate, false, fieldTypeId, fieldTypMod, + fieldCollation, lnext(i), rhs, location); @@ -696,6 +705,7 @@ transformAssignmentIndirection(ParseState *pstate, targetName, targetTypeId, targetTypMod, + targetCollation, subscripts, isSlice, NULL, @@ -747,6 +757,7 @@ transformAssignmentSubscripts(ParseState *pstate, const char *targetName, Oid targetTypeId, int32 targetTypMod, + Oid targetCollation, List *subscripts, bool isSlice, ListCell *next_indirection, @@ -758,6 +769,7 @@ transformAssignmentSubscripts(ParseState *pstate, int32 arrayTypMod; Oid elementTypeId; Oid typeNeeded; + Oid collationNeeded; Assert(subscripts != NIL); @@ -769,6 +781,16 @@ transformAssignmentSubscripts(ParseState *pstate, /* Identify type that RHS must provide */ typeNeeded = isSlice ? arrayType : elementTypeId; + /* + * Array normally has same collation as elements, but there's an + * exception: we might be subscripting a domain over an array type. + * In that case use collation of the base type. + */ + if (arrayType == targetTypeId) + collationNeeded = targetCollation; + else + collationNeeded = get_typcollation(arrayType); + /* recurse to create appropriate RHS for array assign */ rhs = transformAssignmentIndirection(pstate, NULL, @@ -776,6 +798,7 @@ transformAssignmentSubscripts(ParseState *pstate, true, typeNeeded, arrayTypMod, + collationNeeded, next_indirection, rhs, location); |