PostgreSQL C String到CHARACTER内部表示

时间:2014-07-25 05:09:08

标签: postgresql

我正在尝试将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

谢谢。

1 个答案:

答案 0 :(得分:1)

除非您使用char数据类型,否则您不需要bpchar

简单CStringGetDatum(适用于cstring类型值)或CStringGetTextDatum(适用于text类型值)就足够了。


您似乎 使用char(n),即bpchar。坦率地说,最好的办法是不要这样做;它几乎是一种古怪的类型,几乎在所有情况下都应该用普通textvarchar替换。

如果你必须使用它......好吧,让我们来看看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'textvarchar个条目。根据手册,b表示:

  

这些类型是二进制可强制的,因此不需要转换

...因此您可以使用CStringGetTextDatum生成bpchar。但是,不会进行长度检查。

如果要进行类型检查,则必须调用bpchar函数,该函数在char-to-char强制转换中调用。它会进行长度检查/截断。它需要三个参数 - 文本,最大长度,以及它是隐式还是显式的演员。

e.g。 (另):

DirectFunctionCall3( 
      CStringGetTextDatum(my_cstr), 
      Int32GetDatum(max_len),
      BoolGetDatum(false) 
    );

最后一个arg控制截断规则;有关详细信息,请参阅bpcharsrc/backend/utils/adt/varchar.c的评论。