[pgsql-jp: 41244] Re: ユーザー定義関数の作り方

Tomoaki Sato sato @ sraoss.co.jp
2012年 10月 11日 (木) 02:40:06 JST


佐藤です。

# 連続して失礼します。

よく考えると、配列の要素を足すだけなら、C で関数を作らずに SQL、

=# select sum(n) from unnest(ARRAY[ARRAY[1,2,3],ARRAY[4,5,6]]) AS n;
 sum
-----
  21
(1 row)

または SQL 関数でいいのでは?

=# create function sum_array(anyarray) returns anyelement as $$
$#     select sum(n) from unnest($1) AS n;
$# $$ language sql;
CREATE FUNCTION
=# select sum_array(ARRAY[ARRAY[1,2,3],ARRAY[4,5,6]]);
 sum_array
-----------
        21
(1 row)

> 佐藤です。
> 
> From: 山田 明 <lennygcc @ infoseek.jp>
> Date: Wed, 10 Oct 2012 19:53:18 +0900
> 
>> 戻り値ではなくて、anyarrayを引数としたC言語によるユーザー定義関数において、
>> 引数の取り出し方がよく分からないのです。
>> 
>> マニュアルに記載された多様体の例の引数は、elementであって、anyarrayでは
>> ありません。配列の引数は、C言語から、どのように取り出すのでしょう。
> 
> 配列でも引数はマクロ PG_GETARG_* で取り出せます。配列の要素にアクセス
> するには関数 deconstruct_array で一次元にばらすのが簡単だと思います。
> 
>   arg = PG_GETARG_ARRAYTYPE_P(0);
>   elmtyp = ARR_ELEMTYPE(arg);
> 
>   get_typlenbyvalalign(elmtyp, &elmlen, &elmbyval, &elmalign);
>   deconstruct_array(arg, elmtyp, elmlen, elmbyval, elmalign,
>                     &elemsp, &nullsp, &nelemsp);
>   result = 0;
>   for (i = 0; i < nelemsp; i++)
>   {
>       // 配列の要素が NULL かどうか
>       if (nullsp[i])
>       {
>           continue;
>       }
> 
>       // 配列の要素の値を加える
>       result += DatumGetInt32(elemsp[i]);
>   }
> 
> 上記では anyarray 型であることを考えていませんが、変数 elmtyp を見れば
> データ型に応じて処理を分けれられます。
> 
> ほかにイテレータでもアクセスできるみたいです。
> 
> Web にもあまり情報がないようなので、ヘッダファイル utils/array.h やソー
> スファイル src/backend/utils/adt/arrayfuncs.c あたりを読むのがいいです。
> 
> あるいは、C でないといけない理由がないなら、PL/pgSQL で書いたほうが簡
> 単だと思います。
> 
>>> 米林です。
>>>
>>> かなり昔にやったものですが
>>>
>>> http://d.hatena.ne.jp/yone098/20080729/1217300716
>>>
>>> ブログのように、まずは固定値を返すユーザ定義関数を作って動作させ
>>> そのあとに、ブログにある引き数を取得をデバッグしながら試してみて下さい。
>>> 固定値を返す関数が作成出来て
>>> 引き数を取得する関数が作成出来れば
>>> ゴールは近いはずです。


----
Tomoaki Sato <sato @ sraoss.co.jp>
SRA OSS, Inc. Japan


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