Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit5683b34

Browse files
committed
Ensure plpgsql result tuples have the right composite type marking.
A function that is declared to return a named composite type mustreturn tuple datums that are physically marked as having that type.The plpgsql code path that allowed directly returning an expanded-recorddatum forgot to check that, so that an expanded record marked as typeRECORDOID could be returned if it had a physically-compatible tupdesc.This'd be harmless, I think, if the record value never escaped thecurrent session --- but it's possible for it to get stored into a table,and then subsequent sessions can't interpret the anonymous record type.Fix by flattening the record into a tuple datum and overwriting itstype/typmod fields, if its declared type doesn't match the function'sdeclared type. (In principle it might be possible to just change theexpanded record's stored type ID info, but there are enough trickyconsequences that I didn't want to mess with that, especially not ina back-patched bug fix.)Per bug report from Steve Rogerson. Back-patch to v11 where the bugwas introduced.Discussion:https://postgr.es/m/cbaecae6-7b87-584e-45f6-4d047b92ca2a@yewtc.demon.co.uk
1 parent03e7b30 commit5683b34

File tree

3 files changed

+48
-0
lines changed

3 files changed

+48
-0
lines changed

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

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -654,3 +654,16 @@ NOTICE: processing row 2
654654
NOTICE: processing row 3
655655
ERROR: value for domain ordered_texts violates check constraint "ordered_texts_check"
656656
CONTEXT: PL/pgSQL function inline_code_block line 8 at assignment
657+
-- check coercion of a record result to named-composite function output type
658+
create function compresult(int8) returns two_int8s language plpgsql as
659+
$$ declare r record; begin r := row($1,$1); return r; end $$;
660+
create table two_int8s_tab (f1 two_int8s);
661+
insert into two_int8s_tab values (compresult(42));
662+
-- reconnect so we lose any local knowledge of anonymous record types
663+
\c -
664+
table two_int8s_tab;
665+
f1
666+
---------
667+
(42,42)
668+
(1 row)
669+

‎src/pl/plpgsql/src/pl_exec.c

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -808,6 +808,31 @@ coerce_function_result_tuple(PLpgSQL_execstate *estate, TupleDesc tupdesc)
808808
estate->retval=PointerGetDatum(SPI_returntuple(rettup,tupdesc));
809809
/* no need to free map, we're about to return anyway */
810810
}
811+
elseif (!(tupdesc->tdtypeid==erh->er_decltypeid||
812+
(tupdesc->tdtypeid==RECORDOID&&
813+
!ExpandedRecordIsDomain(erh))))
814+
{
815+
/*
816+
* The expanded record has the right physical tupdesc, but the
817+
* wrong type ID. (Typically, the expanded record is RECORDOID
818+
* but the function is declared to return a named composite type.
819+
* As in exec_move_row_from_datum, we don't allow returning a
820+
* composite-domain record from a function declared to return
821+
* RECORD.) So we must flatten the record to a tuple datum and
822+
* overwrite its type fields with the right thing. spi.c doesn't
823+
* provide any easy way to deal with this case, so we end up
824+
* duplicating the guts of datumCopy() :-(
825+
*/
826+
Sizeresultsize;
827+
HeapTupleHeadertuphdr;
828+
829+
resultsize=EOH_get_flat_size(&erh->hdr);
830+
tuphdr= (HeapTupleHeader)SPI_palloc(resultsize);
831+
EOH_flatten_into(&erh->hdr, (void*)tuphdr,resultsize);
832+
HeapTupleHeaderSetTypeId(tuphdr,tupdesc->tdtypeid);
833+
HeapTupleHeaderSetTypMod(tuphdr,tupdesc->tdtypmod);
834+
estate->retval=PointerGetDatum(tuphdr);
835+
}
811836
else
812837
{
813838
/*

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

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -441,3 +441,13 @@ begin
441441
d.f2 :=r.b;
442442
end loop;
443443
end$$;
444+
445+
-- check coercion of a record result to named-composite function output type
446+
createfunctioncompresult(int8) returns two_int8s language plpgsqlas
447+
$$ declare r record;begin r := row($1,$1); return r; end $$;
448+
449+
createtabletwo_int8s_tab (f1 two_int8s);
450+
insert into two_int8s_tabvalues (compresult(42));
451+
-- reconnect so we lose any local knowledge of anonymous record types
452+
\c-
453+
table two_int8s_tab;

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp