Location via proxy:   [ UP ]  
[Report a bug]   [Manage cookies]                
Skip to content

Commit 507a0a2

Browse files
committed
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.
1 parent f806421 commit 507a0a2

File tree

18 files changed

+192
-288
lines changed

18 files changed

+192
-288
lines changed

doc/src/sgml/arch-dev.sgml

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -3758,7 +3758,7 @@ $\ldots$/src/backend/tcop/postgres.c}.
37583758
List *
37593759
pg_parse_and_plan(char *query_string, Oid *typev,
37603760
int nargs,
3761-
QueryTreeList **queryListP,
3761+
List **queryListP,
37623762
CommandDest dest)
37633763
{
37643764
.
@@ -4032,7 +4032,7 @@ instead.
40324032

40334033
if(IsA(tree, SelectStmt))
40344034
{
4035-
QueryTreeList *qtree;
4035+
List *qtrees;
40364036

40374037
/* If we get to the tree given in first_select
40384038
* return parsetree instead of performing
@@ -4044,9 +4044,8 @@ instead.
40444044
else
40454045
{
40464046
/* transform the unprocessed Query nodes */
4047-
qtree =
4048-
parse_analyze(lcons(tree, NIL), NULL);
4049-
result = (Node *)qtree->qtrees[0];
4047+
qtrees = parse_analyze(lcons(tree, NIL), NULL);
4048+
result = (Node *) lfirst(qtrees);
40504049
}
40514050
}
40524051
if(IsA(tree,Expr))

src/backend/catalog/heap.c

Lines changed: 11 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
*
88
*
99
* IDENTIFICATION
10-
* $Header: /cvsroot/pgsql/src/backend/catalog/heap.c,v 1.79 1999/05/10 04:02:03 momjian Exp $
10+
* $Header: /cvsroot/pgsql/src/backend/catalog/heap.c,v 1.80 1999/05/13 07:28:26 tgl Exp $
1111
*
1212
*
1313
* INTERFACE ROUTINES
@@ -1498,9 +1498,9 @@ StoreAttrDefault(Relation rel, AttrDefault *attrdef)
14981498
char str[MAX_PARSE_BUFFER];
14991499
char cast[2 * NAMEDATALEN] = {0};
15001500
Form_pg_attribute atp = rel->rd_att->attrs[attrdef->adnum - 1];
1501-
QueryTreeList *queryTree_list;
1502-
Query *query;
1501+
List *queryTree_list;
15031502
List *planTree_list;
1503+
Query *query;
15041504
TargetEntry *te;
15051505
Resdom *resdom;
15061506
Node *expr;
@@ -1522,9 +1522,10 @@ start:;
15221522
"select %s%s from \"%.*s\"", attrdef->adsrc, cast,
15231523
NAMEDATALEN, rel->rd_rel->relname.data);
15241524
setheapoverride(true);
1525-
planTree_list = (List *) pg_parse_and_plan(str, NULL, 0, &queryTree_list, None, FALSE);
1525+
planTree_list = pg_parse_and_plan(str, NULL, 0,
1526+
&queryTree_list, None, FALSE);
15261527
setheapoverride(false);
1527-
query = (Query *) (queryTree_list->qtrees[0]);
1528+
query = (Query *) lfirst(queryTree_list);
15281529

15291530
if (length(query->rtable) > 1 ||
15301531
flatten_tlist(query->targetList) != NIL)
@@ -1582,9 +1583,9 @@ static void
15821583
StoreRelCheck(Relation rel, ConstrCheck *check)
15831584
{
15841585
char str[MAX_PARSE_BUFFER];
1585-
QueryTreeList *queryTree_list;
1586-
Query *query;
1586+
List *queryTree_list;
15871587
List *planTree_list;
1588+
Query *query;
15881589
Plan *plan;
15891590
List *qual;
15901591
char *ccbin;
@@ -1603,9 +1604,10 @@ StoreRelCheck(Relation rel, ConstrCheck *check)
16031604
"select 1 from \"%.*s\" where %s",
16041605
NAMEDATALEN, rel->rd_rel->relname.data, check->ccsrc);
16051606
setheapoverride(true);
1606-
planTree_list = (List *) pg_parse_and_plan(str, NULL, 0, &queryTree_list, None, FALSE);
1607+
planTree_list = pg_parse_and_plan(str, NULL, 0,
1608+
&queryTree_list, None, FALSE);
16071609
setheapoverride(false);
1608-
query = (Query *) (queryTree_list->qtrees[0]);
1610+
query = (Query *) lfirst(queryTree_list);
16091611

16101612
if (length(query->rtable) > 1)
16111613
elog(ERROR, "Only relation '%.*s' can be referenced",

src/backend/catalog/pg_proc.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
*
88
*
99
* IDENTIFICATION
10-
* $Header: /cvsroot/pgsql/src/backend/catalog/pg_proc.c,v 1.27 1999/04/18 02:57:22 tgl Exp $
10+
* $Header: /cvsroot/pgsql/src/backend/catalog/pg_proc.c,v 1.28 1999/05/13 07:28:27 tgl Exp $
1111
*
1212
*-------------------------------------------------------------------------
1313
*/
@@ -67,7 +67,7 @@ ProcedureCreate(char *procedureName,
6767
Oid languageObjectId;
6868
Oid typeObjectId;
6969
List *x;
70-
QueryTreeList *querytree_list;
70+
List *querytree_list;
7171
List *plan_list;
7272
Oid typev[8];
7373
Oid relid;

src/backend/executor/functions.c

Lines changed: 10 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
*
99
*
1010
* IDENTIFICATION
11-
* $Header: /cvsroot/pgsql/src/backend/executor/functions.c,v 1.24 1999/02/13 23:15:20 momjian Exp $
11+
* $Header: /cvsroot/pgsql/src/backend/executor/functions.c,v 1.25 1999/05/13 07:28:29 tgl Exp $
1212
*
1313
*-------------------------------------------------------------------------
1414
*/
@@ -97,26 +97,23 @@ init_execution_state(FunctionCachePtr fcache,
9797
execution_state *newes;
9898
execution_state *nextes;
9999
execution_state *preves;
100-
QueryTreeList *queryTree_list;
101-
int i;
102-
List *planTree_list;
103-
int nargs;
104-
105-
nargs = fcache->nargs;
100+
List *queryTree_list,
101+
*planTree_list,
102+
*qtl_item;
103+
int nargs = fcache->nargs;
106104

107105
newes = (execution_state *) palloc(sizeof(execution_state));
108106
nextes = newes;
109107
preves = (execution_state *) NULL;
110108

109+
planTree_list = pg_parse_and_plan(fcache->src, fcache->argOidVect,
110+
nargs, &queryTree_list, None, FALSE);
111111

112-
planTree_list = (List *)
113-
pg_parse_and_plan(fcache->src, fcache->argOidVect, nargs, &queryTree_list, None, FALSE);
114-
115-
for (i = 0; i < queryTree_list->len; i++)
112+
foreach (qtl_item, queryTree_list)
116113
{
117-
EState *estate;
118-
Query *queryTree = (Query *) (queryTree_list->qtrees[i]);
114+
Query *queryTree = lfirst(qtl_item);
119115
Plan *planTree = lfirst(planTree_list);
116+
EState *estate;
120117

121118
if (!nextes)
122119
nextes = (execution_state *) palloc(sizeof(execution_state));

src/backend/executor/spi.c

Lines changed: 31 additions & 47 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
* spi.c
44
* Server Programming Interface
55
*
6-
* $Id: spi.c,v 1.36 1999/03/30 01:37:23 momjian Exp $
6+
* $Id: spi.c,v 1.37 1999/05/13 07:28:30 tgl Exp $
77
*
88
*-------------------------------------------------------------------------
99
*/
@@ -602,18 +602,18 @@ spi_printtup(HeapTuple tuple, TupleDesc tupdesc, DestReceiver* self)
602602
static int
603603
_SPI_execute(char *src, int tcount, _SPI_plan *plan)
604604
{
605-
QueryTreeList *queryTree_list;
605+
List *queryTree_list;
606606
List *planTree_list;
607+
List *queryTree_list_item;
607608
List *ptlist;
608609
QueryDesc *qdesc;
609610
Query *queryTree;
610611
Plan *planTree;
611612
EState *state;
612-
int qlen;
613613
int nargs = 0;
614614
Oid *argtypes = NULL;
615-
int res;
616-
int i;
615+
int res = 0;
616+
bool islastquery;
617617

618618
/* Increment CommandCounter to see changes made by now */
619619
CommandCounterIncrement();
@@ -628,18 +628,17 @@ _SPI_execute(char *src, int tcount, _SPI_plan *plan)
628628
nargs = plan->nargs;
629629
argtypes = plan->argtypes;
630630
}
631-
ptlist = planTree_list = (List *)
631+
ptlist = planTree_list =
632632
pg_parse_and_plan(src, argtypes, nargs, &queryTree_list, None, FALSE);
633633

634634
_SPI_current->qtlist = queryTree_list;
635635

636-
qlen = queryTree_list->len;
637-
for (i = 0;; i++)
636+
foreach (queryTree_list_item, queryTree_list)
638637
{
639-
queryTree = (Query *) (queryTree_list->qtrees[i]);
638+
queryTree = (Query *) lfirst(queryTree_list_item);
640639
planTree = lfirst(planTree_list);
641-
642640
planTree_list = lnext(planTree_list);
641+
islastquery = (planTree_list == NIL); /* assume lists are same len */
643642

644643
if (queryTree->commandType == CMD_UTILITY)
645644
{
@@ -659,32 +658,32 @@ _SPI_execute(char *src, int tcount, _SPI_plan *plan)
659658
if (plan == NULL)
660659
{
661660
ProcessUtility(queryTree->utilityStmt, None);
662-
if (i < qlen - 1)
661+
if (! islastquery)
663662
CommandCounterIncrement();
664663
else
665664
return res;
666665
}
667-
else if (i >= qlen - 1)
666+
else if (islastquery)
668667
break;
669668
}
670669
else if (plan == NULL)
671670
{
672671
qdesc = CreateQueryDesc(queryTree, planTree,
673-
(i < qlen - 1) ? None : SPI);
672+
islastquery ? SPI : None);
674673
state = CreateExecutorState();
675-
res = _SPI_pquery(qdesc, state, (i < qlen - 1) ? 0 : tcount);
676-
if (res < 0 || i >= qlen - 1)
674+
res = _SPI_pquery(qdesc, state, islastquery ? tcount : 0);
675+
if (res < 0 || islastquery)
677676
return res;
678677
CommandCounterIncrement();
679678
}
680679
else
681680
{
682681
qdesc = CreateQueryDesc(queryTree, planTree,
683-
(i < qlen - 1) ? None : SPI);
684-
res = _SPI_pquery(qdesc, NULL, (i < qlen - 1) ? 0 : tcount);
682+
islastquery ? SPI : None);
683+
res = _SPI_pquery(qdesc, NULL, islastquery ? tcount : 0);
685684
if (res < 0)
686685
return res;
687-
if (i >= qlen - 1)
686+
if (islastquery)
688687
break;
689688
}
690689
}
@@ -693,23 +692,22 @@ _SPI_execute(char *src, int tcount, _SPI_plan *plan)
693692
plan->ptlist = ptlist;
694693

695694
return res;
696-
697695
}
698696

699697
static int
700698
_SPI_execute_plan(_SPI_plan *plan, Datum *Values, char *Nulls, int tcount)
701699
{
702-
QueryTreeList *queryTree_list = plan->qtlist;
700+
List *queryTree_list = plan->qtlist;
703701
List *planTree_list = plan->ptlist;
702+
List *queryTree_list_item;
704703
QueryDesc *qdesc;
705704
Query *queryTree;
706705
Plan *planTree;
707706
EState *state;
708707
int nargs = plan->nargs;
709-
int qlen = queryTree_list->len;
710-
int res;
711-
int i,
712-
k;
708+
int res = 0;
709+
bool islastquery;
710+
int k;
713711

714712
/* Increment CommandCounter to see changes made by now */
715713
CommandCounterIncrement();
@@ -719,25 +717,25 @@ _SPI_execute_plan(_SPI_plan *plan, Datum *Values, char *Nulls, int tcount)
719717
_SPI_current->tuptable = NULL;
720718
_SPI_current->qtlist = NULL;
721719

722-
for (i = 0;; i++)
720+
foreach (queryTree_list_item, queryTree_list)
723721
{
724-
queryTree = (Query *) (queryTree_list->qtrees[i]);
722+
queryTree = (Query *) lfirst(queryTree_list_item);
725723
planTree = lfirst(planTree_list);
726-
727724
planTree_list = lnext(planTree_list);
725+
islastquery = (planTree_list == NIL); /* assume lists are same len */
728726

729727
if (queryTree->commandType == CMD_UTILITY)
730728
{
731729
ProcessUtility(queryTree->utilityStmt, None);
732-
if (i < qlen - 1)
730+
if (! islastquery)
733731
CommandCounterIncrement();
734732
else
735733
return SPI_OK_UTILITY;
736734
}
737735
else
738736
{
739737
qdesc = CreateQueryDesc(queryTree, planTree,
740-
(i < qlen - 1) ? None : SPI);
738+
islastquery ? SPI : None);
741739
state = CreateExecutorState();
742740
if (nargs > 0)
743741
{
@@ -756,15 +754,14 @@ _SPI_execute_plan(_SPI_plan *plan, Datum *Values, char *Nulls, int tcount)
756754
}
757755
else
758756
state->es_param_list_info = NULL;
759-
res = _SPI_pquery(qdesc, state, (i < qlen - 1) ? 0 : tcount);
760-
if (res < 0 || i >= qlen - 1)
757+
res = _SPI_pquery(qdesc, state, islastquery ? tcount : 0);
758+
if (res < 0 || islastquery)
761759
return res;
762760
CommandCounterIncrement();
763761
}
764762
}
765763

766764
return res;
767-
768765
}
769766

770767
static int
@@ -955,12 +952,7 @@ _SPI_end_call(bool procmem)
955952
*/
956953
_SPI_curid--;
957954

958-
if (_SPI_current->qtlist) /* free _SPI_plan allocations */
959-
{
960-
free(_SPI_current->qtlist->qtrees);
961-
free(_SPI_current->qtlist);
962-
_SPI_current->qtlist = NULL;
963-
}
955+
_SPI_current->qtlist = NULL;
964956

965957
if (procmem) /* switch to the procedure memory context */
966958
{ /* but free Executor memory before */
@@ -1000,7 +992,6 @@ _SPI_copy_plan(_SPI_plan *plan, int location)
1000992
{
1001993
_SPI_plan *newplan;
1002994
MemoryContext oldcxt = NULL;
1003-
int i;
1004995

1005996
if (location == _SPI_CPLAN_PROCXT)
1006997
oldcxt = MemoryContextSwitchTo((MemoryContext)
@@ -1009,14 +1000,7 @@ _SPI_copy_plan(_SPI_plan *plan, int location)
10091000
oldcxt = MemoryContextSwitchTo(TopMemoryContext);
10101001

10111002
newplan = (_SPI_plan *) palloc(sizeof(_SPI_plan));
1012-
newplan->qtlist = (QueryTreeList *) palloc(sizeof(QueryTreeList));
1013-
newplan->qtlist->len = plan->qtlist->len;
1014-
newplan->qtlist->qtrees = (Query **) palloc(plan->qtlist->len *
1015-
sizeof(Query *));
1016-
for (i = 0; i < plan->qtlist->len; i++)
1017-
newplan->qtlist->qtrees[i] = (Query *)
1018-
copyObject(plan->qtlist->qtrees[i]);
1019-
1003+
newplan->qtlist = (List *) copyObject(plan->qtlist);
10201004
newplan->ptlist = (List *) copyObject(plan->ptlist);
10211005
newplan->nargs = plan->nargs;
10221006
if (plan->nargs > 0)

src/backend/optimizer/plan/planner.c

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
*
88
*
99
* IDENTIFICATION
10-
* $Header: /cvsroot/pgsql/src/backend/optimizer/plan/planner.c,v 1.51 1999/05/12 15:01:37 wieck Exp $
10+
* $Header: /cvsroot/pgsql/src/backend/optimizer/plan/planner.c,v 1.52 1999/05/13 07:28:32 tgl Exp $
1111
*
1212
*-------------------------------------------------------------------------
1313
*/
@@ -671,7 +671,7 @@ make_sortplan(List *tlist, List *sortcls, Plan *plannode)
671671
* XXX Why is this function in this module?
672672
*/
673673
void
674-
pg_checkretval(Oid rettype, QueryTreeList *queryTreeList)
674+
pg_checkretval(Oid rettype, List *queryTreeList)
675675
{
676676
Query *parse;
677677
List *tlist;
@@ -686,7 +686,7 @@ pg_checkretval(Oid rettype, QueryTreeList *queryTreeList)
686686
int i;
687687

688688
/* find the final query */
689-
parse = queryTreeList->qtrees[queryTreeList->len - 1];
689+
parse = (Query *) nth(length(queryTreeList)-1, queryTreeList);
690690

691691
/*
692692
* test 1: if the last query is a utility invocation, then there had

0 commit comments

Comments
 (0)