summaryrefslogtreecommitdiff
path: root/src/backend/parser
diff options
context:
space:
mode:
authorTom Lane1999-05-13 07:29:22 +0000
committerTom Lane1999-05-13 07:29:22 +0000
commit507a0a2ab09144f524e3239b7fc201ad1ad1b78e (patch)
tree77c434943724f627e3c901f06443f02ae57d467b /src/backend/parser
parentf80642137cc0d2dbdaea68b8e439de0d50a5c01f (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.c47
-rw-r--r--src/backend/parser/parse_clause.c15
-rw-r--r--src/backend/parser/parse_expr.c17
-rw-r--r--src/backend/parser/parser.c24
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);