@@ -40,6 +40,7 @@ static Node *transformAssignmentIndirection(ParseState *pstate,
40
40
bool targetIsArray ,
41
41
Oid targetTypeId ,
42
42
int32 targetTypMod ,
43
+ Oid targetCollation ,
43
44
ListCell * indirection ,
44
45
Node * rhs ,
45
46
int location );
@@ -48,6 +49,7 @@ static Node *transformAssignmentSubscripts(ParseState *pstate,
48
49
const char * targetName ,
49
50
Oid targetTypeId ,
50
51
int32 targetTypMod ,
52
+ Oid targetCollation ,
51
53
List * subscripts ,
52
54
bool isSlice ,
53
55
ListCell * next_indirection ,
@@ -455,6 +457,7 @@ transformAssignedExpr(ParseState *pstate,
455
457
false,
456
458
attrtype ,
457
459
attrtypmod ,
460
+ attrcollation ,
458
461
list_head (indirection ),
459
462
(Node * ) expr ,
460
463
location );
@@ -548,8 +551,9 @@ updateTargetListEntry(ParseState *pstate,
548
551
* targetIsArray is true if we're subscripting it. These are just for
549
552
* error reporting.
550
553
*
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).
553
557
*
554
558
* indirection is the sublist remaining to process. When it's NULL, we're
555
559
* done recursing and can just coerce and return the RHS.
@@ -569,6 +573,7 @@ transformAssignmentIndirection(ParseState *pstate,
569
573
bool targetIsArray ,
570
574
Oid targetTypeId ,
571
575
int32 targetTypMod ,
576
+ Oid targetCollation ,
572
577
ListCell * indirection ,
573
578
Node * rhs ,
574
579
int location )
@@ -585,6 +590,7 @@ transformAssignmentIndirection(ParseState *pstate,
585
590
586
591
ctest -> typeId = targetTypeId ;
587
592
ctest -> typeMod = targetTypMod ;
593
+ ctest -> collation = targetCollation ;
588
594
basenode = (Node * ) ctest ;
589
595
}
590
596
@@ -617,6 +623,7 @@ transformAssignmentIndirection(ParseState *pstate,
617
623
AttrNumber attnum ;
618
624
Oid fieldTypeId ;
619
625
int32 fieldTypMod ;
626
+ Oid fieldCollation ;
620
627
621
628
Assert (IsA (n , String ));
622
629
@@ -629,6 +636,7 @@ transformAssignmentIndirection(ParseState *pstate,
629
636
targetName ,
630
637
targetTypeId ,
631
638
targetTypMod ,
639
+ targetCollation ,
632
640
subscripts ,
633
641
isSlice ,
634
642
i ,
@@ -662,8 +670,8 @@ transformAssignmentIndirection(ParseState *pstate,
662
670
strVal (n )),
663
671
parser_errposition (pstate , location )));
664
672
665
- get_atttypetypmod (typrelid , attnum ,
666
- & fieldTypeId , & fieldTypMod );
673
+ get_atttypetypmodcoll (typrelid , attnum ,
674
+ & fieldTypeId , & fieldTypMod , & fieldCollation );
667
675
668
676
/* recurse to create appropriate RHS for field assign */
669
677
rhs = transformAssignmentIndirection (pstate ,
@@ -672,6 +680,7 @@ transformAssignmentIndirection(ParseState *pstate,
672
680
false,
673
681
fieldTypeId ,
674
682
fieldTypMod ,
683
+ fieldCollation ,
675
684
lnext (i ),
676
685
rhs ,
677
686
location );
@@ -696,6 +705,7 @@ transformAssignmentIndirection(ParseState *pstate,
696
705
targetName ,
697
706
targetTypeId ,
698
707
targetTypMod ,
708
+ targetCollation ,
699
709
subscripts ,
700
710
isSlice ,
701
711
NULL ,
@@ -747,6 +757,7 @@ transformAssignmentSubscripts(ParseState *pstate,
747
757
const char * targetName ,
748
758
Oid targetTypeId ,
749
759
int32 targetTypMod ,
760
+ Oid targetCollation ,
750
761
List * subscripts ,
751
762
bool isSlice ,
752
763
ListCell * next_indirection ,
@@ -758,6 +769,7 @@ transformAssignmentSubscripts(ParseState *pstate,
758
769
int32 arrayTypMod ;
759
770
Oid elementTypeId ;
760
771
Oid typeNeeded ;
772
+ Oid collationNeeded ;
761
773
762
774
Assert (subscripts != NIL );
763
775
@@ -769,13 +781,24 @@ transformAssignmentSubscripts(ParseState *pstate,
769
781
/* Identify type that RHS must provide */
770
782
typeNeeded = isSlice ? arrayType : elementTypeId ;
771
783
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
+
772
794
/* recurse to create appropriate RHS for array assign */
773
795
rhs = transformAssignmentIndirection (pstate ,
774
796
NULL ,
775
797
targetName ,
776
798
true,
777
799
typeNeeded ,
778
800
arrayTypMod ,
801
+ collationNeeded ,
779
802
next_indirection ,
780
803
rhs ,
781
804
location );
0 commit comments