Skalare Funktion in der Sprache Java
In diesem Beispiel wird der folgende Dateiname verwendet:
TestJavaInterface.java
Code erstellen
Der Code in diesem Beispiel zeigt, dass dieses Programm mit geringfügigen Änderungen im Remote-Modus funktioniert. Die Änderung befindet sich in der Hauptdatei, wo eine Schleife um getAPI hinzugefügt wurde, so dass es zweimal aufgerufen wird. Wenn es sich um eine Remote-Verbindung handelt, wird sie an einen neuen Thread übergeben, der auf eine neue Verbindung wartet. Wenn es sich nicht um eine Fernverbindung handelt, brechen Sie die Schleife nach der ersten Iteration ab. Dieser Code funktioniert wie eine lokale AE und behandelt zwei Iterationen wie eine entfernte AE.
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;
}
}
Kompilierung
Verwenden Sie die Standardkompilierung wie im lokalen Modus:
$NZ_EXPORT_DIR/ae/utilities/bin/compile_ae --language java --template \
compile TestJavaInterface.java --version 3
Registrierung
Die Registrierung ist etwas anders. Führen Sie zunächst diesen Befehl aus, um sich zu registrieren:
$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
Damit wird festgelegt, dass der Code als Remote-Ae mit dem Remote-Namen testjavapi registriert wird, der dem Code entspricht. Außerdem wird ein Launcher registriert:
$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
Mit Ausnahme von --rname, --exe und dem Namensteil von --sig sehen alle Startprogramme wie oben beschrieben aus. In diesem Fall ist es ein UDTF, da dies die Schnittstelle für alle Launcher ist. Der Wert von --rname muss mit dem Namen im Code übereinstimmen.
Aktiv
Um die AE im Remote-Modus auszuführen, wird die ausführbare Datei als "Server" ausgeführt In diesem Fall werden nur die auf dem Host ausgeführten Abfragen bearbeitet. In der Regel werden die Agrarumweltmaßnahmen auch auf den SPUs gestartet. Starten Sie eine Instanz auf dem Host:
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)
Beachten Sie, dass eine andere Syntax verwendet wird, um das Startprogramm für die Tabellenfunktion aufzurufen. Dies ist die Syntax für den Aufruf jeder UDTF-basierten AE. Führen Sie nun die AE aus:
SELECT rem_applyop_java('+', 4,5,1.1);
REM_APPLYOP_JAVA
------------------
10.1
(1 row)
Schließlich verursachen Sie einen Fehler:
SELECT rem_applyop_java(1);
ERROR: first input column expected to be a string type