diff options
| author | Tom Lane <tgl@sss.pgh.pa.us> | 1999-06-06 17:38:11 +0000 |
|---|---|---|
| committer | Tom Lane <tgl@sss.pgh.pa.us> | 1999-06-06 17:38:11 +0000 |
| commit | b4210ae0f03cb680176286910845fb0d6e99c8a1 (patch) | |
| tree | bb289064cc7b0eb60bfc91e090493719a47d222c /src/backend/optimizer/prep | |
| parent | 08abe0acb6bef1921c112531ba00e64e45443384 (diff) | |
| download | postgresql-b4210ae0f03cb680176286910845fb0d6e99c8a1.tar.gz | |
Fix problems with grouping/aggregation in queries that use
inheritance ... basically it was completely busted :-(
Diffstat (limited to 'src/backend/optimizer/prep')
| -rw-r--r-- | src/backend/optimizer/prep/prepunion.c | 81 |
1 files changed, 51 insertions, 30 deletions
diff --git a/src/backend/optimizer/prep/prepunion.c b/src/backend/optimizer/prep/prepunion.c index 6bd493a488..478186b631 100644 --- a/src/backend/optimizer/prep/prepunion.c +++ b/src/backend/optimizer/prep/prepunion.c @@ -7,7 +7,7 @@ * * * IDENTIFICATION - * $Header: /cvsroot/pgsql/src/backend/optimizer/prep/prepunion.c,v 1.31 1999/05/25 16:09:47 momjian Exp $ + * $Header: /cvsroot/pgsql/src/backend/optimizer/prep/prepunion.c,v 1.32 1999/06/06 17:38:11 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -35,7 +35,7 @@ #include "optimizer/planmain.h" static List *plan_inherit_query(Relids relids, Index rt_index, - RangeTblEntry *rt_entry, Query *parse, + RangeTblEntry *rt_entry, Query *parse, List *tlist, List **union_rtentriesPtr); static RangeTblEntry *new_rangetable_entry(Oid new_relid, RangeTblEntry *old_entry); @@ -208,19 +208,33 @@ plan_union_queries(Query *parse) * * 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 + * Inputs: + * parse = parent parse tree + * tlist = target list for inheritance subqueries (not same as parent's!) + * rt_index = rangetable index for current inheritance item + * + * Returns an APPEND node that forms the result of performing the given + * query for each member relation of the inheritance group. + * + * If grouping, aggregation, or sorting is specified in the parent plan, + * the subplans should not do any of those steps --- we must do those + * operations just once above the APPEND node. The given tlist has been + * modified appropriately to remove group/aggregate expressions, but the + * Query node still has the relevant fields set. We remove them in the + * copies used for subplans (see plan_inherit_query). + * + * NOTE: this can be invoked recursively if more than one inheritance wildcard + * is present. At each level of recursion, the first wildcard remaining in + * the rangetable is expanded. */ Append * -plan_inherit_queries(Query *parse, Index rt_index) +plan_inherit_queries(Query *parse, List *tlist, Index rt_index) { - List *union_plans = NIL; - List *rangetable = parse->rtable; RangeTblEntry *rt_entry = rt_fetch(rt_index, rangetable); List *inheritrtable = NIL; - List *union_relids = NIL; + List *union_relids; + List *union_plans; union_relids = find_all_inheritors(lconsi(rt_entry->relid, NIL), @@ -228,12 +242,12 @@ plan_inherit_queries(Query *parse, Index rt_index) /* * Remove the flag for this relation, since we're about to handle it - * (do it before recursing!). XXX destructive parse tree change + * (do it before recursing!). XXX destructive change to parent parse tree */ - rt_fetch(rt_index, rangetable)->inh = false; + rt_entry->inh = false; union_plans = plan_inherit_query(union_relids, rt_index, rt_entry, - parse, &inheritrtable); + parse, tlist, &inheritrtable); return (make_append(union_plans, NULL, @@ -252,11 +266,12 @@ plan_inherit_query(Relids relids, Index rt_index, RangeTblEntry *rt_entry, Query *root, + List *tlist, List **union_rtentriesPtr) { - List *i; List *union_plans = NIL; List *union_rtentries = NIL; + List *i; foreach(i, relids) { @@ -268,19 +283,21 @@ plan_inherit_query(Relids relids, new_rt_entry); /* - * reset the uniqueflag and sortclause in parse tree root, so that - * sorting will only be done once after append + * Insert the desired simplified tlist into the subquery + */ + new_root->targetList = copyObject(tlist); + + /* + * Clear the sorting and grouping qualifications in the subquery, + * so that sorting will only be done once after append */ new_root->uniqueFlag = NULL; new_root->sortClause = NULL; new_root->groupClause = NULL; new_root->havingQual = NULL; + new_root->hasAggs = false; /* shouldn't be any left ... */ - if (new_root->hasAggs) - { - new_root->hasAggs = false; - del_agg_tlist_references(new_root->targetList); - } + /* Fix attribute numbers as necessary */ fix_parsetree_attnums(rt_index, rt_entry->relid, relid, @@ -346,7 +363,7 @@ int first_inherit_rt_entry(List *rangetable) { int count = 0; - List *temp = NIL; + List *temp; foreach(temp, rangetable) { @@ -393,8 +410,8 @@ static Query * subst_rangetable(Query *root, Index index, RangeTblEntry *new_entry) { Query *new_root = copyObject(root); - List *temp = NIL; - int i = 0; + List *temp; + int i; for (temp = new_root->rtable, i = 1; i < index; temp = lnext(temp), i++) ; @@ -403,6 +420,15 @@ subst_rangetable(Query *root, Index index, RangeTblEntry *new_entry) return new_root; } +/* + * Adjust varnos for child tables. This routine makes it possible for + * child tables to have different column positions for the "same" attribute + * as a parent, which helps ALTER TABLE ADD COLUMN. Unfortunately this isn't + * nearly enough to make it work transparently; there are other places where + * things fall down if children and parents don't have the same column numbers + * for inherited attributes. It'd be better to rip this code out and fix + * ALTER TABLE... + */ static void fix_parsetree_attnums_nodes(Index rt_index, Oid old_relid, @@ -433,16 +459,11 @@ fix_parsetree_attnums_nodes(Index rt_index, case T_Var: { Var *var = (Var *) node; - Oid old_typeid, - new_typeid; - - 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)); + var->varattno = get_attnum(new_relid, + get_attname(old_relid, var->varattno)); } } break; |
