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.
This commit is contained in:
Tom Lane 2008-11-11 18:13:54 +00:00
parent 8f74153732
commit 5aa70422df
3 changed files with 8 additions and 79 deletions

View File

@ -8,7 +8,7 @@
*
*
* IDENTIFICATION
* $PostgreSQL: pgsql/src/backend/optimizer/path/allpaths.c,v 1.154.2.2 2008/01/11 04:02:25 tgl Exp $
* $PostgreSQL: pgsql/src/backend/optimizer/path/allpaths.c,v 1.154.2.3 2008/11/11 18:13:54 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@ -326,14 +326,12 @@ set_append_rel_pathlist(PlannerInfo *root, RelOptInfo *rel,
appinfo);
/*
* Copy the parent's attr_needed data as well, with appropriate
* adjustment of relids and attribute numbers.
* Note: we could compute appropriate attr_needed data for the
* child's variables, by transforming the parent's attr_needed
* through the translated_vars mapping. However, currently there's
* no need because attr_needed is only examined for base relations
* not otherrels. So we just leave the child's attr_needed empty.
*/
pfree(childrel->attr_needed);
childrel->attr_needed =
adjust_appendrel_attr_needed(rel, appinfo,
childrel->min_attr,
childrel->max_attr);
/*
* Compute the child's access paths, and add the cheapest one to the

View File

@ -22,7 +22,7 @@
*
*
* IDENTIFICATION
* $PostgreSQL: pgsql/src/backend/optimizer/prep/prepunion.c,v 1.134.2.1 2007/07/12 18:27:09 tgl Exp $
* $PostgreSQL: pgsql/src/backend/optimizer/prep/prepunion.c,v 1.134.2.2 2008/11/11 18:13:54 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@ -1255,70 +1255,6 @@ adjust_relid_set(Relids relids, Index oldrelid, Index newrelid)
return relids;
}
/*
* adjust_appendrel_attr_needed
* Adjust an attr_needed[] array to reference a member rel instead of
* the original appendrel
*
* oldrel: source of data (we use the attr_needed, min_attr, max_attr fields)
* appinfo: supplies parent_relid, child_relid, col_mappings
* new_min_attr, new_max_attr: desired bounds of new attr_needed array
*
* The relid sets are adjusted by substituting child_relid for parent_relid.
* (NOTE: oldrel is not necessarily the parent_relid relation!) We are also
* careful to map attribute numbers within the array properly. User
* attributes have to be mapped through col_mappings, but system attributes
* and whole-row references always have the same attno.
*
* Returns a palloc'd array with the specified bounds
*/
Relids *
adjust_appendrel_attr_needed(RelOptInfo *oldrel, AppendRelInfo *appinfo,
AttrNumber new_min_attr, AttrNumber new_max_attr)
{
Relids *new_attr_needed;
Index parent_relid = appinfo->parent_relid;
Index child_relid = appinfo->child_relid;
int parent_attr;
ListCell *lm;
/* Create empty result array */
new_attr_needed = (Relids *)
palloc0((new_max_attr - new_min_attr + 1) * sizeof(Relids));
/* Process user attributes, with appropriate attno mapping */
parent_attr = 1;
foreach(lm, appinfo->col_mappings)
{
int child_attr = lfirst_int(lm);
if (child_attr > 0)
{
Relids attrneeded;
Assert(parent_attr <= oldrel->max_attr);
Assert(child_attr <= new_max_attr);
attrneeded = oldrel->attr_needed[parent_attr - oldrel->min_attr];
attrneeded = adjust_relid_set(attrneeded,
parent_relid, child_relid);
new_attr_needed[child_attr - new_min_attr] = attrneeded;
}
parent_attr++;
}
/* Process system attributes, including whole-row references */
Assert(new_min_attr <= oldrel->min_attr);
for (parent_attr = oldrel->min_attr; parent_attr <= 0; parent_attr++)
{
Relids attrneeded;
attrneeded = oldrel->attr_needed[parent_attr - oldrel->min_attr];
attrneeded = adjust_relid_set(attrneeded,
parent_relid, child_relid);
new_attr_needed[parent_attr - new_min_attr] = attrneeded;
}
return new_attr_needed;
}
/*
* Adjust the targetlist entries of an inherited UPDATE operation
*

View File

@ -7,7 +7,7 @@
* Portions Copyright (c) 1996-2006, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California
*
* $PostgreSQL: pgsql/src/include/optimizer/prep.h,v 1.57 2006/10/04 00:30:09 momjian Exp $
* $PostgreSQL: pgsql/src/include/optimizer/prep.h,v 1.57.2.1 2008/11/11 18:13:54 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@ -50,9 +50,4 @@ extern void expand_inherited_tables(PlannerInfo *root);
extern Node *adjust_appendrel_attrs(Node *node, AppendRelInfo *appinfo);
extern Relids *adjust_appendrel_attr_needed(RelOptInfo *oldrel,
AppendRelInfo *appinfo,
AttrNumber new_min_attr,
AttrNumber new_max_attr);
#endif /* PREP_H */