/*
Copyright (c) 2007-2009 Netezza Corporation, an IBM Company
All rights reserved.
The aggregate PackChildren allows us to "pack" multiple children of one
node into a varchar (binary representation)
REGISTRATION:
create or replace aggregate PackChildren (INT4) returns VARCHAR(400)
state (VARCHAR(400))
language cpp parameter style npsgeneric
EXTERNAL CLASS NAME 'CPackChildren'
EXTERNAL HOST OBJECT '/home/nz/osf/packchildren.o_x86'
EXTERNAL SPU OBJECT '/home/nz/osf/packchildren.o_spu10';
Usage:
create table packtest (a int4);
insert into packtest values (1);
insert into packtest values (2);
insert into packtest values (3);
select PackChildren(a) from packtest;
*/
#include "udxinc.h"
#include <string.h>
using namespace nz::udx;
#define MAXCHILDREN 4000
class CPackChildren : public Uda
{
public:
static Uda* instantiate();
void initializeState()
{
StringArg *s = stringState(0);
s->length = 0;
setStateNull(0, false);
}
virtual void accumulate()
{
StringArg *s = stringState(0);
int32 value = int32Arg(0);
if (s->length < MAXCHILDREN * 4)
{
*((int32*)(s->data+s->length)) = value;
s->length = s->length + 4;
}
}
virtual void merge()
{
/* Destination */
StringArg *s = stringState(0);
/* Source */
StringArg *s2 = stringArg(0);
if (s->length + s2->length <= MAXCHILDREN * 4)
{
memcpy(s->data+s->length, s2->data, s2->length);
s->length = s->length + s2->length;
}
}
virtual ReturnValue finalResult()
{
setReturnNull(false);
StringReturn *ret = stringReturnInfo();
StringArg *s = stringArg(0);
printf("got %d\n", s->length);
ret->size = s->length;
memcpy(ret->data,s->data,s->length);
NZ_UDX_RETURN_STRING(ret);
}
};
Uda* CPackChildren::instantiate()
{
return new CPackChildren;
}