mirror of
https://github.com/postgres/postgres.git
synced 2025-06-25 01:02:05 +03:00
UNION work for UNION ALL and other union stuff.
This commit is contained in:
@ -7,7 +7,7 @@
|
||||
*
|
||||
*
|
||||
* IDENTIFICATION
|
||||
* $Header: /cvsroot/pgsql/src/backend/optimizer/plan/planner.c,v 1.16 1997/12/24 06:06:01 momjian Exp $
|
||||
* $Header: /cvsroot/pgsql/src/backend/optimizer/plan/planner.c,v 1.17 1997/12/27 06:41:07 momjian Exp $
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
@ -72,8 +72,6 @@ planner(Query *parse)
|
||||
{
|
||||
List *tlist = parse->targetList;
|
||||
List *rangetable = parse->rtable;
|
||||
char *uniqueflag = parse->uniqueFlag;
|
||||
List *sortclause = parse->sortClause;
|
||||
|
||||
Plan *result_plan = (Plan *) NULL;
|
||||
|
||||
@ -83,7 +81,7 @@ planner(Query *parse)
|
||||
|
||||
if (parse->unionClause)
|
||||
{
|
||||
result_plan = (Plan *) plan_union_queries(0, /* none */
|
||||
result_plan = (Plan *) plan_union_queries( 0, /* none */
|
||||
parse,
|
||||
UNION_FLAG);
|
||||
/* XXX do we need to do this? bjm 12/19/97 */
|
||||
@ -173,16 +171,16 @@ planner(Query *parse)
|
||||
* the optimization step later.
|
||||
*/
|
||||
|
||||
if (uniqueflag)
|
||||
if (parse->uniqueFlag)
|
||||
{
|
||||
Plan *sortplan = make_sortplan(tlist, sortclause, result_plan);
|
||||
Plan *sortplan = make_sortplan(tlist, parse->sortClause, result_plan);
|
||||
|
||||
return ((Plan *) make_unique(tlist, sortplan, uniqueflag));
|
||||
return ((Plan *) make_unique(tlist, sortplan, parse->uniqueFlag));
|
||||
}
|
||||
else
|
||||
{
|
||||
if (sortclause)
|
||||
return (make_sortplan(tlist, sortclause, result_plan));
|
||||
if (parse->sortClause)
|
||||
return (make_sortplan(tlist, parse->sortClause, result_plan));
|
||||
else
|
||||
return ((Plan *) result_plan);
|
||||
}
|
||||
|
@ -7,7 +7,7 @@
|
||||
*
|
||||
*
|
||||
* IDENTIFICATION
|
||||
* $Header: /cvsroot/pgsql/src/backend/optimizer/prep/prepunion.c,v 1.14 1997/12/26 06:02:26 vadim Exp $
|
||||
* $Header: /cvsroot/pgsql/src/backend/optimizer/prep/prepunion.c,v 1.15 1997/12/27 06:41:17 momjian Exp $
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
@ -23,6 +23,7 @@
|
||||
#include "nodes/relation.h"
|
||||
|
||||
#include "parser/parsetree.h"
|
||||
#include "parser/parse_clause.h"
|
||||
|
||||
#include "utils/elog.h"
|
||||
#include "utils/lsyscache.h"
|
||||
@ -42,7 +43,7 @@ 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,
|
||||
static Append *make_append(List *unionplans, List *unionrts, Index rt_index,
|
||||
List *union_rt_entries, List *tlist);
|
||||
|
||||
|
||||
@ -136,73 +137,102 @@ plan_union_queries(Index rt_index,
|
||||
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);
|
||||
/*
|
||||
* 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;
|
||||
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));
|
||||
break;
|
||||
List *rangetable = parse->rtable;
|
||||
RangeTblEntry *rt_entry = rt_fetch(rt_index, rangetable);
|
||||
List *union_rt_entries = NIL;
|
||||
List *union_relids = NIL;
|
||||
|
||||
union_relids =
|
||||
find_all_inheritors(lconsi(rt_entry->relid,
|
||||
NIL),
|
||||
NIL);
|
||||
/*
|
||||
* 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;
|
||||
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,
|
||||
NULL,
|
||||
rt_index,
|
||||
union_rt_entries,
|
||||
((Plan *) lfirst(union_plans))->targetlist));
|
||||
break;
|
||||
}
|
||||
case UNION_FLAG:
|
||||
{
|
||||
List *ulist, *hold_union, *union_plans;
|
||||
List *ulist, *hold_union, *union_plans, *union_rts;
|
||||
|
||||
hold_union = parse->unionClause;
|
||||
parse->unionClause = NULL; /* prevent looping */
|
||||
|
||||
union_plans = lcons(planner(parse), NIL);
|
||||
|
||||
union_rts = lcons(parse->rtable, NIL);
|
||||
foreach(ulist, hold_union)
|
||||
union_plans = lappend(union_plans, planner(lfirst(ulist)));
|
||||
return (make_append(union_plans,
|
||||
rt_index, rangetable,
|
||||
{
|
||||
Query *u = lfirst(ulist);
|
||||
|
||||
union_plans = lappend(union_plans, planner(u));
|
||||
union_rts = lappend(union_rts, u->rtable);
|
||||
}
|
||||
|
||||
/* We have already split UNION and UNION ALL */
|
||||
if (!((Query *)lfirst(hold_union))->unionall)
|
||||
{
|
||||
parse->uniqueFlag = "*";
|
||||
parse->sortClause = transformSortClause(NULL, NIL,
|
||||
((Plan *)lfirst(union_plans))->targetlist, "*");
|
||||
}
|
||||
else
|
||||
{
|
||||
/* needed so we don't take the flag from the first query */
|
||||
parse->uniqueFlag = NULL;
|
||||
parse->sortClause = NIL;
|
||||
}
|
||||
|
||||
parse->havingQual = NULL;
|
||||
parse->qry_numAgg = 0;
|
||||
parse->qry_aggs = NULL;
|
||||
|
||||
return (make_append(union_plans, union_rts,
|
||||
rt_index /* is 0, none */, NULL,
|
||||
((Plan *) lfirst(union_plans))->targetlist));
|
||||
}
|
||||
break;
|
||||
|
||||
#ifdef NOT_USED
|
||||
case VERSION_FLAG:
|
||||
union_relids = VersionGetParents(rt_entry->relid);
|
||||
break;
|
||||
|
||||
#endif
|
||||
default:
|
||||
/* do nothing */
|
||||
break;
|
||||
}
|
||||
return NULL;
|
||||
|
||||
return ((Append*)NULL); /* to make gcc happy */
|
||||
}
|
||||
@ -392,6 +422,7 @@ fix_parsetree_attnums(Index rt_index,
|
||||
|
||||
static Append *
|
||||
make_append(List *unionplans,
|
||||
List *unionrts,
|
||||
Index rt_index,
|
||||
List *union_rt_entries,
|
||||
List *tlist)
|
||||
@ -399,6 +430,7 @@ make_append(List *unionplans,
|
||||
Append *node = makeNode(Append);
|
||||
|
||||
node->unionplans = unionplans;
|
||||
node->unionrts = unionrts;
|
||||
node->unionrelid = rt_index;
|
||||
node->unionrtentries = union_rt_entries;
|
||||
node->plan.cost = 0.0;
|
||||
|
Reference in New Issue
Block a user