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

Commitafdef54

Browse files
committed
[PGPRO-7614] Fix crash by using cursor after rollback of cursor creation
Tags: pg_variables
1 parent02d5dac commitafdef54

File tree

4 files changed

+171
-8
lines changed

4 files changed

+171
-8
lines changed

‎expected/pg_variables_trans.out

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3834,3 +3834,51 @@ SELECT pgv_free();
38343834
--
38353835
SELECT pgv_insert('test', 'x5', ROW ((2::int, 1::int)), TRUE);
38363836
ERROR: could not identify a hash function for type record
3837+
--
3838+
-- Test case for PGPRO-7614: crash by using cursor after rollback of cursor
3839+
-- creation.
3840+
--
3841+
BEGIN;
3842+
SELECT pgv_insert('test', 'x', ROW (1::int, 2::int), true);
3843+
pgv_insert
3844+
------------
3845+
3846+
(1 row)
3847+
3848+
DECLARE r1_cur CURSOR FOR SELECT pgv_select('test', 'x');
3849+
SAVEPOINT sp1;
3850+
FETCH 1 in r1_cur;
3851+
pgv_select
3852+
------------
3853+
(1,2)
3854+
(1 row)
3855+
3856+
ROLLBACK TO SAVEPOINT sp1;
3857+
FETCH 1 in r1_cur;
3858+
pgv_select
3859+
------------
3860+
(0 rows)
3861+
3862+
ROLLBACK;
3863+
BEGIN;
3864+
SELECT pgv_insert('test', 'x', ROW (1::int, 2::int), TRUE);
3865+
pgv_insert
3866+
------------
3867+
3868+
(1 row)
3869+
3870+
DECLARE r1_cur CURSOR FOR SELECT pgv_stats();
3871+
SAVEPOINT sp1;
3872+
FETCH 1 in r1_cur;
3873+
pgv_stats
3874+
--------------
3875+
(test,32768)
3876+
(1 row)
3877+
3878+
ROLLBACK TO SAVEPOINT sp1;
3879+
FETCH 1 in r1_cur;
3880+
pgv_stats
3881+
-----------
3882+
(0 rows)
3883+
3884+
ROLLBACK;

‎expected/pg_variables_trans_0.out

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3838,3 +3838,51 @@ SELECT pgv_insert('test', 'x5', ROW ((2::int, 1::int)), TRUE);
38383838

38393839
(1 row)
38403840

3841+
--
3842+
-- Test case for PGPRO-7614: crash by using cursor after rollback of cursor
3843+
-- creation.
3844+
--
3845+
BEGIN;
3846+
SELECT pgv_insert('test', 'x', ROW (1::int, 2::int), true);
3847+
pgv_insert
3848+
------------
3849+
3850+
(1 row)
3851+
3852+
DECLARE r1_cur CURSOR FOR SELECT pgv_select('test', 'x');
3853+
SAVEPOINT sp1;
3854+
FETCH 1 in r1_cur;
3855+
pgv_select
3856+
------------
3857+
(1,2)
3858+
(1 row)
3859+
3860+
ROLLBACK TO SAVEPOINT sp1;
3861+
FETCH 1 in r1_cur;
3862+
pgv_select
3863+
------------
3864+
(0 rows)
3865+
3866+
ROLLBACK;
3867+
BEGIN;
3868+
SELECT pgv_insert('test', 'x', ROW (1::int, 2::int), TRUE);
3869+
pgv_insert
3870+
------------
3871+
3872+
(1 row)
3873+
3874+
DECLARE r1_cur CURSOR FOR SELECT pgv_stats();
3875+
SAVEPOINT sp1;
3876+
FETCH 1 in r1_cur;
3877+
pgv_stats
3878+
--------------
3879+
(test,32768)
3880+
(1 row)
3881+
3882+
ROLLBACK TO SAVEPOINT sp1;
3883+
FETCH 1 in r1_cur;
3884+
pgv_stats
3885+
-----------
3886+
(0 rows)
3887+
3888+
ROLLBACK;

‎pg_variables.c

Lines changed: 53 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -166,12 +166,14 @@ typedef struct tagVariableStatEntry
166166
Variable*variable;
167167
Package*package;
168168
Levelslevels;
169+
void**user_fctx;/* pointer to funcctx->user_fctx */
169170
}VariableStatEntry;
170171

171172
typedefstructtagPackageStatEntry
172173
{
173174
HASH_SEQ_STATUS*status;
174175
Levelslevels;
176+
void**user_fctx;/* pointer to funcctx->user_fctx */
175177
}PackageStatEntry;
176178

177179
#ifdefPGPRO_EE
@@ -268,6 +270,25 @@ PackageStatEntry_status_ptr(void *entry)
268270
return ((PackageStatEntry*)entry)->status;
269271
}
270272

273+
/*
274+
* VariableStatEntry and PackageStatEntry functions for clear function context.
275+
*/
276+
staticvoid
277+
VariableStatEntry_clear_fctx(void*entry)
278+
{
279+
VariableStatEntry*e= (VariableStatEntry*)entry;
280+
if (e->user_fctx)
281+
*e->user_fctx=NULL;
282+
}
283+
284+
staticvoid
285+
PackageStatEntry_clear_fctx(void*entry)
286+
{
287+
PackageStatEntry*e= (PackageStatEntry*)entry;
288+
if (e->user_fctx)
289+
*e->user_fctx=NULL;
290+
}
291+
271292
/*
272293
* Generic remove_if algorithm.
273294
*
@@ -289,6 +310,7 @@ typedef struct tagRemoveIfContext
289310
HASH_SEQ_STATUS*(*getter) (void*);/* status getter */
290311
boolmatch_first;/* return on first match */
291312
boolterm;/* hash_seq_term on match */
313+
void(*clear_fctx) (void*);/* clear function context */
292314
}RemoveIfContext;
293315

294316
staticvoid
@@ -316,6 +338,8 @@ list_remove_if(RemoveIfContext ctx)
316338
hash_seq_term(ctx.getter(entry));
317339
#endif
318340

341+
ctx.clear_fctx(entry);
342+
319343
pfree(ctx.getter(entry));
320344
pfree(entry);
321345

@@ -352,6 +376,8 @@ list_remove_if(RemoveIfContext ctx)
352376
hash_seq_term(ctx.getter(entry));
353377
#endif
354378

379+
ctx.clear_fctx(entry);
380+
355381
pfree(ctx.getter(entry));
356382
pfree(entry);
357383

@@ -375,7 +401,8 @@ remove_variables_status(List **list, HASH_SEQ_STATUS *status)
375401
.eq=VariableStatEntry_status_eq,
376402
.getter=VariableStatEntry_status_ptr,
377403
.match_first= true,
378-
.term= false
404+
.term= false,
405+
.clear_fctx=VariableStatEntry_clear_fctx
379406
};
380407

381408
list_remove_if(ctx);
@@ -398,7 +425,8 @@ remove_variables_variable(List **list, Variable *variable)
398425
.eq=VariableStatEntry_variable_eq,
399426
.getter=VariableStatEntry_status_ptr,
400427
.match_first= false,
401-
.term= true
428+
.term= true,
429+
.clear_fctx=VariableStatEntry_clear_fctx
402430
};
403431

404432
list_remove_if(ctx);
@@ -417,7 +445,8 @@ remove_variables_package(List **list, Package *package)
417445
.eq=VariableStatEntry_package_eq,
418446
.getter=VariableStatEntry_status_ptr,
419447
.match_first= false,
420-
.term= true
448+
.term= true,
449+
.clear_fctx=VariableStatEntry_clear_fctx
421450
};
422451

423452
list_remove_if(ctx);
@@ -436,7 +465,8 @@ remove_variables_level(List **list, Levels *levels)
436465
.eq=VariableStatEntry_level_eq,
437466
.getter=VariableStatEntry_status_ptr,
438467
.match_first= false,
439-
.term= false
468+
.term= false,
469+
.clear_fctx=VariableStatEntry_clear_fctx
440470
};
441471

442472
list_remove_if(ctx);
@@ -455,7 +485,8 @@ remove_variables_all(List **list)
455485
.eq=VariableStatEntry_eq_all,
456486
.getter=VariableStatEntry_status_ptr,
457487
.match_first= false,
458-
.term= true
488+
.term= true,
489+
.clear_fctx=VariableStatEntry_clear_fctx
459490
};
460491

461492
list_remove_if(ctx);
@@ -474,7 +505,8 @@ remove_packages_status(List **list, HASH_SEQ_STATUS *status)
474505
.eq=PackageStatEntry_status_eq,
475506
.getter=PackageStatEntry_status_ptr,
476507
.match_first= true,
477-
.term= false
508+
.term= false,
509+
.clear_fctx=PackageStatEntry_clear_fctx
478510
};
479511

480512
list_remove_if(ctx);
@@ -493,7 +525,8 @@ remove_packages_level(List **list, Levels *levels)
493525
.eq=PackageStatEntry_level_eq,
494526
.getter=PackageStatEntry_status_ptr,
495527
.match_first= false,
496-
.term= true
528+
.term= true,
529+
.clear_fctx=PackageStatEntry_clear_fctx
497530
};
498531

499532
list_remove_if(ctx);
@@ -513,7 +546,8 @@ remove_variables_transactional(List **list)
513546
.eq=VariableStatEntry_is_transactional,
514547
.getter=VariableStatEntry_status_ptr,
515548
.match_first= false,
516-
.term= true
549+
.term= true,
550+
.clear_fctx=VariableStatEntry_clear_fctx
517551
};
518552

519553
list_remove_if(ctx);
@@ -1027,6 +1061,7 @@ variable_select(PG_FUNCTION_ARGS)
10271061
#ifdefPGPRO_EE
10281062
entry->levels.atxlevel=getNestLevelATX();
10291063
#endif
1064+
entry->user_fctx=&funcctx->user_fctx;
10301065
variables_stats=lcons((void*)entry,variables_stats);
10311066

10321067
MemoryContextSwitchTo(oldcontext);
@@ -1036,6 +1071,15 @@ variable_select(PG_FUNCTION_ARGS)
10361071

10371072
funcctx=SRF_PERCALL_SETUP();
10381073

1074+
if (funcctx->user_fctx==NULL)
1075+
{
1076+
/*
1077+
* VariableStatEntry was removed. For example, after call
1078+
* 'ROLLBACK TO SAVEPOINT ...'
1079+
*/
1080+
SRF_RETURN_DONE(funcctx);
1081+
}
1082+
10391083
/* Get next hash record */
10401084
rstat= (HASH_SEQ_STATUS*)funcctx->user_fctx;
10411085
item= (HashRecordEntry*)hash_seq_search(rstat);
@@ -1672,6 +1716,7 @@ get_packages_stats(PG_FUNCTION_ARGS)
16721716
#ifdefPGPRO_EE
16731717
entry->levels.atxlevel=getNestLevelATX();
16741718
#endif
1719+
entry->user_fctx=&funcctx->user_fctx;
16751720
packages_stats=lcons((void*)entry,packages_stats);
16761721
MemoryContextSwitchTo(ctx);
16771722
}

‎sql/pg_variables_trans.sql

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1169,3 +1169,25 @@ SELECT pgv_free();
11691169
-- Test case for issue #38 [PGPRO-4676]
11701170
--
11711171
SELECT pgv_insert('test','x5', ROW ((2::int,1::int)), TRUE);
1172+
1173+
--
1174+
-- Test case for PGPRO-7614: crash by using cursor after rollback of cursor
1175+
-- creation.
1176+
--
1177+
BEGIN;
1178+
SELECT pgv_insert('test','x', ROW (1::int,2::int), true);
1179+
DECLARE r1_cur CURSOR FORSELECT pgv_select('test','x');
1180+
SAVEPOINT sp1;
1181+
FETCH1in r1_cur;
1182+
ROLLBACK TO SAVEPOINT sp1;
1183+
FETCH1in r1_cur;
1184+
ROLLBACK;
1185+
1186+
BEGIN;
1187+
SELECT pgv_insert('test','x', ROW (1::int,2::int), TRUE);
1188+
DECLARE r1_cur CURSOR FORSELECT pgv_stats();
1189+
SAVEPOINT sp1;
1190+
FETCH1in r1_cur;
1191+
ROLLBACK TO SAVEPOINT sp1;
1192+
FETCH1in r1_cur;
1193+
ROLLBACK;

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp