#include "postgres.h"
#include "fmgr.h"
#include "executor/spi.h"
#include "funcapi.h"
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
PG_MODULE_MAGIC;
PG_FUNCTION_INFO_V1(vpersonne);
PGDLLEXPORT
Datum
vpersonne(PG_FUNCTION_ARGS)
{
int spi_ret;
char sql[100];
FuncCallContext *funcctx;
MemoryContext oldcontext;
Datum result;
if (SRF_IS_FIRSTCALL()) {
funcctx = SRF_FIRSTCALL_INIT();
oldcontext = MemoryContextSwitchTo(funcctx->multi_call_memory_ctx);
SPI_connect();
snprintf(sql, sizeof(sql), "SELECT id, prenom, lenom FROM personne;");
spi_ret = SPI_execute(sql, true, 0);
funcctx->max_calls = SPI_processed;
MemoryContextSwitchTo(oldcontext);
}
funcctx = SRF_PERCALL_SETUP();
if (funcctx->call_cntr < funcctx->max_calls) {
result=PointerGetDatum(SPI_returntuple(SPI_tuptable->vals[funcctx->call_cntr],SPI_tuptable->tupdesc));
SRF_RETURN_NEXT(funcctx, result);
} else {
SPI_finish();
SRF_RETURN_DONE(funcctx);
}
}
La fonction dans PostgreSQL
CREATE OR REPLACE FUNCTION vpersonne(integer)
RETURNS SETOF record AS
'fnpgsqlsrf.dll', 'vpersonne'
LANGUAGE c
Le test de la fonction
SELECT * from vpersonne(null) as (id int, prenom varchar, nom varchar);
@+
]]>#include "postgres.h"
#include "fmgr.h"
#include "executor/spi.h"
#include "funcapi.h" // to return set of rows and cope with tuples
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
PG_MODULE_MAGIC;
PG_FUNCTION_INFO_V1(get_level1_c);
PGDLLEXPORT
Datum
get_level1_c(PG_FUNCTION_ARGS)
{
int spi_ret;
char sql[100];
char *id;
FuncCallContext *funcctx;
MemoryContext oldcontext;
Datum result;
if (SRF_IS_FIRSTCALL()) {
funcctx = SRF_FIRSTCALL_INIT();
oldcontext = MemoryContextSwitchTo(funcctx->multi_call_memory_ctx);
SPI_connect();
snprintf(sql, sizeof(sql), "SELECT id, prenom, lenom FROM personne;");
spi_ret = SPI_execute(sql, true, 0);
funcctx->max_calls = SPI_processed;
MemoryContextSwitchTo(oldcontext);
}
funcctx = SRF_PERCALL_SETUP();
if (funcctx->call_cntr < funcctx->max_calls) {
HeapTuple tuple = SPI_tuptable->vals[funcctx->call_cntr];// ligne que j'ai ajouté
//id = SPI_getvalue(SPI_tuptable->vals[funcctx->call_cntr], SPI_tuptable->tupdesc, 1);
//result = Int32GetDatum(atoi(id));
result=HeapTupleGetDatum(tuple);// ligne que j'ai ajouté
SRF_RETURN_NEXT(funcctx, result);
} else {
SPI_finish();
SRF_RETURN_DONE(funcctx);
}
}
La fonction correspondante dans postgresql...
CREATE OR REPLACE FUNCTION get_level1_c(IN integer)
RETURNS table(id integer, prenom character varying(30), lenom character varying(20)) AS
'fnpgsqlsrf.dll', 'get_level1_c'
LANGUAGE C
Sans les lignes ajoutées j'obtiens une seule colonne. J'ai essayé d'avoir plusieurs colonnes mais j'ai l'erreur...
ERREUR: cache lookup failed for type 0
État SQL :XX000
J’ai espoir que quelqu'un m'aidera à compléter cette fonction.
Merci d'avance.
Tout d'abord il n'est pas possible de créer de vue en C, uniquement des fonctions. Ensuite, je vous déconseillerai très fortement de partir sur une obfuscation du code via des fonctions en C, tout d'abord parce que les requêtes effectuées seront récupérables d'une manière ou d'une autre, et ensuite car cela complexifierait énormément toute votre application : beaucoup de bug, difficulté de livraison, nécessité compiler le code et de redémarrer l'instance pour mettre à jour une fonction.
]]>