C++ language simple table function
This example uses the following file name: split.cpp
Code
The code in this example creates a function that splits a string into multiple strings based on
the delimiter. This example may return more rows of output than input. Because of this, it cannot
use the handler model and requires additional error handling logic. Note the try catch block in the
main and the loop logic in run. Also note that code must be supplied to retrieve the record objects,
output the object, and delete the record objects.
#include <nzaefactory.hpp>
using namespace nz::ae;
using namespace std;
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);
try {
run(api.aeFunction);
}
catch (nz::ae::NzaeException &ex) {
if (api.aeFunction) {
api.aeFunction->userError(ex.what());
}
break;
}
if (!helper.isRemote())
break;
}
return 0;
}
static void split_string(string text,char delim, vector<string>& words)
{
int i=0;
char ch;
string word;
while((ch=text[i++]))
{
if (ch == delim)
{
if (!word.empty())
{
words.push_back(word);
}
word = "";
}
else
{
word += ch;
}
}
if (!word.empty())
{
words.push_back(word);
}
}
static int run(NzaeFunction *aeFunc)
{
const NzaeMetadata& meta = aeFunc->getMetadata();
if (meta.getOutputColumnCount() != 1 ||
meta.getOutputType(0) != NzaeDataTypes::NZUDSUDX_VARIABLE) {
throw NzaeException("expecting one output column of type string");
}
if (meta.getInputColumnCount() != 1) {
throw NzaeException("expecting one input column");
}
if (meta.getInputType(0) != NzaeDataTypes::NZUDSUDX_FIXED &&
meta.getInputType(0) != NzaeDataTypes::NZUDSUDX_VARIABLE) {
throw NzaeException("first input column expected to be a string type");
}
for (;;)
{
nz::ae::NzaeRecord *input = aeFunc->next();
if (!input)
break;
nz::ae::NzaeRecord *output = aeFunc->createOutputRecord();
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 str = (std::string)sf;
vector<string> words;
split_string(str,',', words);
for (int i=0; i < (int)words.size(); i++) {
string tip = words[i];
NzaeStringField &sf = (NzaeStringField&) output->get(0);
sf = tip;
aeFunc->outputResult(*output);
}
delete input;
delete output;
}
aeFunc->done();
return 0;
}
Compilation
Use the standard
compile:
$NZ_EXPORT_DIR/ae/utilities/bin/compile_ae --language cpp --template compile \
--exe splitae --compargs "-g -Wall" --linkargs "-g" split.cpp --version 3
Registration
Register the newly created
"splitae"
executable:$NZ_EXPORT_DIR/ae/utilities/bin/register_ae --sig "splitae(VARCHAR(ANY))" \
--return "table(val varchar(2000))" --language cpp --template udtf \
--exe splitae --version 3
Running
Run the query in nzsql:
SELECT * FROM TABLE WITH FINAL(splitae('12:30:15'));
VAL
----------
12:30:15
(1 row)
SELECT * FROM TABLE WITH FINAL(splitae('12:30:15,two,three'));
VAL
----------
12:30:15
two
three
(3 rows)
SELECT * FROM TABLE WITH FINAL(splitae(NULL));
ERROR: first input COLUMN may NOT be NULL