Fonction de tableau simple en langage C
Cet exemple utilise le nom de fichier suivant : " sstring.c
Coder
Le code de cet exemple crée une fonction qui divise une chaîne en plusieurs chaînes en fonction du délimiteur. Cet exemple peut renvoyer plus de lignes de sortie que de lignes d'entrée. Notez la logique de boucle supplémentaire dans l'exécution.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "nzaeapis.h"
static int run(NZAE_HANDLE h);
int main(int argc, char * argv[])
{
if (nzaeIsLocal())
{
NzaeInitialization arg;
memset(&arg, 0, sizeof(arg));
arg.ldkVersion = NZAE_LDK_VERSION;
if (nzaeInitialize(&arg))
{
fprintf(stderr, "initialization failed\n");
return -1;
}
run(arg.handle);
nzaeClose(arg.handle);
}
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;
}
if (api.apiType != NZAE_API_FUNCTION)
{
fprintf(stderr, "unexpected API returned\n");
fflush(stderr);
nzaeconptClose(hConpt);
nzaeRemprotClose(hRemprot);
return -1;
}
printf("testcapi: accepted a remote request\n");
fflush(stdout);
run(api.handle.function);
}
nzaeRemprotClose(hRemprot);
nzaeconptClose(hConpt);
}
return 0;
}
static int run(NZAE_HANDLE h)
{
NzaeMetadata metadata;
if (nzaeGetMetadata(h, &metadata))
{
fprintf(stderr, "get metadata failed\n");
return -1;
}
#define CHECK(value) \
{ \
NzaeRcCode rc = value; \
if (rc) \
{ \
const char * format = "%s in %s at %d"; \
fprintf(stderr, format, \
nzaeGetLastErrorText(h), __FILE__, __LINE__); \
nzaeUserError(h, format, \
nzaeGetLastErrorText(h), __FILE__, __LINE__); \
exit(-1); \
} \
}
if (metadata.outputColumnCount != 1 ||
metadata.outputTypes[0] != NZUDSUDX_VARIABLE)
{
nzaeUserError(h, "expecting one output column of type string");
nzaeDone(h);
return -1;
}
if (metadata.inputColumnCount != 1)
{
nzaeUserError(h, "expecting one input column");
nzaeDone(h);
return -1;
}
if (metadata.inputTypes[0] != NZUDSUDX_FIXED
&& metadata.inputTypes[0] != NZUDSUDX_VARIABLE)
{
nzaeUserError(h, "first input column expected to be a string type");
nzaeDone(h);
return -1;
}
for (;;)
{
int i;
double result = 0;
NzaeRcCode rc = nzaeGetNext(h);
if (rc == NZAE_RC_END)
{
break;
}
NzudsData * input = NULL;
CHECK(nzaeGetInputColumn(h, 0, &input));
const char * opString;
if (input->isNull)
{
nzaeUserError(h, "first input column may not be null");
nzaeDone(h);
return -1;
}
if (input->type == NZUDSUDX_FIXED)
{
opString = input->data.pFixedString;
} else if (input->type == NZUDSUDX_VARIABLE)
{
opString = input->data.pVariableString;
} else
{
nzaeUserError(h, "first input column expected to be a string \
type");
nzaeDone(h);
return -1;
}
const char *ptr = opString;
char *token;
while ((token = strtok(ptr, ",")) != NULL) {
ptr = NULL;
CHECK(nzaeSetOutputString(h, 0, token));
CHECK(nzaeOutputResult(h));
}
}
nzaeDone(h);
return 0;
}
Compilation
Utiliser la compilation standard :
$NZ_EXPORT_DIR/ae/utilities/bin/compile_ae --language system --version 3 \
--template compile sstring.c --exe sstring
Enregistrement
Enregistrer l'exécutable "
"sstring"
nouvellement créé :$NZ_EXPORT_DIR/ae/utilities/bin/register_ae --language system --version 3 \
--template udtf --exe sstring --sig "sstring_c(VARCHAR(ANY))" \
--return "TABLE (val varchar(2000))"
En cours d'exécution
Exécutez la requête dans nzsql :
SELECT * FROM TABLE WITH FINAL(sstring_c('12:30:15'));
VAL
----------
12:30:15
(1 row)
SELECT * FROM TABLE WITH FINAL(sstring_c('12:30:15,two,three'));
VAL
----------
12:30:15
two
three
(3 rows)
SELECT * FROM TABLE WITH FINAL(sstring_c(NULL));
ERROR: first input COLUMN may NOT be NULL