[pgsql-jp: 34066] Re: データサイズの取得方法

Katsuhiko Okano k_okano @ po.ntts.co.jp
2004年 10月 6日 (水) 11:19:33 JST


岡野と申します。

satoken wrote:
>  一応、以下の様にしてvarchar宣言した列のサイズを取得できたのですが
> 取得したatttypmodの値は宣言した値よりも常に4だけ大きかったです。
> 
> select attname, atttypmod  from pg_attribute  where attnum > 0
>  and attrelid = (select relfilenode from pg_class where relname = 'テーブル名')
>  and attname = '列名';

ソースファイルのsrc\include\c.hを見ると、
可変長型の場合は、頭に32bit(int32 = 4バイト)、
続いて実際の文字列char(Cの基本データ型。1バイト)が必要な長さ分だけ続くようです。
>struct varlena
>{
>	int32		vl_len;
>	char		vl_dat[1];
>};

postgresql-6.5.3でもpostgresql-8.0.0beta1でも同じだったので、
大きな設計変更がない限り今後も変わらないのではないでしょうか?





---
以下は私の個人的な勉強のためにピックアップした、関連しそうなソースと意訳です。
間違いがあるかもしれませんが、何かのお役に立てばと思います。
長くてすいません。


postgresql-8.0.0beta1\src\include\catalog\pg_attribute.h
	/*
	 * atttypmod records type-specific data supplied at table creation
	 * time (for example, the max length of a varchar field).  It is
	 * passed to type-specific input and output functions as the third
	 * argument. The value will generally be -1 for types that do not need
	 * typmod.
	 */
	int4		atttypmod;
atttypmodは、テーブル生成時に指定された、型に固有のデータを記録します。
(例えばvarcharフィールドの最大長)
それは3つめの引数(argument)として入出力関数(functions)に渡されます。
このatttypmodは、一般的に-1となります。
これは、型は(固定長なため)一般的にtypmod(長さ)を必要としないためです。


postgresql-8.0.0beta1\src\include\catalog\pg_type.h
	/*
	 * For a fixed-size type, typlen is the number of bytes we use to
	 * represent a value of this type, e.g. 4 for an int4.	But for a
	 * variable-length type, typlen is negative.  We use -1 to indicate a
	 * "varlena" type (one that has a length word), -2 to indicate a
	 * null-terminated C string.
	 */
	int2		typlen;
固定長の型の場合、typlenはその型を表現するのに必要なバイト数(number of bytes)です。
たとえば、int4の表現する場合は4です。
可変長の場合、typlenは負の数(negative)です。
-1は、"varlena"型("varlena" type)(長さ語??(length word)を持つ一つ(one))を指し、
-2は、終端がNULLのCの文字列を指します。


postgresql-8.0.0beta1\src\include\c.h
/* ----------------
 *		Variable-length datatypes all share the 'struct varlena' header.
 *
 * NOTE: for TOASTable types, this is an oversimplification, since the value
 * may be compressed or moved out-of-line.	However datatype-specific routines
 * are mostly content to deal with de-TOASTed values only, and of course
 * client-side routines should never see a TOASTed value.  See postgres.h for
 * details of the TOASTed form.
 * ----------------
 */
struct varlena
{
	int32		vl_len;
	char		vl_dat[1];
};


-- 
----------------------------------------
Katsuhiko Okano
k_okano @ po.ntts.co.jp
NTT Software Corp. (division "NBRO-PT6")




pgsql-jp メーリングリストの案内