Le programme d'exemple string_pad_create.cpp

Le programme d'exemple " string_pad_create.cpp prend en entrée une taille de chaîne et une chaîne et crée un SPUPad pour stocker la chaîne sous la forme d'un tableau de caractères.

Remarque : les exemples string_pad_* utilisent getPad( comme fonction de création et d'accès au SPUPad. Vous pouvez remplacer getPad getPad() par getMemPad() pour créer le SPUPad en mémoire partagée, ou vous pouvez remplacer getPad() par getFilePad() dans les exemples pour créer le SPUPad en mémoire adossée à un fichier.
/**
* 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;
}