Crear el archivo C++ para la UDF
Para empezar, utilice cualquier editor de texto para crear el archivo C++. El nombre de archivo debe tener una extensión .cpp. Es posible que desee crear un directorio como /home/nz/udx_files como área para los archivos de código de UDX.
Su archivo C++ debe incluir el archivo de cabecera ' udxinc.h ', que contiene las declaraciones necesarias para las funciones definidas por el usuario y el procesamiento en las SPUs.
#include "udxinc.h"
#include "udxinc.h"
#include <string.h>
nz::udx_ver2
. (Los UDX de la API versión
1 utilizan el espacio de nombres nz::udx
.) El programa C++ debe hacer referencia al espacio de nombres correcto. Por ejemplo:#include "udxinc.h"
#include <string.h>
using namespace nz::udx_ver2;
udx_ver2
como espacio de nombres por defecto para los ejemplos que siguen. Las secciones señalan las diferencias con la versión 1 de UDX, y la referencia de funciones y agregados definidos por el usuario de ejemplo contiene ejemplos de definiciones de las versiones 1 y 2. Puede continuar creando las funciones de UDX versión 1 y las nuevas funciones de la versión 2; ambas funciones se ejecutan en el release 6.0.x. Sin embargo, las funciones de la versión 1 funcionan en sistemas ' Netezza Performance Server ' release ' 5.0.x y posteriores, por lo que podrían ser más portables para sus sistemas ' Netezza Performance Server '.customername
:#include "udxinc.h"
#include <string.h>
using namespace nz::udx_ver2;
class CCustomerName: public nz::udx_ver2::Udf
{
public:
};
Cada UDF debe implementar los dos métodos siguientes:
- El método instantiate() se llama a través del motor de tiempo de ejecución para crear el objeto dinámicamente. La implementación estática debe estar fuera de la definición de clase. En la versión 2 de UDX, el método instantiate toma un argumentoUdxInit *pInit), que permite acceder a la especificación de memoria, la configuración de registro y el entorno UDX (consulte Entorno UDX). El constructor también debe tomar un objeto UdxInit y pasarlo al constructor de clase base. El método instantiate crea un objeto de un tipo de clase derivada utilizando el nuevo operador y devolviéndolo (como tipo de clase base Udf) al motor de tiempo de ejecución. El motor de tiempo de ejecución suprime el objeto cuando ya no es necesario. A continuación, se muestra un ejemplo del método
instantiate para la API versión 2:
#include "udxinc.h" #include <string.h> using namespace nz::udx_ver2; class CCustomerName: public nz::udx_ver2::Udf { public: CCustomerName(UdxInit *pInit) : Udf(pInit) { } static nz::udx_ver2::Udf* instantiate(UdxInit *pInit); }; nz::udx_ver2::Udf* CCustomerName::instantiate(UdxInit *pInit) { return new CCustomerName(pInit); }
- Se llama al método evaluate() una vez para cada fila de datos durante la ejecución.
#include "udxinc.h" #include <string.h> using namespace nz::udx_ver2; class CCustomerName: public nz::udx_ver2::Udf { public: CCustomerName(UdxInit *pInit) : Udf(pInit) { } static nz::udx_ver2::Udf* instantiate(UdxInit *pInit); virtual nz::udx_ver2::ReturnValue evaluate() { // Code to be inserted here } }; nz::udx_ver2::Udf* CCustomerName::instantiate(UdxInit *pInit) { return new CCustomerName(pInit); }
Puede implementar constructores y destructores según sea necesario. En la API versión 1, los constructores son opcionales. En la API versión 2, los constructores son necesarios; debe especificar un constructor aunque sólo invoque al constructor de clase base, como en el ejemplo anterior. Algunas acciones comunes a incluir en los constructores son las rutinas de reserva de memoria (ya que new y delete son relativamente caras), y la configuración de cualquier estructura necesaria para el cálculo (por ejemplo, la configuración de una matriz para rutinas de cifrado).
customername
', el UDF toma una cadena y devuelve el entero 1 si la cadena empieza por "Cliente A", de lo contrario devuelve el entero 0. El código para el método evaluate es el siguiente:virtual nz::udx_ver2::ReturnValue evaluate()
{
StringArg *str;
str = stringArg(0); // 4
int lengths = str->length; // 5
char *datas = str->data; // 6
int32 retval = 0;
if (lengths >= 10)
if (memcmp("Customer A",datas,10) == 0)
retval = 1;
NZ_UDX_RETURN_INT32(retval); // 11
}
En el programa de ejemplo, la línea 4 declara y usa una estructura StringArg para pasar el argumento a la UDF. Los argumentos para las UDF se recuperan utilizando funciones como StringArg. Si esta UDF toma un segundo argumento de serie, StringArg(1) debe hacer referencia al segundo argumento. Para obtener una lista completa de los tipos de argumentos admitidos y sus funciones de ayuda asociadas, consulte Referencia de la API de ayuda de tipos de datos. Las líneas 5 y 6 extraen la longitud y el puntero del carácter (char*) de la estructura StringArg.
La línea 11 utiliza una macro UDX para devolver el valor calculado al motor de Netezza Performance Server. La macro NZ_UDX_RETURN_INT32 le ayuda a confirmar que el valor de retorno es del tipo esperado. Para obtener una lista de las macros de retorno disponibles, consulte Macros de valor de retorno UDX.
Para utilizar la función, debe compilarla y registrarla como función disponible en el sistema Netezza Performance Server.