C++ language aggregates

This example uses the following file name: max.cpp

Code

The code in this example is slightly longer than the C language aggregate example because the code is designed to handle all possible data types.
#include <nzaefactory.hpp>
using namespace nz::ae;
static int run(nz::ae::NzaeFunction *aeFunc);
int main(int argc, char * argv[])
{
NzaeApiGenerator helper;
// The following line is only needed if a launcher is not used
helper.setName("testcapi");
for (int i=0; i < 2; i++) {
nz::ae::NzaeApi &api = helper.getApi(nz::ae::NzaeApi::FUNCTION);
run(api.aeFunction);
if (!helper.isRemote())
break;
}
return 0;
}
class MyHandler : public NzaeFunctionMessageHandler
{
public:
MyHandler() {
m_Once = false;
}
void doOnce(NzaeFunction& api) {
const NzaeMetadata& meta = api.getMetadata();
if (meta.getOutputColumnCount() != 1 ||
meta.getOutputType(0) != NzaeDataTypes::NZUDSUDX_VARIABLE) {
throw NzaeException("expecting one output column of type string");
}
if (meta.getInputColumnCount() != 2) {
throw NzaeException("expecting at least two input columns");
}
if (meta.getInputType(0) != NzaeDataTypes::NZUDSUDX_FIXED &&
meta.getInputType(0) != NzaeDataTypes::NZUDSUDX_VARIABLE) {
throw NzaeException("first input column expected to be a string
type");
}
if (meta.getInputType(1) != NzaeDataTypes::NZUDSUDX_INT32) {
throw NzaeException("second input column expected to be int32 type");
}
m_Once = true;
}
void evaluate(NzaeFunction& api, NzaeRecord &input, NzaeRecord &result) {
if (!m_Once)
doOnce(api);
NzaeField &field = input.get(0);
if (field.isNull())
throw NzaeException("first input column may not be null");
NzaeStringField &sf = (NzaeStringField&) input.get(0);
std::string strop = (std::string)sf;
NzaeField &field2 = input.get(1);
if (field2.isNull())
throw NzaeException("secondinput column may not be null");
NzaeInt32Field &inf = (NzaeInt32Field&) input.get(1);
int type = (int32_t)inf;
NzaeStringField &of= (NzaeStringField&)result.get(0);
if (type == 0) {
// env
const NzaeEnvironment& env = api.getEnvironment();
const char* val = env.getValue(strop.c_str());
if (!val)
of.setNull(true);
else
of = std::string(val);
}
else {
const NzaeLibrary& libs = api.getLibrary();
const NzaeLibrary::NzaeLibraryInfo *info =
libs.getLibraryInfo(strop.c_str(), false ,
NzaeLibrary::NzaeLibrarySearchBoth);
if (!info)
of.setNull(true);
else
of = info->libraryFullPath;
}
}
bool m_Once;
};
static int run(NzaeFunction *aeFunc)
{
aeFunc->run(new MyHandler());
return 0;
}

Compilation

Use the standard compile:
$NZ_EXPORT_DIR/ae/utilities/bin/compile_ae --language cpp --template compile \
--exe envae --compargs "-g -Wall" --linkargs "-g" env.cpp --version 3

Registration

Register the example:
$NZ_EXPORT_DIR/ae/utilities/bin/register_ae --sig "envae(VARCHAR(ANY),int4)" \
--return "table(val varchar(1000))" --language cpp --template udtf \
--exe envae --version 3 --deps inza..LIBNZAEADAPTERS
This example assumes you have added the LIBNZAEADAPTERS shared library.

Running

Note that the output from this example is specific to the environment. Therefore, your actual output will resemble, but not match, the text below.
SELECT * FROM TABLE WITH FINAL(envae('inza..libnzaeadapters', 1));
VAL
-----------------------------------------------------------------------
/nz/data.1.0/base/1/library/237951/host/libnzaeadapters.so
(1 row)
SELECT * FROM TABLE WITH FINAL(envae('libnzaeadapters2', 1));
VAL
-----
(1 row)
SELECT * FROM TABLE WITH FINAL(envae('NZAE_DYNAMIC_ENVIRONMENT', 0));
VAL
-----
0
(1 row)
SELECT * FROM TABLE WITH FINAL(envae('NZAE_DYNAMIC_ENVIRONMENT2', 0));
VAL
-----
(1 row)