Python language scalar function

The following example shows a simple scalar function that sums a set of numbers. This example starts from the beginning to construct a simple AE. It uses the following file name: applyop.py

Code

  1. Derive a class from nzae.Ae. The base class handles most of the work, so typically you call the class-method "run()". The run() function instantiates the class, sets up error handling, and calls the appropriate derived function. For UDF-based AEs such as this one, the _getFunctionResult() function must be overridden, as it gets called once for each row of input. Save the following code in a file called applyop.py:
    import nzae
    class ApplyOpUdfAe(nzae.Ae):
    def _getFunctionResult(self, row):
    # OUR CUSTOM CODE WILL GO HERE.
    ApplyOpUdfAe.run()
  2. Complete the custom Python code. In this UDF, you pass in a string operator, which is either a plus sign (+) to add or an asterisk (*) to multiply, as well as two integers. The code returns either the product or the sum of the integers. In SQL, a simple version of this can be called by either:
    SELECT applyop('+', 3, 5);
    or
    SELECT applyop('*', 3, 5);
    Although the mentioned example has only one input, the NPS system deals with streams of input. Therefore, the NPS system is more likely to use:
    SELECT applyop(mytable.operator, mytable.value1, mytable.value2) FROM mytable;

    In the first example, the NPS system takes the constants, "+", 3, and 5 and turns them into a stream of length one containing three elements. One row is"seen" by _getFunctionResult() with the three elements in it. Internally, all the mentioned cases are handled in the same manner and the assumption can be made that there are multiple inputs to the applyop AE.

  3. Enter custom code to handle one row of input, as loop handling input is needed to hand off one row to the function at a time:
    import nzae
    class ApplyOpUdfAe(nzae.Ae):
    def _getFunctionResult(self, row):
    # BREAK APART OUR ROW OF INPUT.
    operator, leftInput, rightInput = row
    # HANDLE ADDITION.
    if operator == "+":
    return leftInput + rightInput
    # HANDLE MULTIPLICATION.
    if operator == "*":
    return leftInput * rightInput
    # ERROR ON ALL OTHER.
    self.userError("Unhandled operator to ApplyOp: '" + operator + "'.")
    ApplyOpUdfAe.run()

    The function self.userError() reports an error to the SQL user. Whatever is returned by _getFunctionResult() is the result of the SQL operation. Because this is run as a UDF, there can be only one column in the result. A later example demonstrates how to use UDTFs to output multiple columns. When the code is complete, it must be deployed and registered.

Compilation

The Python AEs do not require compilation.

Deployment

Although Python AEs do not require compilation, they do require deployment. The compile_ae command is still used with the --template deployment option to deploy the script to the default location on the shared export drive.
$NZ_EXPORT_DIR/ae/utilities/bin/compile_ae --language python64 \
--template deploy ./applyop.py --version 3

Registration

Register the Python file:
$NZ_EXPORT_DIR/ae/utilities/bin/register_ae --language python64 --version 3 \
--template udf --exe applyop.py --sig "applyop(varchar(1), int4, int4)" \
--return int4

Running

The AE can now be run in SQL:
SELECT applyop('+', 4, 10);
APPLYOP
---------
14
(1 row)
Note that to validate types in _getFunctionResult(), self.userError() is called. The following example triggers an error:
SELECT applyop('-', 1, 2);
ERROR: Unhandled operator TO ApplyOp: '-'.