如果你有一个可变参数,你需要:
- 声明它
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
在当前git头的3842行中的src/backend/utils/adt/varlena.c
;你的线路号码会有所不同。大部分工作都在concat_internal
完成。
又如format
功能,具有C实现text_format
(通过查找在pg_proc.h
),位于varlena.c
(根据git grep '^text_format'
; PG编码样式规则指定该函数名必须开始就行的硬左侧),当前git中的3953行。虽然一个更复杂的函数可能会更好地作为你的例子,因为它在一个地方完成了所有工作,而不是为辅助函数调用分开。它在声明pg_proc.h
但如果它是在SQL宣布它会看起来像:
CREATE FUNCTION format(text, VARIADIC text) RETURNS text AS 'internal','text_format';
在那里你会看到VARIADIC
参数都像任何其他从C
访问,使用PG_GETARG_...(argno)
宏。宏PG_NARGS()
报告传递的参数数量。 VARIADIC
参数可能为空,因此您必须使用PG_ARGISNULL(argno)
并处理空参数的情况。
所以:我会使用PG_NARGS
,PG_GETARG_TEXT_P
,PG_ARGISNULL
将它写成VARIADIC
函数。由于PG的VARIADIC
功能不能隐零个可变参数调用时,我会写的,因为该3个参数的情况下,包装:
CREATE OR REPLACE FUNCTION embed_0(text,text,text) RETURNS text AS $$
SELECT embed_0($1,$2,$2, VARIADIC ARRAY[]::text[]);
$$ LANGUAGE 'SQL';
,传递一个空数组作为一个可变参数。这样你可以用3个参数来调用它。
BTW,编码要知道,在PG text
中的字符串不是空终止,不像那些传递给main()
时。您必须使用PostgreSQL提供的长度。。请参阅src/include/fmgr.h
,本教程以及源代码中的函数中的文本处理。请勿使用strlen
,strcat
,strcpy
等,因为它们期望以空字符结尾的字符串。