Skip to content

Commit cb475f6

Browse files
authored
Merge pull request #36 from postgrespro/bugfix/issue-32
Bugfix/issue 32 - fix error on insert from table
2 parents 992db9f + 2e3f14f commit cb475f6

File tree

6 files changed

+169
-37
lines changed

6 files changed

+169
-37
lines changed

expected/pg_variables.out

Lines changed: 62 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -563,11 +563,13 @@ ERROR: variable "j1" requires "jsonb" value
563563
SELECT pgv_insert('vars3', 'r1', tab) FROM tab;
564564
ERROR: there is a record in the variable "r1" with same key
565565
SELECT pgv_insert('vars3', 'r1', row(1, 'str1', 'str2'));
566-
ERROR: new record structure differs from variable "r1" structure
566+
ERROR: new record structure have 3 attributes, but variable "r1" structure have 2.
567567
SELECT pgv_insert('vars3', 'r1', row(1, 1));
568-
ERROR: new record structure differs from variable "r1" structure
568+
ERROR: new record attribute type for attribute number 2 differs from variable "r1" structure.
569+
HINT: You may need explicit type casts.
569570
SELECT pgv_insert('vars3', 'r1', row('str1', 'str1'));
570-
ERROR: new record structure differs from variable "r1" structure
571+
ERROR: new record attribute type for attribute number 1 differs from variable "r1" structure.
572+
HINT: You may need explicit type casts.
571573
SELECT pgv_select('vars3', 'r1', ARRAY[[1,2]]); -- fail
572574
ERROR: searching for elements in multidimensional arrays is not supported
573575
-- Test variables caching
@@ -929,3 +931,60 @@ SELECT * FROM pgv_list() order by package, name;
929931
---------+------+------------------
930932
(0 rows)
931933

934+
-- Check insert of record with various amount of fields
935+
CREATE TEMP TABLE foo(id int, t text);
936+
INSERT INTO foo VALUES (0, 'str00');
937+
SELECT pgv_insert('vars', 'r1', row(1, 'str1'::text, 'str2'::text));
938+
pgv_insert
939+
------------
940+
941+
(1 row)
942+
943+
SELECT pgv_select('vars', 'r1');
944+
pgv_select
945+
---------------
946+
(1,str1,str2)
947+
(1 row)
948+
949+
SELECT pgv_insert('vars', 'r1', foo) FROM foo;
950+
ERROR: new record structure have 2 attributes, but variable "r1" structure have 3.
951+
SELECT pgv_select('vars', 'r1');
952+
pgv_select
953+
---------------
954+
(1,str1,str2)
955+
(1 row)
956+
957+
SELECT pgv_insert('vars', 'r2', row(1, 'str1'));
958+
pgv_insert
959+
------------
960+
961+
(1 row)
962+
963+
SELECT pgv_insert('vars', 'r2', foo) FROM foo;
964+
ERROR: new record attribute type for attribute number 2 differs from variable "r2" structure.
965+
HINT: You may need explicit type casts.
966+
SELECT pgv_select('vars', 'r2');
967+
pgv_select
968+
------------
969+
(1,str1)
970+
(1 row)
971+
972+
SELECT pgv_insert('vars', 'r3', row(1, 'str1'::text));
973+
pgv_insert
974+
------------
975+
976+
(1 row)
977+
978+
SELECT pgv_insert('vars', 'r3', foo) FROM foo;
979+
pgv_insert
980+
------------
981+
982+
(1 row)
983+
984+
SELECT pgv_select('vars', 'r3');
985+
pgv_select
986+
------------
987+
(1,str1)
988+
(0,str00)
989+
(2 rows)
990+

expected/pg_variables_trans.out

Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3773,3 +3773,59 @@ SELECT pgv_free();
37733773

37743774
(1 row)
37753775

3776+
---
3777+
--- Test case for issue #32 [PGPRO-4456]
3778+
---
3779+
CREATE TEMP TABLE tab (id int, t varchar);
3780+
INSERT INTO tab VALUES (0, 'str00');
3781+
SELECT pgv_insert('vars', 'r1', row(1, 'str1', 'str2'));
3782+
pgv_insert
3783+
------------
3784+
3785+
(1 row)
3786+
3787+
SELECT pgv_insert('vars', 'a', tab) FROM tab;
3788+
pgv_insert
3789+
------------
3790+
3791+
(1 row)
3792+
3793+
SELECT pgv_insert('vars', 'r1', tab) FROM tab;
3794+
ERROR: new record structure have 2 attributes, but variable "r1" structure have 3.
3795+
SELECT pgv_select('vars', 'r1');
3796+
pgv_select
3797+
---------------
3798+
(1,str1,str2)
3799+
(1 row)
3800+
3801+
SELECT pgv_insert('vars', 'r2', row(1, 'str1'::varchar));
3802+
pgv_insert
3803+
------------
3804+
3805+
(1 row)
3806+
3807+
SELECT pgv_insert('vars', 'b', tab) FROM tab;
3808+
pgv_insert
3809+
------------
3810+
3811+
(1 row)
3812+
3813+
SELECT pgv_insert('vars', 'r2', tab) FROM tab;
3814+
pgv_insert
3815+
------------
3816+
3817+
(1 row)
3818+
3819+
SELECT pgv_select('vars', 'r2');
3820+
pgv_select
3821+
------------
3822+
(1,str1)
3823+
(0,str00)
3824+
(2 rows)
3825+
3826+
SELECT pgv_free();
3827+
pgv_free
3828+
----------
3829+
3830+
(1 row)
3831+

pg_variables.c

Lines changed: 10 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -121,8 +121,6 @@ static MemoryContext ModuleContext = NULL;
121121
static Package *LastPackage = NULL;
122122
/* Recent variable */
123123
static Variable *LastVariable = NULL;
124-
/* Recent row type id */
125-
static Oid LastTypeId = InvalidOid;
126124

127125
/* Saved hook values for recall */
128126
static ExecutorEnd_hook_type prev_ExecutorEnd = NULL;
@@ -696,35 +694,25 @@ variable_insert(PG_FUNCTION_ARGS)
696694
tupTypmod = HeapTupleHeaderGetTypMod(rec);
697695

698696
record = &(GetActualValue(variable).record);
699-
if (!record->tupdesc)
697+
tupdesc = lookup_rowtype_tupdesc(tupType, tupTypmod);
698+
699+
if (!record->tupdesc || variable->is_deleted)
700700
{
701701
/*
702702
* This is the first record for the var_name. Initialize record.
703703
*/
704-
tupdesc = lookup_rowtype_tupdesc(tupType, tupTypmod);
705704
init_record(record, tupdesc, variable);
705+
variable->is_deleted = false;
706706
}
707-
else if (LastTypeId == RECORDOID || !OidIsValid(LastTypeId) ||
708-
LastTypeId != tupType)
707+
else
709708
{
710709
/*
711710
* We need to check attributes of the new row if this is a transient
712711
* record type or if last record has different id.
713712
*/
714-
tupdesc = lookup_rowtype_tupdesc(tupType, tupTypmod);
715-
if (variable->is_deleted)
716-
{
717-
init_record(record, tupdesc, variable);
718-
variable->is_deleted = false;
719-
}
720-
else
721-
{
722-
check_attributes(variable, tupdesc);
723-
}
713+
check_attributes(variable, tupdesc);
724714
}
725715

726-
LastTypeId = tupType;
727-
728716
insert_record(variable, rec);
729717

730718
/* Release resources */
@@ -749,6 +737,7 @@ variable_update(PG_FUNCTION_ARGS)
749737
bool res;
750738
Oid tupType;
751739
int32 tupTypmod;
740+
TupleDesc tupdesc = NULL;
752741

753742
/* Checks */
754743
CHECK_ARGS_FOR_NULL();
@@ -801,17 +790,9 @@ variable_update(PG_FUNCTION_ARGS)
801790
tupType = HeapTupleHeaderGetTypeId(rec);
802791
tupTypmod = HeapTupleHeaderGetTypMod(rec);
803792

804-
if (LastTypeId == RECORDOID || !OidIsValid(LastTypeId) ||
805-
LastTypeId != tupType)
806-
{
807-
TupleDesc tupdesc = NULL;
808-
809-
tupdesc = lookup_rowtype_tupdesc(tupType, tupTypmod);
810-
check_attributes(variable, tupdesc);
811-
ReleaseTupleDesc(tupdesc);
812-
}
813-
814-
LastTypeId = tupType;
793+
tupdesc = lookup_rowtype_tupdesc(tupType, tupTypmod);
794+
check_attributes(variable, tupdesc);
795+
ReleaseTupleDesc(tupdesc);
815796

816797
res = update_record(variable, rec);
817798

@@ -1337,7 +1318,6 @@ resetVariablesCache(void)
13371318
/* Remove package and variable from cache */
13381319
LastPackage = NULL;
13391320
LastVariable = NULL;
1340-
LastTypeId = InvalidOid;
13411321
}
13421322

13431323
/*

pg_variables_record.c

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -188,8 +188,9 @@ check_attributes(Variable *variable, TupleDesc tupdesc)
188188
if (record->tupdesc->natts != tupdesc->natts)
189189
ereport(ERROR,
190190
(errcode(ERRCODE_INVALID_PARAMETER_VALUE),
191-
errmsg("new record structure differs from variable \"%s\" "
192-
"structure", GetName(variable))));
191+
errmsg("new record structure have %d attributes, but variable "
192+
"\"%s\" structure have %d.",
193+
tupdesc->natts, GetName(variable), record->tupdesc->natts)));
193194

194195
/* Second, check columns type. */
195196
for (i = 0; i < tupdesc->natts; i++)
@@ -202,8 +203,10 @@ check_attributes(Variable *variable, TupleDesc tupdesc)
202203
|| (attr1->atttypmod != attr2->atttypmod))
203204
ereport(ERROR,
204205
(errcode(ERRCODE_INVALID_PARAMETER_VALUE),
205-
errmsg("new record structure differs from variable \"%s\" "
206-
"structure", GetName(variable))));
206+
errmsg("new record attribute type for attribute number %d "
207+
"differs from variable \"%s\" structure.",
208+
i + 1, GetName(variable)),
209+
errhint("You may need explicit type casts.")));
207210
}
208211
}
209212

sql/pg_variables.sql

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -259,3 +259,19 @@ SELECT pgv_free();
259259
SELECT pgv_exists('vars');
260260

261261
SELECT * FROM pgv_list() order by package, name;
262+
-- Check insert of record with various amount of fields
263+
CREATE TEMP TABLE foo(id int, t text);
264+
INSERT INTO foo VALUES (0, 'str00');
265+
266+
SELECT pgv_insert('vars', 'r1', row(1, 'str1'::text, 'str2'::text));
267+
SELECT pgv_select('vars', 'r1');
268+
SELECT pgv_insert('vars', 'r1', foo) FROM foo;
269+
SELECT pgv_select('vars', 'r1');
270+
271+
SELECT pgv_insert('vars', 'r2', row(1, 'str1'));
272+
SELECT pgv_insert('vars', 'r2', foo) FROM foo;
273+
SELECT pgv_select('vars', 'r2');
274+
275+
SELECT pgv_insert('vars', 'r3', row(1, 'str1'::text));
276+
SELECT pgv_insert('vars', 'r3', foo) FROM foo;
277+
SELECT pgv_select('vars', 'r3');

sql/pg_variables_trans.sql

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1145,3 +1145,21 @@ COMMIT;
11451145

11461146
DROP VIEW pgv_stats_view;
11471147
SELECT pgv_free();
1148+
1149+
---
1150+
--- Test case for issue #32 [PGPRO-4456]
1151+
---
1152+
CREATE TEMP TABLE tab (id int, t varchar);
1153+
INSERT INTO tab VALUES (0, 'str00');
1154+
1155+
SELECT pgv_insert('vars', 'r1', row(1, 'str1', 'str2'));
1156+
SELECT pgv_insert('vars', 'a', tab) FROM tab;
1157+
SELECT pgv_insert('vars', 'r1', tab) FROM tab;
1158+
SELECT pgv_select('vars', 'r1');
1159+
1160+
SELECT pgv_insert('vars', 'r2', row(1, 'str1'::varchar));
1161+
SELECT pgv_insert('vars', 'b', tab) FROM tab;
1162+
SELECT pgv_insert('vars', 'r2', tab) FROM tab;
1163+
SELECT pgv_select('vars', 'r2');
1164+
1165+
SELECT pgv_free();

0 commit comments

Comments
 (0)