如果您有可变数量的参数,您需要:
- 声明它
VARIADIC
;
- 为具有不同数量参数的函数创建n 个不同的签名;或者
- 仅
C
创建最通用的形式,即 7 参数变体,然后为调用最通用形式的更少参数的情况创建 SQL 函数包装器。
如果你真的只需要 3、4、5、6 和 7 个参数的版本,我会这样做:
CREATE FUNCTION embed0(text,text,text,text,text,text,text) RETURNS text
LANGUAGE 'C' AS 'embed0','embed0';
CREATE OR REPLACE FUNCTION embed0(text,text,text) RETURNS text AS $$
SELECT embed0($1,$2,$2,NULL,NULL,NULL,NULL);
$$ LANGUAGE 'SQL';
// ... etc
如果 7 args 只是一个任意的上限,并且您实际上可以采用任意数量的参数,那么您应该只写:
CREATE FUNCTION embed0(text,text,text,VARIADIC text) RETURNS text
LANGUAGE 'C' AS 'embed0','embed0';
并处理函数中的变量参数C
。concat
有关如何操作的功能,请参阅 PostgreSQL 源代码。它的实现text_concat
在src/backend/utils/adt/varlena.c
当前 git head 的第 3842 行;您的行号会有所不同。大部分工作都是在concat_internal
.
另一个例子是format
具有 C 实现(text_format
通过pg_proc.h
在 虽然是一个更复杂的函数,但作为一个示例对您来说可能更好,因为它在一个地方完成所有工作,而不是拆分为辅助函数调用。它是在其中声明的,但如果它是在 SQL 中声明的,它看起来像:varlena.c
git grep '^text_format'
pg_proc.h
CREATE FUNCTION format(text, VARIADIC text) RETURNS text AS 'internal','text_format';
在那里,您会看到使用宏VARIADIC
可以像访问任何其他 from 一样访问参数。宏报告传递的参数数量。arguments 可能为 null,因此您必须使用和处理 null 参数的情况。C
PG_GETARG_...(argno)
PG_NARGS()
VARIADIC
PG_ARGISNULL(argno)
所以:我会用, ,将它写成一个VARIADIC
函数。因为 Pg 的函数不能用零可变参数隐式调用,所以我会为 3 参数情况编写一个包装器:PG_NARGS
PG_GETARG_TEXT_P
PG_ARGISNULL
VARIADIC
CREATE OR REPLACE FUNCTION embed_0(text,text,text) RETURNS text AS $$
SELECT embed_0($1,$2,$2, VARIADIC ARRAY[]::text[]);
$$ LANGUAGE 'SQL';
,传递一个空数组作为可变参数。这样你也可以用 3 个参数调用它。
顺便说一句,在编码时要注意 Pg 中的字符串text
不是以空结尾的,这与传递给main()
. 您必须使用 PostgreSQL 提供的长度。. 请参阅src/include/fmgr.h
、教程和源代码中函数中的文本处理。不要使用strlen
, strcat
,strcpy
等,因为它们需要以空字符结尾的字符串。