PostgreSQL C字符串到字符的内部表示法
我正在尝试将C字符串转换为PostgreSQL的字符内部表示形式。我正在PostgreSQL C字符串到字符的内部表示法,postgresql,Postgresql,我正在尝试将C字符串转换为PostgreSQL的字符内部表示形式。我正在varchar.c中使用bpcharin函数。此函数需要两个参数:C字符串数据和atttypmod。需要指出的是,atttypmod是类型的声明长度加上VARHDRSZ 我的转换功能是: result = DirectFunctionCall2(bpcharin, CStringGetDatum(str), VARHDRSZ +
varchar.c
中使用bpcharin
函数。此函数需要两个参数:C字符串数据和atttypmod
。需要指出的是,atttypmod
是类型的声明长度加上VARHDRSZ
我的转换功能是:
result = DirectFunctionCall2(bpcharin,
CStringGetDatum(str),
VARHDRSZ + ?);
我的字符串str
值将是我的表的列数据类型之一。因此,我需要声明的列数据类型长度。此信息存储在信息\u架构的字符\u最大长度列中
我的问题是,如何在C代码中获得字符的最大长度
多谢各位 除非您使用的是char
数据类型,否则不需要bpchar
一个简单的CStringGetDatum
(用于cstring
类型化值)或cstringgettextdatatum
(用于text
类型化值)就足够了
似乎您正在使用char(n)
,即bpchar
。坦率地说,最好的办法是不要那样做;这是一种奇怪的类型,在几乎所有情况下都应该用纯文本
或varchar
替换
如果你必须使用它。。。好吧,让我们看一看pg_cast
:
regress=> select c.*, tfrom.typname, f.proname
from pg_cast c
inner join pg_type tfrom on c.castsource = tfrom.oid
inner join pg_type tto on c.casttarget = tto.oid
left outer join pg_proc f on c.castfunc = f.oid
where tto.typname = 'bpchar';
castsource | casttarget | castfunc | castcontext | castmethod | typname | proname
------------+------------+----------+-------------+------------+---------+---------
25 | 1042 | 0 | i | b | text |
1043 | 1042 | 0 | i | b | varchar |
18 | 1042 | 860 | a | f | char | bpchar
19 | 1042 | 408 | a | f | name | bpchar
650 | 1042 | 730 | a | f | cidr | text
869 | 1042 | 730 | a | f | inet | text
16 | 1042 | 2971 | a | f | bool | text
142 | 1042 | 0 | a | b | xml |
1042 | 1042 | 668 | i | f | bpchar | bpchar
(9 rows)
对于text
和varchar
,有castmethod='b'
条目。根据手册,b
表示:
类型是二进制强制的,因此不需要转换
。。。因此,您可以使用cstringgettextdatam
生成bpchar
。但是,不会执行长度检查
如果要进行类型检查,必须调用bpchar
函数,该函数在char-to-char转换中调用。它将执行长度检查/截断。它需要三个参数-文本、最大长度以及是隐式还是显式转换
e、 g.(未经测试):
最后一个参数控制截断规则;有关详细信息,请参见src/backend/utils/adt/varchar.c
中的bpchar
注释。我使用的是char
数据类型。在这种情况下应该怎么做?@user2761431 Blech-最好不要使用bpchar
。但请参见上面的编辑。谢谢您的回答。我想我的问题是找到max\u len
。有什么建议吗?我使用的是TPCH数据库,几乎每个关系都有一个CHAR(n)数据类型。
DirectFunctionCall3(
CStringGetTextDatum(my_cstr),
Int32GetDatum(max_len),
BoolGetDatum(false)
);