@@ -40,6 +40,7 @@ static Node *transformAssignmentIndirection(ParseState *pstate,
4040bool targetIsArray ,
4141Oid targetTypeId ,
4242int32 targetTypMod ,
43+ Oid targetCollation ,
4344ListCell * indirection ,
4445Node * rhs ,
4546int location );
@@ -48,6 +49,7 @@ static Node *transformAssignmentSubscripts(ParseState *pstate,
4849const char * targetName ,
4950Oid targetTypeId ,
5051int32 targetTypMod ,
52+ Oid targetCollation ,
5153List * subscripts ,
5254bool isSlice ,
5355ListCell * next_indirection ,
@@ -455,6 +457,7 @@ transformAssignedExpr(ParseState *pstate,
455457 false,
456458attrtype ,
457459attrtypmod ,
460+ attrcollation ,
458461list_head (indirection ),
459462 (Node * )expr ,
460463location );
@@ -548,8 +551,9 @@ updateTargetListEntry(ParseState *pstate,
548551 * targetIsArray is true if we're subscripting it. These are just for
549552 * error reporting.
550553 *
551- * targetTypeId and targetTypMod indicate the datatype of the object to
552- * be assigned to (initially the target column, later some subobject).
554+ * targetTypeId, targetTypMod, targetCollation indicate the datatype and
555+ * collation of the object to be assigned to (initially the target column,
556+ * later some subobject).
553557 *
554558 * indirection is the sublist remaining to process. When it's NULL, we're
555559 * done recursing and can just coerce and return the RHS.
@@ -569,6 +573,7 @@ transformAssignmentIndirection(ParseState *pstate,
569573bool targetIsArray ,
570574Oid targetTypeId ,
571575int32 targetTypMod ,
576+ Oid targetCollation ,
572577ListCell * indirection ,
573578Node * rhs ,
574579int location )
@@ -585,6 +590,7 @@ transformAssignmentIndirection(ParseState *pstate,
585590
586591ctest -> typeId = targetTypeId ;
587592ctest -> typeMod = targetTypMod ;
593+ ctest -> collation = targetCollation ;
588594basenode = (Node * )ctest ;
589595}
590596
@@ -617,6 +623,7 @@ transformAssignmentIndirection(ParseState *pstate,
617623AttrNumber attnum ;
618624Oid fieldTypeId ;
619625int32 fieldTypMod ;
626+ Oid fieldCollation ;
620627
621628Assert (IsA (n ,String ));
622629
@@ -629,6 +636,7 @@ transformAssignmentIndirection(ParseState *pstate,
629636targetName ,
630637targetTypeId ,
631638targetTypMod ,
639+ targetCollation ,
632640subscripts ,
633641isSlice ,
634642i ,
@@ -662,8 +670,8 @@ transformAssignmentIndirection(ParseState *pstate,
662670strVal (n )),
663671parser_errposition (pstate ,location )));
664672
665- get_atttypetypmod (typrelid ,attnum ,
666- & fieldTypeId ,& fieldTypMod );
673+ get_atttypetypmodcoll (typrelid ,attnum ,
674+ & fieldTypeId ,& fieldTypMod , & fieldCollation );
667675
668676/* recurse to create appropriate RHS for field assign */
669677rhs = transformAssignmentIndirection (pstate ,
@@ -672,6 +680,7 @@ transformAssignmentIndirection(ParseState *pstate,
672680 false,
673681fieldTypeId ,
674682fieldTypMod ,
683+ fieldCollation ,
675684lnext (i ),
676685rhs ,
677686location );
@@ -696,6 +705,7 @@ transformAssignmentIndirection(ParseState *pstate,
696705targetName ,
697706targetTypeId ,
698707targetTypMod ,
708+ targetCollation ,
699709subscripts ,
700710isSlice ,
701711NULL ,
@@ -747,6 +757,7 @@ transformAssignmentSubscripts(ParseState *pstate,
747757const char * targetName ,
748758Oid targetTypeId ,
749759int32 targetTypMod ,
760+ Oid targetCollation ,
750761List * subscripts ,
751762bool isSlice ,
752763ListCell * next_indirection ,
@@ -758,6 +769,7 @@ transformAssignmentSubscripts(ParseState *pstate,
758769int32 arrayTypMod ;
759770Oid elementTypeId ;
760771Oid typeNeeded ;
772+ Oid collationNeeded ;
761773
762774Assert (subscripts != NIL );
763775
@@ -769,13 +781,24 @@ transformAssignmentSubscripts(ParseState *pstate,
769781/* Identify type that RHS must provide */
770782typeNeeded = isSlice ?arrayType :elementTypeId ;
771783
784+ /*
785+ * Array normally has same collation as elements, but there's an
786+ * exception: we might be subscripting a domain over an array type.
787+ * In that case use collation of the base type.
788+ */
789+ if (arrayType == targetTypeId )
790+ collationNeeded = targetCollation ;
791+ else
792+ collationNeeded = get_typcollation (arrayType );
793+
772794/* recurse to create appropriate RHS for array assign */
773795rhs = transformAssignmentIndirection (pstate ,
774796NULL ,
775797targetName ,
776798 true,
777799typeNeeded ,
778800arrayTypMod ,
801+ collationNeeded ,
779802next_indirection ,
780803rhs ,
781804location );