このページを編集する際は、編集に関する方針に従ってください。
概要 †
- 0から引数tupleDesc->natts-1までの整数について、インデックスiを定義して、以下の小計1、小計2を算出する。
- ただし、isnull[i]<>NULLの場合、以下の小計1、小計2をスキップする。
- 小計1として、tupleDesc->attrs[i]->attalignの値で判別し、直前の小計2をもとに、以下の値を取得。
- 'i'の場合、直前の小計2以上であるALIGNOF_INTの倍数のうち最小値。
- 'c'の場合、直前の小計2を(long型にキャストして)そのまま。
- 'd'の場合、直前の小計2以上であるALIGNOF_DOUBLEの倍数のうち最小値。
- それ以外の場合、直前の小計2以上であるALIGNOF_SHORTの倍数のうち、最小値。
- 小計2として、tupleDesc->attrs[i]->attlenの値で判別し、小計1に以下の値を加算した値を取得。
- attrs[i]->attlen>0の場合、attrs[i]->attlen。
- attrs[i]->attlen=-1の場合、values[i]->va_header。
- attrs[i]->attlen=-2の場合、values[i]のサイズ。
- tupleDesc->natts-1まで加算したら、その小計2を合計値として返す。
小計1の例 †
- たとえば、以下のようなattrs[]を持つtupleDescがあると仮定する。また、ALIGNOF_INTを4、ALIGNOF_SHORTを2とする。
| attalign | attlen |
attrs[0] | 'c' | 15 |
attrs[1] | 's' | 2 |
attrs[2] | 'i' | 4 |
- このときは、以下のように計算され、合計サイズは24となる。
| attalign | ALIGN | ALIGN後の値(小計1) | attlen | 小計2 |
attrs[0] | 'c' | なし | 0 | 15 | 15 |
attrs[1] | 's' | ALIGNOF_SHORT=2 | 16 | 2 | 18 |
attrs[2] | 'i' | ALIGNOF_INT=4 | 20 | 4 | 24 |
小計2の例 †
- たとえば、以下のようなattrs[]を持つtupleDescと、value[]があると仮定する。
i | attrs[i]-> attalign | attrs[i]-> attlen | value[i] | value[i]-> va_header | value[i]のサイズ |
0 | 'c' | -1 | 'aaaaa' | 0x61616161 | 5 |
1 | 'c' | -2 | 'bbbbb' | 0x62626262 | 5 |
- このときは、以下のように計算され、合計サイズは1633771878となる。
i | attrs[i]-> attalign | ALIGN | ALIGN後の値(小計1) | attrs[i]-> attlen | value[i] | value[i]-> va_header | value[i]のサイズ | 小計2 |
0 | 'c' | なし | 0 | -1 | 'aaaaa' | 0x61616161 = 1633771873 | 5 | 1633771873 |
1 | 'c' | なし | 1633771873 | -2 | 'bbbbb' | 0x62626262 | 5 | 1633771878 |
引数 †
- tupleDesc : TupleDesc 型
- values : Datum 型へのポインタ
- isnull : bool 型へのポインタ
実装 †
Size
heap_compute_data_size(TupleDesc tupleDesc,
- 以下のメンバを持つ構造体。詳細はTupleDesc/postgresql-8.1.4参照。
- nattsを、intとして定義。
- attrsを、以下のメンバを持つ構造体Form_pg_attributeへのポインタとして定義。
- (略)
- attlenを、int2(int16(signed short)の別名)として定義。
- (略)
- attalignを、charとして定義。
- (略)
- (略)
Datum *values,
bool *isnull)
{
Size data_length = 0;
int i;
int numberOfAttributes = tupleDesc->natts;
Form_pg_attribute *att = tupleDesc->attrs;
for (i = 0; i < numberOfAttributes; i++)
{
if (isnull[i])
continue;
data_length = att_align(data_length, att[i]->attalign);
- data_lengthに、以下の値を代入。詳細はatt_align()/postgresql-8.1.4参照。
- attalignの値が'i'の場合、data_length以上であるALIGNOF_INTの倍数のうち最小値を返す。
- attalignの値が'c'の場合、data_lengthを(long型にキャストして)そのまま返す。
- attalignの値が'd'の場合、data_length以上であるALIGNOF_DOUBLEの倍数のうち最小値を返す。
- それ以外の場合、data_length以上であるALIGNOF_SHORTの倍数のうち、最小値を返す
。ただし、USE_ASSERT_CHECKING指定してコンパイルしたバイナリの場合、attalignが's'でなければエラーメッセージを出力して終了する。
data_length = att_addlength(data_length, att[i]->attlen, values[i]);
- data_lengthに、以下の値を加算。詳細はatt_addlength()/postgresql-8.1.4参照。
- att[i]->attlenが0より大きい場合、att[i]->attlenの値。
- att[i]->attlenが-1の場合、values[i]をvarattrib*型にキャストしてva_headerメンバの値を取得し、上位2ビットを除外した値。
- att[i]->attlenが-2の場合、values[i]を文字列としてサイズを算出した結果。
- それ以外の場合は、-2の場合と同じ。ただし、USE_ASSERT_CHECKING指定してコンパイルしたバイナリの場合、エラーメッセージを出力してプログラムを終了する。
}
return data_length;
}
呼出元 †
備考 †
* heap_compute_data_size
* Determine size of the data area of a tuple to be constructed
履歴 †
コメント †