Generic UDF example

The following UDF, var_concat, takes two input VARCHAR strings of any length, concatenates them, and returns the combined VARCHAR string, which is also declared as a generic return value to support the combined string length.

The function can also concatenate national character strings (NVARCHAR). Within the sample, note the additional registration command definition to create an nvar_concat UDF.

/**
* UDF var_concat(Xvarchar(any), Xvarchar(any)) -> Xvarchar(any)
* 
* COMPILATION:
 nzudxcompile UDX_Concat.cpp -o /tmp/udx_test/UDX_Concat.o
* 
* REGISTRATION:
    CREATE OR REPLACE FUNCTION var_concat(VARCHAR(ANY), VARCHAR(ANY))
RETURNS VARCHAR(ANY)
LANGUAGE CPP
PARAMETER STYLE NPSGENERIC
CALLED ON NULL INPUT
NOT DETERMINISTIC
EXTERNAL CLASS NAME 'Concat'
EXTERNAL HOST OBJECT '/tmp/udx_test/UDX_Concat.o_x86'
EXTERNAL SPU OBJECT '/tmp/udx_test/UDX_Concat.o_spu10';

CREATE OR REPLACE FUNCTION nvar_concat(NVARCHAR(ANY), NVARCHAR(ANY))
RETURNS NVARCHAR(ANY)
LANGUAGE CPP
PARAMETER STYLE NPSGENERIC
CALLED ON NULL INPUT
NOT DETERMINISTIC
EXTERNAL CLASS NAME 'Concat'
EXTERNAL HOST OBJECT '/tmp/udx_test/UDX_Concat.o_x86'
EXTERNAL SPU OBJECT '/tmp/udx_test/UDX_Concat.o_spu10';
*
* USAGE: 
select var_concat('str1','str2');
* 
* Copyright (c) 2007-2009 Netezza Corporation, an IBM Company
* All rights reserved.
*/
#include "udxinc.h"
#include <string.h>

using namespace nz::udx;

class Concat: public Udf
{
   static Udf* instantiate();
   inline bool isValidArgType(int at) const
   {
     return 
at==UDX_FIXED||at==UDX_VARIABLE||at==UDX_NATIONAL_FIXED||at==UDX_NATIO
NAL_VARIABLE;
   }
   virtual ReturnValue evaluate()
   {
     if(numArgs()!=2)
     {
       throwUdxException("var_concat number of arguments is not 2");
     }

     if (isArgNull(0))
       NZ_UDX_RETURN_NULL();

     if (isArgNull(1))
       NZ_UDX_RETURN_NULL();

     setReturnNull(false);

     int argType0=argType(0);
     int argType1=argType(1);
 
     if(isValidArgType(argType0)&&isValidArgType(argType1))
     {
       StringArg *a = stringArg(0);
       StringArg *b = stringArg(1);
       StringReturn *ret = stringReturnInfo();
       ret->size=a->length+b->length;
       memcpy(ret->data,a->data, a->length);
       memcpy(ret->data+a->length, b->data, b->length);
       NZ_UDX_RETURN_STRING(ret);
     }
     else
     {
       throwUdxException("Datatype mismatch.");
     }
   }
   virtual uint64 calculateSize() const
   {
     int argType0=sizerArgType(0);
     int argType1=sizerArgType(1);
     if(isValidArgType(argType0)&&isValidArgType(argType1))
     {
       return sizerStringSizeValue(sizerStringArgSize(0) 
+sizerStringArgSize(1));
     }
     else
     {
       throwUdxException("Datatype mismatch.");
     }
   }
};

Udf* Concat::instantiate()
{
   return new Concat;
}