Skip to content

Commit a682cc3

Browse files
CherkashinSergeyza-arthur
authored andcommitted
Count valid variables to display package does not exists
if there is no valid variables
1 parent ab95102 commit a682cc3

File tree

3 files changed

+100
-42
lines changed

3 files changed

+100
-42
lines changed

expected/pg_variables_trans.out

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1879,7 +1879,7 @@ SELECT pgv_remove('vars', 'any1');
18791879

18801880
RELEASE comm;
18811881
SELECT pgv_get('vars', 'any1',NULL::text);
1882-
ERROR: unrecognized variable "any1"
1882+
ERROR: unrecognized package "vars"
18831883
COMMIT;
18841884
-- Tests for PGPRO-2440
18851885
SELECT pgv_insert('vars3', 'r3', row(1 :: integer, NULL::varchar), true);

pg_variables.c

Lines changed: 94 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -71,8 +71,14 @@ static bool isObjectChangedInCurrentTrans(TransObject *object);
7171
static bool isObjectChangedInUpperTrans(TransObject *object);
7272

7373
static void addToChangesStack(TransObject *object, TransObjectType type);
74+
static void addToChangesStackUpperLevel(TransObject *object,
75+
TransObjectType type);
7476
static void pushChangesStack(void);
7577

78+
static int numOfRegVars(Package *package);
79+
/* Debug function */
80+
static int _numOfTransVars(Package *package);
81+
7682
/* Constructors */
7783
static void makePackHTAB(Package *package, bool is_trans);
7884
static inline ChangedObject *makeChangedObject(TransObject *object,
@@ -892,10 +898,13 @@ remove_variable(PG_FUNCTION_ARGS)
892898
addToChangesStack(transObject, TRANS_VARIABLE);
893899
}
894900
GetActualState(variable)->is_valid = false;
901+
numOfTransVars(package)--;
895902
}
896903
else
897904
removeObject(&variable->transObject, TRANS_VARIABLE);
898905

906+
Assert (numOfTransVars(package) == _numOfTransVars(package));
907+
899908
resetVariablesCache(false);
900909

901910
PG_FREE_IF_COPY(package_name, 0);
@@ -950,6 +959,7 @@ removePackageInternal(Package *package)
950959
addToChangesStack(transObject, TRANS_PACKAGE);
951960
}
952961
GetActualState(package)->is_valid = false;
962+
numOfTransVars(package) = 0;
953963
}
954964

955965
static bool
@@ -1338,7 +1348,8 @@ getPackage(text *name, bool strict)
13381348
{
13391349
package = (Package *) hash_search(packagesHash, key, HASH_FIND, &found);
13401350

1341-
if (found && GetActualState(package)->is_valid)
1351+
if (found && GetActualState(package)->is_valid &&
1352+
numOfTransVars(package) + numOfRegVars(package))
13421353
return package;
13431354
}
13441355
/* Package not found or it's current state is "invalid" */
@@ -1410,17 +1421,15 @@ createPackage(text *name, bool is_trans)
14101421
packState = MemoryContextAllocZero(ModuleContext, sizeof(PackState));
14111422
dlist_push_head(GetStateStorage(package), &(packState->state.node));
14121423
packState->state.is_valid = true;
1424+
packState->trans_var_num = 0;
1425+
/* Add to changes list */
1426+
if (!isObjectChangedInCurrentTrans(&package->transObject))
1427+
addToChangesStack(&package->transObject, TRANS_PACKAGE);
14131428
}
14141429

14151430
/* Create corresponding HTAB if not exists */
14161431
if (!pack_htab(package, is_trans))
14171432
makePackHTAB(package, is_trans);
1418-
/* Add to changes list */
1419-
if (!isObjectChangedInCurrentTrans(&package->transObject))
1420-
{
1421-
createSavepoint(&package->transObject, TRANS_PACKAGE);
1422-
addToChangesStack(&package->transObject, TRANS_PACKAGE);
1423-
}
14241433

14251434
return package;
14261435
}
@@ -1586,7 +1595,13 @@ createVariableInternal(Package *package, text *name, Oid typid, bool is_record,
15861595
}
15871596
}
15881597

1598+
if (is_transactional &&
1599+
(!found || !GetActualState(variable)->is_valid))
1600+
numOfTransVars(package)++;
15891601
GetActualState(variable)->is_valid = true;
1602+
1603+
Assert (numOfTransVars(package) == _numOfTransVars(package));
1604+
15901605
/* If it is necessary, put variable to changedVars */
15911606
if (is_transactional)
15921607
addToChangesStack(transObject, TRANS_VARIABLE);
@@ -1715,8 +1730,11 @@ createSavepoint(TransObject *object, TransObjectType type)
17151730

17161731
prevState = GetActualState(object);
17171732
if (type == TRANS_PACKAGE)
1733+
{
17181734
newState = (TransState *) MemoryContextAllocZero(ModuleContext,
17191735
sizeof(PackState));
1736+
((PackState *)newState)->trans_var_num = ((PackState *)prevState)->trans_var_num;
1737+
}
17201738
else
17211739
{
17221740
Variable *var = (Variable *) object;
@@ -1729,6 +1747,15 @@ createSavepoint(TransObject *object, TransObjectType type)
17291747
newState->is_valid = prevState->is_valid;
17301748
}
17311749

1750+
static int
1751+
numOfRegVars(Package *package)
1752+
{
1753+
if (package->varHashRegular)
1754+
return hash_get_num_entries(package->varHashRegular);
1755+
else
1756+
return 0;
1757+
}
1758+
17321759
/*
17331760
* Rollback object to its previous state
17341761
*/
@@ -1738,32 +1765,27 @@ rollbackSavepoint(TransObject *object, TransObjectType type)
17381765
TransState *state;
17391766

17401767
state = GetActualState(object);
1741-
if (type == TRANS_PACKAGE)
1768+
removeState(object, type, state);
1769+
1770+
if (dlist_is_empty(&object->states))
17421771
{
1743-
if (!state->is_valid && !isPackageEmpty((Package *)object))
1772+
if (type == TRANS_PACKAGE && numOfRegVars((Package *)object))
17441773
{
1745-
if (dlist_has_next(&object->states, &state->node))
1774+
PackState *packState;
1775+
1776+
packState = MemoryContextAllocZero(ModuleContext, sizeof(PackState));
1777+
dlist_push_head(&object->states, &(packState->state.node));
1778+
packState->state.is_valid = true;
1779+
packState->state.level = GetCurrentTransactionNestLevel() - 1;
1780+
packState->trans_var_num = 0;
1781+
1782+
if (!dlist_is_empty(changesStack))
17461783
{
1747-
dlist_pop_head_node(&object->states);
1748-
pfree(state);
1784+
addToChangesStackUpperLevel(object, type);
17491785
}
1750-
else
1751-
state->is_valid = true;
1752-
/* Restore regular vars HTAB */
1753-
makePackHTAB((Package *) object, false);
17541786
}
17551787
else
1756-
/* Pass current state to parent level */
1757-
releaseSavepoint(object, TRANS_PACKAGE);
1758-
}
1759-
else
1760-
{
1761-
/* Remove current state */
1762-
removeState(object, TRANS_VARIABLE, state);
1763-
1764-
/* Remove variable if it was created in rolled back transaction */
1765-
if (dlist_is_empty(&object->states))
1766-
removeObject(object, TRANS_VARIABLE);
1788+
removeObject(object, type);
17671789
}
17681790
}
17691791

@@ -1802,21 +1824,31 @@ releaseSavepoint(TransObject *object, TransObjectType type)
18021824
/* If the object does not yet have a record in previous level changesStack,
18031825
* create it. */
18041826
else if (!dlist_is_empty(changesStack))
1805-
{
1806-
ChangedObject *co_new;
1807-
ChangesStackNode *csn;
1808-
/*
1809-
* Impossible to push in upper list existing node
1810-
* because it was created in another context
1811-
*/
1812-
csn = dlist_head_element(ChangesStackNode, node, changesStack);
1813-
co_new = makeChangedObject(object, csn->ctx);
1814-
dlist_push_head(type == TRANS_PACKAGE ? csn->changedPacksList :
1815-
csn->changedVarsList,
1816-
&co_new->node);
1817-
}
1827+
addToChangesStackUpperLevel(object, type);
1828+
18181829
/* Change subxact level due to release */
18191830
GetActualState(object)->level--;
1831+
if (type == TRANS_PACKAGE)
1832+
{
1833+
Package *package = (Package *)object;
1834+
Assert (numOfTransVars(package) == _numOfTransVars(package));
1835+
}
1836+
}
1837+
1838+
static void
1839+
addToChangesStackUpperLevel(TransObject *object, TransObjectType type)
1840+
{
1841+
ChangedObject *co_new;
1842+
ChangesStackNode *csn;
1843+
/*
1844+
* Impossible to push in upper list existing node
1845+
* because it was created in another context
1846+
*/
1847+
csn = dlist_head_element(ChangesStackNode, node, changesStack);
1848+
co_new = makeChangedObject(object, csn->ctx);
1849+
dlist_push_head(type == TRANS_PACKAGE ? csn->changedPacksList :
1850+
csn->changedVarsList,
1851+
&co_new->node);
18201852
}
18211853

18221854
/*
@@ -2136,3 +2168,25 @@ _PG_fini(void)
21362168
UnregisterSubXactCallback(pgvSubTransCallback, NULL);
21372169
ExecutorEnd_hook = prev_ExecutorEnd;
21382170
}
2171+
2172+
/* Get exact count of valid variables in package. For debug only. */
2173+
static int
2174+
_numOfTransVars(Package *package)
2175+
{
2176+
HASH_SEQ_STATUS vstat;
2177+
Variable *variable;
2178+
unsigned long res = 0;
2179+
2180+
if (package->varHashTransact)
2181+
{
2182+
hash_seq_init(&vstat, package->varHashTransact);
2183+
while ((variable = (Variable *) hash_seq_search(&vstat)) != NULL)
2184+
{
2185+
if (GetActualState(variable)->is_valid &&
2186+
GetActualState(package)->is_valid)
2187+
res++;
2188+
}
2189+
}
2190+
2191+
return res;
2192+
}

pg_variables.h

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -63,7 +63,8 @@ typedef struct TransState
6363
/* List node that stores one of the package's states */
6464
typedef struct PackState
6565
{
66-
TransState state;
66+
TransState state;
67+
unsigned long trans_var_num; /* Number of valid transactional variables */
6768
} PackState;
6869

6970
/* List node that stores one of the variable's states */
@@ -170,6 +171,9 @@ extern void removeObject(TransObject *object, TransObjectType type);
170171
#define GetActualValue(variable) \
171172
(((VarState *) GetActualState(variable))->value)
172173

174+
#define numOfTransVars(package) \
175+
(((PackState *) GetActualState(package))->trans_var_num)
176+
173177
#define GetName(object) \
174178
(AssertVariableIsOfTypeMacro(object->transObject, TransObject), \
175179
object->transObject.name)

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