mirror of
https://github.com/postgres/postgres.git
synced 2025-08-21 10:42:50 +03:00
Fix handling of collations in multi-row VALUES constructs.
Per spec we ought to apply select_common_collation() across the expressions in each column of the VALUES table. The original coding was just taking the first row and assuming it was representative. This patch adds a field to struct RangeTblEntry to carry the resolved collations, so initdb is forced for changes in stored rule representation.
This commit is contained in:
@@ -1220,6 +1220,7 @@ addRangeTableEntryForFunction(ParseState *pstate,
|
||||
RangeTblEntry *
|
||||
addRangeTableEntryForValues(ParseState *pstate,
|
||||
List *exprs,
|
||||
List *collations,
|
||||
Alias *alias,
|
||||
bool inFromCl)
|
||||
{
|
||||
@@ -1233,6 +1234,7 @@ addRangeTableEntryForValues(ParseState *pstate,
|
||||
rte->relid = InvalidOid;
|
||||
rte->subquery = NULL;
|
||||
rte->values_lists = exprs;
|
||||
rte->values_collations = collations;
|
||||
rte->alias = alias;
|
||||
|
||||
eref = alias ? copyObject(alias) : makeAlias(refname, NIL);
|
||||
@@ -1657,7 +1659,9 @@ expandRTE(RangeTblEntry *rte, int rtindex, int sublevels_up,
|
||||
ListCell *l3;
|
||||
int attnum = 0;
|
||||
|
||||
forthree(l1, rte->funccoltypes, l2, rte->funccoltypmods, l3, rte->funccolcollations)
|
||||
forthree(l1, rte->funccoltypes,
|
||||
l2, rte->funccoltypmods,
|
||||
l3, rte->funccolcollations)
|
||||
{
|
||||
Oid attrtype = lfirst_oid(l1);
|
||||
int32 attrtypmod = lfirst_int(l2);
|
||||
@@ -1687,12 +1691,15 @@ expandRTE(RangeTblEntry *rte, int rtindex, int sublevels_up,
|
||||
{
|
||||
/* Values RTE */
|
||||
ListCell *aliasp_item = list_head(rte->eref->colnames);
|
||||
ListCell *lc;
|
||||
ListCell *lcv;
|
||||
ListCell *lcc;
|
||||
|
||||
varattno = 0;
|
||||
foreach(lc, (List *) linitial(rte->values_lists))
|
||||
forboth(lcv, (List *) linitial(rte->values_lists),
|
||||
lcc, rte->values_collations)
|
||||
{
|
||||
Node *col = (Node *) lfirst(lc);
|
||||
Node *col = (Node *) lfirst(lcv);
|
||||
Oid colcollation = lfirst_oid(lcc);
|
||||
|
||||
varattno++;
|
||||
if (colnames)
|
||||
@@ -1712,7 +1719,7 @@ expandRTE(RangeTblEntry *rte, int rtindex, int sublevels_up,
|
||||
varnode = makeVar(rtindex, varattno,
|
||||
exprType(col),
|
||||
exprTypmod(col),
|
||||
exprCollation(col),
|
||||
colcollation,
|
||||
sublevels_up);
|
||||
varnode->location = location;
|
||||
*colvars = lappend(*colvars, varnode);
|
||||
@@ -1789,7 +1796,9 @@ expandRTE(RangeTblEntry *rte, int rtindex, int sublevels_up,
|
||||
ListCell *lcc;
|
||||
|
||||
varattno = 0;
|
||||
forthree(lct, rte->ctecoltypes, lcm, rte->ctecoltypmods, lcc, rte->ctecolcollations)
|
||||
forthree(lct, rte->ctecoltypes,
|
||||
lcm, rte->ctecoltypmods,
|
||||
lcc, rte->ctecolcollations)
|
||||
{
|
||||
Oid coltype = lfirst_oid(lct);
|
||||
int32 coltypmod = lfirst_int(lcm);
|
||||
@@ -2116,6 +2125,7 @@ get_rte_attribute_type(RangeTblEntry *rte, AttrNumber attnum,
|
||||
case RTE_VALUES:
|
||||
{
|
||||
/* Values RTE --- get type info from first sublist */
|
||||
/* collation is stored separately, though */
|
||||
List *collist = (List *) linitial(rte->values_lists);
|
||||
Node *col;
|
||||
|
||||
@@ -2125,7 +2135,7 @@ get_rte_attribute_type(RangeTblEntry *rte, AttrNumber attnum,
|
||||
col = (Node *) list_nth(collist, attnum - 1);
|
||||
*vartype = exprType(col);
|
||||
*vartypmod = exprTypmod(col);
|
||||
*varcollid = exprCollation(col);
|
||||
*varcollid = list_nth_oid(rte->values_collations, attnum - 1);
|
||||
}
|
||||
break;
|
||||
case RTE_JOIN:
|
||||
|
Reference in New Issue
Block a user