- android - 多次调用 OnPrimaryClipChangedListener
- android - 无法更新 RecyclerView 中的 TextView 字段
- android.database.CursorIndexOutOfBoundsException : Index 0 requested, 光标大小为 0
- android - 使用 AppCompat 时,我们是否需要明确指定其 UI 组件(Spinner、EditText)颜色
我正在尝试将一些 C 测试代码转换为 PostgreSQL v1 模块
代码最初设计为一个简单的命令行,它接受可变数量的文本参数——一个数组;从 3 到 7
原始代码的声明被注释了;我现在正在尝试将其转换为 PG 共享对象函数。该函数的所有参数都是文本字符串(基本命令、选项等)
如何声明/将数组传递给函数?
PG_FUNCTION_INFO_V1(embed_0);
Datum
embed_0(PG_FUNCTION_ARGS)
// THIS was the declaration when it was a C executable:
// int main(int argc, char *argv[])
{
// don't think mapping argc to a PG type is needed here, right?
// (argc is not a parameter?)
int *argc; // = PG_GETARG_INT32(0);
char argv[] = PG_GETARG_TEXT_P(0);
int i;
Object *pName, *pCall, *pPart1, *pPart2, *pArgs, *pValue;
最佳答案
如果您有可变数量的参数,您需要:
VARIADIC
;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 个参数只是一个任意的上限,并且您实际上可以采用任意数量的参数,您应该改为只写:
CREATE FUNCTION embed0(text,text,text,VARIADIC text) RETURNS text
LANGUAGE 'C' AS 'embed0','embed0';
并处理 C
函数中的可变参数。有关操作方法,请参阅 concat
函数的 PostgreSQL 源代码。它的实现是src/backend/utils/adt/varlena.c
中的text_concat
,当前git head中第3842行;您的行号会有所不同。大部分工作在 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 个参数调用它。
顺便说一句,在编码时请注意 Pg text
中的字符串不是空终止的,这与传递给 main()
的字符串不同。您必须使用 PostgreSQL 提供的长度。。请参阅 src/include/fmgr.h
、教程和源代码中函数中的文本处理。不要使用 strlen
、strcat
、strcpy
等,因为它们需要以 null 结尾的字符串。
关于c - PostgreSQL 模块 - 如何将参数数组映射到函数中?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12679619/
我是一名优秀的程序员,十分优秀!