[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 メーリングリストの案内