Skip to content

Commit a927929

Browse files
author
Maxim Orlov
committed
Issue #27: Error with transactional pgv_insert/pgv_remove
1 parent 13a77d5 commit a927929

File tree

4 files changed

+176
-3
lines changed

4 files changed

+176
-3
lines changed

expected/pg_variables_trans.out

Lines changed: 111 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2032,3 +2032,114 @@ SELECT pgv_free();
20322032

20332033
(1 row)
20342034

2035+
-- Variables should be insertable after pgv_remove
2036+
BEGIN;
2037+
SELECT pgv_insert('test', 'x', ROW (1::int), TRUE);
2038+
pgv_insert
2039+
------------
2040+
2041+
(1 row)
2042+
2043+
SELECT pgv_remove('test', 'x');
2044+
pgv_remove
2045+
------------
2046+
2047+
(1 row)
2048+
2049+
SELECT pgv_insert('test', 'x', ROW (1::int), TRUE);
2050+
pgv_insert
2051+
------------
2052+
2053+
(1 row)
2054+
2055+
ROLLBACK;
2056+
SELECT * FROM pgv_list() order by package, name;
2057+
package | name | is_transactional
2058+
---------+------+------------------
2059+
(0 rows)
2060+
2061+
BEGIN;
2062+
SELECT pgv_insert('test', 'x', ROW (1::int), TRUE);
2063+
pgv_insert
2064+
------------
2065+
2066+
(1 row)
2067+
2068+
SELECT pgv_remove('test', 'x');
2069+
pgv_remove
2070+
------------
2071+
2072+
(1 row)
2073+
2074+
SELECT pgv_insert('test', 'x', ROW (1::int), TRUE);
2075+
pgv_insert
2076+
------------
2077+
2078+
(1 row)
2079+
2080+
COMMIT;
2081+
SELECT * FROM pgv_list() order by package, name;
2082+
package | name | is_transactional
2083+
---------+------+------------------
2084+
test | x | t
2085+
(1 row)
2086+
2087+
-- Variables should be insertable after pgv_free
2088+
BEGIN;
2089+
SELECT pgv_insert('test', 'y', ROW (1::int), TRUE);
2090+
pgv_insert
2091+
------------
2092+
2093+
(1 row)
2094+
2095+
SELECT pgv_free();
2096+
pgv_free
2097+
----------
2098+
2099+
(1 row)
2100+
2101+
SELECT pgv_insert('test', 'y', ROW (1::int), TRUE);
2102+
pgv_insert
2103+
------------
2104+
2105+
(1 row)
2106+
2107+
ROLLBACK;
2108+
SELECT * FROM pgv_list() order by package, name;
2109+
package | name | is_transactional
2110+
---------+------+------------------
2111+
test | x | t
2112+
(1 row)
2113+
2114+
BEGIN;
2115+
SELECT pgv_insert('test', 'y', ROW (1::int), TRUE);
2116+
pgv_insert
2117+
------------
2118+
2119+
(1 row)
2120+
2121+
SELECT pgv_free();
2122+
pgv_free
2123+
----------
2124+
2125+
(1 row)
2126+
2127+
SELECT pgv_insert('test', 'y', ROW (1::int), TRUE);
2128+
pgv_insert
2129+
------------
2130+
2131+
(1 row)
2132+
2133+
COMMIT;
2134+
SELECT * FROM pgv_list() order by package, name;
2135+
package | name | is_transactional
2136+
---------+------+------------------
2137+
test | y | t
2138+
(1 row)
2139+
2140+
SELECT pgv_free();
2141+
pgv_free
2142+
----------
2143+
2144+
(1 row)
2145+

pg_variables.c

Lines changed: 28 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -403,7 +403,10 @@ variable_insert(PG_FUNCTION_ARGS)
403403
* record type or if last record has different id.
404404
*/
405405
tupdesc = lookup_rowtype_tupdesc(tupType, tupTypmod);
406-
check_attributes(variable, tupdesc);
406+
if (variable->is_deleted)
407+
init_record(record, tupdesc, variable);
408+
else
409+
check_attributes(variable, tupdesc);
407410
}
408411

409412
LastTypeId = tupType;
@@ -901,6 +904,7 @@ remove_variable(PG_FUNCTION_ARGS)
901904
createSavepoint(transObject, TRANS_VARIABLE);
902905
addToChangesStack(transObject, TRANS_VARIABLE);
903906
}
907+
variable->is_deleted = true;
904908
GetActualState(variable)->is_valid = false;
905909
GetPackState(package)->trans_var_num--;
906910
if ((GetPackState(package)->trans_var_num + numOfRegVars(package)) == 0)
@@ -909,7 +913,7 @@ remove_variable(PG_FUNCTION_ARGS)
909913
else
910914
removeObject(&variable->transObject, TRANS_VARIABLE);
911915

912-
resetVariablesCache(false);
916+
resetVariablesCache(true);
913917

914918
PG_FREE_IF_COPY(package_name, 0);
915919
PG_FREE_IF_COPY(var_name, 1);
@@ -945,7 +949,27 @@ remove_package(PG_FUNCTION_ARGS)
945949
static void
946950
removePackageInternal(Package *package)
947951
{
948-
TransObject *transObject;
952+
TransObject *transObject;
953+
Variable *variable;
954+
HTAB *htab;
955+
HASH_SEQ_STATUS vstat;
956+
int i;
957+
958+
/* Set all the variables from package is deleted */
959+
for (i = 0; i < 2; i++)
960+
{
961+
if ((htab = pack_htab(package, i)) != NULL)
962+
{
963+
hash_seq_init(&vstat, htab);
964+
965+
while ((variable =
966+
(Variable *) hash_seq_search(&vstat)) != NULL)
967+
{
968+
if (GetActualState(variable)->is_valid)
969+
variable->is_deleted = true;
970+
}
971+
}
972+
}
949973

950974
/* All regular variables will be freed */
951975
if (package->hctxRegular)
@@ -1596,6 +1620,7 @@ createVariableInternal(Package *package, text *name, Oid typid, bool is_record,
15961620
variable->package = package;
15971621
variable->is_record = is_record;
15981622
variable->is_transactional = is_transactional;
1623+
variable->is_deleted = false;
15991624
initObjectHistory(transObject, TRANS_VARIABLE);
16001625

16011626
if (!isObjectChangedInCurrentTrans(&package->transObject))

pg_variables.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -113,6 +113,7 @@ typedef struct Variable
113113
* specified only when creating a variable.
114114
*/
115115
bool is_transactional;
116+
bool is_deleted;
116117
} Variable;
117118

118119
typedef struct HashRecordKey

sql/pg_variables_trans.sql

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -534,3 +534,39 @@ ROLLBACK;
534534
SELECT package FROM pgv_stats() ORDER BY package;
535535

536536
SELECT pgv_free();
537+
538+
-- Variables should be insertable after pgv_remove
539+
BEGIN;
540+
SELECT pgv_insert('test', 'x', ROW (1::int), TRUE);
541+
SELECT pgv_remove('test', 'x');
542+
SELECT pgv_insert('test', 'x', ROW (1::int), TRUE);
543+
ROLLBACK;
544+
545+
SELECT * FROM pgv_list() order by package, name;
546+
547+
BEGIN;
548+
SELECT pgv_insert('test', 'x', ROW (1::int), TRUE);
549+
SELECT pgv_remove('test', 'x');
550+
SELECT pgv_insert('test', 'x', ROW (1::int), TRUE);
551+
COMMIT;
552+
553+
SELECT * FROM pgv_list() order by package, name;
554+
555+
-- Variables should be insertable after pgv_free
556+
BEGIN;
557+
SELECT pgv_insert('test', 'y', ROW (1::int), TRUE);
558+
SELECT pgv_free();
559+
SELECT pgv_insert('test', 'y', ROW (1::int), TRUE);
560+
ROLLBACK;
561+
562+
SELECT * FROM pgv_list() order by package, name;
563+
564+
BEGIN;
565+
SELECT pgv_insert('test', 'y', ROW (1::int), TRUE);
566+
SELECT pgv_free();
567+
SELECT pgv_insert('test', 'y', ROW (1::int), TRUE);
568+
COMMIT;
569+
570+
SELECT * FROM pgv_list() order by package, name;
571+
572+
SELECT pgv_free();

0 commit comments

Comments
 (0)