1
0
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:
Tom Lane
2011-03-26 14:25:48 -04:00
parent 92f4786fa9
commit b23c9fa929
9 changed files with 49 additions and 44 deletions

View File

@ -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);