@@ -961,13 +961,11 @@ removePackageInternal(Package *package)
961961GetPackState (package )-> trans_var_num = 0 ;
962962}
963963
964+ /* Check if package has any valid variables */
964965static bool
965966isPackageEmpty (Package * package )
966967{
967- int var_num = 0 ;
968-
969- if (package -> varHashTransact )
970- var_num += hash_get_num_entries (package -> varHashTransact );
968+ int var_num = GetPackState (package )-> trans_var_num ;
971969
972970if (package -> varHashRegular )
973971var_num += hash_get_num_entries (package -> varHashRegular );
@@ -1357,7 +1355,7 @@ initObjectHistory(TransObject *object, TransObjectType type)
13571355VarState * varState = (VarState * )state ;
13581356ScalarVar * scalar = & (varState -> value .scalar );
13591357
1360- get_typlenbyval (variable -> typid ,& scalar -> typlen ,
1358+ get_typlenbyval (variable -> typid ,& scalar -> typlen ,
13611359& scalar -> typbyval );
13621360varState -> value .scalar .is_null = true;
13631361}
@@ -1613,7 +1611,7 @@ createVariableInternal(Package *package, text *name, Oid typid, bool is_record,
16131611(!found || !GetActualState (variable )-> is_valid ))
16141612GetPackState (package )-> trans_var_num ++ ;
16151613GetActualState (variable )-> is_valid = true;
1616-
1614+
16171615/* If it is necessary, put variable to changedVars */
16181616if (is_transactional )
16191617addToChangesStack (transObject ,TRANS_VARIABLE );
@@ -1779,16 +1777,49 @@ rollbackSavepoint(TransObject *object, TransObjectType type)
17791777state = GetActualState (object );
17801778removeState (object ,type ,state );
17811779
1782- if (dlist_is_empty ( & object -> states ) )
1780+ if (type == TRANS_PACKAGE )
17831781{
1784- if (type == TRANS_PACKAGE && numOfRegVars ((Package * )object )> 0 )
1782+ /* If there is no more states... */
1783+ if (dlist_is_empty (& object -> states ))
1784+ {
1785+ /* ...but object is a package and has some regular variables... */
1786+ if (numOfRegVars ((Package * )object )> 0 )
1787+ {
1788+ /* ...create a new state to make package valid. */
1789+ initObjectHistory (object ,type );
1790+ GetActualState (object )-> level = GetCurrentTransactionNestLevel ()- 1 ;
1791+ if (!dlist_is_empty (changesStack ))
1792+ addToChangesStackUpperLevel (object ,type );
1793+ }
1794+ else
1795+ /* ...or remove an object if it is no longer needed. */
1796+ removeObject (object ,type );
1797+ }
1798+ /*
1799+ * But if a package has more states, but hasn't valid variables,
1800+ * mark it as not valid or remove at top level transaction.
1801+ */
1802+ else if (isPackageEmpty ((Package * )object ))
17851803{
1786- initObjectHistory (object ,type );
1787- GetActualState (object )-> level = GetCurrentTransactionNestLevel ()- 1 ;
1788- if (!dlist_is_empty (changesStack ))
1804+ if (dlist_is_empty (changesStack ))
1805+ {
1806+ removeObject (object ,type );
1807+ return ;
1808+ }
1809+ else if (!isObjectChangedInUpperTrans (object )&&
1810+ !dlist_is_empty (changesStack ))
1811+ {
1812+ createSavepoint (object ,type );
17891813addToChangesStackUpperLevel (object ,type );
1814+ GetActualState (object )-> level = GetCurrentTransactionNestLevel ()- 1 ;
1815+ }
1816+ GetActualState (object )-> is_valid = false;
17901817}
1791- else
1818+ }
1819+ else
1820+ {
1821+ if (dlist_is_empty (& object -> states ))
1822+ /* Remove a variable if it is no longer needed. */
17921823removeObject (object ,type );
17931824}
17941825}
@@ -1840,9 +1871,9 @@ addToChangesStackUpperLevel(TransObject *object, TransObjectType type)
18401871ChangedObject * co_new ;
18411872ChangesStackNode * csn ;
18421873/*
1843- * Impossible to push in upper list existing node
1844- * because it was created in another context
1845- */
1874+ * Impossible to push in upper list existing node
1875+ * because it was created in another context
1876+ */
18461877csn = dlist_head_element (ChangesStackNode ,node ,changesStack );
18471878co_new = makeChangedObject (object ,csn -> ctx );
18481879dlist_push_head (type == TRANS_PACKAGE ?csn -> changedPacksList :
@@ -1875,13 +1906,14 @@ isObjectChangedInUpperTrans(TransObject *object)
18751906* prev_state ;
18761907
18771908cur_state = GetActualState (object );
1878- if (dlist_has_next (& object -> states ,& cur_state -> node ))
1909+ if (dlist_has_next (& object -> states ,& cur_state -> node )&&
1910+ cur_state -> level == GetCurrentTransactionNestLevel ())
18791911{
18801912prev_state = dlist_container (TransState ,node ,cur_state -> node .next );
18811913return prev_state -> level == GetCurrentTransactionNestLevel ()- 1 ;
18821914}
1883-
1884- return false ;
1915+ else
1916+ return cur_state -> level == GetCurrentTransactionNestLevel () - 1 ;
18851917}
18861918
18871919/*