Java言語スカラー関数
この例では以下のファイル名を使用している:
TestJavaInterface.java
コード
この例のコードは、ちょっとした変更で、このプログラムがリモート・モードで動作することを示している。 変更点はメインにあり、getAPIの周りにループが追加され、2回呼び出されるようになっている。 接続がリモートの場合、新しいスレッドで実行され、新しい接続を待つように引き渡される。 最後に、接続がリモートでない場合は、最初の反復の後にループを抜ける。 このコードはローカルAEのように動作し、リモートAEとして2つの反復を処理する。
import org.netezza.ae.*;
import java.util.concurrent.Executor;
import java.util.concurrent.Executors;
public class TestJavaInterface {
private static final Executor exec =
Executors.newCachedThreadPool();
public static final void main(String [] args) {
try {
mainImpl(args);
} catch (Throwable t) {
System.err.println(t.toString());
NzaeUtil.logException(t, "main");
}
}
public static final void mainImpl(String [] args) {
NzaeApiGenerator helper = new NzaeApiGenerator();
while (true) {
final NzaeApi api = helper.getApi(NzaeApi.FUNCTION);
if (api.apiType == NzaeApi.FUNCTION) {
if (!helper.isRemote()) {
run(api.aeFunction);
break;
} else {
Runnable task = new Runnable() {
public void run() {
try {
TestJavaInterface.run(api.aeFunction);
} finally {
api.aeFunction.close();
}
}
};
exec.execute(task);
}
}
}
helper.close();
}
public static class MyHandler implements NzaeMessageHandler
{
public void evaluate(Nzae ae, NzaeRecord input, NzaeRecord output) {
final NzaeMetadata meta = ae.getMetadata();
int op = 0;
double result = 0;
if (meta.getOutputColumnCount() != 1 ||
meta.getOutputNzType(0) != NzaeDataTypes.NZUDSUDX_DOUBLE) {
throw new NzaeException("expecting one output column of type
double");
}
if (meta.getInputColumnCount() < 1) {
throw new NzaeException("expecting at least one input column");
}
if (meta.getInputNzType(0) != NzaeDataTypes.NZUDSUDX_FIXED &&
meta.getInputNzType(0) != NzaeDataTypes.NZUDSUDX_VARIABLE) {
throw new NzaeException("first input column expected to be a
string type");
}
for (int i = 0; i < input.size(); i++) {
if (input.getField(i) == null) {
continue;
}
int dataType = meta.getInputNzType(i);
if (i == 0) {
if (!(dataType == NzaeDataTypes.NZUDSUDX_FIXED
|| dataType == NzaeDataTypes.NZUDSUDX_VARIABLE)) {
ae.userError("first column must be a string");
}
String opStr = input.getFieldAsString(0);
if (opStr.equals("*")) {
result = 1;
op = OP_MULT;
}
else if (opStr.equals("+")) {
result = 0;
op = OP_ADD;
}
else {
ae.userError("invalid operator = " + opStr);
}
continue;
}
switch (dataType) {
case NzaeDataTypes.NZUDSUDX_INT8:
case NzaeDataTypes.NZUDSUDX_INT16:
case NzaeDataTypes.NZUDSUDX_INT32:
case NzaeDataTypes.NZUDSUDX_INT64:
case NzaeDataTypes.NZUDSUDX_FLOAT:
case NzaeDataTypes.NZUDSUDX_DOUBLE:
case NzaeDataTypes.NZUDSUDX_NUMERIC32:
case NzaeDataTypes.NZUDSUDX_NUMERIC64:
case NzaeDataTypes.NZUDSUDX_NUMERIC128:
switch (op) {
case OP_ADD:
result +=
input.getFieldAsNumber(i).doubleValue();
break;
case OP_MULT:
result *=
input.getFieldAsNumber(i).doubleValue();
break;
default:
break;
}
break;
default:
break;
}
} // end of column for loop
output.setField(0, result);
}
}
private static final int OP_ADD = 1;
private static final int OP_MULT = 2;
public static int run(Nzae ae)
{
ae.run(new MyHandler());
return 0;
}
}
コンパイル
ローカルモードと同様に標準コンパイルを使用する:
$NZ_EXPORT_DIR/ae/utilities/bin/compile_ae --language java --template \
compile TestJavaInterface.java --version 3
登録
登録方法は若干異なる。 まずこれを実行して登録する:
$NZ_EXPORT_DIR/ae/utilities/bin/register_ae --sig "rem_applyop_java(varargs)" \
--return "double" --class AeUdf --language java --template udf \
--define "java_class=TestJavaInterface" --version 3 --remote \
--rname testjavapi
これは、コードがリモート名testjavapiのリモートaeとして登録されることを指定します。 さらに、ランチャーも登録されている:
$NZ_EXPORT_DIR/ae/utilities/bin/register_ae --sig "rem_applyop_launch(int8)" \
--return "TABLE(aeresult varchar(255))" --class AeUdtf --language java \
--template udtf --define "java_class=TestJavaInterface" --version 3 \
--remote --rname testjavapi --launch
rname、--exe、--sigの名前部分を除いて、すべてのランチャーは上記のようになる。 この場合、UDTFがすべてのランチャーのインターフェースだからだ。 rnameの値は、コード中の名前と一致しなければならない。
実行中
リモートモードでAEを実行するには、実行ファイルを "サーバー "として実行する この例では、ホスト上で実行されるクエリーだけを処理する。 通常、AEはSPUでも開始される。 ホスト上でインスタンスを起動する:
SELECT * FROM TABLE WITH FINAL(rem_applyop_launch(0));
AERESULT
-------------------------------------------------------------------------
tran: 14896 session: 18286 DATA slc: 0 hardware: 0 machine: bdrosendev process:
15937 thread: 15938
(1 row)
テーブル・ファンクション・スタイル・ランチャーを呼び出すには、異なる構文が使われていることに注目してほしい。 これは、UDTFベースのAEを呼び出す際に使用される構文である。 次にAEを走らせる:
SELECT rem_applyop_java('+', 4,5,1.1);
REM_APPLYOP_JAVA
------------------
10.1
(1 row)
最後に、エラーを引き起こす:
SELECT rem_applyop_java(1);
ERROR: first input column expected to be a string type