4

Postgres External C Functions でテストを始めたところです。数値を渡して返すと、関数は正常に機能します。(例)

サンプル機能

PG_FUNCTION_INFO_V1(numericTesting);
Datum
numericTesting(PG_FUNCTION_ARGS)
{
    Numeric       p = PG_GETARG_NUMERIC(0);
    PG_RETURN_NUMERIC(p);
}

ただし、渡された変数に対して数学関数を実行しようとすると、コンパイルされません。私は得る

エラー: バイナリへのオペランドが無効です *

サンプル機能

PG_FUNCTION_INFO_V1(numericTesting);
Datum
numericTesting(PG_FUNCTION_ARGS)
{
    Numeric       p = PG_GETARG_NUMERIC(0);
    PG_RETURN_NUMERIC(p * .5);
}

これは何が原因ですか?数値データ型には、数学を可能にする関数が必要だと思います。使用してみました: PG_RETURN_NUMERIC(DatumGetNumeric(p * .5)) が、同じ結果が得られました。

4

3 に答える 3

4

Numericはプリミティブ型ではないため、直接算術演算を行うことはできません。C には演算子のオーバーロードがないため、Numeric に乗算演算子を追加する方法はありません。数値を乗算するには、適切な関数呼び出しを使用する必要があります。

Pg 拡張関数を作成するときのほとんどの場合と同様に、ソースを読んで、それが他の場所でどのように行われているかを確認することが役立ちます。

この場合、 を見てくださいsrc/backend/utils/adt/numeric.c。作業を行うために使用する場所を調べDatum numeric_mul(PG_FUNCTION_ARGS)ますmul_var(...)

残念ながら外でmul_varstatic使えませんnumeric.c。イライラして驚く。オペレーターを呼び出すために使用するコメントで示したように、オペレーター呼び出しを介して作業を行うために spi/fmgr を使用せずに拡張関数NUMERICから処理する合理的な方法が必要です。CSQLDirectFunctionCall2numeric_mul

Cから直接呼び出せるNumericのパブリックなものが入ってsrc/include/utils/numeric.hいるようですので、そちらを見てみましょう。おっと、多くはありませんが、いくつかのヘルパーとマクロの間Numericで変換するためのいくつかのマクロです。SQL 呼び出しによる使用が唯一の方法のようです。DatumGETARGRETURN

DirectFunctionCall2Numeric の SQL インターフェイスを使用して行き詰った場合は、 int4_numeric.

解決策が見つからない場合は、pgsql-general メーリング リストに投稿してください。C 拡張機能とソース コードの経験を積んだ人が増えます。その場合は、この投稿にリンクしてください。

于 2012-09-27T00:59:42.080 に答える
0

のオペランドは両方とも*算術型 (整数型または浮動小数点型) でなければなりません。Numeric単純な整数型または浮動小数点型ではないものの型定義であることは 、かなり良い賭けです。

残念ながら、私は Postgres API について十分に理解していません。Numericaを算術型に変換したり、算術演算を型に適用したりできるマクロまたは関数があることを願っていますNumeric

于 2012-09-25T18:14:00.747 に答える