digoal
2022-09-20
PostgreSQL , plpgsql , record
这个patch增强了plpgsql 使用record作为输入参数类型的使用, record是一种任意row结构, 调用非常灵活.
Improve plpgsql's ability to handle arguments declared as RECORD.
author Tom Lane <tgl@sss.pgh.pa.us>
Fri, 16 Sep 2022 17:23:01 +0000 (13:23 -0400)
committer Tom Lane <tgl@sss.pgh.pa.us>
Fri, 16 Sep 2022 17:23:01 +0000 (13:23 -0400)
commit bfd6b3bc4e19db19289ae92a17799edae2cdd5f3
tree fb9ab44d1f395314fb600f5629c3c227d9901525 tree
parent d08a049db9b47c32f3e7b6985a3105cae0da3681 commit | diff
Improve plpgsql's ability to handle arguments declared as RECORD.
Treat arguments declared as RECORD as if that were a polymorphic type
(which it is, sort of), in that we substitute the actual argument type
while forming the function cache lookup key. This allows the specific
composite type to be known in some cases where it was not before,
at the cost of making a separate function cache entry for each named
composite type that's passed to the function during a session. The
particular symptom discussed in bug #17610 could be solved in other
more-efficient ways, but only at the cost of considerable development
work, and there are other cases where we'd still fail without this.
Per bug #17610 from Martin Jurča. Back-patch to v11 where we first
allowed plpgsql functions to be declared as taking type RECORD.
Discussion: https://postgr.es/m/17610-fb1eef75bf6c2364@postgresql.org
create type two_int4s as (f1 int4, f2 int4);
+create type more_int4s as (f0 text, f1 int4, f2 int4);
+select getf1(row(1,2)::two_int4s);
+ getf1
+-------
+ 1
+(1 row)
+
+select getf1(row('foo',123,456)::more_int4s);
+ getf1
+-------
+ 123
+(1 row)
+-- this seemingly-equivalent case behaves a bit differently,
+-- because the core parser's handling of N symbols is simplistic
+create function getf2(record) returns int language plpgsql as
+ begin return 1.f2; end ;
+select getf2(row(1,2)); -- ideally would work, but does not
+ERROR: could not identify column "f2" in record data type
+LINE 1: 1.f2
+ ^
+QUERY: 1.f2
+CONTEXT: PL/pgSQL function getf2(record) line 1 at RETURN
+select getf2(row(1,2)::two_int4s);
+ getf2
+-------
+ 2
+(1 row)
+
+select getf2(row('foo',123,456)::more_int4s);
+ getf2
+-------
+ 456
+(1 row)