@@ -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 ,
7068TransState * stateToDelete );
7169static bool isObjectChangedInCurrentTrans (TransObject * object );
@@ -160,7 +158,7 @@ variable_set(text *package_name, text *var_name,
160158ScalarVar * scalar ;
161159
162160package = getPackageByName (package_name , true, false);
163- variable = createVariableInternal (package ,var_name ,typid ,
161+ variable = createVariableInternal (package ,var_name ,typid , false,
164162is_transactional );
165163
166164scalar = & (GetActualValue (variable ).scalar );
@@ -197,7 +195,7 @@ variable_get(text *package_name, text *var_name,
197195return 0 ;
198196}
199197
200- variable = getVariableInternal (package ,var_name ,typid ,strict );
198+ variable = getVariableInternal (package ,var_name ,typid ,false, strict );
201199
202200if (variable == NULL )
203201{
@@ -343,7 +341,7 @@ variable_insert(PG_FUNCTION_ARGS)
343341VARSIZE_ANY_EXHDR (var_name ))!= 0 )
344342{
345343variable = createVariableInternal (package ,var_name ,RECORDOID ,
346- is_transactional );
344+ true, is_transactional );
347345LastVariable = variable ;
348346}
349347else
@@ -455,7 +453,8 @@ variable_update(PG_FUNCTION_ARGS)
455453strncmp (VARDATA_ANY (var_name ),GetName (LastVariable ),
456454VARSIZE_ANY_EXHDR (var_name ))!= 0 )
457455{
458- variable = getVariableInternal (package ,var_name ,RECORDOID , true);
456+ variable = getVariableInternal (package ,var_name ,RECORDOID , true,
457+ true);
459458LastVariable = variable ;
460459}
461460else
@@ -543,7 +542,8 @@ variable_delete(PG_FUNCTION_ARGS)
543542strncmp (VARDATA_ANY (var_name ),GetName (LastVariable ),
544543VARSIZE_ANY_EXHDR (var_name ))!= 0 )
545544{
546- variable = getVariableInternal (package ,var_name ,RECORDOID , true);
545+ variable = getVariableInternal (package ,var_name ,RECORDOID , true,
546+ true);
547547LastVariable = variable ;
548548}
549549else
@@ -592,7 +592,8 @@ variable_select(PG_FUNCTION_ARGS)
592592var_name = PG_GETARG_TEXT_PP (1 );
593593
594594package = getPackageByName (package_name , false, true);
595- variable = getVariableInternal (package ,var_name ,RECORDOID , true);
595+ variable = getVariableInternal (package ,var_name ,RECORDOID , true,
596+ true);
596597
597598record = & (GetActualValue (variable ).record );
598599
@@ -667,7 +668,7 @@ variable_select_by_value(PG_FUNCTION_ARGS)
667668}
668669
669670package = getPackageByName (package_name , false, true);
670- variable = getVariableInternal (package ,var_name ,RECORDOID , true);
671+ variable = getVariableInternal (package ,var_name ,RECORDOID , true, true );
671672
672673if (!value_is_null )
673674check_record_key (variable ,value_type );
@@ -736,7 +737,8 @@ variable_select_by_values(PG_FUNCTION_ARGS)
736737var_name = PG_GETARG_TEXT_PP (1 );
737738
738739package = getPackageByName (package_name , false, true);
739- variable = getVariableInternal (package ,var_name ,RECORDOID , true);
740+ variable = getVariableInternal (package ,var_name ,RECORDOID , true,
741+ true);
740742
741743check_record_key (variable ,ARR_ELEMTYPE (values ));
742744
@@ -870,7 +872,7 @@ remove_variable(PG_FUNCTION_ARGS)
870872var_name = PG_GETARG_TEXT_PP (1 );
871873
872874package = 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 */
876878if (!isObjectChangedInCurrentTrans (& package -> transObject ))
@@ -908,7 +910,6 @@ remove_package(PG_FUNCTION_ARGS)
908910{
909911Package * package ;
910912text * package_name ;
911- char key [NAMEDATALEN ];
912913
913914if (PG_ARGISNULL (0 ))
914915ereport (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{
14351437Variable * variable ;
14361438char key [NAMEDATALEN ];
@@ -1447,15 +1449,25 @@ getVariableInternal(Package *package, text *name, Oid typid, bool strict)
14471449/* Check variable type */
14481450if (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}
14601472if (!GetActualState (variable )-> is_valid && strict )
14611473ereport (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 ,
14831495bool is_transactional )
14841496{
14851497Variable * variable ;
@@ -1521,6 +1533,12 @@ createVariableInternal(Package *package, text *name, Oid typid,
15211533key ,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. */
15411559variable -> typid = typid ;
15421560variable -> package = package ;
1561+ variable -> is_record = is_record ;
15431562variable -> is_transactional = is_transactional ;
15441563
15451564dlist_init (GetStateStorage (variable ));
15461565varState = MemoryContextAllocZero (pack_hctx (package ,is_transactional ),
15471566sizeof (VarState ));
15481567
15491568dlist_push_head (GetStateStorage (variable ),& varState -> state .node );
1550- if (typid != RECORDOID )
1569+ if (! variable -> is_record )
15511570{
15521571ScalarVar * scalar = & (varState -> value .scalar );
15531572
@@ -1578,7 +1597,7 @@ copyValue(VarState *src, VarState *dest, Variable *destVar)
15781597
15791598oldcxt = MemoryContextSwitchTo (destVar -> package -> hctxTransact );
15801599
1581- if (destVar -> typid == RECORDOID )
1600+ if (destVar -> is_record )
15821601/* copy record value */
15831602{
15841603HASH_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 */
16181637MemoryContextDelete (varstate -> value .record .hctx );
16191638}
1620- else if (varstate -> value .scalar .typbyval == false&&
1639+ else if (! is_record && varstate -> value .scalar .typbyval == false&&
16211640varstate -> value .scalar .is_null == false&&
16221641varstate -> value .scalar .value )
1623- {
16241642pfree (DatumGetPointer (varstate -> value .scalar .value ));
1625- }
16261643}
16271644
16281645static void
@@ -1632,7 +1649,7 @@ removeState(TransObject *object, TransObjectType type, TransState *stateToDelete
16321649{
16331650Variable * var = (Variable * )object ;
16341651
1635- freeValue ((VarState * )stateToDelete ,var -> typid );
1652+ freeValue ((VarState * )stateToDelete ,var -> is_record );
16361653}
16371654dlist_delete (& stateToDelete -> node );
16381655pfree (stateToDelete );