Programa de ejemplo string_pad_create.cpp

El programa de ejemplo string_pad_create.cpp recibe un tamaño de serie de entrada y una serie, y crea un SPUPad para almacenar la serie como una matriz de caracteres.

Nota: Los ejemplos de string_pad_* utilizan getPad() como la función que crea y accede al SPUPad. Puede sustituir getPad() por getMemPad() para crear el SPUPad en memoria compartida o puede sustituir getPad() por getFilePad() en los ejemplos para crear el SPUPad en la memoria de copia de seguridad de archivos.
/**
* UDF: string_pad_create(int4, varchar(64000)) -> bool
*
* Creates a SPUPad called "stringpad" with size and content 
* as specified in the arguments. The data from "stringpad" can 
* then be accessed by string_pad_get() and string_pad_size().
*
* argument1: the initial size of the pad. Must be between 1 and 64000.
* argument2: the initial data to put in the pad. Must be between 
* 0 and argument1 characters.
*
* returns true if pad created successfully. returns false if
* "stringpad" already exists when called.
*
* throws error if argument1 is null or if argument2 is null or 
* the arguments are out of range.
*
* REGISTRATION:
* CREATE OR REPLACE FUNCTION string_pad_create (int4, varchar(64000))
* RETURNS bool
* LANGUAGE CPP
* PARAMETER STYLE NPSGENERIC NOT FENCED 
* CALLED ON NULL INPUT
* NOT DETERMINISTIC
* EXTERNAL CLASS NAME 'StringPadCreate'
* EXTERNAL HOST OBJECT '/tmp/test/UDX_StringPadCreate.o_x86'
* EXTERNAL SPU OBJECT '/tmp/test/UDX_StringPadCreate.o_spu10';
*
* -->>Do NOT register any spu-pad related UDFs as 'deterministic'
*
* USAGE
* You need a user table that is defined on at least one SPU, such as:
* CREATE TABLE one_dslice(c1 int4);
* INSERT INTO one_dslice VALUES(1);
* SELECT string_pad_create(10, 'netezza') FROM one_dslice;
* This select creates a SPUPad on the SPU that manages the dataslice
* where one_dslice resides.
*
* To create the pad on multiple SPUs, create a table
* T with X distinct values where X>=NUM_DATASLICES. Then issue 
* 'SELECT string_pad_create(...,...) FROM T;'
* expect NUM_SPUS 't' values and X-NUM_SPUS 'f' values in the 
* result set.
*
* Copyright (c) 2007-2010 Netezza Corporation, an IBM Company
* All rights reserved.
*
*/
#include "udxinc.h"
#include <string.h>

using namespace nz::udx;

struct Root
{
 char* data;
 int size;
};

class StringPadCreate: public Udf
{
private:

public:
  static Udf* instantiate();
  virtual ReturnValue evaluate()
   {
    if(isArgNull(0)||isArgNull(1))
    {
    throwUdxException("cannot accept null arguments.");
    }
    if(argType(0)!=UDX_INT32)
    {
    throwUdxException("First argument must be int4.");
    }
    if(argType(1)!=UDX_VARIABLE)
    {
    throwUdxException("2nd argument must be a varchar.");
    }

   CPad* pad = getPad("stringpad");
   Root *ro = (Root*) pad->getRootObject(sizeof(Root));
   if(!ro)
   {
     ro=PAD_NEW(pad,Root);
     int32 size = int32Arg(0);
     StringArg* a = stringArg(1);
     int32 stringSize=a->length;
     if (size<1 || size > 64000)
     {
      throwUdxException("Given size is out of range.");
     }
     if(stringSize > size)
     {
      throwUdxException("Given string bigger than given size.");
     }
     ro->size=size;
     ro->data=PAD_NEW(pad,char)[size];
     for(int i=0; i<size; i++)
     {
       if(i<stringSize)
       {
         ro->data[i]=a->data[i];
       }
       else
       {
         ro->data[i]=' ';
       }
     }
     pad->setRootObject(ro, sizeof(Root));
     NZ_UDX_RETURN_BOOL(true);
   }
   else
   {
     NZ_UDX_RETURN_BOOL(false);
   }
  }
};
Udf* StringPadCreate::instantiate()
{
  return new StringPadCreate;
}