Location via proxy:   [ UP ]  
[Report a bug]   [Manage cookies]                
Skip to content

Commit bf46153

Browse files
committed
When expanding a whole-row Var into a RowExpr during ResolveNew(), attach
the column alias names of the RTE referenced by the Var to the RowExpr. This is needed to allow ruleutils.c to correctly deparse FieldSelect nodes referencing such a construct. Per my recent bug report. Adding a field to RowExpr forces initdb (because of stored rules changes) so this solution is not back-patchable; which is unfortunate because 8.2 and 8.3 have this issue. But it only affects EXPLAIN for some pretty odd corner cases, so we can probably live without a solution for the back branches.
1 parent e64bb65 commit bf46153

File tree

13 files changed

+49
-16
lines changed

13 files changed

+49
-16
lines changed

src/backend/nodes/copyfuncs.c

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@
1515
* Portions Copyright (c) 1994, Regents of the University of California
1616
*
1717
* IDENTIFICATION
18-
* $PostgreSQL: pgsql/src/backend/nodes/copyfuncs.c,v 1.406 2008/10/04 21:56:53 tgl Exp $
18+
* $PostgreSQL: pgsql/src/backend/nodes/copyfuncs.c,v 1.407 2008/10/06 17:39:25 tgl Exp $
1919
*
2020
*-------------------------------------------------------------------------
2121
*/
@@ -1257,6 +1257,7 @@ _copyRowExpr(RowExpr *from)
12571257
COPY_NODE_FIELD(args);
12581258
COPY_SCALAR_FIELD(row_typeid);
12591259
COPY_SCALAR_FIELD(row_format);
1260+
COPY_NODE_FIELD(colnames);
12601261
COPY_LOCATION_FIELD(location);
12611262

12621263
return newnode;

src/backend/nodes/equalfuncs.c

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@
2222
* Portions Copyright (c) 1994, Regents of the University of California
2323
*
2424
* IDENTIFICATION
25-
* $PostgreSQL: pgsql/src/backend/nodes/equalfuncs.c,v 1.332 2008/10/04 21:56:53 tgl Exp $
25+
* $PostgreSQL: pgsql/src/backend/nodes/equalfuncs.c,v 1.333 2008/10/06 17:39:26 tgl Exp $
2626
*
2727
*-------------------------------------------------------------------------
2828
*/
@@ -511,6 +511,7 @@ _equalRowExpr(RowExpr *a, RowExpr *b)
511511
b->row_format != COERCE_DONTCARE)
512512
return false;
513513

514+
COMPARE_NODE_FIELD(colnames);
514515
COMPARE_LOCATION_FIELD(location);
515516

516517
return true;

src/backend/nodes/nodeFuncs.c

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
*
99
*
1010
* IDENTIFICATION
11-
* $PostgreSQL: pgsql/src/backend/nodes/nodeFuncs.c,v 1.33 2008/10/04 21:56:53 tgl Exp $
11+
* $PostgreSQL: pgsql/src/backend/nodes/nodeFuncs.c,v 1.34 2008/10/06 17:39:26 tgl Exp $
1212
*
1313
*-------------------------------------------------------------------------
1414
*/
@@ -1172,6 +1172,7 @@ expression_tree_walker(Node *node,
11721172
case T_ArrayExpr:
11731173
return walker(((ArrayExpr *) node)->elements, context);
11741174
case T_RowExpr:
1175+
/* Assume colnames isn't interesting */
11751176
return walker(((RowExpr *) node)->args, context);
11761177
case T_RowCompareExpr:
11771178
{
@@ -1735,6 +1736,7 @@ expression_tree_mutator(Node *node,
17351736

17361737
FLATCOPY(newnode, rowexpr, RowExpr);
17371738
MUTATE(newnode->args, rowexpr->args, List *);
1739+
/* Assume colnames needn't be duplicated */
17381740
return (Node *) newnode;
17391741
}
17401742
break;
@@ -2174,6 +2176,7 @@ raw_expression_tree_walker(Node *node, bool (*walker) (), void *context)
21742176
}
21752177
break;
21762178
case T_RowExpr:
2179+
/* Assume colnames isn't interesting */
21772180
return walker(((RowExpr *) node)->args, context);
21782181
case T_CoalesceExpr:
21792182
return walker(((CoalesceExpr *) node)->args, context);

src/backend/nodes/outfuncs.c

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
*
99
*
1010
* IDENTIFICATION
11-
* $PostgreSQL: pgsql/src/backend/nodes/outfuncs.c,v 1.340 2008/10/04 21:56:53 tgl Exp $
11+
* $PostgreSQL: pgsql/src/backend/nodes/outfuncs.c,v 1.341 2008/10/06 17:39:26 tgl Exp $
1212
*
1313
* NOTES
1414
* Every node type that can appear in stored rules' parsetrees *must*
@@ -1037,6 +1037,7 @@ _outRowExpr(StringInfo str, RowExpr *node)
10371037
WRITE_NODE_FIELD(args);
10381038
WRITE_OID_FIELD(row_typeid);
10391039
WRITE_ENUM_FIELD(row_format, CoercionForm);
1040+
WRITE_NODE_FIELD(colnames);
10401041
WRITE_LOCATION_FIELD(location);
10411042
}
10421043

src/backend/nodes/readfuncs.c

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
*
99
*
1010
* IDENTIFICATION
11-
* $PostgreSQL: pgsql/src/backend/nodes/readfuncs.c,v 1.215 2008/10/04 21:56:53 tgl Exp $
11+
* $PostgreSQL: pgsql/src/backend/nodes/readfuncs.c,v 1.216 2008/10/06 17:39:26 tgl Exp $
1212
*
1313
* NOTES
1414
* Path and Plan nodes do not have any readfuncs support, because we
@@ -744,6 +744,7 @@ _readRowExpr(void)
744744
READ_NODE_FIELD(args);
745745
READ_OID_FIELD(row_typeid);
746746
READ_ENUM_FIELD(row_format, CoercionForm);
747+
READ_NODE_FIELD(colnames);
747748
READ_LOCATION_FIELD(location);
748749

749750
READ_DONE();

src/backend/optimizer/prep/prepunion.c

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@
2222
*
2323
*
2424
* IDENTIFICATION
25-
* $PostgreSQL: pgsql/src/backend/optimizer/prep/prepunion.c,v 1.156 2008/10/04 21:56:53 tgl Exp $
25+
* $PostgreSQL: pgsql/src/backend/optimizer/prep/prepunion.c,v 1.157 2008/10/06 17:39:26 tgl Exp $
2626
*
2727
*-------------------------------------------------------------------------
2828
*/
@@ -1493,6 +1493,7 @@ adjust_appendrel_attrs_mutator(Node *node, AppendRelInfo *context)
14931493
rowexpr->args = fields;
14941494
rowexpr->row_typeid = var->vartype;
14951495
rowexpr->row_format = COERCE_IMPLICIT_CAST;
1496+
rowexpr->colnames = NIL;
14961497
rowexpr->location = -1;
14971498

14981499
return (Node *) rowexpr;

src/backend/optimizer/util/var.c

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
*
99
*
1010
* IDENTIFICATION
11-
* $PostgreSQL: pgsql/src/backend/optimizer/util/var.c,v 1.79 2008/09/01 20:42:44 tgl Exp $
11+
* $PostgreSQL: pgsql/src/backend/optimizer/util/var.c,v 1.80 2008/10/06 17:39:26 tgl Exp $
1212
*
1313
*-------------------------------------------------------------------------
1414
*/
@@ -663,6 +663,7 @@ flatten_join_alias_vars_mutator(Node *node,
663663
rowexpr->args = fields;
664664
rowexpr->row_typeid = var->vartype;
665665
rowexpr->row_format = COERCE_IMPLICIT_CAST;
666+
rowexpr->colnames = NIL;
666667
rowexpr->location = -1;
667668

668669
return (Node *) rowexpr;

src/backend/parser/parse_coerce.c

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
*
99
*
1010
* IDENTIFICATION
11-
* $PostgreSQL: pgsql/src/backend/parser/parse_coerce.c,v 2.167 2008/09/10 18:29:40 tgl Exp $
11+
* $PostgreSQL: pgsql/src/backend/parser/parse_coerce.c,v 2.168 2008/10/06 17:39:26 tgl Exp $
1212
*
1313
*-------------------------------------------------------------------------
1414
*/
@@ -926,6 +926,7 @@ coerce_record_to_complex(ParseState *pstate, Node *node,
926926
rowexpr->args = newargs;
927927
rowexpr->row_typeid = targetTypeId;
928928
rowexpr->row_format = cformat;
929+
rowexpr->colnames = NIL; /* not needed for named target type */
929930
rowexpr->location = location;
930931
return (Node *) rowexpr;
931932
}

src/backend/parser/parse_expr.c

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
*
99
*
1010
* IDENTIFICATION
11-
* $PostgreSQL: pgsql/src/backend/parser/parse_expr.c,v 1.234 2008/09/01 20:42:44 tgl Exp $
11+
* $PostgreSQL: pgsql/src/backend/parser/parse_expr.c,v 1.235 2008/10/06 17:39:26 tgl Exp $
1212
*
1313
*-------------------------------------------------------------------------
1414
*/
@@ -1534,6 +1534,7 @@ transformRowExpr(ParseState *pstate, RowExpr *r)
15341534
/* Barring later casting, we consider the type RECORD */
15351535
newr->row_typeid = RECORDOID;
15361536
newr->row_format = COERCE_IMPLICIT_CAST;
1537+
newr->colnames = NIL; /* ROW() has anonymous columns */
15371538
newr->location = r->location;
15381539

15391540
return (Node *) newr;

src/backend/rewrite/rewriteManip.c

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
*
88
*
99
* IDENTIFICATION
10-
* $PostgreSQL: pgsql/src/backend/rewrite/rewriteManip.c,v 1.114 2008/10/04 21:56:54 tgl Exp $
10+
* $PostgreSQL: pgsql/src/backend/rewrite/rewriteManip.c,v 1.115 2008/10/06 17:39:26 tgl Exp $
1111
*
1212
*-------------------------------------------------------------------------
1313
*/
@@ -1057,25 +1057,28 @@ ResolveNew_mutator(Node *node, ResolveNew_context *context)
10571057
{
10581058
/* Must expand whole-tuple reference into RowExpr */
10591059
RowExpr *rowexpr;
1060+
List *colnames;
10601061
List *fields;
10611062

10621063
/*
10631064
* If generating an expansion for a var of a named rowtype
10641065
* (ie, this is a plain relation RTE), then we must include
10651066
* dummy items for dropped columns. If the var is RECORD (ie,
1066-
* this is a JOIN), then omit dropped columns.
1067+
* this is a JOIN), then omit dropped columns. Either way,
1068+
* attach column names to the RowExpr for use of ruleutils.c.
10671069
*/
10681070
expandRTE(context->target_rte,
10691071
this_varno, this_varlevelsup, var->location,
10701072
(var->vartype != RECORDOID),
1071-
NULL, &fields);
1073+
&colnames, &fields);
10721074
/* Adjust the generated per-field Vars... */
10731075
fields = (List *) ResolveNew_mutator((Node *) fields,
10741076
context);
10751077
rowexpr = makeNode(RowExpr);
10761078
rowexpr->args = fields;
10771079
rowexpr->row_typeid = var->vartype;
10781080
rowexpr->row_format = COERCE_IMPLICIT_CAST;
1081+
rowexpr->colnames = colnames;
10791082
rowexpr->location = -1;
10801083

10811084
return (Node *) rowexpr;

src/backend/utils/adt/ruleutils.c

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99
*
1010
*
1111
* IDENTIFICATION
12-
* $PostgreSQL: pgsql/src/backend/utils/adt/ruleutils.c,v 1.285 2008/10/04 21:56:54 tgl Exp $
12+
* $PostgreSQL: pgsql/src/backend/utils/adt/ruleutils.c,v 1.286 2008/10/06 17:39:26 tgl Exp $
1313
*
1414
*-------------------------------------------------------------------------
1515
*/
@@ -3236,6 +3236,18 @@ get_name_for_var_field(Var *var, int fieldno,
32363236
TupleDesc tupleDesc;
32373237
Node *expr;
32383238

3239+
/*
3240+
* If it's a RowExpr that was expanded from a whole-row Var, use the
3241+
* column names attached to it.
3242+
*/
3243+
if (IsA(var, RowExpr))
3244+
{
3245+
RowExpr *r = (RowExpr *) var;
3246+
3247+
if (fieldno > 0 && fieldno <= list_length(r->colnames))
3248+
return strVal(list_nth(r->colnames, fieldno - 1));
3249+
}
3250+
32393251
/*
32403252
* If it's a Var of type RECORD, we have to find what the Var refers to;
32413253
* if not, we can use get_expr_result_type. If that fails, we try

src/include/catalog/catversion.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@
3737
* Portions Copyright (c) 1996-2008, PostgreSQL Global Development Group
3838
* Portions Copyright (c) 1994, Regents of the University of California
3939
*
40-
* $PostgreSQL: pgsql/src/include/catalog/catversion.h,v 1.495 2008/10/06 14:13:17 heikki Exp $
40+
* $PostgreSQL: pgsql/src/include/catalog/catversion.h,v 1.496 2008/10/06 17:39:26 tgl Exp $
4141
*
4242
*-------------------------------------------------------------------------
4343
*/
@@ -53,6 +53,6 @@
5353
*/
5454

5555
/* yyyymmddN */
56-
#define CATALOG_VERSION_NO 200810062
56+
#define CATALOG_VERSION_NO 200810063
5757

5858
#endif

src/include/nodes/primnodes.h

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@
1010
* Portions Copyright (c) 1996-2008, PostgreSQL Global Development Group
1111
* Portions Copyright (c) 1994, Regents of the University of California
1212
*
13-
* $PostgreSQL: pgsql/src/include/nodes/primnodes.h,v 1.142 2008/10/04 21:56:55 tgl Exp $
13+
* $PostgreSQL: pgsql/src/include/nodes/primnodes.h,v 1.143 2008/10/06 17:39:26 tgl Exp $
1414
*
1515
*-------------------------------------------------------------------------
1616
*/
@@ -740,6 +740,12 @@ typedef struct ArrayExpr
740740
* not RECORD types, since those are built from the RowExpr itself rather
741741
* than vice versa.) It is important not to assume that length(args) is
742742
* the same as the number of columns logically present in the rowtype.
743+
*
744+
* colnames is NIL in a RowExpr built from an ordinary ROW() expression.
745+
* It is provided in cases where we expand a whole-row Var into a RowExpr,
746+
* to retain the column alias names of the RTE that the Var referenced
747+
* (which would otherwise be very difficult to extract from the parsetree).
748+
* Like the args list, it is one-for-one with physical fields of the rowtype.
743749
*/
744750
typedef struct RowExpr
745751
{
@@ -754,6 +760,7 @@ typedef struct RowExpr
754760
* parsetrees. We must assume typmod -1 for a RowExpr node.
755761
*/
756762
CoercionForm row_format; /* how to display this node */
763+
List *colnames; /* list of String, or NIL */
757764
int location; /* token location, or -1 if unknown */
758765
} RowExpr;
759766

0 commit comments

Comments
 (0)