Skip to content

Commit c7898fc

Browse files
committed
[PGPRO-7614] Fix error caused by changing ATX level of package state at sub-transaction commit
Tags: pg_variables, atx
1 parent 2b5fd99 commit c7898fc

File tree

4 files changed

+65
-5
lines changed

4 files changed

+65
-5
lines changed

expected/pg_variables_atx_pkg.out

+24
Original file line numberDiff line numberDiff line change
@@ -406,6 +406,30 @@ BEGIN;
406406

407407
COMMIT;
408408
ROLLBACK;
409+
--
410+
--
411+
-- Test for case: pgv_set() created a regular variable and package with
412+
-- (atxlevel=1, level=1). ROLLBACK changes this level to (atxlevel=0, level=0).
413+
-- But ROLLBACK shouldn't change atxlevel in case rollback of sub-transaction.
414+
--
415+
BEGIN;
416+
BEGIN AUTONOMOUS;
417+
SAVEPOINT sp1;
418+
SELECT pgv_set('vars1', 'int1', 0);
419+
pgv_set
420+
---------
421+
422+
(1 row)
423+
424+
ROLLBACK TO sp1;
425+
COMMIT;
426+
ROLLBACK;
427+
SELECT pgv_remove('vars1', 'int1');
428+
pgv_remove
429+
------------
430+
431+
(1 row)
432+
409433
SELECT pgv_free();
410434
pgv_free
411435
----------

expected/pg_variables_atx_pkg_1.out

+22
Original file line numberDiff line numberDiff line change
@@ -446,6 +446,28 @@ LINE 1: BEGIN AUTONOMOUS;
446446
WARNING: there is no transaction in progress
447447
ROLLBACK;
448448
WARNING: there is no transaction in progress
449+
--
450+
--
451+
-- Test for case: pgv_set() created a regular variable and package with
452+
-- (atxlevel=1, level=1). ROLLBACK changes this level to (atxlevel=0, level=0).
453+
-- But ROLLBACK shouldn't change atxlevel in case rollback of sub-transaction.
454+
--
455+
BEGIN;
456+
BEGIN AUTONOMOUS;
457+
ERROR: syntax error at or near "AUTONOMOUS"
458+
LINE 1: BEGIN AUTONOMOUS;
459+
^
460+
SAVEPOINT sp1;
461+
ERROR: current transaction is aborted, commands ignored until end of transaction block
462+
SELECT pgv_set('vars1', 'int1', 0);
463+
ERROR: current transaction is aborted, commands ignored until end of transaction block
464+
ROLLBACK TO sp1;
465+
ERROR: savepoint "sp1" does not exist
466+
COMMIT;
467+
ROLLBACK;
468+
WARNING: there is no transaction in progress
469+
SELECT pgv_remove('vars1', 'int1');
470+
ERROR: unrecognized package "vars1"
449471
SELECT pgv_free();
450472
pgv_free
451473
----------

pg_variables.c

+5-5
Original file line numberDiff line numberDiff line change
@@ -65,7 +65,7 @@ static void resetVariablesCache(void);
6565
/* Functions to work with transactional objects */
6666
static void createSavepoint(TransObject *object, TransObjectType type);
6767
static void releaseSavepoint(TransObject *object, TransObjectType type, bool sub);
68-
static void rollbackSavepoint(TransObject *object, TransObjectType type);
68+
static void rollbackSavepoint(TransObject *object, TransObjectType type, bool sub);
6969

7070
static void copyValue(VarState *src, VarState *dest, Variable *destVar);
7171
static void freeValue(VarState *varstate, bool is_record);
@@ -2329,7 +2329,7 @@ numOfRegVars(Package *package)
23292329
* Rollback object to its previous state
23302330
*/
23312331
static void
2332-
rollbackSavepoint(TransObject *object, TransObjectType type)
2332+
rollbackSavepoint(TransObject *object, TransObjectType type, bool sub)
23332333
{
23342334
TransState *state;
23352335

@@ -2359,9 +2359,9 @@ rollbackSavepoint(TransObject *object, TransObjectType type)
23592359
* as 'object has been changed in upper level' because in this
23602360
* case we will remove state in releaseSavepoint() but this
23612361
* state may be used pgvRestoreContext(). So atxlevel should
2362-
* be 0.
2362+
* be 0 in case rollback of autonomous transaction.
23632363
*/
2364-
GetActualState(object)->levels.atxlevel = 0;
2364+
GetActualState(object)->levels.atxlevel = sub ? getNestLevelATX() : 0;
23652365
#endif
23662366
GetActualState(object)->levels.level = GetCurrentTransactionNestLevel() - 1;
23672367
if (!dlist_is_empty(changesStack))
@@ -2677,7 +2677,7 @@ applyAction(Action action, TransObjectType type, dlist_head *list, bool sub)
26772677
switch (action)
26782678
{
26792679
case ROLLBACK_TO_SAVEPOINT:
2680-
rollbackSavepoint(object, type);
2680+
rollbackSavepoint(object, type, sub);
26812681
break;
26822682
case RELEASE_SAVEPOINT:
26832683

sql/pg_variables_atx_pkg.sql

+14
Original file line numberDiff line numberDiff line change
@@ -199,5 +199,19 @@ BEGIN;
199199
SELECT pgv_set('vars', 'int1', 2, true);
200200
COMMIT;
201201
ROLLBACK;
202+
--
203+
--
204+
-- Test for case: pgv_set() created a regular variable and package with
205+
-- (atxlevel=1, level=1). ROLLBACK changes this level to (atxlevel=0, level=0).
206+
-- But ROLLBACK shouldn't change atxlevel in case rollback of sub-transaction.
207+
--
208+
BEGIN;
209+
BEGIN AUTONOMOUS;
210+
SAVEPOINT sp1;
211+
SELECT pgv_set('vars1', 'int1', 0);
212+
ROLLBACK TO sp1;
213+
COMMIT;
214+
ROLLBACK;
215+
SELECT pgv_remove('vars1', 'int1');
202216

203217
SELECT pgv_free();

0 commit comments

Comments
 (0)