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

Lines changed: 24 additions & 0 deletions
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

Lines changed: 22 additions & 0 deletions
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

Lines changed: 5 additions & 5 deletions
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

Lines changed: 14 additions & 0 deletions
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)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy