diff options
| author | Tom Lane | 1999-05-13 07:29:22 +0000 |
|---|---|---|
| committer | Tom Lane | 1999-05-13 07:29:22 +0000 |
| commit | 507a0a2ab09144f524e3239b7fc201ad1ad1b78e (patch) | |
| tree | 77c434943724f627e3c901f06443f02ae57d467b /src/backend/parser | |
| parent | f80642137cc0d2dbdaea68b8e439de0d50a5c01f (diff) | |
Rip out QueryTreeList structure, root and branch. Querytree
lists are now plain old garden-variety Lists, allocated with palloc,
rather than specialized expansible-array data allocated with malloc.
This substantially simplifies their handling and eliminates several
sources of memory leakage.
Several basic types of erroneous queries (syntax error, attempt to
insert a duplicate key into a unique index) now demonstrably leak
zero bytes per query.
Diffstat (limited to 'src/backend/parser')
| -rw-r--r-- | src/backend/parser/analyze.c | 47 | ||||
| -rw-r--r-- | src/backend/parser/parse_clause.c | 15 | ||||
| -rw-r--r-- | src/backend/parser/parse_expr.c | 17 | ||||
| -rw-r--r-- | src/backend/parser/parser.c | 24 |
4 files changed, 45 insertions, 58 deletions
diff --git a/src/backend/parser/analyze.c b/src/backend/parser/analyze.c index 2384c70c9f4..98c57488684 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 61359e3452a..ceabc549a3d 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 24b1e1b91d2..91bba7fc277 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 5361be4ca19..b1059936413 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); |
