Fortran言語のスカラー関数
次の例は、数値の集合を合計する単純なスカラー関数を示している。 この例では、単純なAEを作るところから始める。 ファイル名は「applyop.f。
コード
- プログラムを作成し、「
nzaeRun()
呼び出す。 この呼び出しはAEをセットアップし、Fortranの実装に必要なコールバックを'nzaeHandleRequest()
に行う。 これは通常、以下の方法で実現できる:program applyopProgram call nzaeRun() stop end subroutine nzaeHandleRequest(handle) c Our custom Fortran code will go here. return end
- カスタムFortranコードを完成させる。 このUDFでは、"+"(加算)または "*"(乗算)の文字列演算子と、2つの整数を渡す。 このコードは整数の積か和を返す。 SQLでは、この単純なバージョンは次のどちらかで呼び出される:
またはSELECT applyop('+', 3, 5);
SELECT applyop('*', 3, 5);
前述の例では入力は1つだけだが、NPSシステムは入力のストリームを扱う。 従って、NPSシステムの方が利用しやすい:SELECT applyop(mytable.operator, mytable.value1, mytable.value2) FROM mytable;
最初の例では、NPSシステムは定数 "+"、3、5を受け取り、それらを3つの要素を含む長さ1のストリームに変換する。 内部的には、前述のケースはすべて同じように処理され、「
applyop
AEには複数の入力があると仮定できる。 - ループ処理入力が必要で、Fortran77では'
if
文と'goto
文で実現できる。 例:program applyopProgram call nzaeRun() stop end subroutine nzaeHandleRequest(handle) integer hasNext, leftInput, rightInput, result character operator hasNext = -1 10 call nzaeGetNext(handle, hasNext) if (hasNext .eq. 0) then goto 20 endif c Our loop work will go here. goto 10 20 return end
hasNext
変数の初期化に注意。 これは、基礎となるインターフェイスを呼び出す "out "変数に必要である。 これがないと、'hasNext
ポインタは未割り当てのままとなり、基礎となるコールからデータを受け取ることができない。nzaeGetNext()
関数は、ストリームに別の要素があれば変数 'hasNext
に1(TRUE)を設定し、ストリームが終了すれば0(FALSE)を設定する。 - ロジックを追加する:
program applyOpProgram call nzaeRun() stop end subroutine nzaeHandleRequest(handle) integer hasNext, leftInput, rightInput, isNull, result character operator hasNext = -1 leftInput = 0 rightInput = 0 operator = 'f' isNull = 0 10 call nzaeGetNext(handle, hasNext) if (hasNext .eq. 0) then goto 20 endif c GET OUR INPUT. call nzaeGetInputString(handle, 0, operator, isNull) call nzaeGetInputInt32(handle, 1, leftInput, isNull) call nzaeGetInputInt32(handle, 2, rightInput, isNull) c OPERATE. if (operator .eq. '+') then result = leftInput + rightInput else if (operator .eq. '*') then result = leftInput * rightInput else call nzaeUserError(handle, 'Unhandled operator.') endif c OUTPUT. call nzaeSetOutputInt32(handle, 0, result) call nzaeOutputResult(handle) goto 10 20 return end
ループ内の各入力には、関数に渡される3つの要素が含まれている。 関数'
nzaeGetInputX()
は、1つのユーザーリクエストを表すハンドル、列インデックス(この場合、0が演算子、1が左入力、2が右入力を表す)、および出力変数を受け取る。 関数'nzaeUserError()
はSQLユーザーにエラーを報告する。 関数「nzaeSetOutputX()
」は結果を出力する。 これはUDFとして実行されるため、結果には1つの列しか存在しない。 後の例では、UDTFを使って複数の列を出力する方法を示す。 コードが完成したら、コンパイルして登録しなければならない。
コンパイル
$NZ_EXPORT_DIR/ae/utilities/bin/compile_ae --language fortran --version 3 \
--template compile --exe applyopFortran applyop.f
The output executables, one for the host and one for the SPU, are placed under the host and spu directories in /nz/export/ae/applications/$NZ_USER/$NZ_DATABASE
登録
$NZ_EXPORT_DIR/ae/utilities/bin/register_ae --language fortran --version 3 \
--template udf --exe applyopFortran \
--sig "applyop_fortran(varchar(1), int4, int4)" --return int4
実行中
SELECT applyop_fortran('+', 4, 10);
APPLYOP
---------
14
(1 row)
nzaeHandleRequest()
で型を検証するとき、'nzaeUserError()
を呼び出してエラーを送信していることに注意。 次の例ではエラーが発生する:SELECT applyop_fortran('-',1,2);
ERROR: Unhandled operator.