@@ -955,6 +955,7 @@ removePackageInternal(Package *package)
955955 {
956956 MemoryContextDelete (package -> hctxRegular );
957957 package -> hctxRegular = NULL ;
958+ package -> varHashRegular = NULL ;
958959 }
959960
960961 /* Add to changes list */
@@ -967,6 +968,17 @@ removePackageInternal(Package *package)
967968 GetActualState (package )-> is_valid = false;
968969}
969970
971+ static bool
972+ isPackageEmpty (Package * package )
973+ {
974+ int var_num = hash_get_num_entries (package -> varHashTransact );
975+
976+ if (package -> varHashRegular )
977+ var_num += hash_get_num_entries (package -> varHashRegular );
978+
979+ return var_num == 0 ;
980+ }
981+
970982/*
971983 * Reset cache variables to their default values. It is necessary to do in case
972984 * of some changes: removing, rollbacking, etc.
@@ -1657,6 +1669,7 @@ removeObject(TransObject *object, TransObjectType type)
16571669{
16581670 bool found ;
16591671 HTAB * hash ;
1672+ Package * package = NULL ;
16601673
16611674 /*
16621675 * Delete an object from the change history of the overlying
@@ -1666,16 +1679,20 @@ removeObject(TransObject *object, TransObjectType type)
16661679 removeFromChangesStack (object , type );
16671680 if (type == TRANS_PACKAGE )
16681681 {
1669- Package * package = (Package * ) object ;
1682+ package = (Package * ) object ;
16701683
16711684 /* Regular variables had already removed */
16721685 MemoryContextDelete (package -> hctxTransact );
16731686 hash = packagesHash ;
16741687 }
16751688 else
1676- hash = ((Variable * ) object )-> is_transactional ?
1677- ((Variable * ) object )-> package -> varHashTransact :
1678- ((Variable * ) object )-> package -> varHashRegular ;
1689+ {
1690+ Variable * var = (Variable * ) object ;
1691+ package = var -> package ;
1692+ hash = var -> is_transactional ?
1693+ var -> package -> varHashTransact :
1694+ var -> package -> varHashRegular ;
1695+ }
16791696
16801697 /* Remove all object's states */
16811698 while (!dlist_is_empty (& object -> states ))
@@ -1684,6 +1701,12 @@ removeObject(TransObject *object, TransObjectType type)
16841701 /* Remove object from hash table */
16851702 hash_search (hash , object -> name , HASH_REMOVE , & found );
16861703
1704+ /* Remove package if it is became empty */
1705+ if (type == TRANS_VARIABLE &&
1706+ isObjectChangedInCurrentTrans (& package -> transObject ) &&
1707+ isPackageEmpty (package ))
1708+ GetActualState (& package -> transObject )-> is_valid = false;
1709+
16871710 resetVariablesCache (true);
16881711}
16891712
@@ -1725,8 +1748,19 @@ rollbackSavepoint(TransObject *object, TransObjectType type)
17251748 {
17261749 if (!state -> is_valid )
17271750 {
1728- dlist_pop_head_node (& object -> states );
1729- pfree (state );
1751+ if (isPackageEmpty ((Package * )object ))
1752+ {
1753+ removeObject (object , TRANS_PACKAGE );
1754+ return ;
1755+ }
1756+
1757+ if (dlist_has_next (& object -> states , & state -> node ))
1758+ {
1759+ dlist_pop_head_node (& object -> states );
1760+ pfree (state );
1761+ }
1762+ else
1763+ state -> is_valid = true;
17301764 /* Restore regular vars HTAB */
17311765 makePackHTAB ((Package * ) object , false);
17321766 }
@@ -1797,6 +1831,13 @@ releaseSavepoint(TransObject *object, TransObjectType type)
17971831 !dlist_has_next (states , dlist_head_node (states )))
17981832 {
17991833 removeObject (object , type );
1834+ /* Remove package if it becomes empty */
1835+ if (type == TRANS_VARIABLE )
1836+ {
1837+ Package * pack = ((Variable * ) object )-> package ;
1838+ if (isPackageEmpty (pack ))
1839+ (GetActualState (& pack -> transObject ))-> is_valid = false;
1840+ }
18001841 return ;
18011842 }
18021843 }
0 commit comments