Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commitaaff0a5

Browse files
committed
Clean up a couple of problems in crosstab_hash's use of a hash table.
The original coding leaked memory (at least 8K per crosstab_hash call)because it allowed the hash table to be allocated as a child ofTopMemoryContext and then never freed it. Fix that by putting thehash table under per_query_ctx, instead. Also get rid of useof a static variable to point to the hash table. Aside from beingugly, that would actively do the wrong thing in the case of re-entrantcalls to crosstab_hash, which are at least theoretically possiblesince it was expecting the static variable to stay valid acrossa SPI_execute call.
1 parentcac82bb commitaaff0a5

File tree

1 file changed

+25
-22
lines changed

1 file changed

+25
-22
lines changed

‎contrib/tablefunc/tablefunc.c‎

Lines changed: 25 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -44,9 +44,9 @@
4444

4545
PG_MODULE_MAGIC;
4646

47-
staticintload_categories_hash(char*cats_sql,MemoryContextper_query_ctx);
47+
staticHTAB*load_categories_hash(char*cats_sql,MemoryContextper_query_ctx);
4848
staticTuplestorestate*get_crosstab_tuplestore(char*sql,
49-
intnum_categories,
49+
HTAB*crosstab_hash,
5050
TupleDesctupdesc,
5151
MemoryContextper_query_ctx);
5252
staticvoidvalidateConnectbyTupleDesc(TupleDesctupdesc,boolshow_branch,boolshow_serial);
@@ -121,40 +121,37 @@ typedef struct
121121
/* sign, 10 digits, '\0' */
122122
#defineINT32_STRLEN12
123123

124-
/* hash table support */
125-
staticHTAB*crosstab_HashTable;
126-
127-
/* The information we cache about loaded procedures */
124+
/* stored info for a crosstab category */
128125
typedefstructcrosstab_cat_desc
129126
{
130-
char*catname;
127+
char*catname;/* full category name */
131128
intattidx;/* zero based */
132129
}crosstab_cat_desc;
133130

134131
#defineMAX_CATNAME_LENNAMEDATALEN
135132
#defineINIT_CATS64
136133

137-
#definecrosstab_HashTableLookup(CATNAME,CATDESC) \
134+
#definecrosstab_HashTableLookup(HASHTAB,CATNAME,CATDESC) \
138135
do { \
139136
crosstab_HashEnt *hentry; char key[MAX_CATNAME_LEN]; \
140137
\
141138
MemSet(key, 0, MAX_CATNAME_LEN); \
142139
snprintf(key, MAX_CATNAME_LEN - 1, "%s", CATNAME); \
143-
hentry = (crosstab_HashEnt*) hash_search(crosstab_HashTable, \
140+
hentry = (crosstab_HashEnt*) hash_search(HASHTAB, \
144141
key, HASH_FIND, NULL); \
145142
if (hentry) \
146143
CATDESC = hentry->catdesc; \
147144
else \
148145
CATDESC = NULL; \
149146
} while(0)
150147

151-
#definecrosstab_HashTableInsert(CATDESC) \
148+
#definecrosstab_HashTableInsert(HASHTAB,CATDESC) \
152149
do { \
153150
crosstab_HashEnt *hentry; bool found; char key[MAX_CATNAME_LEN]; \
154151
\
155152
MemSet(key, 0, MAX_CATNAME_LEN); \
156153
snprintf(key, MAX_CATNAME_LEN - 1, "%s", CATDESC->catname); \
157-
hentry = (crosstab_HashEnt*) hash_search(crosstab_HashTable, \
154+
hentry = (crosstab_HashEnt*) hash_search(HASHTAB, \
158155
key, HASH_ENTER, &found); \
159156
if (found) \
160157
ereport(ERROR, \
@@ -704,7 +701,7 @@ crosstab_hash(PG_FUNCTION_ARGS)
704701
TupleDesctupdesc;
705702
MemoryContextper_query_ctx;
706703
MemoryContextoldcontext;
707-
intnum_categories;
704+
HTAB*crosstab_hash;
708705

709706
/* check to see if caller supports us returning a tuplestore */
710707
if (rsinfo==NULL|| !IsA(rsinfo,ReturnSetInfo))
@@ -737,14 +734,14 @@ crosstab_hash(PG_FUNCTION_ARGS)
737734
"crosstab function are not compatible")));
738735

739736
/* load up the categories hash table */
740-
num_categories=load_categories_hash(cats_sql,per_query_ctx);
737+
crosstab_hash=load_categories_hash(cats_sql,per_query_ctx);
741738

742739
/* let the caller know we're sending back a tuplestore */
743740
rsinfo->returnMode=SFRM_Materialize;
744741

745742
/* now go build it */
746743
rsinfo->setResult=get_crosstab_tuplestore(sql,
747-
num_categories,
744+
crosstab_hash,
748745
tupdesc,
749746
per_query_ctx);
750747

@@ -764,24 +761,29 @@ crosstab_hash(PG_FUNCTION_ARGS)
764761
/*
765762
* load up the categories hash table
766763
*/
767-
staticint
764+
staticHTAB*
768765
load_categories_hash(char*cats_sql,MemoryContextper_query_ctx)
769766
{
767+
HTAB*crosstab_hash;
770768
HASHCTLctl;
771769
intret;
772770
intproc;
773771
MemoryContextSPIcontext;
774-
intnum_categories=0;
775772

776773
/* initialize the category hash table */
774+
MemSet(&ctl,0,sizeof(ctl));
777775
ctl.keysize=MAX_CATNAME_LEN;
778776
ctl.entrysize=sizeof(crosstab_HashEnt);
777+
ctl.hcxt=per_query_ctx;
779778

780779
/*
781780
* use INIT_CATS, defined above as a guess of how many hash table entries
782781
* to create, initially
783782
*/
784-
crosstab_HashTable=hash_create("crosstab hash",INIT_CATS,&ctl,HASH_ELEM);
783+
crosstab_hash=hash_create("crosstab hash",
784+
INIT_CATS,
785+
&ctl,
786+
HASH_ELEM |HASH_CONTEXT);
785787

786788
/* Connect to SPI manager */
787789
if ((ret=SPI_connect())<0)
@@ -790,7 +792,7 @@ load_categories_hash(char *cats_sql, MemoryContext per_query_ctx)
790792

791793
/* Retrieve the category name rows */
792794
ret=SPI_execute(cats_sql, true,0);
793-
num_categories=proc=SPI_processed;
795+
proc=SPI_processed;
794796

795797
/* Check for qualifying tuples */
796798
if ((ret==SPI_OK_SELECT)&& (proc>0))
@@ -828,7 +830,7 @@ load_categories_hash(char *cats_sql, MemoryContext per_query_ctx)
828830
catdesc->attidx=i;
829831

830832
/* Add the proc description block to the hashtable */
831-
crosstab_HashTableInsert(catdesc);
833+
crosstab_HashTableInsert(crosstab_hash,catdesc);
832834

833835
MemoryContextSwitchTo(SPIcontext);
834836
}
@@ -838,19 +840,20 @@ load_categories_hash(char *cats_sql, MemoryContext per_query_ctx)
838840
/* internal error */
839841
elog(ERROR,"load_categories_hash: SPI_finish() failed");
840842

841-
returnnum_categories;
843+
returncrosstab_hash;
842844
}
843845

844846
/*
845847
* create and populate the crosstab tuplestore using the provided source query
846848
*/
847849
staticTuplestorestate*
848850
get_crosstab_tuplestore(char*sql,
849-
intnum_categories,
851+
HTAB*crosstab_hash,
850852
TupleDesctupdesc,
851853
MemoryContextper_query_ctx)
852854
{
853855
Tuplestorestate*tupstore;
856+
intnum_categories=hash_get_num_entries(crosstab_hash);
854857
AttInMetadata*attinmeta=TupleDescGetAttInMetadata(tupdesc);
855858
char**values;
856859
HeapTupletuple;
@@ -978,7 +981,7 @@ get_crosstab_tuplestore(char *sql,
978981

979982
if (catname!=NULL)
980983
{
981-
crosstab_HashTableLookup(catname,catdesc);
984+
crosstab_HashTableLookup(crosstab_hash,catname,catdesc);
982985

983986
if (catdesc)
984987
values[catdesc->attidx+ncols-2]=

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp