@@ -40,6 +40,7 @@ static Node *transformAssignmentIndirection(ParseState *pstate,
4040 bool targetIsArray ,
4141 Oid targetTypeId ,
4242 int32 targetTypMod ,
43+ Oid targetCollation ,
4344 ListCell * indirection ,
4445 Node * rhs ,
4546 int location );
@@ -48,6 +49,7 @@ static Node *transformAssignmentSubscripts(ParseState *pstate,
4849 const char * targetName ,
4950 Oid targetTypeId ,
5051 int32 targetTypMod ,
52+ Oid targetCollation ,
5153 List * subscripts ,
5254 bool isSlice ,
5355 ListCell * next_indirection ,
@@ -455,6 +457,7 @@ transformAssignedExpr(ParseState *pstate,
455457 false,
456458 attrtype ,
457459 attrtypmod ,
460+ attrcollation ,
458461 list_head (indirection ),
459462 (Node * ) expr ,
460463 location );
@@ -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,
569573 bool targetIsArray ,
570574 Oid targetTypeId ,
571575 int32 targetTypMod ,
576+ Oid targetCollation ,
572577 ListCell * indirection ,
573578 Node * rhs ,
574579 int location )
@@ -585,6 +590,7 @@ transformAssignmentIndirection(ParseState *pstate,
585590
586591 ctest -> typeId = targetTypeId ;
587592 ctest -> typeMod = targetTypMod ;
593+ ctest -> collation = targetCollation ;
588594 basenode = (Node * ) ctest ;
589595 }
590596
@@ -617,6 +623,7 @@ transformAssignmentIndirection(ParseState *pstate,
617623 AttrNumber attnum ;
618624 Oid fieldTypeId ;
619625 int32 fieldTypMod ;
626+ Oid fieldCollation ;
620627
621628 Assert (IsA (n , String ));
622629
@@ -629,6 +636,7 @@ transformAssignmentIndirection(ParseState *pstate,
629636 targetName ,
630637 targetTypeId ,
631638 targetTypMod ,
639+ targetCollation ,
632640 subscripts ,
633641 isSlice ,
634642 i ,
@@ -662,8 +670,8 @@ transformAssignmentIndirection(ParseState *pstate,
662670 strVal (n )),
663671 parser_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 */
669677 rhs = transformAssignmentIndirection (pstate ,
@@ -672,6 +680,7 @@ transformAssignmentIndirection(ParseState *pstate,
672680 false,
673681 fieldTypeId ,
674682 fieldTypMod ,
683+ fieldCollation ,
675684 lnext (i ),
676685 rhs ,
677686 location );
@@ -696,6 +705,7 @@ transformAssignmentIndirection(ParseState *pstate,
696705 targetName ,
697706 targetTypeId ,
698707 targetTypMod ,
708+ targetCollation ,
699709 subscripts ,
700710 isSlice ,
701711 NULL ,
@@ -747,6 +757,7 @@ transformAssignmentSubscripts(ParseState *pstate,
747757 const char * targetName ,
748758 Oid targetTypeId ,
749759 int32 targetTypMod ,
760+ Oid targetCollation ,
750761 List * subscripts ,
751762 bool isSlice ,
752763 ListCell * next_indirection ,
@@ -758,6 +769,7 @@ transformAssignmentSubscripts(ParseState *pstate,
758769 int32 arrayTypMod ;
759770 Oid elementTypeId ;
760771 Oid typeNeeded ;
772+ Oid collationNeeded ;
761773
762774 Assert (subscripts != NIL );
763775
@@ -769,13 +781,24 @@ transformAssignmentSubscripts(ParseState *pstate,
769781 /* Identify type that RHS must provide */
770782 typeNeeded = 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 */
773795 rhs = transformAssignmentIndirection (pstate ,
774796 NULL ,
775797 targetName ,
776798 true,
777799 typeNeeded ,
778800 arrayTypMod ,
801+ collationNeeded ,
779802 next_indirection ,
780803 rhs ,
781804 location );
0 commit comments