mirror of
https://github.com/postgres/postgres.git
synced 2025-06-29 10:41:53 +03:00
Clean up a few failures to set collation fields in expression nodes.
I'm not sure these have any non-cosmetic implications, but I'm not sure they don't, either. In particular, ensure the CaseTestExpr generated by transformAssignmentIndirection to represent the base target column carries the correct collation, because parse_collate.c won't fix that. Tweak lsyscache.c API so that we can get the appropriate collation without an extra syscache lookup.
This commit is contained in:
@ -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);
|
||||
|
Reference in New Issue
Block a user