head 1.32; access; symbols Version_2_1:1.22 C_Demo_1:1.11 Retrieve_x_qual:1.7 Retrieve_x_all:1.6 Retrieve_x_1:1.5; locks; strict; comment @ * @; 1.32 date 92.08.10.21.44.13; author mer; state Exp; branches; next 1.31; 1.31 date 92.07.24.04.32.12; author mao; state Exp; branches; next 1.30; 1.30 date 92.07.24.04.13.46; author mao; state Exp; branches; next 1.29; 1.29 date 92.07.24.01.26.57; author mao; state Exp; branches; next 1.28; 1.28 date 92.07.10.20.26.09; author mao; state Exp; branches; next 1.27; 1.27 date 92.07.10.18.57.41; author mao; state Exp; branches; next 1.26; 1.26 date 92.03.31.23.13.55; author mer; state Exp; branches; next 1.25; 1.25 date 92.02.18.17.40.08; author hong; state Exp; branches; next 1.24; 1.24 date 91.11.15.16.26.23; author hong; state Exp; branches; next 1.23; 1.23 date 91.06.18.23.28.29; author cimarron; state Exp; branches; next 1.22; 1.22 date 90.09.30.17.01.57; author goh; state Exp; branches; next 1.21; 1.21 date 90.09.25.16.36.48; author kemnitz; state Exp; branches; next 1.20; 1.20 date 90.05.30.18.56.57; author cimarron; state Exp; branches; next 1.19; 1.19 date 90.03.16.15.28.00; author ong; state Exp; branches; next 1.18; 1.18 date 90.03.13.19.17.52; author ong; state Exp; branches; next 1.17; 1.17 date 90.03.12.13.06.25; author ong; state Exp; branches; next 1.16; 1.16 date 90.01.31.10.46.09; author jamesb; state Exp; branches; next 1.15; 1.15 date 90.01.30.18.19.35; author jamesb; state Exp; branches; next 1.14; 1.14 date 90.01.30.18.13.18; author sp; state Exp; branches; next 1.13; 1.13 date 89.11.27.20.52.54; author hong; state Exp; branches; next 1.12; 1.12 date 89.10.04.10.30.15; author ong; state Exp; branches; next 1.11; 1.11 date 89.09.05.17.18.00; author mao; state C_Demo_1; branches; next 1.10; 1.10 date 89.08.30.14.22.28; author ong; state Exp; branches; next 1.9; 1.9 date 89.08.23.20.26.26; author ong; state Exp; branches; next 1.8; 1.8 date 89.08.23.16.04.16; author ong; state Exp; branches; next 1.7; 1.7 date 89.08.04.14.30.06; author goh; state Exp; branches; next 1.6; 1.6 date 89.08.04.13.28.51; author goh; state Exp; branches; next 1.5; 1.5 date 89.08.01.14.36.21; author goh; state Exp; branches; next 1.4; 1.4 date 89.07.25.17.38.32; author ong; state Exp; branches; next 1.3; 1.3 date 89.07.25.12.58.48; author goh; state Exp; branches; next 1.2; 1.2 date 89.07.21.12.08.07; author goh; state Exp; branches; next 1.1; 1.1 date 89.07.18.15.17.10; author ong; state Exp; branches; next ; desc @main planner routine. @ 1.32 log @fix up the old hack to make planning reentrant (existential code is dead no?) @ text @/* * FILE * planner * * DESCRIPTION * The query optimizer external interface. * */ /* RcsId ("$Header: /private/mer/pg/src/planner/plan/RCS/planner.c,v 1.31 1992/07/24 04:32:12 mao Exp mer $"); */ /* * EXPORTS * planner */ #include "tmp/c.h" #include "nodes/pg_lisp.h" #include "nodes/relation.h" #include "nodes/relation.a.h" #include "parser/parse.h" #include "planner/internal.h" #include "planner/planner.h" #include "catalog/pg_type.h" /* for pg_checkretval() */ #include "utils/log.h" /* ---------------- * Existential creator declaration * ---------------- */ extern Existential RMakeExistential(); /* * *** Module loading *** * */ #include "planner/cfi.h" /* C function interface routines */ /* #include "pppp.h" */ /* POSTGRES plan pretty printer */ /* #include "storeplan.h" */ /* plan i/o routines */ /* * PLANNER INITIALIZATION * */ /* ...Query tree preprocessing */ #include "planner/prepqual.h" /* for rule queries */ #include "planner/preptlist.h" /* normal targetlist preprocessing */ #include "planner/prepunion.h" /* for union (archive, inheritance, ...) queries */ /* * PLAN CREATION * */ /* ...Planner driver routines */ #include "planner/planmain.h" /* ...Subplanner initialization */ #include "planner/initsplan.h" /* ...Query plan generation */ #include "planner/createplan.h" /* routines to create optimal subplan */ #include "planner/setrefs.h" /* routines to set vars to reference other nodes */ /* #include "planner/sortresult.h" */ /* routines to manipulate sort keys */ /* * SUBPLAN GENERATION * */ #include "planner/allpaths.h" /* main routines to generate subplans */ #include "planner/indxpath.h" /* main routines to generate index paths */ #include "planner/orindxpath.h" #include "planner/prune.h" /* routines to prune the path space */ #include "planner/joinpath.h" /* main routines to create join paths */ #include "planner/joinrels.h" /* routines to determine which relations to join */ #include "planner/joinutils.h" /* generic join method key/clause routines */ #include "planner/mergeutils.h" /* routines to deal with merge keys and clauses */ #include "planner/hashutils.h" /* routines to deal with hash keys and clauses */ /* * SUBPLAN SELECTION - utilities for planner, create-plan, join routines * */ #include "planner/clausesel.h" /* routines to compute clause selectivities */ #include "planner/costsize.h" /* routines to compute costs and sizes */ /* * DATA STRUCTURE CREATION/MANIPULATION ROUTINES * */ #include "nodes/relation.h" #include "planner/clauseinfo.h" #include "planner/indexnode.h" #include "planner/joininfo.h" #include "planner/keys.h" #include "planner/ordering.h" #include "planner/pathnode.h" #include "planner/clause.h" #include "planner/relnode.h" #include "planner/tlist.h" #include "planner/var.h" extern bool DebugPrintPlan; /* * *** Query optimizer entry point *** * */ /* * planner * * Main query optimizer routine. * * Invokes the planner on union queries if there are any left, * recursing if necessary to get them all, then processes normal plans. * * Returns a query plan. * */ /* .. make-rule-plans, plan-union-query, process-rules */ Plan planner (parse) LispValue parse ; { LispValue root = parse_root (parse); LispValue tlist = parse_targetlist (parse); LispValue qual = parse_qualification (parse); LispValue rangetable = root_rangetable (root); LispValue commandType = root_command_type_atom (root); LispValue uniqueflag = root_uniqueflag(root); LispValue sortclause = root_sortclause(root); LispValue sortkeys = LispNil; LispValue sortops = LispNil; Plan special_plans = (Plan)NULL; Plan regular_plans = (Plan)NULL; LispValue flag = LispNil; List plan_list = LispNil; plan_list = lispCons(lispAtom("inherits"), lispCons(lispAtom("union"), lispCons(lispAtom("archive"),LispNil))); foreach (flag,plan_list) { Index rt_index = first_matching_rt_entry (rangetable,CAR(flag)); if ( rt_index != -1 ) special_plans = (Plan)plan_union_queries (rt_index, CAtom(CAR(flag)), root, tlist, qual,rangetable); } /* * For now, before we hand back the plan, check to see if there * is a user-specified sort that needs to be done. Eventually, this * will be moved into the guts of the planner s.t. user specified * sorts will be considered as part of the planning process. * Since we can only make use of user-specified sorts in * special cases, we can do the optimization step later. * * sortkeys: a list of resdom nodes corresponding to the attributes in * the tlist that are to be sorted. * sortops: a corresponding list of sort operators. */ if (uniqueflag || sortclause) { sortkeys = CADR(sortclause); sortops = CADDR(sortclause); } if (special_plans) { if (uniqueflag) { Plan sortplan = make_sortplan(tlist,sortkeys, sortops,special_plans); return((Plan)make_unique(tlist,sortplan)); } else if (sortclause) return(make_sortplan(tlist,sortkeys,sortops,special_plans)); else return((Plan)special_plans); } else { regular_plans = init_query_planner(root,tlist,qual); if (uniqueflag) { Plan sortplan = make_sortplan(tlist,sortkeys, sortops,regular_plans); return((Plan)make_unique(tlist,sortplan)); } else if (sortclause) return(make_sortplan(tlist,sortkeys,sortops,regular_plans)); else return(regular_plans); } } /* function end */ /* * make_sortplan * * Returns a sortplan which is basically a SORT node attached to the * top of the plan returned from the planner. It also adds the * cost of sorting into the plan. * * sortkeys: ( resdom1 resdom2 resdom3 ...) * sortops: (sortop1 sortop2 sortop3 ...) */ Plan make_sortplan(tlist,sortkeys,sortops,plannode) List tlist; List sortkeys; List sortops; Plan plannode; { Plan sortplan = (Plan)NULL; List temp_tlist = LispNil; LispValue i = LispNil; Resdom resnode = (Resdom)NULL; Resdom resdom = (Resdom)NULL; int keyno =1; /* First make a copy of the tlist so that we don't corrupt the * the original . */ temp_tlist = new_unsorted_tlist(tlist); foreach (i, sortkeys) { resnode = (Resdom)CAR(i); resdom = tlist_resdom(temp_tlist,resnode); /* Order the resdom keys and replace the operator OID for each * key with the regproc OID. */ set_reskey (resdom,keyno); set_reskeyop (resdom,(OperatorTupleForm)get_opcode (CInteger(CAR(sortops)))); keyno += 1; sortops = CDR(sortops); } sortplan = (Plan) make_sort(temp_tlist, _TEMP_RELATION_ID_, (Plan)plannode, length(sortkeys)); /* * XXX Assuming that an internal sort has no. cost. * This is wrong, but given that at this point, we don't * know the no. of tuples returned, etc, we can't do * better than to add a constant cost. * This will be fixed once we move the sort further into the planner, * but for now ... functionality.... */ set_cost(sortplan, get_cost(plannode)); return(sortplan); } /* * init-query-planner * * Deals with all non-union preprocessing, including existential * qualifications and CNFifying the qualifications. * * Returns a query plan. * MODIFIES: tlist,qual * */ /* .. plan-union-queries, planner */ Plan init_query_planner (root,tlist,qual) LispValue root,tlist,qual ; { LispValue primary_qual; LispValue existential_qual; Existential exist_plan; _query_max_level_ = root_numlevels (root); _query_command_type_ = (int) root_command_type (root); _query_result_relation_ = root_result_relation (root); _query_range_table_ = root_rangetable (root); tlist = preprocess_targetlist (tlist, _query_command_type_, _query_result_relation_, _query_range_table_); qual = preprocess_qualification (qual,tlist); if ( DebugPrintPlan ) { printf("after preprocessing, qual is :\n"); lispDisplay(qual); printf("\n"); fflush(stdout); } if (qual) { primary_qual = CAR(qual); existential_qual = CADR(qual); } else { primary_qual = LispNil; existential_qual = LispNil; } if(lispNullp (existential_qual)) { return(query_planner(_query_command_type_, tlist, primary_qual, 1,_query_max_level_)); } else { char *globals; int temp = _query_command_type_; Plan existential_plan; /* with saved globals */ globals = save_globals(); _query_command_type_ = RETRIEVE; existential_plan = query_planner(temp,LispNil,existential_qual,1, _query_max_level_); exist_plan = make_existential (existential_plan, query_planner (_query_command_type_, tlist,primary_qual, 1, _query_max_level_)); restore_globals(globals); return((Plan)exist_plan); } } /* function end */ /* * make_existential * ( NB: no corresponding lisp code ) * * Instantiates an existential plan node and fills in * the left and right subtree slots. */ Existential make_existential(left,right) Plan left,right; { Existential node = RMakeExistential(); set_lefttree(node,(PlanPtr)left); set_righttree(node,(PlanPtr)right); return(node); } /* * pg_checkretval() -- check return value of a list of postquel parse * trees. * * The return value of a postquel function is the value returned by * the final query in the function. We do some ad-hoc define-time * type checking here to be sure that the user is returning the * type he claims. */ void pg_checkretval(rettype, parselist) ObjectId rettype; List parselist; { LispValue parse; LispValue tlist; LispValue tle; LispValue root; LispValue rt; LispValue rte; int cmd; char *typ; Resdom resnode; LispValue thenode; Relation reln; ObjectId relid; ObjectId tletype; int relnatts; int i; /* find the final query */ while (CDR(parselist) != LispNil) parselist = CDR(parselist); parse = CAR(parselist); /* * test 1: if the last query is a utility invocation, then there * had better not be a return value declared. */ if (atom(CAR(parse))) { if (rettype == InvalidObjectId) return; else elog(WARN, "return type mismatch in function decl: final query is a catalog utility"); } /* okay, it's an ordinary query */ root = parse_root(parse); tlist = parse_targetlist(parse); rt = root_rangetable(root); cmd = (int) root_command_type(root); /* * test 2: if the function is declared to return no value, then the * final query had better not be a retrieve. */ if (rettype == InvalidObjectId) { if (cmd == RETRIEVE) elog(WARN, "function declared with no return type, but final query is a retrieve"); else return; } /* by here, the function is declared to return some type */ if ((typ = (char *) get_id_type(rettype)) == (char *) NULL) elog(WARN, "can't find return type %d for function\n", rettype); /* * test 3: if the function is declared to return a value, then the * final query had better be a retrieve. */ if (cmd != RETRIEVE) elog(WARN, "function declared to return type %s, but final query is not a retrieve", tname(typ)); /* * test 4: for base type returns, the target list should have exactly * one entry, and its type should agree with what the user declared. */ if (get_typrelid(typ) == InvalidObjectId) { if (ExecTargetListLength(tlist) > 1) elog(WARN, "function declared to return %s returns multiple values in final retrieve", tname(typ)); resnode = (Resdom) CAR(CAR(tlist)); if (get_restype(resnode) != rettype) elog(WARN, "return type mismatch in function: declared to return %s, returns %s", tname(typ), tname(get_id_type(get_restype(resnode)))); /* by here, base return types match */ return; } /* * If the target list is of length 1, and the type of the varnode * in the target list is the same as the declared return type, this * is okay. This can happen, for example, where the body of the * function is 'retrieve (x = func2())', where func2 has the same * return type as the function that's calling it. */ if (ExecTargetListLength(tlist) == 1) { resnode = (Resdom) CAR(CAR(tlist)); if (get_restype(resnode) == rettype) return; } /* * By here, the procedure returns a (set of) tuples. This part of * the typechecking is a hack. We look up the relation that is * the declared return type, and be sure that attributes 1 .. n * in the target list match the declared types. */ reln = heap_open(get_typrelid(typ)); if (!RelationIsValid(reln)) elog(WARN, "cannot open relation relid %d", get_typrelid(typ)); relid = reln->rd_id; relnatts = reln->rd_rel->relnatts; if (ExecTargetListLength(tlist) != relnatts) elog(WARN, "function declared to return type %s does not retrieve (%s.all)", tname(typ), tname(typ)); /* expect attributes 1 .. n in order */ for (i = 1; i <= relnatts; i++) { tle = CAR(tlist); tlist = CDR(tlist); thenode = CADR(tle); /* this is tedious */ if (IsA(thenode,Var)) tletype = (ObjectId) get_vartype((Var)thenode); else if (IsA(thenode,Const)) tletype = (ObjectId) get_consttype((Const)thenode); else if (IsA(thenode,Param)) tletype = (ObjectId) get_paramtype((Param)thenode); else if (IsA(thenode,LispList)) { thenode = CAR(thenode); if (IsA(thenode,Oper)) tletype = (ObjectId) get_opresulttype((Oper)thenode); else if (IsA(thenode,Func)) tletype = (ObjectId) get_functype((Func)thenode); else elog(WARN, "function declared to return type %s does not retrieve (%s.all)", tname(typ), tname(typ)); } else elog(WARN, "function declared to return type %s does not retrieve (%s.all)", tname(typ), tname(typ)); /* reach right in there, why don't you? */ if (tletype != reln->rd_att.data[i-1]->atttypid) elog(WARN, "function declared to return type %s does not retrieve (%s.all)", tname(typ), tname(typ)); } heap_close(reln); /* success */ return; } @ 1.31 log @handle oper, function invocations in the target list for typechecking @ text @d10 1 a10 1 /* RcsId ("$Header: /private/mao/postgres/src/planner/plan/RCS/planner.c,v 1.30 1992/07/24 04:13:46 mao Exp mao $"); */ d374 1 d379 1 a379 1 save_globals(); d391 1 a391 1 restore_globals(); @ 1.30 log @in typechecker for tuple returns, handle param nodes correctly @ text @d10 1 a10 1 /* RcsId ("$Header: /private/mao/postgres/src/planner/plan/RCS/planner.c,v 1.29 1992/07/24 01:26:57 mao Exp mao $"); */ d556 9 a564 1 else @ 1.29 log @fix up typechecking -- more forgiving now; allow pq funcs to assemble tuples of the appropriate types in their target lists. also lets users define pq funcs on views @ text @d10 1 a10 1 /* RcsId ("$Header: /private/mao/postgres/src/planner/plan/RCS/planner.c,v 1.28 1992/07/10 20:26:09 mao Exp mao $"); */ d549 1 d554 2 @ 1.28 log @add another permissible case to the postquel function return value type checker @ text @d10 1 a10 1 /* RcsId ("$Header: /private/mao/postgres/src/planner/plan/RCS/planner.c,v 1.27 1992/07/10 18:57:41 mao Exp mao $"); */ d439 1 a439 1 Var varnode; d442 1 a444 2 ObjectId rtrelid; int varno, varattno; d529 1 a529 3 * for that relation appear in the target list, in order, and that * no others do. This is because .all expansion happens in the * wrong place in postgres. a539 2 heap_close(reln); d547 1 a547 1 varnode = (Var) CADR(tle); d549 5 a553 1 if (!IsA(varnode,Var)) d556 2 a557 5 varno = get_varno(varnode); varattno = get_varattno(varnode); /* make sure atts are in ascending order */ if (varattno != i) d559 1 d561 1 a561 10 /* get the range table entry */ for (rte = rt; varno > 1; varno--, rte = CDR(rte)) continue; rte = CAR(rte); rtrelid = (ObjectId) CInteger(CADR(CDR(rte))); if (rtrelid != relid) elog(WARN, "function declared to return type %s does not retrieve (%s.all)", tname(typ), tname(typ)); } @ 1.27 log @typecheck postquel function return values @ text @d10 1 a10 1 /* RcsId ("$Header: /private/mao/postgres/src/planner/plan/RCS/planner.c,v 1.26 1992/03/31 23:13:55 mer Exp mao $"); */ d441 2 d513 14 d540 6 a545 1 if (ExecTargetListLength(tlist) != reln->rd_rel->relnatts) d549 1 a549 1 for (i = 1; i <= reln->rd_rel->relnatts; i++) { d571 1 a571 1 if (rtrelid != reln->rd_id) d574 3 @ 1.26 log @change accessor functions into macros @ text @d10 1 a10 1 /* RcsId ("$Header: /users/mer/pg/src/planner/plan/RCS/planner.c,v 1.25 1992/02/18 17:40:08 hong Exp mer $"); */ d28 4 d413 140 @ 1.25 log @use macros to manipulate parsetree, instead of direct calls to nth() @ text @d10 1 a10 1 /* RcsId ("$Header: RCS/planner.c,v 1.24 91/11/15 16:26:23 hong Exp $"); */ d288 1 a288 1 set_reskeyop (resdom,get_opcode (CInteger(CAR(sortops)))); d406 2 a407 2 set_lefttree(node,left); set_righttree(node,right); @ 1.24 log @planner prototyping @ text @d10 1 a10 1 /* RcsId ("$Header: RCS/planner.c,v 1.23 91/06/18 23:28:29 cimarron Exp $"); */ d177 2 a178 2 LispValue uniqueflag = nth(6,root); LispValue sortclause = nth(7,root); @ 1.23 log @reorganized executor to use tuple table properly for nested dot stuff @ text @d10 1 a10 1 /* RcsId ("$Header: RCS/planner.c,v 1.22 90/09/30 17:01:57 goh Exp Locker: cimarron $"); */ d181 2 a182 2 List special_plans = LispNil; Plan regular_plans = (Plan) NULL; d190 1 a190 1 int rt_index = first_matching_rt_entry (rangetable,CAR(flag)); d192 1 a192 1 special_plans = (List)plan_union_queries (rt_index, d262 1 a262 1 List plannode; d349 1 a349 1 lispDisplay(qual,0); @ 1.22 log @now uses DebugPrintPlan instead of Quiet to control plan printing @ text @d10 1 a10 1 /* RcsId ("$Header: RCS/planner.c,v 1.22 90/08/17 08:55:06 cimarron Exp $"); */ a27 5 /*** JJJ ***/ #include "executor/recursion.h" extern Plan RecursiveQueryPlan(); /*** JJJ ***/ a184 1 bool isRecursiveQuery = false; a185 22 if ( (consp(commandType)) && (CInteger(CAR(commandType)) == '*') ) { printf(" *** JJJ *** Planner.c -- recursive flag \n"); isRecursiveQuery = true; commandType = CDR(commandType); root = lispCons(CAR(root), lispCons(commandType, CDR(CDR(root)))); /* XXX the following is a dangerous hack, solves tcop error */ rplaca(parse, root); } /* else, don't touch the command type list -- it is supposed to be there * JJJ - the star IS removed */ /*** JJJ ***/ if ( isRecursiveQuery ) { printf(" *** JJJ *** Planner.c -- recursive flag seconded \n"); special_plans = (List)RecursiveQueryPlan (parse); } /* JJJ fall through with NULL means not recursive, planned below */ /*** JJJ ***/ @ 1.21 log @Updating from revision 1.20 to revision 1.22 @ text @d152 2 a153 1 extern int Quiet; d375 5 a379 5 if (!Quiet) { printf("after preprocessing, qual is :\n"); lispDisplay(qual,0); printf("\n"); fflush(stdout); @ 1.20 log @CreateNode(Foo) --> RMakeFoo() change @ text @d10 1 a10 1 /* RcsId ("$Header: RCS/planner.c,v 1.19 90/03/16 15:28:00 ong Exp Locker: ong $"); */ d17 8 a24 1 #include "c.h" a26 4 #include "pg_lisp.h" #include "relation.h" #include "relation.a.h" #include "parse.h" d29 1 a29 1 #include "recursion.h" d140 1 a140 1 #include "relation.h" @ 1.19 log @fix for sorts @ text @d1 3 a3 1 /* * FILE * planner d10 1 a10 1 /* RcsId ("$Header: RCS/planner.c,v 1.18 90/03/13 19:17:52 ong Exp Locker: ong $"); */ d30 6 d428 1 a428 2 extern void PrintExistential(); extern bool EqualExistential(); a429 4 Existential node = CreateNode(Existential); node->equalFunc = EqualExistential; node->printFunc = PrintExistential; @ 1.18 log @fix for sort and unique @ text @d8 1 a8 1 /* RcsId ("$Header: RCS/planner.c,v 1.17 90/03/12 13:06:25 ong Exp Locker: ong $"); */ d223 1 a223 1 * sortkeys: a list of var nodes corresponding to the var. nodes in d268 3 d283 4 d288 22 a309 3 temp_tlist = set_temp_tlist_operators(new_unsorted_tlist(tlist), lispCons(sortkeys,LispNil), sortops); @ 1.17 log @added sort_by, and unique. @ text @d8 1 a8 1 /* RcsId ("$Header: RCS/planner.c,v 1.16 90/01/31 10:46:09 jamesb Exp Locker: ong $"); */ d282 1 a282 1 sortkeys, @ 1.16 log @removed dependency on preprule.h for spyros @ text @d8 1 a8 1 /* RcsId ("$Header: RCS/planner.c,v 1.15 90/01/30 18:19:35 jamesb Exp Locker: jamesb $"); */ d170 4 d175 1 d187 1 a187 1 /* the following is a dangerous hack, solves tcop error ******** */ d190 3 a192 2 /* else, don't touch the command type list -- it is supposed to be there */ /* JJJ - the star IS removed */ a213 3 if (special_plans) return((Plan)special_plans); else d215 12 a226 1 return(init_query_planner (root,tlist,qual)); d228 32 d261 42 @ 1.15 log @added branch on recursive queries @ text @d8 1 a8 1 /* RcsId ("$Header: RCS/planner.c,v 1.13 89/11/27 20:52:54 hong Exp $"); */ a49 3 /* normal qualification preprocessing */ #include "planner/preprule.h" @ 1.14 log @Got rid of the old rule system calls (namely, 'process_rules()') @ text @d1 1 a1 4 /* * FILE * planner d23 5 d172 1 d176 1 d178 21 d200 2 a201 2 lispCons(lispAtom("union"), lispCons(lispAtom("archive"),LispNil))); a216 1 @ 1.13 log @turn off junk message output when Quiet option is given @ text @d11 1 a11 1 /* RcsId ("$Header: RCS/planner.c,v 1.12 89/10/04 10:30:15 ong Exp Locker: ong $"); */ d174 3 a176 6 if ( root_ruleinfo (root) ) special_plans = process_rules (parse); else plan_list = lispCons(lispAtom("inherits"), lispCons(lispAtom("union"), lispCons(lispAtom("archive"),LispNil))); @ 1.12 log @turns rules back on. @ text @d11 1 a11 1 /* RcsId ("$Header: RCS/planner.c,v 1.11 89/09/05 17:18:00 mao C_Demo_1 Locker: ong $"); */ d142 1 d231 1 d236 1 @ 1.11 log @Working version of C-only demo @ text @d11 1 a11 1 /* RcsId ("$Header: RCS/planner.c,v 1.10 89/08/30 14:22:28 ong Exp Locker: ong $"); */ d173 1 a173 1 /* if ( root_ruleinfo (root) ) a175 3 * * turn rules off for now. */ @ 1.10 log @compiler warnings will now go away. @ text @d11 1 a11 1 /* RcsId ("$Header: RCS/planner.c,v 1.9 89/08/23 20:26:26 ong Exp Locker: ong $"); */ @ 1.9 log @changed the type of exit_plan to Existential. @ text @d11 1 a11 1 /* RcsId ("$Header: RCS/planner.c,v 1.8 89/08/23 16:04:16 ong Exp Locker: ong $"); */ d271 1 a271 1 return(exist_plan); @ 1.8 log @planner supports all but rules and mergesort @ text @d11 1 a11 1 /* RcsId ("$Header: /n/postgres/a/postgres/ong/postgres/src/planner/plan/RCS/planner.c,v 1.7 89/08/04 14:30:06 goh Exp $"); */ d219 1 a219 1 Plan exist_plan; @ 1.7 log @reorganised header files @ text @d11 1 a11 1 /* RcsId ("$Header: planner.c,v 1.6 89/08/04 13:28:51 goh Locked $"); */ d169 3 a171 3 List special_plans; LispValue flag; List plan_list ; d175 16 a190 13 else plan_list = lispCons(lispInteger(INHERITS), lispCons(lispInteger(UNION), lispCons(lispInteger(ARCHIVE),LispNil))); foreach (flag,plan_list) { int rt_index = first_matching_rt_entry (rangetable,flag); if ( rt_index ) special_plans = (List)plan_union_queries (rt_index, flag, root, tlist, qual,rangetable); } d192 1 a192 1 return((Plan)CAR(special_plans)); a193 1 * -XXX hack to make retrieve x= 1 work */ d195 1 a195 1 return(init_query_planner (root,tlist,qual)); @ 1.6 log @checkin for retrieve (x.all) @ text @d11 1 a11 1 /* RcsId ("$Header: planner.c,v 1.5 89/08/01 14:36:21 goh Locked $"); */ d19 2 a20 2 #include "internal.h" #include "planner.h" d31 1 a31 1 /* #include "cfi.h" /* XXX should it be a .h file? */ d47 1 a47 1 #include "prepqual.h" d50 1 a50 1 #include "preprule.h" d53 1 a53 1 #include "preptlist.h" d56 1 a56 1 #include "prepunion.h" d67 1 a67 1 #include "planmain.h" d71 1 a71 1 #include "initsplan.h" d75 1 a75 1 #include "createplan.h" d78 1 a78 1 #include "setrefs.h" d81 1 a81 1 /* #include "sortresult.h" */ d89 1 a89 1 #include "allpaths.h" d92 1 a92 1 #include "indxpath.h" d95 2 a96 2 #include "orindxpath.h" #include "prune.h" d99 1 a99 1 #include "joinpath.h" d102 1 a102 1 #include "joinrels.h" d105 1 a105 1 #include "joinutils.h" d108 1 a108 1 #include "mergeutils.h" d111 1 a111 1 #include "hashutils.h" d119 1 a119 1 #include "clausesel.h" d122 1 a122 1 #include "costsize.h" d131 10 a140 10 #include "clauseinfo.h" #include "indexnode.h" #include "joininfo.h" #include "keys.h" #include "ordering.h" #include "pathnode.h" #include "clause.h" #include "relnode.h" #include "tlist.h" #include "var.h" @ 1.5 log @retrieve (x=1) checkin @ text @d11 1 a11 1 /* RcsId ("$Header: planner.c,v 1.4 89/07/25 17:38:32 ong Exp $"); */ a192 8 printf ("\nroot is "); lispDisplay (root,0); printf ("\ntlist is "); lispDisplay (tlist,0); printf ("\nqual is "); lispDisplay (qual,0); printf("\n"); d217 1 a218 3 lispDisplay(CAR(root),0); printf("\n"); fflush(stdout); d256 2 d262 10 a271 7 return((Plan) (make_existential (existential_plan, query_planner (_query_command_type_, tlist,primary_qual, 1, _query_max_level_)))); } d286 3 d290 3 a292 1 @ 1.4 log @*** empty log message *** @ text @d11 1 a11 1 /* RcsId ("$Header: planner.c,v 1.3 89/07/25 12:58:48 ong Locked $"); */ d169 1 a169 1 Plan special_plan; d171 1 d173 2 a174 2 if ( root_ruleinfo (root) ) special_plan = process_rules (parse); d176 5 a180 3 foreach (flag, list(INHERITS,UNION,ARCHIVE)) { /* XXX - add VERSION too, sometime */ int rt_index = first_matching_rt_entry (rangetable,flag); d182 1 a182 1 special_plan = (Plan)plan_union_queries (rt_index, d188 2 a189 2 if (special_plan) return(special_plan); d191 12 a202 1 return(init_query_planner (root,tlist,qual)); a222 3 /* LispValue tlist; LispValue qual; */ d226 4 a229 1 _query_max_level_ = root_levels (root); d238 1 a239 2 primary_qual = CAR(qual); existential_qual = CADR(qual); d241 14 a254 1 if(null (existential_qual)) { d270 5 a274 4 return(make_existential (existential_plan, query_planner (_query_command_type_, tlist,primary_qual, 1,_query_max_level_))); d287 1 a287 1 Plan @ 1.3 log @*** empty log message *** @ text @d11 1 a11 1 /* RcsId ("$Header: planner.c,v 1.2 89/07/21 12:08:07 goh Locked $"); */ d216 1 a216 1 _query_command_type_ = root_command_type (root); @ 1.2 log @phase 2/3 of checkin @ text @d11 1 a11 1 /* RcsId ("$Header: planner.c,v 1.1 89/07/18 15:17:10 goh Locked $"); */ d268 1 @ 1.1 log @Initial revision @ text @d11 1 a11 1 /* RcsId ("$Header: planner.c,v 1.1 89/04/27 21:04:53 ong Locked $"); */ d18 1 d20 5 a29 1 #include "cfi.h" /* XXX should it be a .h file? */ d31 1 d33 1 a33 2 #include "pppp.h" a34 1 #include "storeplan.h" d36 2 d81 1 a81 1 #include "sortresult.h" d96 1 a96 1 #include "prune.h" d161 1 a161 1 LispValue d165 6 a170 5 LispValue root = parse_root (parse); LispValue tlist = parse_targetlist (parse); LispValue qual = parse_qualification (parse); LispValue rangetable = root_rangetable (root); LispValue special_plan = LispNil; d172 2 a173 2 if ( root_ruleinfo (root) ) special_plan = process_rules (parse); d175 9 a183 9 foreach (flag, list(inheritance,union,version,archive)) { /* XXX - let form, maybe incorrect */ LispValue rt_index = first_matching_rt_entry (rangetable,flag); if ( rt_index != LispNil) special_plan = plan_union_queries (rt_index, flag, root, tlist, qual,rangetable); d185 5 a189 5 if (special_plan != LispNil) return(special_plan); else return(init_query_planner (root,tlist,qual)); d199 1 d205 1 a205 1 LispValue d209 6 d219 28 a246 12 LispValue tlist = preprocess_targetlist (tlist, _query_command_type_, _query_result_relation_, _query_range_table_); LispValue qual = preprocess_qualification (qual,tlist); LispValue primary_qual = nth (0,qual); LispValue existential_qual = nth (1,qual); if(null (existential_qual)) return (with_fast_memory(query_planner(_query_command_type_, tlist, primary_qual, a247 15 else { /* XXX - let form, maybe incorrect */ LispValue temp = LispNil; temp = _query_command_type_; _query_command_type_ = RETRIEVE; LispValue existential_plan = with_saved_globals(_query_command_type_, query_planner(temp,LispNil, existential_qual,1, _query_max_level_)); make_existential (existential_plan, query_planner (_query_command_type_, tlist,primary_qual, 1,_query_max_level_)); d249 2 d252 17 a268 1 } /* function end */ @