aboutsummaryrefslogtreecommitdiff
path: root/src/backend/optimizer/prep/prepunion.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/backend/optimizer/prep/prepunion.c')
-rw-r--r--src/backend/optimizer/prep/prepunion.c628
1 files changed, 327 insertions, 301 deletions
diff --git a/src/backend/optimizer/prep/prepunion.c b/src/backend/optimizer/prep/prepunion.c
index 3142f37c07a..9bf282f8cc3 100644
--- a/src/backend/optimizer/prep/prepunion.c
+++ b/src/backend/optimizer/prep/prepunion.c
@@ -1,13 +1,13 @@
/*-------------------------------------------------------------------------
*
* prepunion.c--
- * Routines to plan archive, inheritance, union, and version queries
+ * Routines to plan archive, inheritance, union, and version queries
*
* Copyright (c) 1994, Regents of the University of California
*
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/backend/optimizer/prep/prepunion.c,v 1.3 1997/01/10 20:18:12 momjian Exp $
+ * $Header: /cvsroot/pgsql/src/backend/optimizer/prep/prepunion.c,v 1.4 1997/09/07 04:44:14 momjian Exp $
*
*-------------------------------------------------------------------------
*/
@@ -34,370 +34,396 @@
#include "optimizer/planner.h"
#include "optimizer/prep.h"
-static List *plan_union_query(List *relids, Index rt_index,
- RangeTblEntry *rt_entry, Query *parse, UnionFlag flag,
- List **union_rtentriesPtr);
-static RangeTblEntry *new_rangetable_entry(Oid new_relid,
- RangeTblEntry *old_entry);
-static Query *subst_rangetable(Query *root, Index index,
- RangeTblEntry *new_entry);
-static void fix_parsetree_attnums(Index rt_index, Oid old_relid,
- Oid new_relid, Query *parsetree);
-static Append *make_append(List *unionplans, Index rt_index,
- List *union_rt_entries, List *tlist);
+static List *
+plan_union_query(List * relids, Index rt_index,
+ RangeTblEntry * rt_entry, Query * parse, UnionFlag flag,
+ List ** union_rtentriesPtr);
+static RangeTblEntry *
+new_rangetable_entry(Oid new_relid,
+ RangeTblEntry * old_entry);
+static Query *
+subst_rangetable(Query * root, Index index,
+ RangeTblEntry * new_entry);
+static void
+fix_parsetree_attnums(Index rt_index, Oid old_relid,
+ Oid new_relid, Query * parsetree);
+static Append *
+make_append(List * unionplans, Index rt_index,
+ List * union_rt_entries, List * tlist);
-/*
+/*
* find-all-inheritors -
- * Returns a list of relids corresponding to relations that inherit
- * attributes from any relations listed in either of the argument relid
- * lists.
+ * Returns a list of relids corresponding to relations that inherit
+ * attributes from any relations listed in either of the argument relid
+ * lists.
*/
-List *
-find_all_inheritors(List *unexamined_relids,
- List *examined_relids)
+List *
+find_all_inheritors(List * unexamined_relids,
+ List * examined_relids)
{
- List *new_inheritors = NIL;
- List *new_examined_relids = NIL;
- List *new_unexamined_relids = NIL;
-
- /* Find all relations which inherit from members of
- * 'unexamined-relids' and store them in 'new-inheritors'.
- */
- List *rels = NIL;
- List *newrels = NIL;
-
- foreach(rels,unexamined_relids) {
- newrels = (List*)LispUnioni(find_inheritance_children(lfirsti(rels)),
- newrels);
- }
- new_inheritors = newrels;
-
- new_examined_relids = (List*)LispUnioni(examined_relids,unexamined_relids);
- new_unexamined_relids = set_differencei(new_inheritors,
- new_examined_relids);
-
- if (new_unexamined_relids==NULL) {
- return(new_examined_relids);
- } else {
- return (find_all_inheritors (new_unexamined_relids,
- new_examined_relids));
- }
+ List *new_inheritors = NIL;
+ List *new_examined_relids = NIL;
+ List *new_unexamined_relids = NIL;
+
+ /*
+ * Find all relations which inherit from members of
+ * 'unexamined-relids' and store them in 'new-inheritors'.
+ */
+ List *rels = NIL;
+ List *newrels = NIL;
+
+ foreach(rels, unexamined_relids)
+ {
+ newrels = (List *) LispUnioni(find_inheritance_children(lfirsti(rels)),
+ newrels);
+ }
+ new_inheritors = newrels;
+
+ new_examined_relids = (List *) LispUnioni(examined_relids, unexamined_relids);
+ new_unexamined_relids = set_differencei(new_inheritors,
+ new_examined_relids);
+
+ if (new_unexamined_relids == NULL)
+ {
+ return (new_examined_relids);
+ }
+ else
+ {
+ return (find_all_inheritors(new_unexamined_relids,
+ new_examined_relids));
+ }
}
-/*
+/*
* first-matching-rt-entry -
- * Given a rangetable, find the first rangetable entry that represents
- * the appropriate special case.
- *
- * Returns a rangetable index., Returns -1 if no matches
+ * Given a rangetable, find the first rangetable entry that represents
+ * the appropriate special case.
+ *
+ * Returns a rangetable index., Returns -1 if no matches
*/
int
-first_matching_rt_entry (List *rangetable, UnionFlag flag)
+first_matching_rt_entry(List * rangetable, UnionFlag flag)
{
- int count = 0;
- List *temp = NIL;
+ int count = 0;
+ List *temp = NIL;
- foreach(temp, rangetable) {
- RangeTblEntry *rt_entry = lfirst(temp);
-
- switch(flag) {
- case INHERITS_FLAG:
- if (rt_entry->inh)
- return count+1;
- break;
- case ARCHIVE_FLAG:
- if (rt_entry->archive)
- return count+1;
- break;
- default:
- break;
+ foreach(temp, rangetable)
+ {
+ RangeTblEntry *rt_entry = lfirst(temp);
+
+ switch (flag)
+ {
+ case INHERITS_FLAG:
+ if (rt_entry->inh)
+ return count + 1;
+ break;
+ case ARCHIVE_FLAG:
+ if (rt_entry->archive)
+ return count + 1;
+ break;
+ default:
+ break;
+ }
+ count++;
}
- count++;
- }
-
- return(-1);
+
+ return (-1);
}
-/*
+/*
* plan-union-queries--
- *
- * Plans the queries for a given parent relation.
- *
+ *
+ * Plans the queries for a given parent relation.
+ *
* Returns a list containing a list of plans and a list of rangetable
* entries to be inserted into an APPEND node.
* XXX - what exactly does this mean, look for make_append
*/
-Append *
+Append *
plan_union_queries(Index rt_index,
- Query *parse,
- UnionFlag flag)
+ Query * parse,
+ UnionFlag flag)
{
- List *rangetable = parse->rtable;
- RangeTblEntry *rt_entry = rt_fetch(rt_index,rangetable);
- List *union_relids = NIL;
- List *union_plans = NIL;
- List *union_rt_entries = NIL;
-
- switch (flag) {
- case INHERITS_FLAG:
- union_relids =
- find_all_inheritors(lconsi(rt_entry->relid,
- NIL),
- NIL);
- break;
-
-#if 0
- case UNION_FLAG:
+ List *rangetable = parse->rtable;
+ RangeTblEntry *rt_entry = rt_fetch(rt_index, rangetable);
+ List *union_relids = NIL;
+ List *union_plans = NIL;
+ List *union_rt_entries = NIL;
+
+ switch (flag)
{
- Index rt_index = 0;
- union_plans = handleunion(root,rangetable,tlist,qual);
- return (make_append (union_plans,
- rt_index, rangetable,
- ((Plan*)lfirst(union_plans))->targetlist ));
- }
- break;
+ case INHERITS_FLAG:
+ union_relids =
+ find_all_inheritors(lconsi(rt_entry->relid,
+ NIL),
+ NIL);
+ break;
+
+#if 0
+ case UNION_FLAG:
+ {
+ Index rt_index = 0;
+
+ union_plans = handleunion(root, rangetable, tlist, qual);
+ return (make_append(union_plans,
+ rt_index, rangetable,
+ ((Plan *) lfirst(union_plans))->targetlist));
+ }
+ break;
#endif
-
- case VERSION_FLAG:
- union_relids = VersionGetParents(rt_entry->relid);
- break;
-
- case ARCHIVE_FLAG:
- union_relids = find_archive_rels(rt_entry->relid);
- break;
-
- default:
- /* do nothing */
- break;
- }
-
- /*
- * Remove the flag for this relation, since we're about to handle it
- * (do it before recursing!).
- * XXX destructive parse tree change
- */
- switch(flag) {
- case INHERITS_FLAG:
- rt_fetch(rt_index,rangetable)->inh = false;
- break;
- case ARCHIVE_FLAG:
- rt_fetch(rt_index,rangetable)->archive = false;
- break;
- default:
- break;
- }
-
- /* XXX - can't find any reason to sort union-relids
- * as paul did, so we're leaving it out for now
- * (maybe forever) - jeff & lp
- *
- * [maybe so. btw, jeff & lp did the lisp conversion, according to Paul.
- * -- ay 10/94.]
- */
- union_plans = plan_union_query(union_relids, rt_index, rt_entry,
- parse, flag, &union_rt_entries);
-
- return (make_append(union_plans,
- rt_index,
- union_rt_entries,
- ((Plan*)lfirst(union_plans))->targetlist));
+
+ case VERSION_FLAG:
+ union_relids = VersionGetParents(rt_entry->relid);
+ break;
+
+ case ARCHIVE_FLAG:
+ union_relids = find_archive_rels(rt_entry->relid);
+ break;
+
+ default:
+ /* do nothing */
+ break;
+ }
+
+ /*
+ * Remove the flag for this relation, since we're about to handle it
+ * (do it before recursing!). XXX destructive parse tree change
+ */
+ switch (flag)
+ {
+ case INHERITS_FLAG:
+ rt_fetch(rt_index, rangetable)->inh = false;
+ break;
+ case ARCHIVE_FLAG:
+ rt_fetch(rt_index, rangetable)->archive = false;
+ break;
+ default:
+ break;
+ }
+
+ /*
+ * XXX - can't find any reason to sort union-relids as paul did, so
+ * we're leaving it out for now (maybe forever) - jeff & lp
+ *
+ * [maybe so. btw, jeff & lp did the lisp conversion, according to Paul.
+ * -- ay 10/94.]
+ */
+ union_plans = plan_union_query(union_relids, rt_index, rt_entry,
+ parse, flag, &union_rt_entries);
+
+ return (make_append(union_plans,
+ rt_index,
+ union_rt_entries,
+ ((Plan *) lfirst(union_plans))->targetlist));
}
-/*
+/*
* plan-union-query--
- * Returns a list of plans for 'relids' and a list of range table entries
- * in union_rtentries.
+ * Returns a list of plans for 'relids' and a list of range table entries
+ * in union_rtentries.
*/
-static List *
-plan_union_query(List *relids,
- Index rt_index,
- RangeTblEntry *rt_entry,
- Query *root,
- UnionFlag flag,
- List **union_rtentriesPtr)
+static List *
+plan_union_query(List * relids,
+ Index rt_index,
+ RangeTblEntry * rt_entry,
+ Query * root,
+ UnionFlag flag,
+ List ** union_rtentriesPtr)
{
- List *i;
- List *union_plans = NIL;
- List *union_rtentries = NIL;
-
- foreach (i, relids) {
- int relid = lfirsti(i);
- RangeTblEntry *new_rt_entry = new_rangetable_entry(relid,
- rt_entry);
- Query *new_root = subst_rangetable(root,
- rt_index,
- new_rt_entry);
-
- /* reset the uniqueflag and sortclause in parse tree root, so that
- * sorting will only be done once after append
- */
-/* new_root->uniqueFlag = false; */
- new_root->uniqueFlag = NULL;
- new_root->sortClause = NULL;
- if (flag == ARCHIVE_FLAG) {
- /*
- * the entire union query uses the same (most recent) schema.
- * to do otherwise would require either ragged tuples or careful
- * archiving and interpretation of pg_attribute...
- */
- } else {
- fix_parsetree_attnums(rt_index,
- rt_entry->relid,
- relid,
- new_root);
- }
+ List *i;
+ List *union_plans = NIL;
+ List *union_rtentries = NIL;
- union_plans = lappend(union_plans, planner(new_root));
- union_rtentries = lappend(union_rtentries, new_rt_entry);
- }
+ foreach(i, relids)
+ {
+ int relid = lfirsti(i);
+ RangeTblEntry *new_rt_entry = new_rangetable_entry(relid,
+ rt_entry);
+ Query *new_root = subst_rangetable(root,
+ rt_index,
+ new_rt_entry);
+
+ /*
+ * reset the uniqueflag and sortclause in parse tree root, so that
+ * sorting will only be done once after append
+ */
+/* new_root->uniqueFlag = false; */
+ new_root->uniqueFlag = NULL;
+ new_root->sortClause = NULL;
+ if (flag == ARCHIVE_FLAG)
+ {
+
+ /*
+ * the entire union query uses the same (most recent) schema.
+ * to do otherwise would require either ragged tuples or
+ * careful archiving and interpretation of pg_attribute...
+ */
+ }
+ else
+ {
+ fix_parsetree_attnums(rt_index,
+ rt_entry->relid,
+ relid,
+ new_root);
+ }
+
+ union_plans = lappend(union_plans, planner(new_root));
+ union_rtentries = lappend(union_rtentries, new_rt_entry);
+ }
- *union_rtentriesPtr = union_rtentries;
- return(union_plans);
+ *union_rtentriesPtr = union_rtentries;
+ return (union_plans);
}
-/*
+/*
* new-rangetable-entry -
- * Replaces the name and relid of 'old-entry' with the values for
- * 'new-relid'.
- *
- * Returns a copy of 'old-entry' with the parameters substituted.
+ * Replaces the name and relid of 'old-entry' with the values for
+ * 'new-relid'.
+ *
+ * Returns a copy of 'old-entry' with the parameters substituted.
*/
static RangeTblEntry *
-new_rangetable_entry(Oid new_relid, RangeTblEntry *old_entry)
+new_rangetable_entry(Oid new_relid, RangeTblEntry * old_entry)
{
- RangeTblEntry *new_entry = copyObject(old_entry);
+ RangeTblEntry *new_entry = copyObject(old_entry);
- /* ??? someone tell me what the following is doing! - ay 11/94 */
- if (!strcmp(new_entry->refname, "*CURRENT*") ||
- !strcmp(new_entry->refname, "*NEW*"))
- new_entry->refname = get_rel_name(new_relid);
- else
- new_entry->relname = get_rel_name(new_relid);
+ /* ??? someone tell me what the following is doing! - ay 11/94 */
+ if (!strcmp(new_entry->refname, "*CURRENT*") ||
+ !strcmp(new_entry->refname, "*NEW*"))
+ new_entry->refname = get_rel_name(new_relid);
+ else
+ new_entry->relname = get_rel_name(new_relid);
- new_entry->relid = new_relid;
- return(new_entry);
+ new_entry->relid = new_relid;
+ return (new_entry);
}
-/*
+/*
* subst-rangetable--
- * Replaces the 'index'th rangetable entry in 'root' with 'new-entry'.
- *
+ * Replaces the 'index'th rangetable entry in 'root' with 'new-entry'.
+ *
* Returns a new copy of 'root'.
*/
-static Query *
-subst_rangetable(Query *root, Index index, RangeTblEntry *new_entry)
+static Query *
+subst_rangetable(Query * root, Index index, RangeTblEntry * new_entry)
{
- Query *new_root = copyObject(root);
- List *temp = NIL;
- int i = 0;
+ Query *new_root = copyObject(root);
+ List *temp = NIL;
+ int i = 0;
- for(temp = new_root->rtable,i =1; i < index; temp =lnext(temp),i++)
- ;
- lfirst(temp) = new_entry;
+ for (temp = new_root->rtable, i = 1; i < index; temp = lnext(temp), i++)
+ ;
+ lfirst(temp) = new_entry;
- return (new_root);
+ return (new_root);
}
static void
fix_parsetree_attnums_nodes(Index rt_index,
- Oid old_relid,
- Oid new_relid,
- Node *node)
+ Oid old_relid,
+ Oid new_relid,
+ Node * node)
{
- if (node==NULL)
- return;
-
- switch(nodeTag(node)) {
- case T_TargetEntry:
- {
- TargetEntry *tle = (TargetEntry *)node;
-
- fix_parsetree_attnums_nodes(rt_index, old_relid, new_relid,
- tle->expr);
- }
- break;
- case T_Expr:
- {
- Expr *expr = (Expr *)node;
- fix_parsetree_attnums_nodes(rt_index, old_relid, new_relid,
- (Node*)expr->args);
- }
- break;
- case T_Var:
- {
- Var *var = (Var *)node;
- Oid old_typeid, new_typeid;
-
-/* old_typeid = RelationIdGetTypeId(old_relid);*/
-/* new_typeid = RelationIdGetTypeId(new_relid);*/
- old_typeid = old_relid;
- new_typeid = new_relid;
-
- if (var->varno == rt_index && var->varattno != 0) {
- var->varattno =
- get_attnum(new_typeid,
- get_attname(old_typeid, var->varattno));
- }
- }
- break;
- case T_List:
+ if (node == NULL)
+ return;
+
+ switch (nodeTag(node))
{
- List *l;
- foreach(l, (List*)node) {
- fix_parsetree_attnums_nodes(rt_index, old_relid, new_relid,
- (Node*)lfirst(l));
- }
+ case T_TargetEntry:
+ {
+ TargetEntry *tle = (TargetEntry *) node;
+
+ fix_parsetree_attnums_nodes(rt_index, old_relid, new_relid,
+ tle->expr);
+ }
+ break;
+ case T_Expr:
+ {
+ Expr *expr = (Expr *) node;
+
+ fix_parsetree_attnums_nodes(rt_index, old_relid, new_relid,
+ (Node *) expr->args);
+ }
+ break;
+ case T_Var:
+ {
+ Var *var = (Var *) node;
+ Oid old_typeid,
+ new_typeid;
+
+/* old_typeid = RelationIdGetTypeId(old_relid);*/
+/* new_typeid = RelationIdGetTypeId(new_relid);*/
+ old_typeid = old_relid;
+ new_typeid = new_relid;
+
+ if (var->varno == rt_index && var->varattno != 0)
+ {
+ var->varattno =
+ get_attnum(new_typeid,
+ get_attname(old_typeid, var->varattno));
+ }
+ }
+ break;
+ case T_List:
+ {
+ List *l;
+
+ foreach(l, (List *) node)
+ {
+ fix_parsetree_attnums_nodes(rt_index, old_relid, new_relid,
+ (Node *) lfirst(l));
+ }
+ }
+ break;
+ default:
+ break;
}
- break;
- default:
- break;
- }
}
-
-/*
+
+/*
* fix-parsetree-attnums--
- * Replaces attribute numbers from the relation represented by
- * 'old-relid' in 'parsetree' with the attribute numbers from
- * 'new-relid'.
- *
+ * Replaces attribute numbers from the relation represented by
+ * 'old-relid' in 'parsetree' with the attribute numbers from
+ * 'new-relid'.
+ *
* Returns the destructively-modified parsetree.
- *
+ *
*/
static void
fix_parsetree_attnums(Index rt_index,
- Oid old_relid,
- Oid new_relid,
- Query *parsetree)
+ Oid old_relid,
+ Oid new_relid,
+ Query * parsetree)
{
- if (old_relid == new_relid)
- return;
+ if (old_relid == new_relid)
+ return;
- fix_parsetree_attnums_nodes(rt_index, old_relid, new_relid,
- (Node*)parsetree->targetList);
- fix_parsetree_attnums_nodes(rt_index, old_relid, new_relid,
- parsetree->qual);
+ fix_parsetree_attnums_nodes(rt_index, old_relid, new_relid,
+ (Node *) parsetree->targetList);
+ fix_parsetree_attnums_nodes(rt_index, old_relid, new_relid,
+ parsetree->qual);
}
-static Append *
-make_append(List *unionplans,
- Index rt_index,
- List *union_rt_entries,
- List *tlist)
+static Append *
+make_append(List * unionplans,
+ Index rt_index,
+ List * union_rt_entries,
+ List * tlist)
{
- Append *node = makeNode(Append);
-
- node->unionplans = unionplans;
- node->unionrelid = rt_index;
- node->unionrtentries = union_rt_entries;
- node->plan.cost = 0.0;
- node->plan.state = (EState*)NULL;
- node->plan.targetlist = tlist;
- node->plan.qual = NIL;
- node->plan.lefttree = (Plan*)NULL;
- node->plan.righttree = (Plan*)NULL;
-
- return(node);
+ Append *node = makeNode(Append);
+
+ node->unionplans = unionplans;
+ node->unionrelid = rt_index;
+ node->unionrtentries = union_rt_entries;
+ node->plan.cost = 0.0;
+ node->plan.state = (EState *) NULL;
+ node->plan.targetlist = tlist;
+ node->plan.qual = NIL;
+ node->plan.lefttree = (Plan *) NULL;
+ node->plan.righttree = (Plan *) NULL;
+
+ return (node);
}