我正在尝试将C String转换为PostgreSQL的字符内部表示。我在bpcharin
中使用varchar.c
函数。此函数需要两个参数:C String Datum和atttypmod
。提到atttypmod
是声明的类型长度加上VARHDRSZ。
我的转换功能是:
result = DirectFunctionCall2(bpcharin,
CStringGetDatum(str),
VARHDRSZ + ?);
我的字符串str
值将是我表的列数据类型之一。所以,我需要声明的列数据类型长度。此信息存储在character_maximum_length
information_schema.columns
视图中。{/ p>
我的问题是,如何在C代码中获取character_maximum_length
?
谢谢。
答案 0 :(得分:1)
除非您使用char
数据类型,否则您不需要bpchar
。
简单CStringGetDatum
(适用于cstring
类型值)或CStringGetTextDatum
(适用于text
类型值)就足够了。
您似乎 使用char(n)
,即bpchar
。坦率地说,最好的办法是不要这样做;它几乎是一种古怪的类型,几乎在所有情况下都应该用普通text
或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)
castmethod = 'b'
和text
有varchar
个条目。根据手册,b
表示:
这些类型是二进制可强制的,因此不需要转换
...因此您可以使用CStringGetTextDatum
生成bpchar
。但是,不会进行长度检查。
如果要进行类型检查,则必须调用bpchar
函数,该函数在char-to-char强制转换中调用。它会进行长度检查/截断。它需要三个参数 - 文本,最大长度,以及它是隐式还是显式的演员。
e.g。 (另):
DirectFunctionCall3(
CStringGetTextDatum(my_cstr),
Int32GetDatum(max_len),
BoolGetDatum(false)
);
最后一个arg控制截断规则;有关详细信息,请参阅bpchar
中src/backend/utils/adt/varchar.c
的评论。