summaryrefslogtreecommitdiff
path: root/src/backend/executor/execTuples.c
diff options
context:
space:
mode:
authorTom Lane <tgl@sss.pgh.pa.us>2022-03-17 18:18:05 -0400
committerTom Lane <tgl@sss.pgh.pa.us>2022-03-17 18:18:05 -0400
commitec62cb0aac5ba31a82339606009ddbd7eb00e2ac (patch)
treeef564a0e0eec8fa4289dee9157d83aedc74778c2 /src/backend/executor/execTuples.c
parent39f0c4bd670c3482f4def87a31108c175da0a8d3 (diff)
Revert applying column aliases to the output of whole-row Vars.
In commit bf7ca1587, I had the bright idea that we could make the result of a whole-row Var (that is, foo.*) track any column aliases that had been applied to the FROM entry the Var refers to. However, that's not terribly logically consistent, because now the output of the Var is no longer of the named composite type that the Var claims to emit. bf7ca1587 tried to handle that by changing the output tuple values to be labeled with a blessed RECORD type, but that's really pretty disastrous: we can wind up storing such tuples onto disk, whereupon they're not readable by other sessions. The only practical fix I can see is to give up on what bf7ca1587 tried to do, and say that the column names of tuples produced by a whole-row Var are always those of the underlying named composite type, query aliases or no. While this introduces some inconsistencies, it removes others, so it's not that awful in the abstract. What *is* kind of awful is to make such a behavioral change in a back-patched bug fix. But corrupt data is worse, so back-patched it will be. (A workaround available to anyone who's unhappy about this is to introduce an extra level of sub-SELECT, so that the whole-row Var is referring to the sub-SELECT's output and not to a named table type. Then the Var is of type RECORD to begin with and there's no issue.) Per report from Miles Delahunty. The faulty commit dates to 9.5, so back-patch to all supported branches. Discussion: https://postgr.es/m/2950001.1638729947@sss.pgh.pa.us
Diffstat (limited to 'src/backend/executor/execTuples.c')
-rw-r--r--src/backend/executor/execTuples.c37
1 files changed, 13 insertions, 24 deletions
diff --git a/src/backend/executor/execTuples.c b/src/backend/executor/execTuples.c
index 2a55d5759d0..06ac253ea0c 100644
--- a/src/backend/executor/execTuples.c
+++ b/src/backend/executor/execTuples.c
@@ -2022,51 +2022,40 @@ ExecTypeFromExprList(List *exprList)
}
/*
- * ExecTypeSetColNames - set column names in a TupleDesc
+ * ExecTypeSetColNames - set column names in a RECORD TupleDesc
*
* Column names must be provided as an alias list (list of String nodes).
- *
- * For some callers, the supplied tupdesc has a named rowtype (not RECORD)
- * and it is moderately likely that the alias list matches the column names
- * already present in the tupdesc. If we do change any column names then
- * we must reset the tupdesc's type to anonymous RECORD; but we avoid doing
- * so if no names change.
*/
void
ExecTypeSetColNames(TupleDesc typeInfo, List *namesList)
{
- bool modified = false;
int colno = 0;
ListCell *lc;
+ /* It's only OK to change col names in a not-yet-blessed RECORD type */
+ Assert(typeInfo->tdtypeid == RECORDOID);
+ Assert(typeInfo->tdtypmod < 0);
+
foreach(lc, namesList)
{
char *cname = strVal(lfirst(lc));
Form_pg_attribute attr;
- /* Guard against too-long names list */
+ /* Guard against too-long names list (probably can't happen) */
if (colno >= typeInfo->natts)
break;
attr = TupleDescAttr(typeInfo, colno);
colno++;
- /* Ignore empty aliases (these must be for dropped columns) */
- if (cname[0] == '\0')
+ /*
+ * Do nothing for empty aliases or dropped columns (these cases
+ * probably can't arise in RECORD types, either)
+ */
+ if (cname[0] == '\0' || attr->attisdropped)
continue;
- /* Change tupdesc only if alias is actually different */
- if (strcmp(cname, NameStr(attr->attname)) != 0)
- {
- namestrcpy(&(attr->attname), cname);
- modified = true;
- }
- }
-
- /* If we modified the tupdesc, it's now a new record type */
- if (modified)
- {
- typeInfo->tdtypeid = RECORDOID;
- typeInfo->tdtypmod = -1;
+ /* OK, assign the column name */
+ namestrcpy(&(attr->attname), cname);
}
}