Grunden til, at psql-klienten spørger, om du ønsker at oprette forbindelse igen, er, at backend'en er segfaulting ifølge kommentarerne.
Det ville være muligt at indsamle et kernedump fra et sådant nedbrud og undersøge det med en debugger (f.eks. gdb) for at finde ud af præcis, hvor det går ned. Mit bedste gæt er dog, at det går ned, fordi du har taget en stor fil skrevet til at være en kernekomponent i postgresql, kompileret den separat og forsøgt at indlæse den som et udvidelsesmodul.
Filen numeric.c indeholder et stort antal funktioner, statiske variabler og datastrukturer, hvoraf du kun forsøger at duplikere én. Alle disse funktioner, variabler osv. findes allerede i det kørende postgresql-system. Når du kompilerer din version af numeric.c og indlæser den, vil den nye funktion, du tilføjer, referere til funktionerne og variablerne i dit bibliotek i stedet for at bruge dem i postgresql-hovedprogrammet. Det refererer sandsynligvis til datastrukturer, som ikke er korrekt initialiseret, hvilket får det til at gå ned.
Jeg anbefaler, at du starter med en tom fil og kun kopierer funktionen int2_avg_accum fra numeric.c (omdøbt som du har gjort). Hvis den funktion kalder andre funktioner i postgresql, eller refererer til variabler, vil den bruge funktionerne og variablerne i postgresql-hovedbinæren, hvilket er det, du ønsker. Du kan #inkludere den originale numeric.h for at få erklæringerne for alle de eksterne funktioner.
Der er nogle andre forskelle mellem, hvordan funktionen er defineret som en intern funktion, og hvordan den skal defineres, når den indlæses som et dynamisk indlæst modul:
-
Du skulle angive, at du bruger V1-kaldekonventionen ved at tilføje makroen:
PG_FUNCTION_INFO_V1(int2_avg_accum2);
Hvis det mangler, vil dette også forårsage segfaults, fordi postgresql vil antage version 0 kaldende konventioner, som ikke matcher funktionsdefinitionen!
-
Som du har angivet, skal du inkludere PG_MODOULE_MAGIC.
Den komplette fil, som fungerede for mig, er:
#include "postgres.h"
#include "fmgr.h"
#include "utils/array.h"
#ifdef PG_MODULE_MAGIC
PG_MODULE_MAGIC;
#endif
typedef struct Int8TransTypeData
{
int64 count;
int64 sum;
} Int8TransTypeData;
PG_FUNCTION_INFO_V1(int2_avg_accum2);
Datum
int2_avg_accum2(PG_FUNCTION_ARGS)
{
ArrayType *transarray;
int16 newval = PG_GETARG_INT16(1);
Int8TransTypeData *transdata;
/*
* If we're invoked as an aggregate, we can cheat and modify our first
* parameter in-place to reduce palloc overhead. Otherwise we need to make
* a copy of it before scribbling on it.
*/
if (AggCheckCallContext(fcinfo, NULL))
transarray = PG_GETARG_ARRAYTYPE_P(0);
else
transarray = PG_GETARG_ARRAYTYPE_P_COPY(0);
if (ARR_HASNULL(transarray) ||
ARR_SIZE(transarray) != ARR_OVERHEAD_NONULLS(1) + sizeof(Int8TransTypeData))
elog(ERROR, "expected 2-element int8 array");
transdata = (Int8TransTypeData *) ARR_DATA_PTR(transarray);
transdata->count++;
transdata->sum += newval;
PG_RETURN_ARRAYTYPE_P(transarray);
}
Kompileret med:
gcc -I/usr/pgsql-9.2/include/server -fPIC -c my_avg_accum.c
gcc -shared -o my_avg_accum.so my_avg_accum.o
Jeg brugte Postgresql 9.2 på Centos 6. Du skal muligvis justere dine stier i henhold til din opsætning.