The string_pad_create.cpp sample program
The string_pad_create.cpp sample program takes an input string size and string and creates a SPUPad to store the string as an array of characters.
Note: The string_pad_* examples use getPad()
as the function that creates and accesses the SPUPad. You could replace
getPad() with getMemPad() to create the SPUPad in shared memory, or
you could replace getPad() with getFilePad() throughout the examples
to create the SPUPad in file-backed memory.
/**
* 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;
}