1 /*-------------------------------------------------------------------------
4 * The query optimizer external interface.
6 * Copyright (c) 1994, Regents of the University of California
10 * $Header: /cvsroot/pgsql/src/backend/optimizer/plan/planner.c,v 1.25 1998/03/31 23:30:51 momjian Exp $
12 *-------------------------------------------------------------------------
14 #include <sys/types.h>
19 #include "nodes/pg_list.h"
20 #include "nodes/plannodes.h"
21 #include "nodes/parsenodes.h"
22 #include "nodes/relation.h"
23 #include "parser/parse_expr.h"
25 #include "utils/elog.h"
26 #include "utils/lsyscache.h"
27 #include "access/heapam.h"
29 #include "optimizer/internal.h"
30 #include "optimizer/planner.h"
31 #include "optimizer/plancat.h"
32 #include "optimizer/prep.h"
33 #include "optimizer/planmain.h"
34 #include "optimizer/subselect.h"
35 #include "optimizer/paths.h"
36 #include "optimizer/cost.h"
38 /* DATA STRUCTURE CREATION/MANIPULATION ROUTINES */
39 #include "nodes/relation.h"
40 #include "optimizer/clauseinfo.h"
41 #include "optimizer/joininfo.h"
42 #include "optimizer/keys.h"
43 #include "optimizer/ordering.h"
44 #include "optimizer/pathnode.h"
45 #include "optimizer/clauses.h"
46 #include "optimizer/tlist.h"
47 #include "optimizer/var.h"
49 #include "executor/executor.h"
51 static Plan *make_sortplan(List *tlist, List *sortcls, Plan *plannode);
53 make_groupPlan(List **tlist, bool tuplePerGroup,
54 List *groupClause, Plan *subplan);
56 /*****************************************************************************
58 * Query optimizer entry point
60 *****************************************************************************/
63 /***S*H***/ /* Anfang */
66 check_having_qual_for_aggs(Node *clause, List *subplanTargetList)
73 TargetEntry *subplanVar;
78 subplanVar = match_varid((Var *) clause, subplanTargetList);
81 * Change the varno & varattno fields of the var node.
84 ((Var *) clause)->varattno = subplanVar->resdom->resno;
88 else if (is_funcclause(clause) || not_clause(clause) ||
89 or_clause(clause) || and_clause(clause))
93 * This is a function. Recursively call this routine for its
96 foreach(t, ((Expr *) clause)->args)
98 agg_list = nconc(agg_list,
99 check_having_qual_for_aggs(lfirst(t), subplanTargetList));
103 else if (IsA(clause, Aggreg))
106 check_having_qual_for_aggs(((Aggreg *) clause)->target, subplanTargetList));
109 else if (IsA(clause, ArrayRef))
111 ArrayRef *aref = (ArrayRef *) clause;
114 * This is an arrayref. Recursively call this routine for its
115 * expression and its index expression...
117 foreach(t, aref->refupperindexpr)
119 agg_list = nconc(agg_list,
120 check_having_qual_for_aggs(lfirst(t), subplanTargetList));
122 foreach(t, aref->reflowerindexpr)
124 agg_list = nconc(agg_list,
125 check_having_qual_for_aggs(lfirst(t), subplanTargetList));
127 agg_list = nconc(agg_list,
128 check_having_qual_for_aggs(aref->refexpr, subplanTargetList));
129 agg_list = nconc(agg_list,
130 check_having_qual_for_aggs(aref->refassgnexpr, subplanTargetList));
134 else if (is_opclause(clause))
138 * This is an operator. Recursively call this routine for both its
139 * left and right operands
141 Node *left = (Node *) get_leftop((Expr *) clause);
142 Node *right = (Node *) get_rightop((Expr *) clause);
144 if (left != (Node *) NULL)
145 agg_list = nconc(agg_list,
146 check_having_qual_for_aggs(left, subplanTargetList));
147 if (right != (Node *) NULL)
148 agg_list = nconc(agg_list,
149 check_having_qual_for_aggs(right, subplanTargetList));
153 else if (IsA(clause, Param) ||IsA(clause, Const))
162 * Ooops! we can not handle that!
164 elog(ERROR, "check_having_qual_for_aggs: Can not handle this having_qual!\n");
168 /***S*H***/ /* Ende */
172 planner(Query *parse)
176 PlannerQueryLevel = 1;
177 PlannerVarParam = NULL;
178 PlannerParamVar = NULL;
179 PlannerInitPlan = NULL;
182 result_plan = union_planner(parse);
184 Assert(PlannerQueryLevel == 1);
185 if (PlannerPlanId > 0)
187 result_plan->initPlan = PlannerInitPlan;
188 (void) SS_finalize_plan(result_plan);
190 result_plan->nParamExec = length(PlannerParamVar);
192 return (result_plan);
198 * Invokes the planner on union queries if there are any left,
199 * recursing if necessary to get them all, then processes normal plans.
201 * Returns a query plan.
205 union_planner(Query *parse)
207 List *tlist = parse->targetList;
208 List *rangetable = parse->rtable;
210 Plan *result_plan = (Plan *) NULL;
215 if (parse->unionClause)
217 result_plan = (Plan *) plan_union_queries(parse);
218 /* XXX do we need to do this? bjm 12/19/97 */
219 tlist = preprocess_targetlist(tlist,
221 parse->resultRelation,
225 first_inherit_rt_entry(rangetable)) != -1)
227 result_plan = (Plan *) plan_inherit_queries(parse, rt_index);
228 /* XXX do we need to do this? bjm 12/19/97 */
229 tlist = preprocess_targetlist(tlist,
231 parse->resultRelation,
238 tlist = preprocess_targetlist(tlist,
240 parse->resultRelation,
242 if (parse->rtable != NULL)
244 vpm = (List **) palloc(length(parse->rtable) * sizeof(List *));
245 memset(vpm, 0, length(parse->rtable) * sizeof(List *));
247 PlannerVarParam = lcons(vpm, PlannerVarParam);
248 result_plan = query_planner(parse,
251 (List *) parse->qual);
252 PlannerVarParam = lnext(PlannerVarParam);
258 * If we have a GROUP BY clause, insert a group node (with the
259 * appropriate sort node.)
261 if (parse->groupClause)
266 * decide whether how many tuples per group the Group node needs
267 * to return. (Needs only one tuple per group if no aggregate is
268 * present. Otherwise, need every tuple from the group to do the
271 tuplePerGroup = parse->hasAggs;
274 make_groupPlan(&tlist,
282 * If aggregate is present, insert the agg node
286 result_plan = (Plan *) make_agg(tlist, result_plan);
289 * set the varno/attno entries to the appropriate references to
290 * the result tuple of the subplans.
292 ((Agg *) result_plan)->aggs =
293 set_agg_tlist_references((Agg *) result_plan);
295 if(parse->havingQual != NULL) {
298 /* set qpqual of having clause */
299 ((Agg *) result_plan)->plan.qual=cnfify((Expr *)parse->havingQual,true);
301 foreach(clause, ((Agg *) result_plan)->plan.qual)
303 ((Agg *) result_plan)->aggs = nconc(((Agg *) result_plan)->aggs,
304 check_having_qual_for_aggs((Node *) lfirst(clause),
305 ((Agg *) result_plan)->plan.lefttree->targetlist));
311 * For now, before we hand back the plan, check to see if there is a
312 * user-specified sort that needs to be done. Eventually, this will
313 * be moved into the guts of the planner s.t. user specified sorts
314 * will be considered as part of the planning process. Since we can
315 * only make use of user-specified sorts in special cases, we can do
316 * the optimization step later.
319 if (parse->uniqueFlag)
321 Plan *sortplan = make_sortplan(tlist, parse->sortClause, result_plan);
323 return ((Plan *) make_unique(tlist, sortplan, parse->uniqueFlag));
327 if (parse->sortClause)
328 return (make_sortplan(tlist, parse->sortClause, result_plan));
330 return ((Plan *) result_plan);
337 * Returns a sortplan which is basically a SORT node attached to the
338 * top of the plan returned from the planner. It also adds the
339 * cost of sorting into the plan.
341 * sortkeys: ( resdom1 resdom2 resdom3 ...)
342 * sortops: (sortop1 sortop2 sortop3 ...)
345 make_sortplan(List *tlist, List *sortcls, Plan *plannode)
347 Plan *sortplan = (Plan *) NULL;
348 List *temp_tlist = NIL;
350 Resdom *resnode = (Resdom *) NULL;
351 Resdom *resdom = (Resdom *) NULL;
355 * First make a copy of the tlist so that we don't corrupt the the
359 temp_tlist = new_unsorted_tlist(tlist);
363 SortClause *sortcl = (SortClause *) lfirst(i);
365 resnode = sortcl->resdom;
366 resdom = tlist_resdom(temp_tlist, resnode);
369 * Order the resdom keys and replace the operator OID for each key
370 * with the regproc OID.
372 resdom->reskey = keyno;
373 resdom->reskeyop = get_opcode(sortcl->opoid);
377 sortplan = (Plan *) make_sort(temp_tlist,
383 * XXX Assuming that an internal sort has no. cost. This is wrong, but
384 * given that at this point, we don't know the no. of tuples returned,
385 * etc, we can't do better than to add a constant cost. This will be
386 * fixed once we move the sort further into the planner, but for now
387 * ... functionality....
390 sortplan->cost = plannode->cost;
396 * pg_checkretval() -- check return value of a list of sql parse
399 * The return value of a sql function is the value returned by
400 * the final query in the function. We do some ad-hoc define-time
401 * type checking here to be sure that the user is returning the
405 pg_checkretval(Oid rettype, QueryTreeList *queryTreeList)
419 /* find the final query */
420 parse = queryTreeList->qtrees[queryTreeList->len - 1];
423 * test 1: if the last query is a utility invocation, then there had
424 * better not be a return value declared.
426 if (parse->commandType == CMD_UTILITY)
428 if (rettype == InvalidOid)
431 elog(ERROR, "return type mismatch in function decl: final query is a catalog utility");
434 /* okay, it's an ordinary query */
435 tlist = parse->targetList;
437 cmd = parse->commandType;
440 * test 2: if the function is declared to return no value, then the
441 * final query had better not be a retrieve.
443 if (rettype == InvalidOid)
445 if (cmd == CMD_SELECT)
447 "function declared with no return type, but final query is a retrieve");
452 /* by here, the function is declared to return some type */
453 if ((typ = typeidType(rettype)) == NULL)
454 elog(ERROR, "can't find return type %d for function\n", rettype);
457 * test 3: if the function is declared to return a value, then the
458 * final query had better be a retrieve.
460 if (cmd != CMD_SELECT)
461 elog(ERROR, "function declared to return type %s, but final query is not a retrieve", typeTypeName(typ));
464 * test 4: for base type returns, the target list should have exactly
465 * one entry, and its type should agree with what the user declared.
468 if (typeTypeRelid(typ) == InvalidOid)
470 if (exec_tlist_length(tlist) > 1)
471 elog(ERROR, "function declared to return %s returns multiple values in final retrieve", typeTypeName(typ));
473 resnode = (Resdom *) ((TargetEntry *) lfirst(tlist))->resdom;
474 if (resnode->restype != rettype)
475 elog(ERROR, "return type mismatch in function: declared to return %s, returns %s", typeTypeName(typ), typeidTypeName(resnode->restype));
477 /* by here, base return types match */
482 * If the target list is of length 1, and the type of the varnode in
483 * the target list is the same as the declared return type, this is
484 * okay. This can happen, for example, where the body of the function
485 * is 'retrieve (x = func2())', where func2 has the same return type
486 * as the function that's calling it.
488 if (exec_tlist_length(tlist) == 1)
490 resnode = (Resdom *) ((TargetEntry *) lfirst(tlist))->resdom;
491 if (resnode->restype == rettype)
496 * By here, the procedure returns a (set of) tuples. This part of the
497 * typechecking is a hack. We look up the relation that is the
498 * declared return type, and be sure that attributes 1 .. n in the
499 * target list match the declared types.
501 reln = heap_open(typeTypeRelid(typ));
503 if (!RelationIsValid(reln))
504 elog(ERROR, "cannot open relation relid %d", typeTypeRelid(typ));
507 relnatts = reln->rd_rel->relnatts;
509 if (exec_tlist_length(tlist) != relnatts)
510 elog(ERROR, "function declared to return type %s does not retrieve (%s.*)", typeTypeName(typ), typeTypeName(typ));
512 /* expect attributes 1 .. n in order */
513 for (i = 1; i <= relnatts; i++)
515 TargetEntry *tle = lfirst(tlist);
516 Node *thenode = tle->expr;
518 tlist = lnext(tlist);
519 tletype = exprType(thenode);
522 /* this is tedious */
523 if (IsA(thenode, Var))
524 tletype = (Oid) ((Var *) thenode)->vartype;
525 else if (IsA(thenode, Const))
526 tletype = (Oid) ((Const *) thenode)->consttype;
527 else if (IsA(thenode, Param))
528 tletype = (Oid) ((Param *) thenode)->paramtype;
529 else if (IsA(thenode, Expr))
532 else if (IsA(thenode, LispList))
534 thenode = lfirst(thenode);
535 if (IsA(thenode, Oper))
536 tletype = (Oid) get_opresulttype((Oper *) thenode);
537 else if (IsA(thenode, Func))
538 tletype = (Oid) get_functype((Func *) thenode);
540 elog(ERROR, "function declared to return type %s does not retrieve (%s.all)", typeTypeName(typ), typeTypeName(typ));
543 elog(ERROR, "function declared to return type %s does not retrieve (%s.all)", typeTypeName(typ), typeTypeName(typ));
545 /* reach right in there, why don't you? */
546 if (tletype != reln->rd_att->attrs[i - 1]->atttypid)
547 elog(ERROR, "function declared to return type %s does not retrieve (%s.all)", typeTypeName(typ), typeTypeName(typ));