Skip to content

Commit 02d5dac

Browse files
committed
[PGPRO-7614] Delete hash_seq_search scans on all ATX levels and before heap
Tags: pg_variables, atx
1 parent a6a399a commit 02d5dac

File tree

4 files changed

+172
-16
lines changed

4 files changed

+172
-16
lines changed

expected/pg_variables_atx_pkg.out

+59-3
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
--
22
-- PGPRO-7614: function pgv_free() inside autonomous transaction
33
--
4-
select pgv_free();
4+
SELECT pgv_free();
55
pgv_free
66
----------
77

@@ -268,7 +268,53 @@ ERROR: unrecognized package "vars"
268268
ROLLBACK;
269269
--
270270
--
271-
-- Do not free hash_seq_search scans of parent transaction.
271+
-- Test for case: do not free hash_seq_search scans of parent transaction
272+
-- at end of the autonomous transaction.
273+
--
274+
BEGIN;
275+
SELECT pgv_insert('test', 'x', row (1::int, 2::int), false);
276+
pgv_insert
277+
------------
278+
279+
(1 row)
280+
281+
SELECT pgv_insert('test', 'x', row (3::int, 4::int), false);
282+
pgv_insert
283+
------------
284+
285+
(1 row)
286+
287+
DECLARE r1_cur CURSOR FOR SELECT pgv_select('test', 'x');
288+
-- (1,2)
289+
FETCH 1 IN r1_cur;
290+
pgv_select
291+
------------
292+
(1,2)
293+
(1 row)
294+
295+
BEGIN AUTONOMOUS;
296+
ROLLBACK;
297+
-- (3,4)
298+
FETCH 1 IN r1_cur;
299+
pgv_select
300+
------------
301+
(3,4)
302+
(1 row)
303+
304+
SELECT pgv_remove('test', 'x');
305+
pgv_remove
306+
------------
307+
308+
(1 row)
309+
310+
-- ERROR: unrecognized package "test"
311+
FETCH 1 IN r1_cur;
312+
ERROR: unrecognized package "test"
313+
ROLLBACK;
314+
--
315+
--
316+
-- Test for case: pgv_free() should free hash_seq_search scans of all
317+
-- (current ATX + parent) transactions.
272318
--
273319
BEGIN;
274320
SELECT pgv_insert('test', 'x', row (1::int, 2::int), false);
@@ -278,16 +324,26 @@ BEGIN;
278324
(1 row)
279325

280326
DECLARE r1_cur CURSOR FOR SELECT pgv_select('test', 'x');
327+
-- (1,2)
281328
FETCH 1 IN r1_cur;
282329
pgv_select
283330
------------
284331
(1,2)
285332
(1 row)
286333

287334
BEGIN AUTONOMOUS;
335+
SELECT pgv_free();
336+
pgv_free
337+
----------
338+
339+
(1 row)
340+
288341
ROLLBACK;
342+
-- ERROR: unrecognized package "test"
343+
FETCH 1 IN r1_cur;
344+
ERROR: unrecognized package "test"
289345
ROLLBACK;
290-
select pgv_free();
346+
SELECT pgv_free();
291347
pgv_free
292348
----------
293349

expected/pg_variables_atx_pkg_1.out

+55-3
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
--
22
-- PGPRO-7614: function pgv_free() inside autonomous transaction
33
--
4-
select pgv_free();
4+
SELECT pgv_free();
55
pgv_free
66
----------
77

@@ -300,7 +300,53 @@ ROLLBACK;
300300
WARNING: there is no transaction in progress
301301
--
302302
--
303-
-- Do not free hash_seq_search scans of parent transaction.
303+
-- Test for case: do not free hash_seq_search scans of parent transaction
304+
-- at end of the autonomous transaction.
305+
--
306+
BEGIN;
307+
SELECT pgv_insert('test', 'x', row (1::int, 2::int), false);
308+
pgv_insert
309+
------------
310+
311+
(1 row)
312+
313+
SELECT pgv_insert('test', 'x', row (3::int, 4::int), false);
314+
pgv_insert
315+
------------
316+
317+
(1 row)
318+
319+
DECLARE r1_cur CURSOR FOR SELECT pgv_select('test', 'x');
320+
-- (1,2)
321+
FETCH 1 IN r1_cur;
322+
pgv_select
323+
------------
324+
(1,2)
325+
(1 row)
326+
327+
BEGIN AUTONOMOUS;
328+
ERROR: syntax error at or near "AUTONOMOUS"
329+
LINE 1: BEGIN AUTONOMOUS;
330+
^
331+
ROLLBACK;
332+
-- (3,4)
333+
FETCH 1 IN r1_cur;
334+
ERROR: cursor "r1_cur" does not exist
335+
SELECT pgv_remove('test', 'x');
336+
pgv_remove
337+
------------
338+
339+
(1 row)
340+
341+
-- ERROR: unrecognized package "test"
342+
FETCH 1 IN r1_cur;
343+
ERROR: cursor "r1_cur" does not exist
344+
ROLLBACK;
345+
WARNING: there is no transaction in progress
346+
--
347+
--
348+
-- Test for case: pgv_free() should free hash_seq_search scans of all
349+
-- (current ATX + parent) transactions.
304350
--
305351
BEGIN;
306352
SELECT pgv_insert('test', 'x', row (1::int, 2::int), false);
@@ -310,6 +356,7 @@ BEGIN;
310356
(1 row)
311357

312358
DECLARE r1_cur CURSOR FOR SELECT pgv_select('test', 'x');
359+
-- (1,2)
313360
FETCH 1 IN r1_cur;
314361
pgv_select
315362
------------
@@ -320,10 +367,15 @@ BEGIN;
320367
ERROR: syntax error at or near "AUTONOMOUS"
321368
LINE 1: BEGIN AUTONOMOUS;
322369
^
370+
SELECT pgv_free();
371+
ERROR: current transaction is aborted, commands ignored until end of transaction block
323372
ROLLBACK;
373+
-- ERROR: unrecognized package "test"
374+
FETCH 1 IN r1_cur;
375+
ERROR: cursor "r1_cur" does not exist
324376
ROLLBACK;
325377
WARNING: there is no transaction in progress
326-
select pgv_free();
378+
SELECT pgv_free();
327379
pgv_free
328380
----------
329381

pg_variables.c

+31-7
Original file line numberDiff line numberDiff line change
@@ -310,7 +310,11 @@ list_remove_if(RemoveIfContext ctx)
310310
*ctx.list = list_delete_cell(*ctx.list, cell, prev);
311311

312312
if (ctx.term)
313+
#ifdef PGPRO_EE
314+
hash_seq_term_all_levels(ctx.getter(entry));
315+
#else
313316
hash_seq_term(ctx.getter(entry));
317+
#endif
314318

315319
pfree(ctx.getter(entry));
316320
pfree(entry);
@@ -342,7 +346,11 @@ list_remove_if(RemoveIfContext ctx)
342346
*ctx.list = foreach_delete_current(*ctx.list, cell);
343347

344348
if (ctx.term)
349+
#ifdef PGPRO_EE
350+
hash_seq_term_all_levels(ctx.getter(entry));
351+
#else
345352
hash_seq_term(ctx.getter(entry));
353+
#endif
346354

347355
pfree(ctx.getter(entry));
348356
pfree(entry);
@@ -1338,12 +1346,17 @@ remove_package(PG_FUNCTION_ARGS)
13381346
package_name = PG_GETARG_TEXT_PP(0);
13391347

13401348
package = getPackage(package_name, true);
1349+
/*
1350+
* Need to remove variables before packages because here calls hash_seq_term()
1351+
* which uses "entry->status->hashp->frozen" but memory context of "hashp"
1352+
* for regular variables can be deleted in removePackageInternal().
1353+
*/
1354+
remove_variables_package(&variables_stats, package);
1355+
13411356
removePackageInternal(package);
13421357

13431358
resetVariablesCache();
13441359

1345-
remove_variables_package(&variables_stats, package);
1346-
13471360
PG_FREE_IF_COPY(package_name, 0);
13481361
PG_RETURN_VOID();
13491362
}
@@ -1430,6 +1443,13 @@ remove_packages(PG_FUNCTION_ARGS)
14301443
if (packagesHash == NULL)
14311444
PG_RETURN_VOID();
14321445

1446+
/*
1447+
* Need to remove variables before packages because here calls hash_seq_term()
1448+
* which uses "entry->status->hashp->frozen" but memory context of "hashp"
1449+
* for regular variables can be deleted in removePackageInternal().
1450+
*/
1451+
remove_variables_all(&variables_stats);
1452+
14331453
/* Get packages list */
14341454
hash_seq_init(&pstat, packagesHash);
14351455
while ((package = (Package *) hash_seq_search(&pstat)) != NULL)
@@ -1438,7 +1458,6 @@ remove_packages(PG_FUNCTION_ARGS)
14381458
}
14391459

14401460
resetVariablesCache();
1441-
remove_variables_all(&variables_stats);
14421461

14431462
PG_RETURN_VOID();
14441463
}
@@ -2201,14 +2220,19 @@ removeObject(TransObject *object, TransObjectType type)
22012220
var->package->varHashRegular;
22022221
}
22032222

2223+
/*
2224+
* Need to remove variables before state because here calls hash_seq_term()
2225+
* which uses "entry->status->hashp->frozen" but memory context of "hashp"
2226+
* for regular variables can be deleted in removeState()->freeValue().
2227+
*/
2228+
/* Remove object from hash table */
2229+
hash_search(hash, object->name, HASH_REMOVE, &found);
2230+
remove_variables_variable(&variables_stats, (Variable*)object);
2231+
22042232
/* Remove all object's states */
22052233
while (!dlist_is_empty(&object->states))
22062234
removeState(object, type, GetActualState(object));
22072235

2208-
/* Remove object from hash table */
2209-
hash_search(hash, object->name, HASH_REMOVE, &found);
2210-
remove_variables_variable(&variables_stats, (Variable *) object);
2211-
22122236
/* Remove package if it became empty */
22132237
if (type == TRANS_VARIABLE && isPackageEmpty(package))
22142238
{

sql/pg_variables_atx_pkg.sql

+27-3
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
--
22
-- PGPRO-7614: function pgv_free() inside autonomous transaction
33
--
4-
select pgv_free();
4+
SELECT pgv_free();
55
--
66
--
77
-- Functions pgv_free() + pgv_get() inside autonomous transaction; package
@@ -133,14 +133,38 @@ BEGIN;
133133
ROLLBACK;
134134
--
135135
--
136-
-- Do not free hash_seq_search scans of parent transaction.
136+
-- Test for case: do not free hash_seq_search scans of parent transaction
137+
-- at end of the autonomous transaction.
137138
--
138139
BEGIN;
139140
SELECT pgv_insert('test', 'x', row (1::int, 2::int), false);
141+
SELECT pgv_insert('test', 'x', row (3::int, 4::int), false);
140142
DECLARE r1_cur CURSOR FOR SELECT pgv_select('test', 'x');
143+
-- (1,2)
141144
FETCH 1 IN r1_cur;
142145
BEGIN AUTONOMOUS;
143146
ROLLBACK;
147+
-- (3,4)
148+
FETCH 1 IN r1_cur;
149+
SELECT pgv_remove('test', 'x');
150+
-- ERROR: unrecognized package "test"
151+
FETCH 1 IN r1_cur;
152+
ROLLBACK;
153+
--
154+
--
155+
-- Test for case: pgv_free() should free hash_seq_search scans of all
156+
-- (current ATX + parent) transactions.
157+
--
158+
BEGIN;
159+
SELECT pgv_insert('test', 'x', row (1::int, 2::int), false);
160+
DECLARE r1_cur CURSOR FOR SELECT pgv_select('test', 'x');
161+
-- (1,2)
162+
FETCH 1 IN r1_cur;
163+
BEGIN AUTONOMOUS;
164+
SELECT pgv_free();
165+
ROLLBACK;
166+
-- ERROR: unrecognized package "test"
167+
FETCH 1 IN r1_cur;
144168
ROLLBACK;
145169

146-
select pgv_free();
170+
SELECT pgv_free();

0 commit comments

Comments
 (0)