aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/backend/access/common/attmap.c28
-rw-r--r--src/pl/plpgsql/src/expected/plpgsql_record.out26
-rw-r--r--src/pl/plpgsql/src/sql/plpgsql_record.sql8
-rw-r--r--src/test/regress/expected/plpgsql.out2
4 files changed, 41 insertions, 23 deletions
diff --git a/src/backend/access/common/attmap.c b/src/backend/access/common/attmap.c
index 4b6cfe05c02..4901ebecef7 100644
--- a/src/backend/access/common/attmap.c
+++ b/src/backend/access/common/attmap.c
@@ -96,33 +96,31 @@ build_attrmap_by_position(TupleDesc indesc,
same = true;
for (i = 0; i < n; i++)
{
- Form_pg_attribute att = TupleDescAttr(outdesc, i);
- Oid atttypid;
- int32 atttypmod;
+ Form_pg_attribute outatt = TupleDescAttr(outdesc, i);
- if (att->attisdropped)
+ if (outatt->attisdropped)
continue; /* attrMap->attnums[i] is already 0 */
noutcols++;
- atttypid = att->atttypid;
- atttypmod = att->atttypmod;
for (; j < indesc->natts; j++)
{
- att = TupleDescAttr(indesc, j);
- if (att->attisdropped)
+ Form_pg_attribute inatt = TupleDescAttr(indesc, j);
+
+ if (inatt->attisdropped)
continue;
nincols++;
/* Found matching column, now check type */
- if (atttypid != att->atttypid ||
- (atttypmod != att->atttypmod && atttypmod >= 0))
+ if (outatt->atttypid != inatt->atttypid ||
+ (outatt->atttypmod != inatt->atttypmod && outatt->atttypmod >= 0))
ereport(ERROR,
(errcode(ERRCODE_DATATYPE_MISMATCH),
errmsg_internal("%s", _(msg)),
- errdetail("Returned type %s does not match expected type %s in column %d.",
- format_type_with_typemod(att->atttypid,
- att->atttypmod),
- format_type_with_typemod(atttypid,
- atttypmod),
+ errdetail("Returned type %s does not match expected type %s in column \"%s\" (position %d).",
+ format_type_with_typemod(inatt->atttypid,
+ inatt->atttypmod),
+ format_type_with_typemod(outatt->atttypid,
+ outatt->atttypmod),
+ NameStr(outatt->attname),
noutcols)));
attrMap->attnums[i] = (AttrNumber) (j + 1);
j++;
diff --git a/src/pl/plpgsql/src/expected/plpgsql_record.out b/src/pl/plpgsql/src/expected/plpgsql_record.out
index 6974c8f4a44..e5de7143606 100644
--- a/src/pl/plpgsql/src/expected/plpgsql_record.out
+++ b/src/pl/plpgsql/src/expected/plpgsql_record.out
@@ -28,7 +28,7 @@ create or replace function retc(int) returns two_int8s language plpgsql as
$$ begin return row($1,1); end $$;
select retc(42);
ERROR: returned record type does not match expected record type
-DETAIL: Returned type integer does not match expected type bigint in column 1.
+DETAIL: Returned type integer does not match expected type bigint in column "q1" (position 1).
CONTEXT: PL/pgSQL function retc(integer) while casting return value to function's return type
-- nor extra columns
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
$$ declare r record; begin r := row($1,1); return r; end $$;
select retc(42);
ERROR: returned record type does not match expected record type
-DETAIL: Returned type integer does not match expected type bigint in column 1.
+DETAIL: Returned type integer does not match expected type bigint in column "q1" (position 1).
CONTEXT: PL/pgSQL function retc(integer) while casting return value to function's return type
create or replace function retc(int) returns two_int8s language plpgsql as
$$ 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)
CONTEXT: PL/pgSQL function returnsrecord(integer) while casting return value to function's return type
select * from returnsrecord(42) as r(x int, y bigint); -- fail
ERROR: returned record type does not match expected record type
-DETAIL: Returned type integer does not match expected type bigint in column 2.
+DETAIL: Returned type integer does not match expected type bigint in column "y" (position 2).
CONTEXT: PL/pgSQL function returnsrecord(integer) while casting return value to function's return type
-- same with an intermediate record variable
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)
CONTEXT: PL/pgSQL function returnsrecord(integer) while casting return value to function's return type
select * from returnsrecord(42) as r(x int, y bigint); -- fail
ERROR: returned record type does not match expected record type
-DETAIL: Returned type integer does not match expected type bigint in column 2.
+DETAIL: Returned type integer does not match expected type bigint in column "y" (position 2).
CONTEXT: PL/pgSQL function returnsrecord(integer) while casting return value to function's return type
-- should work the same with a missing column in the actual result value
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)
CONTEXT: PL/pgSQL function returnsrecord(integer) while casting return value to function's return type
select * from returnsrecord(42) as r(x int, y bigint); -- fail
ERROR: returned record type does not match expected record type
-DETAIL: Returned type integer does not match expected type bigint in column 2.
+DETAIL: Returned type integer does not match expected type bigint in column "y" (position 2).
CONTEXT: PL/pgSQL function returnsrecord(integer) while casting return value to function's return type
-- same with an intermediate record variable
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)
CONTEXT: PL/pgSQL function returnsrecord(integer) while casting return value to function's return type
select * from returnsrecord(42) as r(x int, y bigint); -- fail
ERROR: returned record type does not match expected record type
-DETAIL: Returned type integer does not match expected type bigint in column 2.
+DETAIL: Returned type integer does not match expected type bigint in column "y" (position 2).
CONTEXT: PL/pgSQL function returnsrecord(integer) while casting return value to function's return type
-- check access to a field of an argument declared "record"
create function getf1(x record) returns int language plpgsql as
@@ -545,6 +545,7 @@ begin
return next h;
return next row(5,6);
return next row(7,8)::has_hole;
+ return query select 9, 10;
end$$;
select returnssetofholes();
returnssetofholes
@@ -554,7 +555,8 @@ select returnssetofholes();
(3,4)
(5,6)
(7,8)
-(5 rows)
+ (9,10)
+(6 rows)
create or replace function returnssetofholes() returns setof has_hole language plpgsql as
$$
@@ -575,6 +577,16 @@ select returnssetofholes();
ERROR: returned record type does not match expected record type
DETAIL: Number of returned columns (3) does not match expected column count (2).
CONTEXT: PL/pgSQL function returnssetofholes() line 3 at RETURN NEXT
+create or replace function returnssetofholes() returns setof has_hole language plpgsql as
+$$
+begin
+ return query select 1, 2.0; -- fails
+end$$;
+select returnssetofholes();
+ERROR: structure of query does not match function result type
+DETAIL: Returned type numeric does not match expected type integer in column "f3" (position 2).
+CONTEXT: SQL statement "select 1, 2.0"
+PL/pgSQL function returnssetofholes() line 3 at RETURN QUERY
-- check behavior with changes of a named rowtype
create table mutable(f1 int, f2 text);
create function sillyaddone(int) returns int language plpgsql as
diff --git a/src/pl/plpgsql/src/sql/plpgsql_record.sql b/src/pl/plpgsql/src/sql/plpgsql_record.sql
index 96dcc414e92..4fbed38b8bb 100644
--- a/src/pl/plpgsql/src/sql/plpgsql_record.sql
+++ b/src/pl/plpgsql/src/sql/plpgsql_record.sql
@@ -338,6 +338,7 @@ begin
return next h;
return next row(5,6);
return next row(7,8)::has_hole;
+ return query select 9, 10;
end$$;
select returnssetofholes();
@@ -356,6 +357,13 @@ begin
end$$;
select returnssetofholes();
+create or replace function returnssetofholes() returns setof has_hole language plpgsql as
+$$
+begin
+ return query select 1, 2.0; -- fails
+end$$;
+select returnssetofholes();
+
-- check behavior with changes of a named rowtype
create table mutable(f1 int, f2 text);
diff --git a/src/test/regress/expected/plpgsql.out b/src/test/regress/expected/plpgsql.out
index c5f73fef297..d8ce39dba3c 100644
--- a/src/test/regress/expected/plpgsql.out
+++ b/src/test/regress/expected/plpgsql.out
@@ -3779,7 +3779,7 @@ end;
$$ language plpgsql;
select compos();
ERROR: returned record type does not match expected record type
-DETAIL: Returned type unknown does not match expected type character varying in column 2.
+DETAIL: Returned type unknown does not match expected type character varying in column "y" (position 2).
CONTEXT: PL/pgSQL function compos() while casting return value to function's return type
-- ... but this does
create or replace function compos() returns compostype as $$