diff options
author | Tom Lane <tgl@sss.pgh.pa.us> | 2011-04-18 15:31:52 -0400 |
---|---|---|
committer | Tom Lane <tgl@sss.pgh.pa.us> | 2011-04-18 15:31:52 -0400 |
commit | 918854cc08868d569aad3bdf2529fc61c66ecde5 (patch) | |
tree | e6175eed7446145d62b0bb707d83f29209837556 /src/backend/parser/parse_relation.c | |
parent | 04db0fdbfa9382730bb65f94bca2cd8063a3456a (diff) |
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.
Diffstat (limited to 'src/backend/parser/parse_relation.c')
-rw-r--r-- | src/backend/parser/parse_relation.c | 24 |
1 files changed, 17 insertions, 7 deletions
diff --git a/src/backend/parser/parse_relation.c b/src/backend/parser/parse_relation.c index 0dbf5cbf38a..2a94f73a9ab 100644 --- a/src/backend/parser/parse_relation.c +++ b/src/backend/parser/parse_relation.c @@ -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: |