diff --git a/expected/pg_variables.out b/expected/pg_variables.out
index ba0b64a..180ebd1 100644
--- a/expected/pg_variables.out
+++ b/expected/pg_variables.out
@@ -563,11 +563,13 @@ ERROR:  variable "j1" requires "jsonb" value
 SELECT pgv_insert('vars3', 'r1', tab) FROM tab;
 ERROR:  there is a record in the variable "r1" with same key
 SELECT pgv_insert('vars3', 'r1', row(1, 'str1', 'str2'));
-ERROR:  new record structure differs from variable "r1" structure
+ERROR:  new record structure have 3 attributes, but variable "r1" structure have 2.
 SELECT pgv_insert('vars3', 'r1', row(1, 1));
-ERROR:  new record structure differs from variable "r1" structure
+ERROR:  new record attribute type for attribute number 2 differs from variable "r1" structure.
+HINT:  You may need explicit type casts.
 SELECT pgv_insert('vars3', 'r1', row('str1', 'str1'));
-ERROR:  new record structure differs from variable "r1" structure
+ERROR:  new record attribute type for attribute number 1 differs from variable "r1" structure.
+HINT:  You may need explicit type casts.
 SELECT pgv_select('vars3', 'r1', ARRAY[[1,2]]); -- fail
 ERROR:  searching for elements in multidimensional arrays is not supported
 -- Test variables caching
@@ -929,3 +931,60 @@ SELECT * FROM pgv_list() order by package, name;
 ---------+------+------------------
 (0 rows)
 
+-- Check insert of record with various amount of fields
+CREATE TEMP TABLE foo(id int, t text);
+INSERT INTO foo VALUES (0, 'str00');
+SELECT pgv_insert('vars', 'r1', row(1, 'str1'::text, 'str2'::text));
+ pgv_insert 
+------------
+ 
+(1 row)
+
+SELECT pgv_select('vars', 'r1');
+  pgv_select   
+---------------
+ (1,str1,str2)
+(1 row)
+
+SELECT pgv_insert('vars', 'r1', foo) FROM foo;
+ERROR:  new record structure have 2 attributes, but variable "r1" structure have 3.
+SELECT pgv_select('vars', 'r1');
+  pgv_select   
+---------------
+ (1,str1,str2)
+(1 row)
+
+SELECT pgv_insert('vars', 'r2', row(1, 'str1'));
+ pgv_insert 
+------------
+ 
+(1 row)
+
+SELECT pgv_insert('vars', 'r2', foo) FROM foo;
+ERROR:  new record attribute type for attribute number 2 differs from variable "r2" structure.
+HINT:  You may need explicit type casts.
+SELECT pgv_select('vars', 'r2');
+ pgv_select 
+------------
+ (1,str1)
+(1 row)
+
+SELECT pgv_insert('vars', 'r3', row(1, 'str1'::text));
+ pgv_insert 
+------------
+ 
+(1 row)
+
+SELECT pgv_insert('vars', 'r3', foo) FROM foo;
+ pgv_insert 
+------------
+ 
+(1 row)
+
+SELECT pgv_select('vars', 'r3');
+ pgv_select 
+------------
+ (1,str1)
+ (0,str00)
+(2 rows)
+
diff --git a/expected/pg_variables_trans.out b/expected/pg_variables_trans.out
index 2389efa..2f46e04 100644
--- a/expected/pg_variables_trans.out
+++ b/expected/pg_variables_trans.out
@@ -3773,3 +3773,59 @@ SELECT pgv_free();
  
 (1 row)
 
+---
+--- Test case for issue #32 [PGPRO-4456]
+---
+CREATE TEMP TABLE tab (id int, t varchar);
+INSERT INTO tab VALUES (0, 'str00');
+SELECT pgv_insert('vars', 'r1', row(1, 'str1', 'str2'));
+ pgv_insert 
+------------
+ 
+(1 row)
+
+SELECT pgv_insert('vars', 'a', tab) FROM tab;
+ pgv_insert 
+------------
+ 
+(1 row)
+
+SELECT pgv_insert('vars', 'r1', tab) FROM tab;
+ERROR:  new record structure have 2 attributes, but variable "r1" structure have 3.
+SELECT pgv_select('vars', 'r1');
+  pgv_select   
+---------------
+ (1,str1,str2)
+(1 row)
+
+SELECT pgv_insert('vars', 'r2', row(1, 'str1'::varchar));
+ pgv_insert 
+------------
+ 
+(1 row)
+
+SELECT pgv_insert('vars', 'b', tab) FROM tab;
+ pgv_insert 
+------------
+ 
+(1 row)
+
+SELECT pgv_insert('vars', 'r2', tab) FROM tab;
+ pgv_insert 
+------------
+ 
+(1 row)
+
+SELECT pgv_select('vars', 'r2');
+ pgv_select 
+------------
+ (1,str1)
+ (0,str00)
+(2 rows)
+
+SELECT pgv_free();
+ pgv_free 
+----------
+ 
+(1 row)
+
diff --git a/pg_variables.c b/pg_variables.c
index 4bd6bdd..b75701a 100644
--- a/pg_variables.c
+++ b/pg_variables.c
@@ -121,8 +121,6 @@ static MemoryContext ModuleContext = NULL;
 static Package *LastPackage = NULL;
 /* Recent variable */
 static Variable *LastVariable = NULL;
-/* Recent row type id */
-static Oid LastTypeId = InvalidOid;
 
 /* Saved hook values for recall */
 static ExecutorEnd_hook_type prev_ExecutorEnd = NULL;
@@ -696,35 +694,25 @@ variable_insert(PG_FUNCTION_ARGS)
 	tupTypmod = HeapTupleHeaderGetTypMod(rec);
 
 	record = &(GetActualValue(variable).record);
-	if (!record->tupdesc)
+	tupdesc = lookup_rowtype_tupdesc(tupType, tupTypmod);
+
+	if (!record->tupdesc || variable->is_deleted)
 	{
 		/*
 		 * This is the first record for the var_name. Initialize record.
 		 */
-		tupdesc = lookup_rowtype_tupdesc(tupType, tupTypmod);
 		init_record(record, tupdesc, variable);
+		variable->is_deleted = false;
 	}
-	else if (LastTypeId == RECORDOID || !OidIsValid(LastTypeId) ||
-		LastTypeId != tupType)
+	else
 	{
 		/*
 		 * We need to check attributes of the new row if this is a transient
 		 * record type or if last record has different id.
 		 */
-		tupdesc = lookup_rowtype_tupdesc(tupType, tupTypmod);
-		if (variable->is_deleted)
-		{
-			init_record(record, tupdesc, variable);
-			variable->is_deleted = false;
-		}
-		else
-		{
-			check_attributes(variable, tupdesc);
-		}
+		check_attributes(variable, tupdesc);
 	}
 
-	LastTypeId = tupType;
-
 	insert_record(variable, rec);
 
 	/* Release resources */
@@ -749,6 +737,7 @@ variable_update(PG_FUNCTION_ARGS)
 	bool		res;
 	Oid			tupType;
 	int32		tupTypmod;
+	TupleDesc	tupdesc = NULL;
 
 	/* Checks */
 	CHECK_ARGS_FOR_NULL();
@@ -801,17 +790,9 @@ variable_update(PG_FUNCTION_ARGS)
 	tupType = HeapTupleHeaderGetTypeId(rec);
 	tupTypmod = HeapTupleHeaderGetTypMod(rec);
 
-	if (LastTypeId == RECORDOID || !OidIsValid(LastTypeId) ||
-		LastTypeId != tupType)
-	{
-		TupleDesc	tupdesc = NULL;
-
-		tupdesc = lookup_rowtype_tupdesc(tupType, tupTypmod);
-		check_attributes(variable, tupdesc);
-		ReleaseTupleDesc(tupdesc);
-	}
-
-	LastTypeId = tupType;
+	tupdesc = lookup_rowtype_tupdesc(tupType, tupTypmod);
+	check_attributes(variable, tupdesc);
+	ReleaseTupleDesc(tupdesc);
 
 	res = update_record(variable, rec);
 
@@ -1337,7 +1318,6 @@ resetVariablesCache(void)
 	/* Remove package and variable from cache */
 	LastPackage = NULL;
 	LastVariable = NULL;
-	LastTypeId = InvalidOid;
 }
 
 /*
diff --git a/pg_variables_record.c b/pg_variables_record.c
index b97ffca..3d7ca18 100644
--- a/pg_variables_record.c
+++ b/pg_variables_record.c
@@ -188,8 +188,9 @@ check_attributes(Variable *variable, TupleDesc tupdesc)
 	if (record->tupdesc->natts != tupdesc->natts)
 		ereport(ERROR,
 				(errcode(ERRCODE_INVALID_PARAMETER_VALUE),
-				 errmsg("new record structure differs from variable \"%s\" "
-						"structure", GetName(variable))));
+				 errmsg("new record structure have %d attributes, but variable "
+						"\"%s\" structure have %d.",
+						tupdesc->natts, GetName(variable), record->tupdesc->natts)));
 
 	/* Second, check columns type. */
 	for (i = 0; i < tupdesc->natts; i++)
@@ -202,8 +203,10 @@ check_attributes(Variable *variable, TupleDesc tupdesc)
 			|| (attr1->atttypmod != attr2->atttypmod))
 			ereport(ERROR,
 					(errcode(ERRCODE_INVALID_PARAMETER_VALUE),
-					 errmsg("new record structure differs from variable \"%s\" "
-							"structure", GetName(variable))));
+					 errmsg("new record attribute type for attribute number %d "
+							"differs from variable \"%s\" structure.",
+							i + 1, GetName(variable)),
+					 errhint("You may need explicit type casts.")));
 	}
 }
 
diff --git a/sql/pg_variables.sql b/sql/pg_variables.sql
index a9fdbbd..bad7976 100644
--- a/sql/pg_variables.sql
+++ b/sql/pg_variables.sql
@@ -259,3 +259,19 @@ SELECT pgv_free();
 SELECT pgv_exists('vars');
 
 SELECT * FROM pgv_list() order by package, name;
+-- Check insert of record with various amount of fields
+CREATE TEMP TABLE foo(id int, t text);
+INSERT INTO foo VALUES (0, 'str00');
+
+SELECT pgv_insert('vars', 'r1', row(1, 'str1'::text, 'str2'::text));
+SELECT pgv_select('vars', 'r1');
+SELECT pgv_insert('vars', 'r1', foo) FROM foo;
+SELECT pgv_select('vars', 'r1');
+
+SELECT pgv_insert('vars', 'r2', row(1, 'str1'));
+SELECT pgv_insert('vars', 'r2', foo) FROM foo;
+SELECT pgv_select('vars', 'r2');
+
+SELECT pgv_insert('vars', 'r3', row(1, 'str1'::text));
+SELECT pgv_insert('vars', 'r3', foo) FROM foo;
+SELECT pgv_select('vars', 'r3');
diff --git a/sql/pg_variables_trans.sql b/sql/pg_variables_trans.sql
index 0d67ae1..72d9559 100644
--- a/sql/pg_variables_trans.sql
+++ b/sql/pg_variables_trans.sql
@@ -1145,3 +1145,21 @@ COMMIT;
 
 DROP VIEW pgv_stats_view;
 SELECT pgv_free();
+
+---
+--- Test case for issue #32 [PGPRO-4456]
+---
+CREATE TEMP TABLE tab (id int, t varchar);
+INSERT INTO tab VALUES (0, 'str00');
+
+SELECT pgv_insert('vars', 'r1', row(1, 'str1', 'str2'));
+SELECT pgv_insert('vars', 'a', tab) FROM tab;
+SELECT pgv_insert('vars', 'r1', tab) FROM tab;
+SELECT pgv_select('vars', 'r1');
+
+SELECT pgv_insert('vars', 'r2', row(1, 'str1'::varchar));
+SELECT pgv_insert('vars', 'b', tab) FROM tab;
+SELECT pgv_insert('vars', 'r2', tab) FROM tab;
+SELECT pgv_select('vars', 'r2');
+
+SELECT pgv_free();
