Perl language scalar function
The following example shows a simple scalar function that sums a set of numbers. The example uses the following file name: ApplyOp.pm
Code
- Name the example class by using the Perl package
command:
package ApplyOp;
- Import the
nzae::Ae
package and define the example class as a child class of thenzae::Ae
class.use nzae::Ae; our @ISA = qw(nzae::Ae);
- Define the class. As in the Python examples, the base class handles most of the work. Typically
the
new()
method is called to initialize the class, and therun()
method is then called. Therun()
method 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 by default:package ApplyOp; use strict; use autodie; use nzae::Ae; our @ISA = qw(nzae::Ae); my $ae = ApplyOp->new(); $ae->run(); sub _getFunctionResult(@) { #User defined function code goes here } 1;
- Add the custom Perl code. In this UDF, a string operator is passed in, which is either a plus
sign (+) to add or an asterisk (*) to multiply, and 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:
orSELECT applyopPl('+', 3, 5);
SELECT applyopPl('*', 3, 5);
While 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 applyopPl(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 1 containing three elements. One row is "seen" by
getFunctionResult()
with the three elements in it. In addition, as in Perl convention, the calling object is passed in as the first argument to the function. This is picked up by the function by using the variable$self
. Internally, all the mentioned cases are handled in the same manner and the assumption can be made that there are multiple inputs to theapplyop
AE. - 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:
package ApplyOp; use nzae::Ae; use strict; use autodie; our @ISA = qw(nzae::Ae); my $ae = ApplyOp->new(); $ae->run(); sub _getFunctionResult(@) { my $self = shift; # BREAK APART OUR ROW OF INPUT. my ($operator, $leftInput, $rightInput) = @_; # HANDLE ADDITION. if ($operator eq "+") { return $leftInput + $rightInput; } # HANDLE MULTIPLICATION. if ($operator eq "*") { return $leftInput * $rightInput; } # ERROR ON ALL OTHER. croak(nzae::Exceptions::AeInternalError->new("Unhandled operator to ApplyOp: '" . $operator . "'.")); } 1;
The
croak
function reports the error to the SQL user and, if logging is enabled, returns a trace to the line of error.You can use the
cluck
function in place ofcroak
for writing warnings to the log file. To catch any unhandled exceptions automatically, useautodie
.Die
andwarn
can also be used to report a single-line error or warning, if logging is turned on.Die
errors out the execution of the AE. Set log level by using the--level
option during registration. What is returned by_getFunctionResult()
is the result of the SQL operation, and because this is run as a UDF, there can be only one column in the result.In summary, to write a UDF adding only the actual functionality without customizing the methods for running it, follow the steps:- Create a Perl module file (
ApplyOp.pm
in the mentioned example). - Import and instantiate the
nzae::Ae
class in the file. - Import
autodie
to handle unhandled exceptions during execution. - Override
_getFunctionResult
to implement customized functionality for UDF. Handle errors to be returned to the user by using thecroak()
method. - Execute the
run()
method of thenzae::Ae
object. - Since this is a Perl module, add a “1” at the end of the file
ApplyOp.pm
.
When the code is complete, it must be deployed and registered.
- Create a Perl module file (
Compilation
Perl AEs do not require compilation.
Deployment
--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 perl --version 3 \
--template deploy ApplyOp.pm
Registration
$NZ_EXPORT_DIR/ae/utilities/bin/register_ae --language perl --version 3 \
--template udf --exe ApplyOp.pm --sig "applyopPl(varchar(1), int4, int4)"\
--return int4
Running
SELECT applyopPl('+', 4, 10);
APPLYOPPL
-----------
14
(1 row)
_getFunctionResult()
, the
croak()
method is called. The following example triggers an
error:SELECT applyopPl('-', 1, 2);
ERROR: Unhandled operator to ApplyOp: '-'. at
/nz/export/ae/applications/system/admin/ApplyOp.pm line 28