@@ -50,12 +50,10 @@ static void ensurePackagesHashExists(void);
5050static void getKeyFromName (text * name , char * key );
5151
5252static 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 );
5957static void removePackageInternal (Package * package );
6058static void resetVariablesCache (bool with_package );
6159
@@ -65,7 +63,7 @@ static void releaseSavepoint(TransObject *object, TransObjectType type);
6563static void rollbackSavepoint (TransObject * object , TransObjectType type );
6664
6765static 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 );
6967static void removeState (TransObject * object , TransObjectType type ,
7068 TransState * stateToDelete );
7169static bool isObjectChangedInCurrentTrans (TransObject * object );
@@ -160,7 +158,7 @@ variable_set(text *package_name, text *var_name,
160158 ScalarVar * scalar ;
161159
162160 package = getPackageByName (package_name , true, false);
163- variable = createVariableInternal (package , var_name , typid ,
161+ variable = createVariableInternal (package , var_name , typid , false,
164162 is_transactional );
165163
166164 scalar = & (GetActualValue (variable ).scalar );
@@ -197,7 +195,7 @@ variable_get(text *package_name, text *var_name,
197195 return 0 ;
198196 }
199197
200- variable = getVariableInternal (package , var_name , typid , strict );
198+ variable = getVariableInternal (package , var_name , typid , false, strict );
201199
202200 if (variable == NULL )
203201 {
@@ -343,7 +341,7 @@ variable_insert(PG_FUNCTION_ARGS)
343341 VARSIZE_ANY_EXHDR (var_name )) != 0 )
344342 {
345343 variable = createVariableInternal (package , var_name , RECORDOID ,
346- is_transactional );
344+ true, is_transactional );
347345 LastVariable = variable ;
348346 }
349347 else
@@ -455,7 +453,8 @@ variable_update(PG_FUNCTION_ARGS)
455453 strncmp (VARDATA_ANY (var_name ), GetName (LastVariable ),
456454 VARSIZE_ANY_EXHDR (var_name )) != 0 )
457455 {
458- variable = getVariableInternal (package , var_name , RECORDOID , true);
456+ variable = getVariableInternal (package , var_name , RECORDOID , true,
457+ true);
459458 LastVariable = variable ;
460459 }
461460 else
@@ -543,7 +542,8 @@ variable_delete(PG_FUNCTION_ARGS)
543542 strncmp (VARDATA_ANY (var_name ), GetName (LastVariable ),
544543 VARSIZE_ANY_EXHDR (var_name )) != 0 )
545544 {
546- variable = getVariableInternal (package , var_name , RECORDOID , true);
545+ variable = getVariableInternal (package , var_name , RECORDOID , true,
546+ true);
547547 LastVariable = variable ;
548548 }
549549 else
@@ -592,7 +592,8 @@ variable_select(PG_FUNCTION_ARGS)
592592 var_name = PG_GETARG_TEXT_PP (1 );
593593
594594 package = getPackageByName (package_name , false, true);
595- variable = getVariableInternal (package , var_name , RECORDOID , true);
595+ variable = getVariableInternal (package , var_name , RECORDOID , true,
596+ true);
596597
597598 record = & (GetActualValue (variable ).record );
598599
@@ -667,7 +668,7 @@ variable_select_by_value(PG_FUNCTION_ARGS)
667668 }
668669
669670 package = getPackageByName (package_name , false, true);
670- variable = getVariableInternal (package , var_name , RECORDOID , true);
671+ variable = getVariableInternal (package , var_name , RECORDOID , true, true );
671672
672673 if (!value_is_null )
673674 check_record_key (variable , value_type );
@@ -736,7 +737,8 @@ variable_select_by_values(PG_FUNCTION_ARGS)
736737 var_name = PG_GETARG_TEXT_PP (1 );
737738
738739 package = getPackageByName (package_name , false, true);
739- variable = getVariableInternal (package , var_name , RECORDOID , true);
740+ variable = getVariableInternal (package , var_name , RECORDOID , true,
741+ true);
740742
741743 check_record_key (variable , ARR_ELEMTYPE (values ));
742744
@@ -870,7 +872,7 @@ remove_variable(PG_FUNCTION_ARGS)
870872 var_name = PG_GETARG_TEXT_PP (1 );
871873
872874 package = getPackageByName (package_name , false, true);
873- variable = getVariableInternal (package , var_name , InvalidOid , true);
875+ variable = getVariableInternal (package , var_name , InvalidOid , false, true);
874876
875877 /* Add package to changes list, so we can remove it if it is empty */
876878 if (!isObjectChangedInCurrentTrans (& package -> transObject ))
@@ -908,7 +910,6 @@ remove_package(PG_FUNCTION_ARGS)
908910{
909911 Package * package ;
910912 text * package_name ;
911- char key [NAMEDATALEN ];
912913
913914 if (PG_ARGISNULL (0 ))
914915 ereport (ERROR ,
@@ -1430,7 +1431,8 @@ getPackageByName(text *name, bool create, bool strict)
14301431 * flag 'is_transactional' of this variable is unknown.
14311432 */
14321433static 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 )
14341436{
14351437 Variable * variable ;
14361438 char key [NAMEDATALEN ];
@@ -1447,15 +1449,25 @@ getVariableInternal(Package *package, text *name, Oid typid, bool strict)
14471449 /* Check variable type */
14481450 if (found )
14491451 {
1450- if (typid != InvalidOid && variable -> typid != typid )
1452+ if (typid != InvalidOid )
14511453 {
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 )));
14541459
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" )));
14591471 }
14601472 if (!GetActualState (variable )-> is_valid && strict )
14611473 ereport (ERROR ,
@@ -1475,11 +1487,11 @@ getVariableInternal(Package *package, text *name, Oid typid, bool strict)
14751487
14761488/*
14771489 * 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.
14801492 */
14811493static Variable *
1482- createVariableInternal (Package * package , text * name , Oid typid ,
1494+ createVariableInternal (Package * package , text * name , Oid typid , bool is_record ,
14831495 bool is_transactional )
14841496{
14851497 Variable * variable ;
@@ -1521,6 +1533,12 @@ createVariableInternal(Package *package, text *name, Oid typid,
15211533 key , var_type )));
15221534 }
15231535
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+
15241542 /*
15251543 * Savepoint must be created when variable changed in current
15261544 * transaction. For each transaction level there should be a
@@ -1540,14 +1558,15 @@ createVariableInternal(Package *package, text *name, Oid typid,
15401558 /* Variable entry was created, so initialize new variable. */
15411559 variable -> typid = typid ;
15421560 variable -> package = package ;
1561+ variable -> is_record = is_record ;
15431562 variable -> is_transactional = is_transactional ;
15441563
15451564 dlist_init (GetStateStorage (variable ));
15461565 varState = MemoryContextAllocZero (pack_hctx (package , is_transactional ),
15471566 sizeof (VarState ));
15481567
15491568 dlist_push_head (GetStateStorage (variable ), & varState -> state .node );
1550- if (typid != RECORDOID )
1569+ if (! variable -> is_record )
15511570 {
15521571 ScalarVar * scalar = & (varState -> value .scalar );
15531572
@@ -1578,7 +1597,7 @@ copyValue(VarState *src, VarState *dest, Variable *destVar)
15781597
15791598 oldcxt = MemoryContextSwitchTo (destVar -> package -> hctxTransact );
15801599
1581- if (destVar -> typid == RECORDOID )
1600+ if (destVar -> is_record )
15821601 /* copy record value */
15831602 {
15841603 HASH_SEQ_STATUS rstat ;
@@ -1610,19 +1629,17 @@ copyValue(VarState *src, VarState *dest, Variable *destVar)
16101629}
16111630
16121631static void
1613- freeValue (VarState * varstate , Oid typid )
1632+ freeValue (VarState * varstate , bool is_record )
16141633{
1615- if (typid == RECORDOID && varstate -> value .record .hctx )
1634+ if (is_record && varstate -> value .record .hctx )
16161635 {
16171636 /* All records will be freed */
16181637 MemoryContextDelete (varstate -> value .record .hctx );
16191638 }
1620- else if (varstate -> value .scalar .typbyval == false &&
1639+ else if (! is_record && varstate -> value .scalar .typbyval == false &&
16211640 varstate -> value .scalar .is_null == false &&
16221641 varstate -> value .scalar .value )
1623- {
16241642 pfree (DatumGetPointer (varstate -> value .scalar .value ));
1625- }
16261643}
16271644
16281645static void
@@ -1632,7 +1649,7 @@ removeState(TransObject *object, TransObjectType type, TransState *stateToDelete
16321649 {
16331650 Variable * var = (Variable * ) object ;
16341651
1635- freeValue ((VarState * ) stateToDelete , var -> typid );
1652+ freeValue ((VarState * ) stateToDelete , var -> is_record );
16361653 }
16371654 dlist_delete (& stateToDelete -> node );
16381655 pfree (stateToDelete );
0 commit comments