Java language shapers and sizers
This example uses the following file name: TestJavaIdentity.java
Code
The code in this example demonstrates both a shaper and sizer, each of which use the same code
and perform essentially the same task. The code returns as output the given input. It does not
demonstrate retrieving the literal fields, just the shaper/sizer functionality. This example uses
handlers for both the function logic and the shaper logic.
import java.io.*;
import java.util.concurrent.Executor;
import java.util.concurrent.Executors;
import org.netezza.ae.*;
public class TestJavaIdentity {
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.ANY);
if (api.apiType == NzaeApi.FUNCTION) {
if (!helper.isRemote()) {
run(api.aeFunction);
break;
} else {
Runnable task = new Runnable() {
public void run() {
try {
TestJavaIdentity.run(api.aeFunction);
} finally {
api.aeFunction.close();
}
}
};
exec.execute(task);
}
}
else {
if (!helper.isRemote()) {
doShaper(api.aeShaper);
break;
} else {
Runnable task = new Runnable() {
public void run() {
try {
TestJavaIdentity.doShaper(api.aeShaper);
} finally {
api.aeShaper.close();
}
}
};
exec.execute(task);
}
}
}
helper.close();
}
public static class MyHandler2 implements NzaeShaperMessageHandler
{
public void shaper(NzaeShaper api){
NzaeMetadata m = api.getMetadata();
String name;
if (api.catalogIsUpper())
name = "I";
else
name = "i";
if (m.getInputNzType(0) == NzaeDataTypes.NZUDSUDX_FIXED ||
m.getInputNzType(0) == NzaeDataTypes.NZUDSUDX_VARIABLE ||
m.getInputNzType(0) == NzaeDataTypes.NZUDSUDX_NATIONAL_FIXED ||
m.getInputNzType(0) == NzaeDataTypes.NZUDSUDX_NATIONAL_VARIABLE) {
api.addOutputColumnString(m.getInputNzType(0), name,
m.getInputSize(0));
}
else if (m.getInputNzType(0) == NzaeDataTypes.NZUDSUDX_NUMERIC128 ||
m.getInputNzType(0) == NzaeDataTypes.NZUDSUDX_NUMERIC64 ||
m.getInputNzType(0) == NzaeDataTypes.NZUDSUDX_NUMERIC32) {
api.addOutputColumnNumeric(m.getInputNzType(0), name,
m.getInputSize(0), m.getInputScale(0));
}
else {
api.addOutputColumn(m.getInputNzType(0), name);
}
}
}
public static class MyHandler implements NzaeMessageHandler
{
public void evaluate(Nzae ae, NzaeRecord input, NzaeRecord output) {
output.setField(0, input.getField(0));
}
}
private static final void run(Nzae ae) {
ae.run(new MyHandler());
}
private static final void doShaper(NzaeShaper aeShaper)
{
aeShaper.run(new MyHandler2());
}
}
Note in the main that an API object must be retrieved in local mode, which gets both a function API and a shaper API (although not at the same time). Additionally, the code modifies the loop logic for remote mode so that the shaper is not incremented, allowing the same instance of the program to handle a shaper and a function call in remote mode before exiting. Finally, it adds the shaper message handler.
Compilation
Use the standard
compile:
$NZ_EXPORT_DIR/ae/utilities/bin/compile_ae --language java --template compile \
TestJavaIdentity.java –-version 3Registration
Register the example as a UDF and a
UDTF:
$NZ_EXPORT_DIR/ae/utilities/bin/register_ae --sig "shaperae(varargs)" \
--return "table(any)" --class AeUdtf --language java --template udtf \
--version 3 --define "java_class=TestJavaIdentity"$NZ_EXPORT_DIR/ae/utilities/bin/register_ae --sig "sizerae(varargs)" \
--return "varchar(any)" --class AeUdf --language java --template udf \
--version 3 --define "java_class=TestJavaIdentity"Running
Run the query in nzsql. It returns as output the given input:
SELECT sizerae('test');
SIZERAE
---------
test
(1 row)
SELECT * FROM TABLE WITH FINAL(shaperae('test'));
I
------
test
(1 row)
SELECT * FROM TABLE WITH FINAL(shaperae(1.1));
I
-----
1.1
(1 row)