Location via proxy:   [ UP ]  
[Report a bug]   [Manage cookies]                
Skip to content

Commit 34c3c5c

Browse files
tglsfdcjianhe-funewie
committed
Include column name in build_attrmap_by_position's error reports.
Formerly we only provided the column number, but it's frequently more useful to mention the column name. The input tupdesc often doesn't have useful column names, but the output tupdesc usually contains user-supplied names, so report that one. Author: Marcos Pegoraro <marcos@f10.com.br> Co-authored-by: jian he <jian.universality@gmail.com> Co-authored-by: Tom Lane <tgl@sss.pgh.pa.us> Co-authored-by: Erik Wienhold <ewie@ewie.name> Reviewed-by: Vladlen Popolitov <v.popolitov@postgrespro.ru> Discussion: https://postgr.es/m/CAB-JLwanky28gjAMdnMh1CjyO1b2zLdr6UOA1-oY9G7PVL9KKQ@mail.gmail.com
1 parent b48832c commit 34c3c5c

File tree

4 files changed

+41
-23
lines changed

4 files changed

+41
-23
lines changed

src/backend/access/common/attmap.c

Lines changed: 13 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -96,33 +96,31 @@ build_attrmap_by_position(TupleDesc indesc,
9696
same = true;
9797
for (i = 0; i < n; i++)
9898
{
99-
Form_pg_attribute att = TupleDescAttr(outdesc, i);
100-
Oid atttypid;
101-
int32 atttypmod;
99+
Form_pg_attribute outatt = TupleDescAttr(outdesc, i);
102100

103-
if (att->attisdropped)
101+
if (outatt->attisdropped)
104102
continue; /* attrMap->attnums[i] is already 0 */
105103
noutcols++;
106-
atttypid = att->atttypid;
107-
atttypmod = att->atttypmod;
108104
for (; j < indesc->natts; j++)
109105
{
110-
att = TupleDescAttr(indesc, j);
111-
if (att->attisdropped)
106+
Form_pg_attribute inatt = TupleDescAttr(indesc, j);
107+
108+
if (inatt->attisdropped)
112109
continue;
113110
nincols++;
114111

115112
/* Found matching column, now check type */
116-
if (atttypid != att->atttypid ||
117-
(atttypmod != att->atttypmod && atttypmod >= 0))
113+
if (outatt->atttypid != inatt->atttypid ||
114+
(outatt->atttypmod != inatt->atttypmod && outatt->atttypmod >= 0))
118115
ereport(ERROR,
119116
(errcode(ERRCODE_DATATYPE_MISMATCH),
120117
errmsg_internal("%s", _(msg)),
121-
errdetail("Returned type %s does not match expected type %s in column %d.",
122-
format_type_with_typemod(att->atttypid,
123-
att->atttypmod),
124-
format_type_with_typemod(atttypid,
125-
atttypmod),
118+
errdetail("Returned type %s does not match expected type %s in column \"%s\" (position %d).",
119+
format_type_with_typemod(inatt->atttypid,
120+
inatt->atttypmod),
121+
format_type_with_typemod(outatt->atttypid,
122+
outatt->atttypmod),
123+
NameStr(outatt->attname),
126124
noutcols)));
127125
attrMap->attnums[i] = (AttrNumber) (j + 1);
128126
j++;

src/pl/plpgsql/src/expected/plpgsql_record.out

Lines changed: 19 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ create or replace function retc(int) returns two_int8s language plpgsql as
2828
$$ begin return row($1,1); end $$;
2929
select retc(42);
3030
ERROR: returned record type does not match expected record type
31-
DETAIL: Returned type integer does not match expected type bigint in column 1.
31+
DETAIL: Returned type integer does not match expected type bigint in column "q1" (position 1).
3232
CONTEXT: PL/pgSQL function retc(integer) while casting return value to function's return type
3333
-- nor extra columns
3434
create or replace function retc(int) returns two_int8s language plpgsql as
@@ -50,7 +50,7 @@ create or replace function retc(int) returns two_int8s language plpgsql as
5050
$$ declare r record; begin r := row($1,1); return r; end $$;
5151
select retc(42);
5252
ERROR: returned record type does not match expected record type
53-
DETAIL: Returned type integer does not match expected type bigint in column 1.
53+
DETAIL: Returned type integer does not match expected type bigint in column "q1" (position 1).
5454
CONTEXT: PL/pgSQL function retc(integer) while casting return value to function's return type
5555
create or replace function retc(int) returns two_int8s language plpgsql as
5656
$$ declare r record; begin r := row($1::int8, 1::int8, 42); return r; end $$;
@@ -386,7 +386,7 @@ DETAIL: Number of returned columns (2) does not match expected column count (3)
386386
CONTEXT: PL/pgSQL function returnsrecord(integer) while casting return value to function's return type
387387
select * from returnsrecord(42) as r(x int, y bigint); -- fail
388388
ERROR: returned record type does not match expected record type
389-
DETAIL: Returned type integer does not match expected type bigint in column 2.
389+
DETAIL: Returned type integer does not match expected type bigint in column "y" (position 2).
390390
CONTEXT: PL/pgSQL function returnsrecord(integer) while casting return value to function's return type
391391
-- same with an intermediate record variable
392392
create or replace function returnsrecord(int) returns record language plpgsql as
@@ -409,7 +409,7 @@ DETAIL: Number of returned columns (2) does not match expected column count (3)
409409
CONTEXT: PL/pgSQL function returnsrecord(integer) while casting return value to function's return type
410410
select * from returnsrecord(42) as r(x int, y bigint); -- fail
411411
ERROR: returned record type does not match expected record type
412-
DETAIL: Returned type integer does not match expected type bigint in column 2.
412+
DETAIL: Returned type integer does not match expected type bigint in column "y" (position 2).
413413
CONTEXT: PL/pgSQL function returnsrecord(integer) while casting return value to function's return type
414414
-- should work the same with a missing column in the actual result value
415415
create table has_hole(f1 int, f2 int, f3 int);
@@ -434,7 +434,7 @@ DETAIL: Number of returned columns (2) does not match expected column count (3)
434434
CONTEXT: PL/pgSQL function returnsrecord(integer) while casting return value to function's return type
435435
select * from returnsrecord(42) as r(x int, y bigint); -- fail
436436
ERROR: returned record type does not match expected record type
437-
DETAIL: Returned type integer does not match expected type bigint in column 2.
437+
DETAIL: Returned type integer does not match expected type bigint in column "y" (position 2).
438438
CONTEXT: PL/pgSQL function returnsrecord(integer) while casting return value to function's return type
439439
-- same with an intermediate record variable
440440
create or replace function returnsrecord(int) returns record language plpgsql as
@@ -457,7 +457,7 @@ DETAIL: Number of returned columns (2) does not match expected column count (3)
457457
CONTEXT: PL/pgSQL function returnsrecord(integer) while casting return value to function's return type
458458
select * from returnsrecord(42) as r(x int, y bigint); -- fail
459459
ERROR: returned record type does not match expected record type
460-
DETAIL: Returned type integer does not match expected type bigint in column 2.
460+
DETAIL: Returned type integer does not match expected type bigint in column "y" (position 2).
461461
CONTEXT: PL/pgSQL function returnsrecord(integer) while casting return value to function's return type
462462
-- check access to a field of an argument declared "record"
463463
create function getf1(x record) returns int language plpgsql as
@@ -545,6 +545,7 @@ begin
545545
return next h;
546546
return next row(5,6);
547547
return next row(7,8)::has_hole;
548+
return query select 9, 10;
548549
end$$;
549550
select returnssetofholes();
550551
returnssetofholes
@@ -554,7 +555,8 @@ select returnssetofholes();
554555
(3,4)
555556
(5,6)
556557
(7,8)
557-
(5 rows)
558+
(9,10)
559+
(6 rows)
558560

559561
create or replace function returnssetofholes() returns setof has_hole language plpgsql as
560562
$$
@@ -575,6 +577,16 @@ select returnssetofholes();
575577
ERROR: returned record type does not match expected record type
576578
DETAIL: Number of returned columns (3) does not match expected column count (2).
577579
CONTEXT: PL/pgSQL function returnssetofholes() line 3 at RETURN NEXT
580+
create or replace function returnssetofholes() returns setof has_hole language plpgsql as
581+
$$
582+
begin
583+
return query select 1, 2.0; -- fails
584+
end$$;
585+
select returnssetofholes();
586+
ERROR: structure of query does not match function result type
587+
DETAIL: Returned type numeric does not match expected type integer in column "f3" (position 2).
588+
CONTEXT: SQL statement "select 1, 2.0"
589+
PL/pgSQL function returnssetofholes() line 3 at RETURN QUERY
578590
-- check behavior with changes of a named rowtype
579591
create table mutable(f1 int, f2 text);
580592
create function sillyaddone(int) returns int language plpgsql as

src/pl/plpgsql/src/sql/plpgsql_record.sql

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -338,6 +338,7 @@ begin
338338
return next h;
339339
return next row(5,6);
340340
return next row(7,8)::has_hole;
341+
return query select 9, 10;
341342
end$$;
342343
select returnssetofholes();
343344

@@ -356,6 +357,13 @@ begin
356357
end$$;
357358
select returnssetofholes();
358359

360+
create or replace function returnssetofholes() returns setof has_hole language plpgsql as
361+
$$
362+
begin
363+
return query select 1, 2.0; -- fails
364+
end$$;
365+
select returnssetofholes();
366+
359367
-- check behavior with changes of a named rowtype
360368
create table mutable(f1 int, f2 text);
361369

src/test/regress/expected/plpgsql.out

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3779,7 +3779,7 @@ end;
37793779
$$ language plpgsql;
37803780
select compos();
37813781
ERROR: returned record type does not match expected record type
3782-
DETAIL: Returned type unknown does not match expected type character varying in column 2.
3782+
DETAIL: Returned type unknown does not match expected type character varying in column "y" (position 2).
37833783
CONTEXT: PL/pgSQL function compos() while casting return value to function's return type
37843784
-- ... but this does
37853785
create or replace function compos() returns compostype as $$

0 commit comments

Comments
 (0)