@@ -50,12 +50,10 @@ static void ensurePackagesHashExists(void);
50
50
static void getKeyFromName (text * name , char * key );
51
51
52
52
static Package * getPackageByName (text * name , bool create , bool strict );
53
- static Variable * getVariableInternal (Package * package ,
54
- text * name , Oid typid ,
55
- bool strict );
56
- static Variable * createVariableInternal (Package * package ,
57
- text * name , Oid typid ,
58
- bool is_transactional );
53
+ static Variable * getVariableInternal (Package * package , text * name ,
54
+ Oid typid , bool is_record , bool strict );
55
+ static Variable * createVariableInternal (Package * package , text * name , Oid typid ,
56
+ bool is_record , bool is_transactional );
59
57
static void removePackageInternal (Package * package );
60
58
static void resetVariablesCache (bool with_package );
61
59
@@ -65,7 +63,7 @@ static void releaseSavepoint(TransObject *object, TransObjectType type);
65
63
static void rollbackSavepoint (TransObject * object , TransObjectType type );
66
64
67
65
static void copyValue (VarState * src , VarState * dest , Variable * destVar );
68
- static void freeValue (VarState * varstate , Oid typid );
66
+ static void freeValue (VarState * varstate , bool is_record );
69
67
static void removeState (TransObject * object , TransObjectType type ,
70
68
TransState * stateToDelete );
71
69
static bool isObjectChangedInCurrentTrans (TransObject * object );
@@ -160,7 +158,7 @@ variable_set(text *package_name, text *var_name,
160
158
ScalarVar * scalar ;
161
159
162
160
package = getPackageByName (package_name , true, false);
163
- variable = createVariableInternal (package , var_name , typid ,
161
+ variable = createVariableInternal (package , var_name , typid , false,
164
162
is_transactional );
165
163
166
164
scalar = & (GetActualValue (variable ).scalar );
@@ -197,7 +195,7 @@ variable_get(text *package_name, text *var_name,
197
195
return 0 ;
198
196
}
199
197
200
- variable = getVariableInternal (package , var_name , typid , strict );
198
+ variable = getVariableInternal (package , var_name , typid , false, strict );
201
199
202
200
if (variable == NULL )
203
201
{
@@ -343,7 +341,7 @@ variable_insert(PG_FUNCTION_ARGS)
343
341
VARSIZE_ANY_EXHDR (var_name )) != 0 )
344
342
{
345
343
variable = createVariableInternal (package , var_name , RECORDOID ,
346
- is_transactional );
344
+ true, is_transactional );
347
345
LastVariable = variable ;
348
346
}
349
347
else
@@ -455,7 +453,8 @@ variable_update(PG_FUNCTION_ARGS)
455
453
strncmp (VARDATA_ANY (var_name ), GetName (LastVariable ),
456
454
VARSIZE_ANY_EXHDR (var_name )) != 0 )
457
455
{
458
- variable = getVariableInternal (package , var_name , RECORDOID , true);
456
+ variable = getVariableInternal (package , var_name , RECORDOID , true,
457
+ true);
459
458
LastVariable = variable ;
460
459
}
461
460
else
@@ -543,7 +542,8 @@ variable_delete(PG_FUNCTION_ARGS)
543
542
strncmp (VARDATA_ANY (var_name ), GetName (LastVariable ),
544
543
VARSIZE_ANY_EXHDR (var_name )) != 0 )
545
544
{
546
- variable = getVariableInternal (package , var_name , RECORDOID , true);
545
+ variable = getVariableInternal (package , var_name , RECORDOID , true,
546
+ true);
547
547
LastVariable = variable ;
548
548
}
549
549
else
@@ -592,7 +592,8 @@ variable_select(PG_FUNCTION_ARGS)
592
592
var_name = PG_GETARG_TEXT_PP (1 );
593
593
594
594
package = getPackageByName (package_name , false, true);
595
- variable = getVariableInternal (package , var_name , RECORDOID , true);
595
+ variable = getVariableInternal (package , var_name , RECORDOID , true,
596
+ true);
596
597
597
598
record = & (GetActualValue (variable ).record );
598
599
@@ -667,7 +668,7 @@ variable_select_by_value(PG_FUNCTION_ARGS)
667
668
}
668
669
669
670
package = getPackageByName (package_name , false, true);
670
- variable = getVariableInternal (package , var_name , RECORDOID , true);
671
+ variable = getVariableInternal (package , var_name , RECORDOID , true, true );
671
672
672
673
if (!value_is_null )
673
674
check_record_key (variable , value_type );
@@ -736,7 +737,8 @@ variable_select_by_values(PG_FUNCTION_ARGS)
736
737
var_name = PG_GETARG_TEXT_PP (1 );
737
738
738
739
package = getPackageByName (package_name , false, true);
739
- variable = getVariableInternal (package , var_name , RECORDOID , true);
740
+ variable = getVariableInternal (package , var_name , RECORDOID , true,
741
+ true);
740
742
741
743
check_record_key (variable , ARR_ELEMTYPE (values ));
742
744
@@ -870,7 +872,7 @@ remove_variable(PG_FUNCTION_ARGS)
870
872
var_name = PG_GETARG_TEXT_PP (1 );
871
873
872
874
package = getPackageByName (package_name , false, true);
873
- variable = getVariableInternal (package , var_name , InvalidOid , true);
875
+ variable = getVariableInternal (package , var_name , InvalidOid , false, true);
874
876
875
877
/* Add package to changes list, so we can remove it if it is empty */
876
878
if (!isObjectChangedInCurrentTrans (& package -> transObject ))
@@ -908,7 +910,6 @@ remove_package(PG_FUNCTION_ARGS)
908
910
{
909
911
Package * package ;
910
912
text * package_name ;
911
- char key [NAMEDATALEN ];
912
913
913
914
if (PG_ARGISNULL (0 ))
914
915
ereport (ERROR ,
@@ -1430,7 +1431,8 @@ getPackageByName(text *name, bool create, bool strict)
1430
1431
* flag 'is_transactional' of this variable is unknown.
1431
1432
*/
1432
1433
static Variable *
1433
- getVariableInternal (Package * package , text * name , Oid typid , bool strict )
1434
+ getVariableInternal (Package * package , text * name , Oid typid , bool is_record ,
1435
+ bool strict )
1434
1436
{
1435
1437
Variable * variable ;
1436
1438
char key [NAMEDATALEN ];
@@ -1447,15 +1449,25 @@ getVariableInternal(Package *package, text *name, Oid typid, bool strict)
1447
1449
/* Check variable type */
1448
1450
if (found )
1449
1451
{
1450
- if (typid != InvalidOid && variable -> typid != typid )
1452
+ if (typid != InvalidOid )
1451
1453
{
1452
- char * var_type = DatumGetCString (DirectFunctionCall1 (regtypeout ,
1453
- ObjectIdGetDatum (variable -> typid )));
1454
+ if (variable -> typid != typid )
1455
+ {
1456
+ char * var_type = DatumGetCString (
1457
+ DirectFunctionCall1 (regtypeout ,
1458
+ ObjectIdGetDatum (variable -> typid )));
1454
1459
1455
- ereport (ERROR ,
1456
- (errcode (ERRCODE_INVALID_PARAMETER_VALUE ),
1457
- errmsg ("variable \"%s\" requires \"%s\" value" ,
1458
- key , var_type )));
1460
+ ereport (ERROR ,
1461
+ (errcode (ERRCODE_INVALID_PARAMETER_VALUE ),
1462
+ errmsg ("variable \"%s\" requires \"%s\" value" ,
1463
+ key , var_type )));
1464
+ }
1465
+
1466
+ if (variable -> is_record != is_record )
1467
+ ereport (ERROR ,
1468
+ (errcode (ERRCODE_INVALID_PARAMETER_VALUE ),
1469
+ errmsg ("\"%s\" isn't a %s variable" ,
1470
+ key , is_record ? "record" : "scalar" )));
1459
1471
}
1460
1472
if (!GetActualState (variable )-> is_valid && strict )
1461
1473
ereport (ERROR ,
@@ -1475,11 +1487,11 @@ getVariableInternal(Package *package, text *name, Oid typid, bool strict)
1475
1487
1476
1488
/*
1477
1489
* Create a variable or return a pointer to existing one.
1478
- * Function is useful to set new value to variable and
1479
- * flag 'is_transactional' is known.
1490
+ * Function is useful to set new value to variable and flag 'is_transactional'
1491
+ * is known.
1480
1492
*/
1481
1493
static Variable *
1482
- createVariableInternal (Package * package , text * name , Oid typid ,
1494
+ createVariableInternal (Package * package , text * name , Oid typid , bool is_record ,
1483
1495
bool is_transactional )
1484
1496
{
1485
1497
Variable * variable ;
@@ -1521,6 +1533,12 @@ createVariableInternal(Package *package, text *name, Oid typid,
1521
1533
key , var_type )));
1522
1534
}
1523
1535
1536
+ if (variable -> is_record != is_record )
1537
+ ereport (ERROR ,
1538
+ (errcode (ERRCODE_INVALID_PARAMETER_VALUE ),
1539
+ errmsg ("\"%s\" isn't a %s variable" ,
1540
+ key , is_record ? "record" : "scalar" )));
1541
+
1524
1542
/*
1525
1543
* Savepoint must be created when variable changed in current
1526
1544
* transaction. For each transaction level there should be a
@@ -1540,14 +1558,15 @@ createVariableInternal(Package *package, text *name, Oid typid,
1540
1558
/* Variable entry was created, so initialize new variable. */
1541
1559
variable -> typid = typid ;
1542
1560
variable -> package = package ;
1561
+ variable -> is_record = is_record ;
1543
1562
variable -> is_transactional = is_transactional ;
1544
1563
1545
1564
dlist_init (GetStateStorage (variable ));
1546
1565
varState = MemoryContextAllocZero (pack_hctx (package , is_transactional ),
1547
1566
sizeof (VarState ));
1548
1567
1549
1568
dlist_push_head (GetStateStorage (variable ), & varState -> state .node );
1550
- if (typid != RECORDOID )
1569
+ if (! variable -> is_record )
1551
1570
{
1552
1571
ScalarVar * scalar = & (varState -> value .scalar );
1553
1572
@@ -1578,7 +1597,7 @@ copyValue(VarState *src, VarState *dest, Variable *destVar)
1578
1597
1579
1598
oldcxt = MemoryContextSwitchTo (destVar -> package -> hctxTransact );
1580
1599
1581
- if (destVar -> typid == RECORDOID )
1600
+ if (destVar -> is_record )
1582
1601
/* copy record value */
1583
1602
{
1584
1603
HASH_SEQ_STATUS rstat ;
@@ -1610,19 +1629,17 @@ copyValue(VarState *src, VarState *dest, Variable *destVar)
1610
1629
}
1611
1630
1612
1631
static void
1613
- freeValue (VarState * varstate , Oid typid )
1632
+ freeValue (VarState * varstate , bool is_record )
1614
1633
{
1615
- if (typid == RECORDOID && varstate -> value .record .hctx )
1634
+ if (is_record && varstate -> value .record .hctx )
1616
1635
{
1617
1636
/* All records will be freed */
1618
1637
MemoryContextDelete (varstate -> value .record .hctx );
1619
1638
}
1620
- else if (varstate -> value .scalar .typbyval == false &&
1639
+ else if (! is_record && varstate -> value .scalar .typbyval == false &&
1621
1640
varstate -> value .scalar .is_null == false &&
1622
1641
varstate -> value .scalar .value )
1623
- {
1624
1642
pfree (DatumGetPointer (varstate -> value .scalar .value ));
1625
- }
1626
1643
}
1627
1644
1628
1645
static void
@@ -1632,7 +1649,7 @@ removeState(TransObject *object, TransObjectType type, TransState *stateToDelete
1632
1649
{
1633
1650
Variable * var = (Variable * ) object ;
1634
1651
1635
- freeValue ((VarState * ) stateToDelete , var -> typid );
1652
+ freeValue ((VarState * ) stateToDelete , var -> is_record );
1636
1653
}
1637
1654
dlist_delete (& stateToDelete -> node );
1638
1655
pfree (stateToDelete );
0 commit comments