diff --git a/doc/src/sgml/arch-dev.sgml b/doc/src/sgml/arch-dev.sgml index 7bc8e8482e11152ded5dc486d3953c4bbb6fcdca..b8d03725bea85e77d8dc485fb0e20899d246e0ac 100644 --- a/doc/src/sgml/arch-dev.sgml +++ b/doc/src/sgml/arch-dev.sgml @@ -3758,7 +3758,7 @@ $\ldots$/src/backend/tcop/postgres.c}. List * pg_parse_and_plan(char *query_string, Oid *typev, int nargs, - QueryTreeList **queryListP, + List **queryListP, CommandDest dest) { . @@ -4032,7 +4032,7 @@ instead. if(IsA(tree, SelectStmt)) { - QueryTreeList *qtree; + List *qtrees; /* If we get to the tree given in first_select * return parsetree instead of performing @@ -4044,9 +4044,8 @@ instead. else { /* transform the unprocessed Query nodes */ - qtree = - parse_analyze(lcons(tree, NIL), NULL); - result = (Node *)qtree->qtrees[0]; + qtrees = parse_analyze(lcons(tree, NIL), NULL); + result = (Node *) lfirst(qtrees); } } if(IsA(tree,Expr)) diff --git a/src/backend/catalog/heap.c b/src/backend/catalog/heap.c index 0caf676bd0f584f63af083402159a8c75cfb7042..71ae1ebf8139b8ffc108b9977f70802440df8916 100644 --- a/src/backend/catalog/heap.c +++ b/src/backend/catalog/heap.c @@ -7,7 +7,7 @@ * * * IDENTIFICATION - * $Header: /cvsroot/pgsql/src/backend/catalog/heap.c,v 1.79 1999/05/10 04:02:03 momjian Exp $ + * $Header: /cvsroot/pgsql/src/backend/catalog/heap.c,v 1.80 1999/05/13 07:28:26 tgl Exp $ * * * INTERFACE ROUTINES @@ -1498,9 +1498,9 @@ StoreAttrDefault(Relation rel, AttrDefault *attrdef) char str[MAX_PARSE_BUFFER]; char cast[2 * NAMEDATALEN] = {0}; Form_pg_attribute atp = rel->rd_att->attrs[attrdef->adnum - 1]; - QueryTreeList *queryTree_list; - Query *query; + List *queryTree_list; List *planTree_list; + Query *query; TargetEntry *te; Resdom *resdom; Node *expr; @@ -1522,9 +1522,10 @@ start:; "select %s%s from \"%.*s\"", attrdef->adsrc, cast, NAMEDATALEN, rel->rd_rel->relname.data); setheapoverride(true); - planTree_list = (List *) pg_parse_and_plan(str, NULL, 0, &queryTree_list, None, FALSE); + planTree_list = pg_parse_and_plan(str, NULL, 0, + &queryTree_list, None, FALSE); setheapoverride(false); - query = (Query *) (queryTree_list->qtrees[0]); + query = (Query *) lfirst(queryTree_list); if (length(query->rtable) > 1 || flatten_tlist(query->targetList) != NIL) @@ -1582,9 +1583,9 @@ static void StoreRelCheck(Relation rel, ConstrCheck *check) { char str[MAX_PARSE_BUFFER]; - QueryTreeList *queryTree_list; - Query *query; + List *queryTree_list; List *planTree_list; + Query *query; Plan *plan; List *qual; char *ccbin; @@ -1603,9 +1604,10 @@ StoreRelCheck(Relation rel, ConstrCheck *check) "select 1 from \"%.*s\" where %s", NAMEDATALEN, rel->rd_rel->relname.data, check->ccsrc); setheapoverride(true); - planTree_list = (List *) pg_parse_and_plan(str, NULL, 0, &queryTree_list, None, FALSE); + planTree_list = pg_parse_and_plan(str, NULL, 0, + &queryTree_list, None, FALSE); setheapoverride(false); - query = (Query *) (queryTree_list->qtrees[0]); + query = (Query *) lfirst(queryTree_list); if (length(query->rtable) > 1) elog(ERROR, "Only relation '%.*s' can be referenced", diff --git a/src/backend/catalog/pg_proc.c b/src/backend/catalog/pg_proc.c index 90c41f57ee8a73ec206e60e6ca79fdd2d8b0531f..7c22ce007cd086095c584b0ad5bfbe3f46034ac3 100644 --- a/src/backend/catalog/pg_proc.c +++ b/src/backend/catalog/pg_proc.c @@ -7,7 +7,7 @@ * * * IDENTIFICATION - * $Header: /cvsroot/pgsql/src/backend/catalog/pg_proc.c,v 1.27 1999/04/18 02:57:22 tgl Exp $ + * $Header: /cvsroot/pgsql/src/backend/catalog/pg_proc.c,v 1.28 1999/05/13 07:28:27 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -67,7 +67,7 @@ ProcedureCreate(char *procedureName, Oid languageObjectId; Oid typeObjectId; List *x; - QueryTreeList *querytree_list; + List *querytree_list; List *plan_list; Oid typev[8]; Oid relid; diff --git a/src/backend/executor/functions.c b/src/backend/executor/functions.c index 1cb57d5651e7c2fb53805dfa4b729734d391e511..f9b729b8386ff2a3dfc9176a3f1af2bc07067fcb 100644 --- a/src/backend/executor/functions.c +++ b/src/backend/executor/functions.c @@ -8,7 +8,7 @@ * * * IDENTIFICATION - * $Header: /cvsroot/pgsql/src/backend/executor/functions.c,v 1.24 1999/02/13 23:15:20 momjian Exp $ + * $Header: /cvsroot/pgsql/src/backend/executor/functions.c,v 1.25 1999/05/13 07:28:29 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -97,26 +97,23 @@ init_execution_state(FunctionCachePtr fcache, execution_state *newes; execution_state *nextes; execution_state *preves; - QueryTreeList *queryTree_list; - int i; - List *planTree_list; - int nargs; - - nargs = fcache->nargs; + List *queryTree_list, + *planTree_list, + *qtl_item; + int nargs = fcache->nargs; newes = (execution_state *) palloc(sizeof(execution_state)); nextes = newes; preves = (execution_state *) NULL; + planTree_list = pg_parse_and_plan(fcache->src, fcache->argOidVect, + nargs, &queryTree_list, None, FALSE); - planTree_list = (List *) - pg_parse_and_plan(fcache->src, fcache->argOidVect, nargs, &queryTree_list, None, FALSE); - - for (i = 0; i < queryTree_list->len; i++) + foreach (qtl_item, queryTree_list) { - EState *estate; - Query *queryTree = (Query *) (queryTree_list->qtrees[i]); + Query *queryTree = lfirst(qtl_item); Plan *planTree = lfirst(planTree_list); + EState *estate; if (!nextes) nextes = (execution_state *) palloc(sizeof(execution_state)); diff --git a/src/backend/executor/spi.c b/src/backend/executor/spi.c index d3064128a4373ed80597f9ab37c810d03a97d974..f6e5b8c585e260283a7a4819a288711963ba32e2 100644 --- a/src/backend/executor/spi.c +++ b/src/backend/executor/spi.c @@ -3,7 +3,7 @@ * spi.c * Server Programming Interface * - * $Id: spi.c,v 1.36 1999/03/30 01:37:23 momjian Exp $ + * $Id: spi.c,v 1.37 1999/05/13 07:28:30 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -602,18 +602,18 @@ spi_printtup(HeapTuple tuple, TupleDesc tupdesc, DestReceiver* self) static int _SPI_execute(char *src, int tcount, _SPI_plan *plan) { - QueryTreeList *queryTree_list; + List *queryTree_list; List *planTree_list; + List *queryTree_list_item; List *ptlist; QueryDesc *qdesc; Query *queryTree; Plan *planTree; EState *state; - int qlen; int nargs = 0; Oid *argtypes = NULL; - int res; - int i; + int res = 0; + bool islastquery; /* Increment CommandCounter to see changes made by now */ CommandCounterIncrement(); @@ -628,18 +628,17 @@ _SPI_execute(char *src, int tcount, _SPI_plan *plan) nargs = plan->nargs; argtypes = plan->argtypes; } - ptlist = planTree_list = (List *) + ptlist = planTree_list = pg_parse_and_plan(src, argtypes, nargs, &queryTree_list, None, FALSE); _SPI_current->qtlist = queryTree_list; - qlen = queryTree_list->len; - for (i = 0;; i++) + foreach (queryTree_list_item, queryTree_list) { - queryTree = (Query *) (queryTree_list->qtrees[i]); + queryTree = (Query *) lfirst(queryTree_list_item); planTree = lfirst(planTree_list); - planTree_list = lnext(planTree_list); + islastquery = (planTree_list == NIL); /* assume lists are same len */ if (queryTree->commandType == CMD_UTILITY) { @@ -659,32 +658,32 @@ _SPI_execute(char *src, int tcount, _SPI_plan *plan) if (plan == NULL) { ProcessUtility(queryTree->utilityStmt, None); - if (i < qlen - 1) + if (! islastquery) CommandCounterIncrement(); else return res; } - else if (i >= qlen - 1) + else if (islastquery) break; } else if (plan == NULL) { qdesc = CreateQueryDesc(queryTree, planTree, - (i < qlen - 1) ? None : SPI); + islastquery ? SPI : None); state = CreateExecutorState(); - res = _SPI_pquery(qdesc, state, (i < qlen - 1) ? 0 : tcount); - if (res < 0 || i >= qlen - 1) + res = _SPI_pquery(qdesc, state, islastquery ? tcount : 0); + if (res < 0 || islastquery) return res; CommandCounterIncrement(); } else { qdesc = CreateQueryDesc(queryTree, planTree, - (i < qlen - 1) ? None : SPI); - res = _SPI_pquery(qdesc, NULL, (i < qlen - 1) ? 0 : tcount); + islastquery ? SPI : None); + res = _SPI_pquery(qdesc, NULL, islastquery ? tcount : 0); if (res < 0) return res; - if (i >= qlen - 1) + if (islastquery) break; } } @@ -693,23 +692,22 @@ _SPI_execute(char *src, int tcount, _SPI_plan *plan) plan->ptlist = ptlist; return res; - } static int _SPI_execute_plan(_SPI_plan *plan, Datum *Values, char *Nulls, int tcount) { - QueryTreeList *queryTree_list = plan->qtlist; + List *queryTree_list = plan->qtlist; List *planTree_list = plan->ptlist; + List *queryTree_list_item; QueryDesc *qdesc; Query *queryTree; Plan *planTree; EState *state; int nargs = plan->nargs; - int qlen = queryTree_list->len; - int res; - int i, - k; + int res = 0; + bool islastquery; + int k; /* Increment CommandCounter to see changes made by now */ CommandCounterIncrement(); @@ -719,17 +717,17 @@ _SPI_execute_plan(_SPI_plan *plan, Datum *Values, char *Nulls, int tcount) _SPI_current->tuptable = NULL; _SPI_current->qtlist = NULL; - for (i = 0;; i++) + foreach (queryTree_list_item, queryTree_list) { - queryTree = (Query *) (queryTree_list->qtrees[i]); + queryTree = (Query *) lfirst(queryTree_list_item); planTree = lfirst(planTree_list); - planTree_list = lnext(planTree_list); + islastquery = (planTree_list == NIL); /* assume lists are same len */ if (queryTree->commandType == CMD_UTILITY) { ProcessUtility(queryTree->utilityStmt, None); - if (i < qlen - 1) + if (! islastquery) CommandCounterIncrement(); else return SPI_OK_UTILITY; @@ -737,7 +735,7 @@ _SPI_execute_plan(_SPI_plan *plan, Datum *Values, char *Nulls, int tcount) else { qdesc = CreateQueryDesc(queryTree, planTree, - (i < qlen - 1) ? None : SPI); + islastquery ? SPI : None); state = CreateExecutorState(); if (nargs > 0) { @@ -756,15 +754,14 @@ _SPI_execute_plan(_SPI_plan *plan, Datum *Values, char *Nulls, int tcount) } else state->es_param_list_info = NULL; - res = _SPI_pquery(qdesc, state, (i < qlen - 1) ? 0 : tcount); - if (res < 0 || i >= qlen - 1) + res = _SPI_pquery(qdesc, state, islastquery ? tcount : 0); + if (res < 0 || islastquery) return res; CommandCounterIncrement(); } } return res; - } static int @@ -955,12 +952,7 @@ _SPI_end_call(bool procmem) */ _SPI_curid--; - if (_SPI_current->qtlist) /* free _SPI_plan allocations */ - { - free(_SPI_current->qtlist->qtrees); - free(_SPI_current->qtlist); - _SPI_current->qtlist = NULL; - } + _SPI_current->qtlist = NULL; if (procmem) /* switch to the procedure memory context */ { /* but free Executor memory before */ @@ -1000,7 +992,6 @@ _SPI_copy_plan(_SPI_plan *plan, int location) { _SPI_plan *newplan; MemoryContext oldcxt = NULL; - int i; if (location == _SPI_CPLAN_PROCXT) oldcxt = MemoryContextSwitchTo((MemoryContext) @@ -1009,14 +1000,7 @@ _SPI_copy_plan(_SPI_plan *plan, int location) oldcxt = MemoryContextSwitchTo(TopMemoryContext); newplan = (_SPI_plan *) palloc(sizeof(_SPI_plan)); - newplan->qtlist = (QueryTreeList *) palloc(sizeof(QueryTreeList)); - newplan->qtlist->len = plan->qtlist->len; - newplan->qtlist->qtrees = (Query **) palloc(plan->qtlist->len * - sizeof(Query *)); - for (i = 0; i < plan->qtlist->len; i++) - newplan->qtlist->qtrees[i] = (Query *) - copyObject(plan->qtlist->qtrees[i]); - + newplan->qtlist = (List *) copyObject(plan->qtlist); newplan->ptlist = (List *) copyObject(plan->ptlist); newplan->nargs = plan->nargs; if (plan->nargs > 0) diff --git a/src/backend/optimizer/plan/planner.c b/src/backend/optimizer/plan/planner.c index a55d444a8b3114a98949b759dc1436b660347910..d68a44e0c275d5d72600d648dc2d0878ac276b4a 100644 --- a/src/backend/optimizer/plan/planner.c +++ b/src/backend/optimizer/plan/planner.c @@ -7,7 +7,7 @@ * * * IDENTIFICATION - * $Header: /cvsroot/pgsql/src/backend/optimizer/plan/planner.c,v 1.51 1999/05/12 15:01:37 wieck Exp $ + * $Header: /cvsroot/pgsql/src/backend/optimizer/plan/planner.c,v 1.52 1999/05/13 07:28:32 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -671,7 +671,7 @@ make_sortplan(List *tlist, List *sortcls, Plan *plannode) * XXX Why is this function in this module? */ void -pg_checkretval(Oid rettype, QueryTreeList *queryTreeList) +pg_checkretval(Oid rettype, List *queryTreeList) { Query *parse; List *tlist; @@ -686,7 +686,7 @@ pg_checkretval(Oid rettype, QueryTreeList *queryTreeList) int i; /* find the final query */ - parse = queryTreeList->qtrees[queryTreeList->len - 1]; + parse = (Query *) nth(length(queryTreeList)-1, queryTreeList); /* * test 1: if the last query is a utility invocation, then there had diff --git a/src/backend/parser/analyze.c b/src/backend/parser/analyze.c index 2384c70c9f49da727d65cdf356237fffce615ea5..98c5748868432d17fc231a8569940be2e843430f 100644 --- a/src/backend/parser/analyze.c +++ b/src/backend/parser/analyze.c @@ -5,7 +5,7 @@ * * Copyright (c) 1994, Regents of the University of California * - * $Id: analyze.c,v 1.102 1999/05/12 07:17:18 thomas Exp $ + * $Id: analyze.c,v 1.103 1999/05/13 07:28:34 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -59,17 +59,12 @@ List *extras_after = NIL; * all transformed to Query while the rest stays the same. * */ -QueryTreeList * +List * parse_analyze(List *pl, ParseState *parentParseState) { - QueryTreeList *result; + List *result = NIL; ParseState *pstate; Query *parsetree; - int i = 0; - - result = malloc(sizeof(QueryTreeList)); - result->len = length(pl); - result->qtrees = (Query **) malloc(result->len * sizeof(Query *)); while (pl != NIL) { @@ -78,35 +73,25 @@ parse_analyze(List *pl, ParseState *parentParseState) if (pstate->p_target_relation != NULL) heap_close(pstate->p_target_relation); - if (extras_before != NIL) + while (extras_before != NIL) { - result->len += length(extras_before); - result->qtrees = (Query **) realloc(result->qtrees, result->len * sizeof(Query *)); - while (extras_before != NIL) - { - result->qtrees[i++] = transformStmt(pstate, lfirst(extras_before)); - if (pstate->p_target_relation != NULL) - heap_close(pstate->p_target_relation); - extras_before = lnext(extras_before); - } + result = lappend(result, + transformStmt(pstate, lfirst(extras_before))); + if (pstate->p_target_relation != NULL) + heap_close(pstate->p_target_relation); + extras_before = lnext(extras_before); } - extras_before = NIL; - result->qtrees[i++] = parsetree; + result = lappend(result, parsetree); - if (extras_after != NIL) + while (extras_after != NIL) { - result->len += length(extras_after); - result->qtrees = (Query **) realloc(result->qtrees, result->len * sizeof(Query *)); - while (extras_after != NIL) - { - result->qtrees[i++] = transformStmt(pstate, lfirst(extras_after)); - if (pstate->p_target_relation != NULL) - heap_close(pstate->p_target_relation); - extras_after = lnext(extras_after); - } + result = lappend(result, + transformStmt(pstate, lfirst(extras_after))); + if (pstate->p_target_relation != NULL) + heap_close(pstate->p_target_relation); + extras_after = lnext(extras_after); } - extras_after = NIL; pl = lnext(pl); pfree(pstate); diff --git a/src/backend/parser/parse_clause.c b/src/backend/parser/parse_clause.c index 61359e3452a68a0bc3240a415c6bf671283b489d..ceabc549a3d903359c142db22aca710fe561b23e 100644 --- a/src/backend/parser/parse_clause.c +++ b/src/backend/parser/parse_clause.c @@ -7,7 +7,7 @@ * * * IDENTIFICATION - * $Header: /cvsroot/pgsql/src/backend/parser/parse_clause.c,v 1.30 1999/05/12 15:01:50 wieck Exp $ + * $Header: /cvsroot/pgsql/src/backend/parser/parse_clause.c,v 1.31 1999/05/13 07:28:36 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -752,23 +752,24 @@ List * transformUnionClause(List *unionClause, List *targetlist) { List *union_list = NIL; - QueryTreeList *qlist; - int i; + List *qlist, + *qlist_item; if (unionClause) { /* recursion */ qlist = parse_analyze(unionClause, NULL); - for (i = 0; i < qlist->len; i++) + foreach (qlist_item, qlist) { + Query *query = (Query *) lfirst(qlist_item); List *prev_target = targetlist; List *next_target; - if (length(targetlist) != length(qlist->qtrees[i]->targetList)) + if (length(targetlist) != length(query->targetList)) elog(ERROR, "Each UNION clause must have the same number of columns"); - foreach(next_target, qlist->qtrees[i]->targetList) + foreach(next_target, query->targetList) { Oid itype; Oid otype; @@ -819,7 +820,7 @@ transformUnionClause(List *unionClause, List *targetlist) } prev_target = lnext(prev_target); } - union_list = lappend(union_list, qlist->qtrees[i]); + union_list = lappend(union_list, query); } return union_list; } diff --git a/src/backend/parser/parse_expr.c b/src/backend/parser/parse_expr.c index 24b1e1b91d2b25bbcc92fa38e0f052ca717ec23c..91bba7fc2770121505113bee2bf92f1729c11502 100644 --- a/src/backend/parser/parse_expr.c +++ b/src/backend/parser/parse_expr.c @@ -7,7 +7,7 @@ * * * IDENTIFICATION - * $Header: /cvsroot/pgsql/src/backend/parser/parse_expr.c,v 1.44 1999/05/12 07:14:24 thomas Exp $ + * $Header: /cvsroot/pgsql/src/backend/parser/parse_expr.c,v 1.45 1999/05/13 07:28:38 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -274,16 +274,19 @@ transformExpr(ParseState *pstate, Node *expr, int precedence) case T_SubLink: { SubLink *sublink = (SubLink *) expr; - QueryTreeList *qtree; + List *qtrees; + Query *qtree; List *llist; pstate->p_hasSubLinks = true; - qtree = parse_analyze(lcons(sublink->subselect, NIL), pstate); - if (qtree->len != 1 || - qtree->qtrees[0]->commandType != CMD_SELECT || - qtree->qtrees[0]->resultRelation != 0) + qtrees = parse_analyze(lcons(sublink->subselect, NIL), pstate); + if (length(qtrees) != 1) elog(ERROR, "parser: bad query in subselect"); - sublink->subselect = (Node *) qtree->qtrees[0]; + qtree = (Query *) lfirst(qtrees); + if (qtree->commandType != CMD_SELECT || + qtree->resultRelation != 0) + elog(ERROR, "parser: bad query in subselect"); + sublink->subselect = (Node *) qtree; if (sublink->subLinkType != EXISTS_SUBLINK) { diff --git a/src/backend/parser/parser.c b/src/backend/parser/parser.c index 5361be4ca19ca1ed64f41d33ed495be803dd442d..b1059936413dde7e231c14c81a858eefe21c2daa 100644 --- a/src/backend/parser/parser.c +++ b/src/backend/parser/parser.c @@ -6,7 +6,7 @@ * * * IDENTIFICATION - * $Header: /cvsroot/pgsql/src/backend/parser/parser.c,v 1.37 1999/02/13 23:17:10 momjian Exp $ + * $Header: /cvsroot/pgsql/src/backend/parser/parser.c,v 1.38 1999/05/13 07:28:39 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -20,34 +20,32 @@ #include "parser/parse_node.h" #include "parser/parser.h" +#if defined(FLEX_SCANNER) +extern void DeleteBuffer(void); +#endif /* FLEX_SCANNER */ + char *parseString; /* the char* which holds the string to be * parsed */ -List *parsetree = NIL; +List *parsetree; /* result of parsing is left here */ #ifdef SETS_FIXED static void fixupsets(); static void define_sets(); - #endif + /* * parser-- returns a list of parse trees - * - * CALLER is responsible for free'ing the list returned */ -QueryTreeList * +List * parser(char *str, Oid *typev, int nargs) { - QueryTreeList *queryList; + List *queryList; int yyresult; -#if defined(FLEX_SCANNER) - extern void DeleteBuffer(void); - -#endif /* FLEX_SCANNER */ - init_io(); parseString = pstrdup(str); + parsetree = NIL; /* in case parser forgets to set it */ parser_init(typev, nargs); yyresult = yyparse(); @@ -59,7 +57,7 @@ parser(char *str, Oid *typev, int nargs) clearerr(stdin); if (yyresult) /* error */ - return (QueryTreeList *) NULL; + return (List *) NULL; queryList = parse_analyze(parsetree, NULL); diff --git a/src/backend/rewrite/rewriteHandler.c b/src/backend/rewrite/rewriteHandler.c index c5503a6f0b18c765f69b1a016032e7dd38eda471..a5300e5672a5e835bbd03c81efd26be661d9f7fc 100644 --- a/src/backend/rewrite/rewriteHandler.c +++ b/src/backend/rewrite/rewriteHandler.c @@ -6,7 +6,7 @@ * * * IDENTIFICATION - * $Header: /cvsroot/pgsql/src/backend/rewrite/rewriteHandler.c,v 1.40 1999/05/12 17:04:47 wieck Exp $ + * $Header: /cvsroot/pgsql/src/backend/rewrite/rewriteHandler.c,v 1.41 1999/05/13 07:28:41 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -3107,25 +3107,25 @@ void create_list(Node *ptr, List **intersect_list) * instead. */ Node *intersect_tree_analyze(Node *tree, Node *first_select, Node *parsetree) { - Node *result = (Node *)NIL; - List *arg; - - if(IsA(tree, SelectStmt)) + Node *result = (Node *) NIL; + List *arg; + + if (IsA(tree, SelectStmt)) { - QueryTreeList *qtree; - - /* If we get to the tree given in first_select return - * parsetree instead of performing parse_analyze() */ - if(tree == first_select){ - result = parsetree; - } - else { - /* transform the 'raw' nodes to 'cooked' Query nodes */ - qtree = parse_analyze(lcons(tree, NIL), NULL); - result = (Node *)qtree->qtrees[0]; - } - + /* If we get to the tree given in first_select return + * parsetree instead of performing parse_analyze() */ + if (tree == first_select) + { + result = parsetree; + } + else + { + /* transform the 'raw' nodes to 'cooked' Query nodes */ + List *qtree = parse_analyze(lcons(tree, NIL), NULL); + result = (Node *) lfirst(qtree); + } } + if(IsA(tree,Expr)) { /* Call recursively for every argument of the node */ diff --git a/src/backend/tcop/postgres.c b/src/backend/tcop/postgres.c index 0a1a45b4dbf7348875c6fd9de387cd97bea0e259..53f8f9186978d95e291058e228003ed808a99d98 100644 --- a/src/backend/tcop/postgres.c +++ b/src/backend/tcop/postgres.c @@ -7,7 +7,7 @@ * * * IDENTIFICATION - * $Header: /cvsroot/pgsql/src/backend/tcop/postgres.c,v 1.112 1999/05/11 09:06:31 wieck Exp $ + * $Header: /cvsroot/pgsql/src/backend/tcop/postgres.c,v 1.113 1999/05/13 07:28:46 tgl Exp $ * * NOTES * this is the "main" module of the postgres backend and @@ -389,19 +389,17 @@ List * pg_parse_and_plan(char *query_string, /* string to execute */ Oid *typev, /* argument types */ int nargs, /* number of arguments */ - QueryTreeList **queryListP, /* pointer to the parse - * trees */ + List **queryListP, /* returned pointer to the parse trees */ CommandDest dest, /* where results should go */ bool aclOverride) { - QueryTreeList *querytree_list; - int i; + List *querytree_list = NIL; List *plan_list = NIL; - Plan *plan; - int j; - QueryTreeList *new_list; - List *rewritten = NIL; + List *querytree_list_item; Query *querytree; + Plan *plan; + List *new_list; + List *rewritten; if (DebugPrintQuery) { @@ -461,22 +459,17 @@ pg_parse_and_plan(char *query_string, /* string to execute */ ShowUsage(); } - /* new_list holds the rewritten queries */ - new_list = (QueryTreeList *) malloc(sizeof(QueryTreeList)); - new_list->len = querytree_list->len; - new_list->qtrees = (Query **) malloc(new_list->len * sizeof(Query *)); - /* ---------------- * (2) rewrite the queries, as necessary * - * j counts queries output into new_list; the number of rewritten - * queries can be different from the original number. + * rewritten queries are collected in new_list. Note there may be + * more or fewer than in the original list. * ---------------- */ - j = 0; - for (i = 0; i < querytree_list->len; i++) + new_list = NIL; + foreach (querytree_list_item, querytree_list) { - querytree = querytree_list->qtrees[i]; + querytree = (Query *) lfirst(querytree_list_item); if (DebugPrintParse || DebugPPrintParse) { @@ -489,46 +482,19 @@ pg_parse_and_plan(char *query_string, /* string to execute */ } } - /* don't rewrite utilites, just dump 'em into new_list */ if (querytree->commandType == CMD_UTILITY) { - new_list->qtrees[j++] = querytree; - continue; + /* don't rewrite utilities, just dump 'em into new_list */ + new_list = lappend(new_list, querytree); } - - /* rewrite regular queries */ - rewritten = QueryRewrite(querytree); - - if (rewritten != NIL) + else { - int len, - k; - - len = length(rewritten); - if (len == 1) - new_list->qtrees[j++] = (Query *) lfirst(rewritten); - else - { - /* rewritten queries are longer than original query */ - /* grow the new_list to accommodate */ - new_list->len += len - 1; /* - 1 because originally - * we allocated one space - * for the query */ - new_list->qtrees = realloc(new_list->qtrees, - new_list->len * sizeof(Query *)); - for (k = 0; k < len; k++) - new_list->qtrees[j++] = (Query *) nth(k, rewritten); - } + /* rewrite regular queries */ + rewritten = QueryRewrite(querytree); + new_list = nconc(new_list, rewritten); } } - /* Update new_list with correct final length */ - new_list->len = j; - - /* we're done with the original lists, free it */ - free(querytree_list->qtrees); - free(querytree_list); - querytree_list = new_list; /* @@ -536,18 +502,18 @@ pg_parse_and_plan(char *query_string, /* string to execute */ */ if (aclOverride) { - for (i = 0; i < querytree_list->len; i++) + foreach (querytree_list_item, querytree_list) { - RangeTblEntry *rte; List *l; - querytree = querytree_list->qtrees[i]; + querytree = (Query *) lfirst(querytree_list_item); + if (querytree->commandType == CMD_UTILITY) continue; foreach(l, querytree->rtable) { - rte = (RangeTblEntry *) lfirst(l); + RangeTblEntry *rte = (RangeTblEntry *) lfirst(l); rte->skipAcl = TRUE; } @@ -559,24 +525,26 @@ pg_parse_and_plan(char *query_string, /* string to execute */ if (DebugPPrintRewrittenParsetree) { TPRINTF(TRACE_PRETTY_REWRITTEN, "after rewriting:"); - for (i = 0; i < querytree_list->len; i++) + foreach (querytree_list_item, querytree_list) { - nodeDisplay(querytree_list->qtrees[i]); + querytree = (Query *) lfirst(querytree_list_item); + nodeDisplay(querytree); printf("\n"); } } else { TPRINTF(TRACE_REWRITTEN, "after rewriting:"); - for (i = 0; i < querytree_list->len; i++) + foreach (querytree_list_item, querytree_list) { - printf("\n%s\n\n", nodeToString(querytree_list->qtrees[i])); + querytree = (Query *) lfirst(querytree_list_item); + printf("\n%s\n\n", nodeToString(querytree)); } } } - for (i = 0; i < querytree_list->len; i++) + foreach (querytree_list_item, querytree_list) { - querytree = querytree_list->qtrees[i]; + querytree = (Query *) lfirst(querytree_list_item); /* * For each query that isn't a utility invocation, generate a @@ -600,11 +568,9 @@ pg_parse_and_plan(char *query_string, /* string to execute */ elog(NOTICE, "(transaction aborted): %s", "queries ignored until END"); - free(querytree_list->qtrees); - free(querytree_list); if (queryListP) - *queryListP = (QueryTreeList *) NULL; - return (List *) NULL; + *queryListP = NIL; + return NIL; } if (ShowPlannerStats) @@ -638,8 +604,6 @@ pg_parse_and_plan(char *query_string, /* string to execute */ } #endif } -#ifdef FUNC_UTIL_PATCH - /* * If the command is an utility append a null plan. This is needed * to keep the plan_list aligned with the querytree_list or the @@ -647,18 +611,6 @@ pg_parse_and_plan(char *query_string, /* string to execute */ */ else plan_list = lappend(plan_list, NULL); -#endif - } - - /* ---------- - * Check if the rewriting had thrown away everything - * ---------- - */ - if (querytree_list->len == 0) - { - free(querytree_list->qtrees); - free(querytree_list); - querytree_list = NULL; } if (queryListP) @@ -702,36 +654,39 @@ pg_exec_query_dest(char *query_string, /* string to execute */ bool aclOverride) /* to give utility commands power * of superusers */ { + List *querytree_list; List *plan_list; - Plan *plan; Query *querytree; - int i, - j; - QueryTreeList *querytree_list; + Plan *plan; + int j; /* plan the queries */ - plan_list = pg_parse_and_plan(query_string, NULL, 0, &querytree_list, dest, aclOverride); + plan_list = pg_parse_and_plan(query_string, NULL, 0, + &querytree_list, dest, aclOverride); + /* if we got a cancel signal whilst planning, quit */ if (QueryCancel) CancelQuery(); - /* pg_parse_and_plan could have failed */ - if (querytree_list == NULL) - return; - - for (i = 0; i < querytree_list->len; i++) - { - querytree = querytree_list->qtrees[i]; + /* OK, do it to it! */ -#ifdef FUNC_UTIL_PATCH + /* NOTE: we do not use "foreach" here because we want to be sure + * the list pointers have been advanced before the query is executed. + * We need to do that because VACUUM has a nasty little habit of doing + * CommitTransactionCommand at startup, and that will release the + * memory holding our parse/plan lists :-(. This needs a better + * solution --- currently, the code will crash if someone submits + * "vacuum; something-else" in a single query string. But memory + * allocation needs redesigned anyway, so this will have to do for now. + */ - /* - * Advance on the plan_list in every case. Now the plan_list has - * the same length of the querytree_list. DZ - 30-8-1996 - */ + while (querytree_list) + { + querytree = (Query *) lfirst(querytree_list); + querytree_list = lnext(querytree_list); plan = (Plan *) lfirst(plan_list); plan_list = lnext(plan_list); -#endif + if (querytree->commandType == CMD_UTILITY) { /* ---------------- @@ -747,19 +702,9 @@ pg_exec_query_dest(char *query_string, /* string to execute */ TPRINTF(TRACE_VERBOSE, "ProcessUtility"); ProcessUtility(querytree->utilityStmt, dest); - } else { -#ifndef FUNC_UTIL_PATCH - - /* - * Moved before the if. DZ - 30-8-1996 - */ - plan = (Plan *) lfirst(plan_list); - plan_list = lnext(plan_list); -#endif - #ifdef INDEXSCAN_PATCH /* @@ -810,12 +755,8 @@ pg_exec_query_dest(char *query_string, /* string to execute */ * visible to subsequent ones. */ - if (querytree_list) - CommandCounterIncrement(); + CommandCounterIncrement(); } - - free(querytree_list->qtrees); - free(querytree_list); } /* -------------------------------- @@ -1544,7 +1485,7 @@ PostgresMain(int argc, char *argv[], int real_argc, char *real_argv[]) if (!IsUnderPostmaster) { puts("\nPOSTGRES backend interactive interface "); - puts("$Revision: 1.112 $ $Date: 1999/05/11 09:06:31 $\n"); + puts("$Revision: 1.113 $ $Date: 1999/05/13 07:28:46 $\n"); } /* ---------------- diff --git a/src/include/executor/spi_priv.h b/src/include/executor/spi_priv.h index 0ed47bf1e1d19fcaf109d67abd3591cc93b4f706..ece8a5a1c74abf256604dc5a88df52c114d05b73 100644 --- a/src/include/executor/spi_priv.h +++ b/src/include/executor/spi_priv.h @@ -3,7 +3,7 @@ * spi.c * Server Programming Interface private declarations * - * $Header: /cvsroot/pgsql/src/include/executor/spi_priv.h,v 1.2 1999/02/13 23:21:29 momjian Exp $ + * $Header: /cvsroot/pgsql/src/include/executor/spi_priv.h,v 1.3 1999/05/13 07:28:58 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -15,7 +15,7 @@ typedef struct { - QueryTreeList *qtlist; /* malloced */ + List *qtlist; uint32 processed; /* by Executor */ SPITupleTable *tuptable; Portal portal; /* portal per procedure */ @@ -25,7 +25,7 @@ typedef struct typedef struct { - QueryTreeList *qtlist; + List *qtlist; List *ptlist; int nargs; Oid *argtypes; diff --git a/src/include/optimizer/planner.h b/src/include/optimizer/planner.h index 12411789683fea3a4b5fd98593d0def362d632c8..6bad60b6ada2c8fe9f7ed5c7c10041f13828811f 100644 --- a/src/include/optimizer/planner.h +++ b/src/include/optimizer/planner.h @@ -6,7 +6,7 @@ * * Copyright (c) 1994, Regents of the University of California * - * $Id: planner.h,v 1.10 1999/02/13 23:21:51 momjian Exp $ + * $Id: planner.h,v 1.11 1999/05/13 07:29:11 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -22,6 +22,6 @@ extern Plan *planner(Query *parse); extern Plan *union_planner(Query *parse); -extern void pg_checkretval(Oid rettype, QueryTreeList *querytree_list); +extern void pg_checkretval(Oid rettype, List *querytree_list); #endif /* PLANNER_H */ diff --git a/src/include/parser/analyze.h b/src/include/parser/analyze.h index 4be7637d744003a04489d19a09e7b47960972b1f..af775c84f896749defa6a55bf84c8c76f1b1a6f0 100644 --- a/src/include/parser/analyze.h +++ b/src/include/parser/analyze.h @@ -5,7 +5,7 @@ * * Copyright (c) 1994, Regents of the University of California * - * $Id: analyze.h,v 1.5 1999/01/18 00:10:11 momjian Exp $ + * $Id: analyze.h,v 1.6 1999/05/13 07:29:17 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -14,7 +14,7 @@ #include <parser/parse_node.h> -extern QueryTreeList *parse_analyze(List *pl, ParseState *parentParseState); +extern List *parse_analyze(List *pl, ParseState *parentParseState); /***S*I***/ extern void create_select_list(Node *ptr, List **select_list, bool *unionall_present); extern Node *A_Expr_to_Expr(Node *ptr, bool *intersect_present); diff --git a/src/include/parser/parse_node.h b/src/include/parser/parse_node.h index 23040b572398751743ac9bf6c0c8715d5fc393e7..9bc4cf2b13bbde2af6b8f2e477a22ccfa260a7d3 100644 --- a/src/include/parser/parse_node.h +++ b/src/include/parser/parse_node.h @@ -5,7 +5,7 @@ * * Copyright (c) 1994, Regents of the University of California * - * $Id: parse_node.h,v 1.11 1998/09/01 04:37:35 momjian Exp $ + * $Id: parse_node.h,v 1.12 1999/05/13 07:29:19 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -19,12 +19,6 @@ #include <parser/parse_type.h> #include <utils/rel.h> -typedef struct QueryTreeList -{ - int len; /* number of queries */ - Query **qtrees; -} QueryTreeList; - /* state information used during parse analysis */ typedef struct ParseState { diff --git a/src/include/parser/parser.h b/src/include/parser/parser.h index 8d13e0288092f01a635f9403745a3c24656c8f92..50b99b48ce6b169253c89048955e71e4944a3fb5 100644 --- a/src/include/parser/parser.h +++ b/src/include/parser/parser.h @@ -6,7 +6,7 @@ * * Copyright (c) 1994, Regents of the University of California * - * $Id: parser.h,v 1.4 1998/09/01 04:37:42 momjian Exp $ + * $Id: parser.h,v 1.5 1999/05/13 07:29:20 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -15,6 +15,6 @@ #include <parser/parse_node.h> -extern QueryTreeList *parser(char *str, Oid *typev, int nargs); +extern List *parser(char *str, Oid *typev, int nargs); #endif /* PARSER_H */ diff --git a/src/include/tcop/tcopprot.h b/src/include/tcop/tcopprot.h index 96da4d56653125da2a494a286465aa2e40fdae0b..41bcaa43f394107fdea092f7bdbb99d396cb4946 100644 --- a/src/include/tcop/tcopprot.h +++ b/src/include/tcop/tcopprot.h @@ -6,7 +6,7 @@ * * Copyright (c) 1994, Regents of the University of California * - * $Id: tcopprot.h,v 1.18 1999/04/20 02:19:55 tgl Exp $ + * $Id: tcopprot.h,v 1.19 1999/05/13 07:29:22 tgl Exp $ * * OLD COMMENTS * This file was created so that other c files could get the two @@ -41,8 +41,8 @@ extern bool InError; #ifndef BOOTSTRAP_INCLUDE extern List *pg_parse_and_plan(char *query_string, Oid *typev, int nargs, - QueryTreeList **queryListP, CommandDest dest, - bool aclOverride); + List **queryListP, CommandDest dest, + bool aclOverride); extern void pg_exec_query(char *query_string); extern void pg_exec_query_acl_override(char *query_string); extern void