diff options
author | Tom Lane <tgl@sss.pgh.pa.us> | 2012-02-14 17:34:19 -0500 |
---|---|---|
committer | Tom Lane <tgl@sss.pgh.pa.us> | 2012-02-14 17:34:56 -0500 |
commit | 398f70ec070fe60151584eaa448f04708aa77892 (patch) | |
tree | 508ae6812ca581b5e39e11bb80206aa87e115046 /src/backend/executor | |
parent | c1d9df4fa227781b31be44a5a3024865a7f48049 (diff) | |
download | postgresql-398f70ec070fe60151584eaa448f04708aa77892.tar.gz postgresql-398f70ec070fe60151584eaa448f04708aa77892.zip |
Preserve column names in the execution-time tupledesc for a RowExpr.
The hstore and json datatypes both have record-conversion functions that
pay attention to column names in the composite values they're handed.
We used to not worry about inserting correct field names into tuple
descriptors generated at runtime, but given these examples it seems
useful to do so. Observe the nicer-looking results in the regression
tests whose results changed.
catversion bump because there is a subtle change in requirements for stored
rule parsetrees: RowExprs from ROW() constructs now have to include field
names.
Andrew Dunstan and Tom Lane
Diffstat (limited to 'src/backend/executor')
-rw-r--r-- | src/backend/executor/execQual.c | 3 | ||||
-rw-r--r-- | src/backend/executor/execTuples.c | 19 | ||||
-rw-r--r-- | src/backend/executor/nodeValuesscan.c | 6 |
3 files changed, 17 insertions, 11 deletions
diff --git a/src/backend/executor/execQual.c b/src/backend/executor/execQual.c index 4a6baeb17ee..a1193a8dc34 100644 --- a/src/backend/executor/execQual.c +++ b/src/backend/executor/execQual.c @@ -4627,7 +4627,8 @@ ExecInitExpr(Expr *node, PlanState *parent) if (rowexpr->row_typeid == RECORDOID) { /* generic record, use runtime type assignment */ - rstate->tupdesc = ExecTypeFromExprList(rowexpr->args); + rstate->tupdesc = ExecTypeFromExprList(rowexpr->args, + rowexpr->colnames); BlessTupleDesc(rstate->tupdesc); /* we won't need to redo this at runtime */ } diff --git a/src/backend/executor/execTuples.c b/src/backend/executor/execTuples.c index 3a9471e462f..e755e7c4f07 100644 --- a/src/backend/executor/execTuples.c +++ b/src/backend/executor/execTuples.c @@ -954,27 +954,28 @@ ExecTypeFromTLInternal(List *targetList, bool hasoid, bool skipjunk) /* * ExecTypeFromExprList - build a tuple descriptor from a list of Exprs * - * Here we must make up an arbitrary set of field names. + * Caller must also supply a list of field names (String nodes). */ TupleDesc -ExecTypeFromExprList(List *exprList) +ExecTypeFromExprList(List *exprList, List *namesList) { TupleDesc typeInfo; - ListCell *l; + ListCell *le; + ListCell *ln; int cur_resno = 1; - char fldname[NAMEDATALEN]; + + Assert(list_length(exprList) == list_length(namesList)); typeInfo = CreateTemplateTupleDesc(list_length(exprList), false); - foreach(l, exprList) + forboth(le, exprList, ln, namesList) { - Node *e = lfirst(l); - - sprintf(fldname, "f%d", cur_resno); + Node *e = lfirst(le); + char *n = strVal(lfirst(ln)); TupleDescInitEntry(typeInfo, cur_resno, - fldname, + n, exprType(e), exprTypmod(e), 0); diff --git a/src/backend/executor/nodeValuesscan.c b/src/backend/executor/nodeValuesscan.c index fc17677d0ac..a6c1b70cca6 100644 --- a/src/backend/executor/nodeValuesscan.c +++ b/src/backend/executor/nodeValuesscan.c @@ -25,6 +25,7 @@ #include "executor/executor.h" #include "executor/nodeValuesscan.h" +#include "parser/parsetree.h" static TupleTableSlot *ValuesNext(ValuesScanState *node); @@ -188,6 +189,8 @@ ValuesScanState * ExecInitValuesScan(ValuesScan *node, EState *estate, int eflags) { ValuesScanState *scanstate; + RangeTblEntry *rte = rt_fetch(node->scan.scanrelid, + estate->es_range_table); TupleDesc tupdesc; ListCell *vtl; int i; @@ -239,7 +242,8 @@ ExecInitValuesScan(ValuesScan *node, EState *estate, int eflags) /* * get info about values list */ - tupdesc = ExecTypeFromExprList((List *) linitial(node->values_lists)); + tupdesc = ExecTypeFromExprList((List *) linitial(node->values_lists), + rte->eref->colnames); ExecAssignScanType(&scanstate->ss, tupdesc); |