Skip to content

Latest commit

 

History

History
111 lines (78 loc) · 3.7 KB

20220920_01.md

File metadata and controls

111 lines (78 loc) · 3.7 KB

PostgreSQL plpgsql 函数 使用RECORD类型输入参数的增强

作者

digoal

日期

2022-09-20

标签

PostgreSQL , plpgsql , record


背景

这个patch增强了plpgsql 使用record作为输入参数类型的使用, record是一种任意row结构, 调用非常灵活.

https://git.postgresql.org/gitweb/?p=postgresql.git;a=commit;h=bfd6b3bc4e19db19289ae92a17799edae2cdd5f3

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)

digoal's wechat