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

Commit1f5e597

Browse files
author
Maxim Orlov
committed
Issue#27: Add fix for leaked hash_seq_search for pgv_stats.
1 parentddf4a22 commit1f5e597

File tree

3 files changed

+190
-26
lines changed

3 files changed

+190
-26
lines changed

‎expected/pg_variables_trans.out‎

Lines changed: 97 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3556,3 +3556,100 @@ SELECT pgv_select('test', 'x') LIMIT 1;
35563556

35573557
ROLLBACK TO SAVEPOINT sp1;
35583558
COMMIT;
3559+
---
3560+
--- Test cases for pgv_stats
3561+
---
3562+
SELECT pgv_insert('test1', 'y', ROW (2::float, 1::float), TRUE);
3563+
pgv_insert
3564+
------------
3565+
3566+
(1 row)
3567+
3568+
SELECT pgv_insert('test1', 'x', ROW (2::float, 1::float), TRUE);
3569+
pgv_insert
3570+
------------
3571+
3572+
(1 row)
3573+
3574+
BEGIN;
3575+
DECLARE r1_cur CURSOR FOR SELECT pgv_stats();
3576+
DECLARE r2_cur CURSOR FOR SELECT pgv_stats();
3577+
FETCH 1 in r1_cur;
3578+
pgv_stats
3579+
--------------
3580+
(test,32768)
3581+
(1 row)
3582+
3583+
FETCH 1 in r2_cur;
3584+
pgv_stats
3585+
--------------
3586+
(test,32768)
3587+
(1 row)
3588+
3589+
COMMIT;
3590+
SELECT pgv_insert('test1', 'y', ROW (2::float, 1::float), TRUE);
3591+
ERROR: there is a record in the variable "y" with same key
3592+
BEGIN;
3593+
DECLARE r1_cur CURSOR FOR SELECT pgv_stats();
3594+
DECLARE r2_cur CURSOR FOR SELECT pgv_stats();
3595+
FETCH 1 in r1_cur;
3596+
pgv_stats
3597+
--------------
3598+
(test,32768)
3599+
(1 row)
3600+
3601+
FETCH 1 in r2_cur;
3602+
pgv_stats
3603+
--------------
3604+
(test,32768)
3605+
(1 row)
3606+
3607+
ROLLBACK;
3608+
SELECT pgv_insert('test1', 'y', ROW (2::float, 1::float), FALSE);
3609+
ERROR: variable "y" already created as TRANSACTIONAL
3610+
SELECT pgv_insert('test1', 'y', ROW (2::float, 1::float), FALSE);
3611+
ERROR: variable "y" already created as TRANSACTIONAL
3612+
SELECT pgv_insert('test1', 'x', ROW (2::float, 1::float), FALSE);
3613+
ERROR: variable "x" already created as TRANSACTIONAL
3614+
BEGIN;
3615+
DECLARE r1_cur CURSOR FOR SELECT pgv_stats();
3616+
DECLARE r2_cur CURSOR FOR SELECT pgv_stats();
3617+
FETCH 1 in r1_cur;
3618+
pgv_stats
3619+
--------------
3620+
(test,32768)
3621+
(1 row)
3622+
3623+
FETCH 1 in r2_cur;
3624+
pgv_stats
3625+
--------------
3626+
(test,32768)
3627+
(1 row)
3628+
3629+
COMMIT;
3630+
SELECT pgv_insert('test1', 'y', ROW (2::float, 1::float), FALSE);
3631+
ERROR: variable "y" already created as TRANSACTIONAL
3632+
BEGIN;
3633+
DECLARE r1_cur CURSOR FOR SELECT pgv_stats();
3634+
DECLARE r2_cur CURSOR FOR SELECT pgv_stats();
3635+
FETCH 1 in r1_cur;
3636+
pgv_stats
3637+
--------------
3638+
(test,32768)
3639+
(1 row)
3640+
3641+
FETCH 1 in r2_cur;
3642+
pgv_stats
3643+
--------------
3644+
(test,32768)
3645+
(1 row)
3646+
3647+
ROLLBACK;
3648+
SELECT pgv_insert('test1', 'y', ROW (2::float, 1::float), FALSE);
3649+
ERROR: variable "y" already created as TRANSACTIONAL
3650+
SELECT pgv_free();
3651+
pgv_free
3652+
----------
3653+
3654+
(1 row)
3655+

‎pg_variables.c‎

Lines changed: 48 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -143,8 +143,10 @@ static MemoryContext changesStackContext = NULL;
143143
* TopTransactionContext is handy here, becouse it wount be reset by the time
144144
* pgvTransCallback is called.
145145
*/
146-
staticList*rstats=NIL;
146+
staticList*variables_stats=NIL;
147+
staticList*packages_stats=NIL;
147148

149+
staticvoidfreeStatsLists(booldeep);
148150
/* Returns a lists of packages and variables changed at current subxact level */
149151
#defineget_actual_changes_list() \
150152
( \
@@ -642,7 +644,7 @@ variable_select(PG_FUNCTION_ARGS)
642644
hash_seq_init(rstat,record->rhash);
643645
funcctx->user_fctx=rstat;
644646

645-
rstats=lcons((void*)rstat,rstats);
647+
variables_stats=lcons((void*)rstat,variables_stats);
646648

647649
MemoryContextSwitchTo(oldcontext);
648650
PG_FREE_IF_COPY(package_name,0);
@@ -663,7 +665,7 @@ variable_select(PG_FUNCTION_ARGS)
663665
}
664666
else
665667
{
666-
rstats=list_delete(rstats,rstat);
668+
variables_stats=list_delete(variables_stats,rstat);
667669
pfree(rstat);
668670
SRF_RETURN_DONE(funcctx);
669671
}
@@ -1232,13 +1234,14 @@ get_packages_stats(PG_FUNCTION_ARGS)
12321234
{
12331235
FuncCallContext*funcctx;
12341236
MemoryContextoldcontext;
1235-
HASH_SEQ_STATUS*pstat;
1237+
HASH_SEQ_STATUS*rstat;
12361238
Package*package;
12371239

12381240
if (SRF_IS_FIRSTCALL())
12391241
{
12401242
TupleDesctupdesc;
12411243

1244+
//elog(INFO, " >>> ");
12421245
funcctx=SRF_FIRSTCALL_INIT();
12431246
oldcontext=MemoryContextSwitchTo(funcctx->multi_call_memory_ctx);
12441247

@@ -1257,11 +1260,16 @@ get_packages_stats(PG_FUNCTION_ARGS)
12571260
*/
12581261
if (packagesHash)
12591262
{
1260-
pstat= (HASH_SEQ_STATUS*)palloc0(sizeof(HASH_SEQ_STATUS));
1263+
MemoryContextctx;
1264+
1265+
ctx=MemoryContextSwitchTo(TopTransactionContext);
1266+
rstat= (HASH_SEQ_STATUS*)palloc0(sizeof(HASH_SEQ_STATUS));
12611267
/* Get packages list */
1262-
hash_seq_init(pstat,packagesHash);
1268+
hash_seq_init(rstat,packagesHash);
12631269

1264-
funcctx->user_fctx=pstat;
1270+
funcctx->user_fctx=rstat;
1271+
packages_stats=lcons((void*)rstat,packages_stats);
1272+
MemoryContextSwitchTo(ctx);
12651273
}
12661274
else
12671275
funcctx->user_fctx=NULL;
@@ -1274,9 +1282,9 @@ get_packages_stats(PG_FUNCTION_ARGS)
12741282
SRF_RETURN_DONE(funcctx);
12751283

12761284
/* Get packages list */
1277-
pstat= (HASH_SEQ_STATUS*)funcctx->user_fctx;
1285+
rstat= (HASH_SEQ_STATUS*)funcctx->user_fctx;
12781286

1279-
package= (Package*)hash_seq_search(pstat);
1287+
package= (Package*)hash_seq_search(rstat);
12801288
if (package!=NULL)
12811289
{
12821290
Datumvalues[2];
@@ -1308,7 +1316,8 @@ get_packages_stats(PG_FUNCTION_ARGS)
13081316
}
13091317
else
13101318
{
1311-
pfree(pstat);
1319+
packages_stats=list_delete(packages_stats,rstat);
1320+
pfree(rstat);
13121321
SRF_RETURN_DONE(funcctx);
13131322
}
13141323
}
@@ -2218,16 +2227,7 @@ pgvTransCallback(XactEvent event, void *arg)
22182227
}
22192228

22202229
if (event==XACT_EVENT_PRE_COMMIT||event==XACT_EVENT_ABORT)
2221-
{
2222-
ListCell*cell;
2223-
2224-
foreach(cell,rstats)
2225-
{
2226-
hash_seq_term((HASH_SEQ_STATUS*)lfirst(cell));
2227-
}
2228-
2229-
rstats=NIL;
2230-
}
2230+
freeStatsLists(true);
22312231
}
22322232

22332233
/*
@@ -2241,16 +2241,38 @@ variable_ExecutorEnd(QueryDesc *queryDesc)
22412241
else
22422242
standard_ExecutorEnd(queryDesc);
22432243

2244+
freeStatsLists(false);
2245+
}
2246+
2247+
/*
2248+
* Free hash_seq_search scans
2249+
*/
2250+
void
2251+
freeStatsLists(booldeep)
2252+
{
2253+
ListCell*cell;
2254+
HASH_SEQ_STATUS*status;
2255+
2256+
foreach(cell,variables_stats)
22442257
{
2245-
ListCell*cell;
2258+
status= (HASH_SEQ_STATUS*)lfirst(cell);
2259+
hash_seq_term(status);
22462260

2247-
foreach(cell,rstats)
2248-
{
2249-
hash_seq_term((HASH_SEQ_STATUS*)lfirst(cell));
2250-
}
2261+
if (deep)
2262+
pfree(status);
2263+
}
2264+
2265+
variables_stats=NIL;
22512266

2252-
rstats=NIL;
2267+
foreach(cell,packages_stats)
2268+
{
2269+
status= (HASH_SEQ_STATUS*)lfirst(cell);
2270+
hash_seq_term(status);
2271+
2272+
pfree(status);
22532273
}
2274+
2275+
packages_stats=NIL;
22542276
}
22552277

22562278
/*

‎sql/pg_variables_trans.sql‎

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1030,3 +1030,48 @@ SAVEPOINT sp1;
10301030
SELECT pgv_select('test','x')LIMIT1;
10311031
ROLLBACK TO SAVEPOINT sp1;
10321032
COMMIT;
1033+
1034+
---
1035+
--- Test cases for pgv_stats
1036+
---
1037+
SELECT pgv_insert('test1','y', ROW (2::float,1::float), TRUE);
1038+
SELECT pgv_insert('test1','x', ROW (2::float,1::float), TRUE);
1039+
BEGIN;
1040+
DECLARE r1_cur CURSOR FORSELECT pgv_stats();
1041+
DECLARE r2_cur CURSOR FORSELECT pgv_stats();
1042+
FETCH1in r1_cur;
1043+
FETCH1in r2_cur;
1044+
COMMIT;
1045+
1046+
SELECT pgv_insert('test1','y', ROW (2::float,1::float), TRUE);
1047+
1048+
BEGIN;
1049+
DECLARE r1_cur CURSOR FORSELECT pgv_stats();
1050+
DECLARE r2_cur CURSOR FORSELECT pgv_stats();
1051+
FETCH1in r1_cur;
1052+
FETCH1in r2_cur;
1053+
ROLLBACK;
1054+
1055+
SELECT pgv_insert('test1','y', ROW (2::float,1::float), FALSE);
1056+
1057+
SELECT pgv_insert('test1','y', ROW (2::float,1::float), FALSE);
1058+
SELECT pgv_insert('test1','x', ROW (2::float,1::float), FALSE);
1059+
BEGIN;
1060+
DECLARE r1_cur CURSOR FORSELECT pgv_stats();
1061+
DECLARE r2_cur CURSOR FORSELECT pgv_stats();
1062+
FETCH1in r1_cur;
1063+
FETCH1in r2_cur;
1064+
COMMIT;
1065+
1066+
SELECT pgv_insert('test1','y', ROW (2::float,1::float), FALSE);
1067+
1068+
BEGIN;
1069+
DECLARE r1_cur CURSOR FORSELECT pgv_stats();
1070+
DECLARE r2_cur CURSOR FORSELECT pgv_stats();
1071+
FETCH1in r1_cur;
1072+
FETCH1in r2_cur;
1073+
ROLLBACK;
1074+
1075+
SELECT pgv_insert('test1','y', ROW (2::float,1::float), FALSE);
1076+
1077+
SELECT pgv_free();

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp