ApplyOperation

Code in this section is saved in a file called ApplyOperation.java.

Concepts

This is a variation of the "ApplyOp" example, with the following modifications:
  • The data-handling logic has been separated from the connection creation logic. The standalone class is reused in multiple AE example applications that use differing connection logic.
  • This AE uses the file-IO paradigm instead of the call-back paradigm to retrieve the input rows. For an example of the call-back paradigm, see MyHandler in Java Language Scalar Function.
  • The code supports the subtraction operator.
Note that because this function AE writes exactly one output row per input row and the output row contains exact one column, the AE can be invoked from either a scalar or table Function.

Code

// ApplyOperation.java
// Function AE
// Performs arithmetic operations (+, -, or *)
// across columns in a row
// Ignores non-numeric columns
// First argument column must be a string type operation
// Handles a variable number of input columns and data types
// Returns a double result
// Can be called as a table function or a scalar function
package org.netezza.education;

import java.io.*;
import java.math.BigDecimal;
import java.text.DateFormat;
import java.sql.Date;
import java.sql.Time;
import java.sql.Timestamp;
import org.netezza.ae.*;

public class ApplyOperation {
    private static final int OP_ADD = 1;
    private static final int OP_MULT = 2;
    private static final int OP_SUBTRACT = 3;

    public static void runAe(Nzae ae) {
        final NzaeMetadata meta = ae.getMetadata();

        for (;;) {
            int op = 0;
            double result = 0;
            NzaeRecord input = ae.next();
            if (input == null) {
                break;
            }
            NzaeRecord output = ae.createOutputRecord();

            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 if (opStr.equals("-")) {
                       result = 0;
                       op = OP_SUBTRACT;
                    } else {
                       ae.userError("invalid operator = " + op);
                    }
                    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_SUBTRACT:
                       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);
           ae.outputResult(output);
       }

       ae.done();
    }
}