Skip to content

Commit 0436679

Browse files
committed
Get rid of adjust_appendrel_attr_needed(), which has been broken ever since
we extended the appendrel mechanism to support UNION ALL optimization. The reason nobody noticed was that we are not actually using attr_needed data for appendrel children; hence it seems more reasonable to rip it out than fix it. Back-patch to 8.2 because an Assert failure is possible in corner cases. Per examination of an example from Jim Nasby. In HEAD, also get rid of AppendRelInfo.col_mappings, which is quite inadequate to represent UNION ALL situations; depend entirely on translated_vars instead.
1 parent ccc9073 commit 0436679

File tree

8 files changed

+46
-146
lines changed

8 files changed

+46
-146
lines changed

src/backend/nodes/copyfuncs.c

Lines changed: 1 addition & 2 deletions
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.410 2008/10/31 08:39:20 heikki Exp $
18+
* $PostgreSQL: pgsql/src/backend/nodes/copyfuncs.c,v 1.411 2008/11/11 18:13:32 tgl Exp $
1919
*
2020
*-------------------------------------------------------------------------
2121
*/
@@ -1640,7 +1640,6 @@ _copyAppendRelInfo(AppendRelInfo *from)
16401640
COPY_SCALAR_FIELD(child_relid);
16411641
COPY_SCALAR_FIELD(parent_reltype);
16421642
COPY_SCALAR_FIELD(child_reltype);
1643-
COPY_NODE_FIELD(col_mappings);
16441643
COPY_NODE_FIELD(translated_vars);
16451644
COPY_SCALAR_FIELD(parent_reloid);
16461645

src/backend/nodes/equalfuncs.c

Lines changed: 1 addition & 2 deletions
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.335 2008/10/31 08:39:20 heikki Exp $
25+
* $PostgreSQL: pgsql/src/backend/nodes/equalfuncs.c,v 1.336 2008/11/11 18:13:32 tgl Exp $
2626
*
2727
*-------------------------------------------------------------------------
2828
*/
@@ -806,7 +806,6 @@ _equalAppendRelInfo(AppendRelInfo *a, AppendRelInfo *b)
806806
COMPARE_SCALAR_FIELD(child_relid);
807807
COMPARE_SCALAR_FIELD(parent_reltype);
808808
COMPARE_SCALAR_FIELD(child_reltype);
809-
COMPARE_NODE_FIELD(col_mappings);
810809
COMPARE_NODE_FIELD(translated_vars);
811810
COMPARE_SCALAR_FIELD(parent_reloid);
812811

src/backend/nodes/outfuncs.c

Lines changed: 1 addition & 2 deletions
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.343 2008/10/21 20:42:52 tgl Exp $
11+
* $PostgreSQL: pgsql/src/backend/nodes/outfuncs.c,v 1.344 2008/11/11 18:13:32 tgl Exp $
1212
*
1313
* NOTES
1414
* Every node type that can appear in stored rules' parsetrees *must*
@@ -1628,7 +1628,6 @@ _outAppendRelInfo(StringInfo str, AppendRelInfo *node)
16281628
WRITE_UINT_FIELD(child_relid);
16291629
WRITE_OID_FIELD(parent_reltype);
16301630
WRITE_OID_FIELD(child_reltype);
1631-
WRITE_NODE_FIELD(col_mappings);
16321631
WRITE_NODE_FIELD(translated_vars);
16331632
WRITE_OID_FIELD(parent_reloid);
16341633
}

src/backend/optimizer/path/allpaths.c

Lines changed: 6 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
*
99
*
1010
* IDENTIFICATION
11-
* $PostgreSQL: pgsql/src/backend/optimizer/path/allpaths.c,v 1.175 2008/10/21 20:42:52 tgl Exp $
11+
* $PostgreSQL: pgsql/src/backend/optimizer/path/allpaths.c,v 1.176 2008/11/11 18:13:32 tgl Exp $
1212
*
1313
*-------------------------------------------------------------------------
1414
*/
@@ -382,14 +382,12 @@ set_append_rel_pathlist(PlannerInfo *root, RelOptInfo *rel,
382382
}
383383

384384
/*
385-
* Copy the parent's attr_needed data as well, with appropriate
386-
* adjustment of relids and attribute numbers.
385+
* Note: we could compute appropriate attr_needed data for the
386+
* child's variables, by transforming the parent's attr_needed
387+
* through the translated_vars mapping. However, currently there's
388+
* no need because attr_needed is only examined for base relations
389+
* not otherrels. So we just leave the child's attr_needed empty.
387390
*/
388-
pfree(childrel->attr_needed);
389-
childrel->attr_needed =
390-
adjust_appendrel_attr_needed(rel, appinfo,
391-
childrel->min_attr,
392-
childrel->max_attr);
393391

394392
/*
395393
* Compute the child's access paths, and add the cheapest one to the

src/backend/optimizer/prep/prepjointree.c

Lines changed: 12 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@
1616
*
1717
*
1818
* IDENTIFICATION
19-
* $PostgreSQL: pgsql/src/backend/optimizer/prep/prepjointree.c,v 1.58 2008/10/22 20:17:52 tgl Exp $
19+
* $PostgreSQL: pgsql/src/backend/optimizer/prep/prepjointree.c,v 1.59 2008/11/11 18:13:32 tgl Exp $
2020
*
2121
*-------------------------------------------------------------------------
2222
*/
@@ -54,9 +54,8 @@ static Node *pull_up_simple_union_all(PlannerInfo *root, Node *jtnode,
5454
static void pull_up_union_leaf_queries(Node *setOp, PlannerInfo *root,
5555
int parentRTindex, Query *setOpQuery,
5656
int childRToffset);
57-
static void make_setop_translation_lists(Query *query,
58-
Index newvarno,
59-
List **col_mappings, List **translated_vars);
57+
static void make_setop_translation_list(Query *query, Index newvarno,
58+
List **translated_vars);
6059
static bool is_simple_subquery(Query *subquery);
6160
static bool is_simple_union_all(Query *subquery);
6261
static bool is_simple_union_all_recurse(Node *setOp, Query *setOpQuery,
@@ -839,9 +838,8 @@ pull_up_union_leaf_queries(Node *setOp, PlannerInfo *root, int parentRTindex,
839838
appinfo->child_relid = childRTindex;
840839
appinfo->parent_reltype = InvalidOid;
841840
appinfo->child_reltype = InvalidOid;
842-
make_setop_translation_lists(setOpQuery, childRTindex,
843-
&appinfo->col_mappings,
844-
&appinfo->translated_vars);
841+
make_setop_translation_list(setOpQuery, childRTindex,
842+
&appinfo->translated_vars);
845843
appinfo->parent_reloid = InvalidOid;
846844
root->append_rel_list = lappend(root->append_rel_list, appinfo);
847845

@@ -874,17 +872,16 @@ pull_up_union_leaf_queries(Node *setOp, PlannerInfo *root, int parentRTindex,
874872
}
875873

876874
/*
877-
* make_setop_translation_lists
878-
* Build the lists of translations from parent Vars to child Vars for
879-
* a UNION ALL member. We need both a column number mapping list
880-
* and a list of Vars representing the child columns.
875+
* make_setop_translation_list
876+
* Build the list of translations from parent Vars to child Vars for
877+
* a UNION ALL member. (At this point it's just a simple list of
878+
* referencing Vars, but if we succeed in pulling up the member
879+
* subquery, the Vars will get replaced by pulled-up expressions.)
881880
*/
882881
static void
883-
make_setop_translation_lists(Query *query,
884-
Index newvarno,
885-
List **col_mappings, List **translated_vars)
882+
make_setop_translation_list(Query *query, Index newvarno,
883+
List **translated_vars)
886884
{
887-
List *numbers = NIL;
888885
List *vars = NIL;
889886
ListCell *l;
890887

@@ -895,15 +892,13 @@ make_setop_translation_lists(Query *query,
895892
if (tle->resjunk)
896893
continue;
897894

898-
numbers = lappend_int(numbers, tle->resno);
899895
vars = lappend(vars, makeVar(newvarno,
900896
tle->resno,
901897
exprType((Node *) tle->expr),
902898
exprTypmod((Node *) tle->expr),
903899
0));
904900
}
905901

906-
*col_mappings = numbers;
907902
*translated_vars = vars;
908903
}
909904

src/backend/optimizer/prep/prepunion.c

Lines changed: 21 additions & 93 deletions
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.160 2008/10/22 20:17:52 tgl Exp $
25+
* $PostgreSQL: pgsql/src/backend/optimizer/prep/prepunion.c,v 1.161 2008/11/11 18:13:32 tgl Exp $
2626
*
2727
*-------------------------------------------------------------------------
2828
*/
@@ -91,11 +91,10 @@ static List *generate_append_tlist(List *colTypes, bool flag,
9191
static List *generate_setop_grouplist(SetOperationStmt *op, List *targetlist);
9292
static void expand_inherited_rtentry(PlannerInfo *root, RangeTblEntry *rte,
9393
Index rti);
94-
static void make_inh_translation_lists(Relation oldrelation,
95-
Relation newrelation,
96-
Index newvarno,
97-
List **col_mappings,
98-
List **translated_vars);
94+
static void make_inh_translation_list(Relation oldrelation,
95+
Relation newrelation,
96+
Index newvarno,
97+
List **translated_vars);
9998
static Node *adjust_appendrel_attrs_mutator(Node *node,
10099
AppendRelInfo *context);
101100
static Relids adjust_relid_set(Relids relids, Index oldrelid, Index newrelid);
@@ -1279,9 +1278,8 @@ expand_inherited_rtentry(PlannerInfo *root, RangeTblEntry *rte, Index rti)
12791278
appinfo->child_relid = childRTindex;
12801279
appinfo->parent_reltype = oldrelation->rd_rel->reltype;
12811280
appinfo->child_reltype = newrelation->rd_rel->reltype;
1282-
make_inh_translation_lists(oldrelation, newrelation, childRTindex,
1283-
&appinfo->col_mappings,
1284-
&appinfo->translated_vars);
1281+
make_inh_translation_list(oldrelation, newrelation, childRTindex,
1282+
&appinfo->translated_vars);
12851283
appinfo->parent_reloid = parentOID;
12861284
appinfos = lappend(appinfos, appinfo);
12871285

@@ -1316,19 +1314,17 @@ expand_inherited_rtentry(PlannerInfo *root, RangeTblEntry *rte, Index rti)
13161314
}
13171315

13181316
/*
1319-
* make_inh_translation_lists
1320-
* Build the lists of translations from parent Vars to child Vars for
1321-
* an inheritance child. We need both a column number mapping list
1322-
* and a list of Vars representing the child columns.
1317+
* make_inh_translation_list
1318+
* Build the list of translations from parent Vars to child Vars for
1319+
* an inheritance child.
13231320
*
13241321
* For paranoia's sake, we match type as well as attribute name.
13251322
*/
13261323
static void
1327-
make_inh_translation_lists(Relation oldrelation, Relation newrelation,
1328-
Index newvarno,
1329-
List **col_mappings, List **translated_vars)
1324+
make_inh_translation_list(Relation oldrelation, Relation newrelation,
1325+
Index newvarno,
1326+
List **translated_vars)
13301327
{
1331-
List *numbers = NIL;
13321328
List *vars = NIL;
13331329
TupleDesc old_tupdesc = RelationGetDescr(oldrelation);
13341330
TupleDesc new_tupdesc = RelationGetDescr(newrelation);
@@ -1347,8 +1343,7 @@ make_inh_translation_lists(Relation oldrelation, Relation newrelation,
13471343
att = old_tupdesc->attrs[old_attno];
13481344
if (att->attisdropped)
13491345
{
1350-
/* Just put 0/NULL into this list entry */
1351-
numbers = lappend_int(numbers, 0);
1346+
/* Just put NULL into this list entry */
13521347
vars = lappend(vars, NULL);
13531348
continue;
13541349
}
@@ -1362,7 +1357,6 @@ make_inh_translation_lists(Relation oldrelation, Relation newrelation,
13621357
*/
13631358
if (oldrelation == newrelation)
13641359
{
1365-
numbers = lappend_int(numbers, old_attno + 1);
13661360
vars = lappend(vars, makeVar(newvarno,
13671361
(AttrNumber) (old_attno + 1),
13681362
atttypid,
@@ -1405,15 +1399,13 @@ make_inh_translation_lists(Relation oldrelation, Relation newrelation,
14051399
elog(ERROR, "attribute \"%s\" of relation \"%s\" does not match parent's type",
14061400
attname, RelationGetRelationName(newrelation));
14071401

1408-
numbers = lappend_int(numbers, new_attno + 1);
14091402
vars = lappend(vars, makeVar(newvarno,
14101403
(AttrNumber) (new_attno + 1),
14111404
atttypid,
14121405
atttypmod,
14131406
0));
14141407
}
14151408

1416-
*col_mappings = numbers;
14171409
*translated_vars = vars;
14181410
}
14191411

@@ -1682,70 +1674,6 @@ adjust_relid_set(Relids relids, Index oldrelid, Index newrelid)
16821674
return relids;
16831675
}
16841676

1685-
/*
1686-
* adjust_appendrel_attr_needed
1687-
* Adjust an attr_needed[] array to reference a member rel instead of
1688-
* the original appendrel
1689-
*
1690-
* oldrel: source of data (we use the attr_needed, min_attr, max_attr fields)
1691-
* appinfo: supplies parent_relid, child_relid, col_mappings
1692-
* new_min_attr, new_max_attr: desired bounds of new attr_needed array
1693-
*
1694-
* The relid sets are adjusted by substituting child_relid for parent_relid.
1695-
* (NOTE: oldrel is not necessarily the parent_relid relation!) We are also
1696-
* careful to map attribute numbers within the array properly. User
1697-
* attributes have to be mapped through col_mappings, but system attributes
1698-
* and whole-row references always have the same attno.
1699-
*
1700-
* Returns a palloc'd array with the specified bounds
1701-
*/
1702-
Relids *
1703-
adjust_appendrel_attr_needed(RelOptInfo *oldrel, AppendRelInfo *appinfo,
1704-
AttrNumber new_min_attr, AttrNumber new_max_attr)
1705-
{
1706-
Relids *new_attr_needed;
1707-
Index parent_relid = appinfo->parent_relid;
1708-
Index child_relid = appinfo->child_relid;
1709-
int parent_attr;
1710-
ListCell *lm;
1711-
1712-
/* Create empty result array */
1713-
new_attr_needed = (Relids *)
1714-
palloc0((new_max_attr - new_min_attr + 1) * sizeof(Relids));
1715-
/* Process user attributes, with appropriate attno mapping */
1716-
parent_attr = 1;
1717-
foreach(lm, appinfo->col_mappings)
1718-
{
1719-
int child_attr = lfirst_int(lm);
1720-
1721-
if (child_attr > 0)
1722-
{
1723-
Relids attrneeded;
1724-
1725-
Assert(parent_attr <= oldrel->max_attr);
1726-
Assert(child_attr <= new_max_attr);
1727-
attrneeded = oldrel->attr_needed[parent_attr - oldrel->min_attr];
1728-
attrneeded = adjust_relid_set(attrneeded,
1729-
parent_relid, child_relid);
1730-
new_attr_needed[child_attr - new_min_attr] = attrneeded;
1731-
}
1732-
parent_attr++;
1733-
}
1734-
/* Process system attributes, including whole-row references */
1735-
Assert(new_min_attr <= oldrel->min_attr);
1736-
for (parent_attr = oldrel->min_attr; parent_attr <= 0; parent_attr++)
1737-
{
1738-
Relids attrneeded;
1739-
1740-
attrneeded = oldrel->attr_needed[parent_attr - oldrel->min_attr];
1741-
attrneeded = adjust_relid_set(attrneeded,
1742-
parent_relid, child_relid);
1743-
new_attr_needed[parent_attr - new_min_attr] = attrneeded;
1744-
}
1745-
1746-
return new_attr_needed;
1747-
}
1748-
17491677
/*
17501678
* Adjust the targetlist entries of an inherited UPDATE operation
17511679
*
@@ -1778,24 +1706,24 @@ adjust_inherited_tlist(List *tlist, AppendRelInfo *context)
17781706
foreach(tl, tlist)
17791707
{
17801708
TargetEntry *tle = (TargetEntry *) lfirst(tl);
1781-
int newattno;
1709+
Var *childvar;
17821710

17831711
if (tle->resjunk)
17841712
continue; /* ignore junk items */
17851713

1786-
/* Look up the translation of this column */
1714+
/* Look up the translation of this column: it must be a Var */
17871715
if (tle->resno <= 0 ||
1788-
tle->resno > list_length(context->col_mappings))
1716+
tle->resno > list_length(context->translated_vars))
17891717
elog(ERROR, "attribute %d of relation \"%s\" does not exist",
17901718
tle->resno, get_rel_name(context->parent_reloid));
1791-
newattno = list_nth_int(context->col_mappings, tle->resno - 1);
1792-
if (newattno <= 0)
1719+
childvar = (Var *) list_nth(context->translated_vars, tle->resno - 1);
1720+
if (childvar == NULL || !IsA(childvar, Var))
17931721
elog(ERROR, "attribute %d of relation \"%s\" does not exist",
17941722
tle->resno, get_rel_name(context->parent_reloid));
17951723

1796-
if (tle->resno != newattno)
1724+
if (tle->resno != childvar->varattno)
17971725
{
1798-
tle->resno = newattno;
1726+
tle->resno = childvar->varattno;
17991727
changed_it = true;
18001728
}
18011729
}

src/include/nodes/relation.h

Lines changed: 3 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
* Portions Copyright (c) 1996-2008, PostgreSQL Global Development Group
88
* Portions Copyright (c) 1994, Regents of the University of California
99
*
10-
* $PostgreSQL: pgsql/src/include/nodes/relation.h,v 1.163 2008/10/22 20:17:52 tgl Exp $
10+
* $PostgreSQL: pgsql/src/include/nodes/relation.h,v 1.164 2008/11/11 18:13:32 tgl Exp $
1111
*
1212
*-------------------------------------------------------------------------
1313
*/
@@ -1239,27 +1239,14 @@ typedef struct AppendRelInfo
12391239
Oid parent_reltype; /* OID of parent's composite type */
12401240
Oid child_reltype; /* OID of child's composite type */
12411241

1242-
/*
1243-
* The N'th element of this list is the integer column number of the child
1244-
* column corresponding to the N'th column of the parent. A list element
1245-
* is zero if it corresponds to a dropped column of the parent (this is
1246-
* only possible for inheritance cases, not UNION ALL).
1247-
*/
1248-
List *col_mappings; /* list of child attribute numbers */
1249-
12501242
/*
12511243
* The N'th element of this list is a Var or expression representing the
12521244
* child column corresponding to the N'th column of the parent. This is
12531245
* used to translate Vars referencing the parent rel into references to
12541246
* the child. A list element is NULL if it corresponds to a dropped
12551247
* column of the parent (this is only possible for inheritance cases, not
1256-
* UNION ALL).
1257-
*
1258-
* This might seem redundant with the col_mappings data, but it is handy
1259-
* because flattening of sub-SELECTs that are members of a UNION ALL will
1260-
* cause changes in the expressions that need to be substituted for a
1261-
* parent Var. Adjusting this data structure lets us track what really
1262-
* needs to be substituted.
1248+
* UNION ALL). The list elements are always simple Vars for inheritance
1249+
* cases, but can be arbitrary expressions in UNION ALL cases.
12631250
*
12641251
* Notice we only store entries for user columns (attno > 0). Whole-row
12651252
* Vars are special-cased, and system columns (attno < 0) need no special

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy