C言語集合体

この例では、次のファイル名を使用する: 'max.c

コード

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "nzaeapis.h"
static int run(NZAEAGG_HANDLE h);
int main(int argc, char * argv[])
{
if (nzaeIsLocal())
{
NzaeApi result;
char errorMessage[1050];
if (nzaeLocprotGetApi(&result, NZAE_LDK_VERSION, \
errorMessage, sizeof(errorMessage)))
{
fprintf(stderr, "%s\n", errorMessage);
return -1;
}
if (result.apiType == NZAE_API_AGGREGATION) {
run(result.handle.aggregation);
nzaeAggClose(result.handle.aggregation);
}
else {
fprintf(stderr, "unexpected API returned\n");
fflush(stderr);
return -1;
}
}
else {
NZAECONPT_HANDLE hConpt = nzaeconptCreate();
if (!hConpt)
{
fprintf(stderr, "error creating connection point\n");
fflush(stderr);
return -1;
}
const char * conPtName = nzaeRemprotGetRemoteName();
if (!conPtName)
{
fprintf(stderr, "error getting connection point name\n");
fflush(stderr);
exit(-1);
}
if (nzaeconptSetName(hConpt, conPtName))
{
fprintf(stderr, "error setting connection point name\n");
fflush(stderr);
nzaeconptClose(hConpt);
return -1;
}
NzaeremprotInitialization args;
memset(&args, 0, sizeof(args));
args.ldkVersion = NZAE_LDK_VERSION;
args.hConpt = hConpt;
if (nzaeRemprotCreateListener(&args))
{
fprintf(stderr, "unable to create listener - %s\n", \
args.errorMessage);
fflush(stderr);
nzaeconptClose(hConpt);
return -1;
}
NZAEREMPROT_HANDLE hRemprot = args.handle;
NzaeApi api;
int i;
for (i = 0; i < 5; i++)
{
if (nzaeRemprotAcceptApi(hRemprot, &api))
{
fprintf(stderr, "unable to accept API - %s\n", \
nzaeRemprotGetLastErrorText(hRemprot));
fflush(stderr);
nzaeconptClose(hConpt);
nzaeRemprotClose(hRemprot);
return -1;
}
printf("testcapi: accepted a remote request\n");
fflush(stdout);
if (api.apiType == NZAE_API_AGGREGATION) {
run(api.handle.aggregation);
nzaeClose(api.handle.aggregation);
}
else {
fprintf(stderr, "unexpected API returned\n");
fflush(stderr);
nzaeconptClose(hConpt);
nzaeRemprotClose(hRemprot);
return -1;
}
}
nzaeRemprotClose(hRemprot);
nzaeconptClose(hConpt);
}
return 0;
}
static int run(NZAEAGG_HANDLE h)
{
NzaeAggMessageType messageType;
for (;;)
{
void * pTemp = nzaeAggNext(h, &messageType);
if (messageType == NZAEAGG_END)
{
break;
}
if (messageType == NZAEAGG_ERROR)
{
nzaeAggUserError(h, nzaeAggGetLastErrorText(h));
break;
}
switch (messageType)
{
case NZAEAGG_INITIALIZE:
{
NzaeAggInitializeState * p = (NzaeAggInitializeState *) pTemp;
p->state.setNull(h, 0);
break;
}
case NZAEAGG_ACCUMULATE:
{
NzaeAggAccumulate * p = (NzaeAggAccumulate *) pTemp;
NzudsData * inputData;
NzudsData * stateData;
p->input.getValue(h, 0, &inputData);
p->state.getValue(h, 0, &stateData);
if (inputData->isNull) break;
if (stateData->isNull || *stateData->data.pInt32 < \
*inputData->data.pInt32)
{
p->state.setValue(h, 0, inputData);
}
break;
}
}
case NZAEAGG_MERGE:
{
NzaeAggMerge * p = (NzaeAggMerge *) pTemp;
NzudsData * inputStateData;
NzudsData * stateData;
p->inputState.getValue(h, 0, &inputStateData);
p->state.getValue(h, 0, &stateData);
if (inputStateData->isNull)
{
break; // no data to merge
}
if (stateData->isNull || *stateData->data.pInt32 \
< *inputStateData->data.pInt32)
{
p->state.setValue(h, 0, inputStateData);
}
break;
}
case NZAEAGG_FINAL_RESULT:
{
NzaeAggFinalResult * p = (NzaeAggFinalResult *) pTemp;
NzudsData * inputStateData;
p->inputState.getValue(h, 0, &inputStateData);
if (inputStateData->isNull)
{
p->result.setNull(h, 0);
} else
{
p->result.setValue(h, 0, inputStateData);
}
break;
}
default:
nzaeAggUserError(h, "unexpected message type");
}
nzaeAggUpdate(h);
}
return 0;
}

コンパイル

標準コンパイルを使用する:
$NZ_EXPORT_DIR/ae/utilities/bin/compile_ae --language system --version 3 \
--template compile max.c --exe max

登録

stateパラメータを使用して、サンプルを UDA として登録します:
$NZ_EXPORT_DIR/ae/utilities/bin/register_ae --language system --version 3 \
--template uda --exe max --sig "max_c(int4)" --return "int4" \
--state "(int4)"

実行中

実行するには、まずダミーのテーブルを作成し、集約を実行する:
CREATE TABLE grp_test (grp int4, val int4);
CREATE TABLE
INSERT INTO grp_test VALUES (1, 1);
INSERT 0 1
INSERT INTO grp_test VALUES (1, 2);
INSERT 0 1
INSERT INTO grp_test VALUES (1, 3);
INSERT 0 1
INSERT INTO grp_test VALUES (2, 4);
INSERT 0 1
SELECT max_c(val) FROM grp_test;
MAX_C
-------
4

(1 row)
SELECT grp, max_c(val) FROM grp_test GROUP BY grp;
GRP | MAX_C
-----+-------
1 | 3
2 | 4
(2 rows)
SELECT grp, max_c(val) over (partition BY grp) FROM grp_test;
GRP | MAX_C
-----+-------
1 | 3
1 | 3
1 | 3
2 | 4
(4 rows)