gpt4 book ai didi

c - PostgreSQL的C语言函数对字符串进行操作

转载 作者:太空宇宙 更新时间:2023-11-04 01:19:51 25 4
gpt4 key购买 nike

我想创建一个 postgresql c 语言函数,其参数和返回值为 varchar,并在处理期间使用 Char []。

但是,它并没有像预期的那样工作。

我做了一个这样的c程序。

#include <postgres.h>
#include <port.h>
#include <fmgr.h>
#include <stdlib.h>

#ifdef PG_MODULE_MAGIC
PG_MODULE_MAGIC;
#endif

// Required for windows.
extern PGDLLEXPORT Datum VARCHAR_CHAR_ARRAY_VARCHAR(PG_FUNCTION_ARGS);

PG_FUNCTION_INFO_V1(VARCHAR_CHAR_ARRAY_VARCHAR);

Datum VARCHAR_CHAR_ARRAY_VARCHAR(PG_FUNCTION_ARGS) {
// Get arg.
VarChar *arg1 = (VarChar *)PG_GETARG_VARCHAR_P(0);

// VarChar to Char[].
char *c = (char *)VARDATA(arg1);

elog(NOTICE, "VarChar to Char[].");
elog(NOTICE, c);//Log1

// Do something.(e.g. replace)
// Since it uses another system, it must be Char [].

//Char[] to VarChar.
VarChar *rtn = (VarChar *)VARDATA(c);
elog(NOTICE, "Char[] to VarChar.");
elog(NOTICE, rtn);//Log2

// Return VarChar.
PG_RETURN_VARCHAR_P(rtn);
}

并且,创建了这样一个脚本。

CREATE OR REPLACE FUNCTION public.VARCHAR_CHAR_ARRAY_VARCHAR(character varying)
RETURNS character varying AS
'$libdir/test/VARCHAR_CHAR_ARRAY_VARCHAR.dll', 'VARCHAR_CHAR_ARRAY_VARCHAR'
LANGUAGE c VOLATILE STRICT;

执行结果是这样的

SELECT VARCHAR_CHAR_ARRAY_VARCHAR('a');
-- Expected value: 'a'
-- Postgresql terminated abnormally... :(

SELECT VARCHAR_CHAR_ARRAY_VARCHAR('Action');
-- Expected return value: 'Action'
-- Actual return value :'n'
-- Log1 :'NOTICE: n'
-- Log2 :''

SELECT VARCHAR_CHAR_ARRAY_VARCHAR('ActionAction');
-- Expected return value: 'ActionAction'
-- Actual return value : '' <-Why?
-- Log1 :''
-- Log2 :''

SELECT VARCHAR_CHAR_ARRAY_VARCHAR('Action Action');
-- Expected return value: 'Action Action'
-- Actual return value : 'n Action'
-- Log1 :'NOTICE: Action Action'
-- Log2 :'NOTICE: ction'

SELECT VARCHAR_CHAR_ARRAY_VARCHAR('1234567890');
-- Expected return value: '1234567890'
-- Actual return value : '6789'
-- Log1 :'NOTICE: 1234567890'
-- Log2 :'NOTICE: 90'

执行环境:

  • Windows Server 2012 R2 x64
  • PostgreSQL 9.5.9,由 Visual C++ build 1800 编译,64 位

我是第一次使用 C 语言,所以很高兴提供示例代码。

对不起,我的英语不好。

最佳答案

像这样手动构造一个 textVarChar 是行不通的。你不能只是

VarChar *rtn = (VarChar *)VARDATA(c);

因为您在那里所做的是尝试将 char*c 解释为 VarChar*,读取前几个字节作为 VARLENA header ,然后在其中获取一些子字符串作为值。不会工作。

使用 cstring_to_texttext_to_cstring 进行转换要容易。 text*VarChar* 完全兼容。 (它们在 utils/builtins.h 中)。

例如

 PG_RETURN_VARCHAR_P(cstring_to_text(c));

要手动执行此操作,必须palloc strlen 字节的字符串 + VARHDRSIZESET_VARSIZE,然后strcpy 数据到 VARDATA 偏移量。请参见 src/include/utils/varlena.hsrc/backend/utils/adt/varlena.c。当 PostgreSQL 具有用于此目的的辅助函数时,这很繁琐且没有必要。

我个人建议在 C 级编程中完全忽略 varchar。将您的函数定义为接受和返回 text

关于c - PostgreSQL的C语言函数对字符串进行操作,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46967377/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com