A razão pela qual o cliente psql está perguntando se você deseja se reconectar é porque o backend está com falha de segmentação, conforme os comentários.
Seria possível coletar um dump de memória de tal travamento e examiná-lo com um depurador (por exemplo, gdb) para descobrir exatamente onde está travando. No entanto, meu melhor palpite é que ele está travando porque você pegou um arquivo grande escrito como um componente principal do postgresql, compilou-o separadamente e tentou carregá-lo como um módulo de extensão.
O arquivo numeric.c contém um grande número de funções, variáveis estáticas e estruturas de dados, das quais você está tentando duplicar apenas uma. Todas essas funções, variáveis, etc já existem no sistema postgresql em execução. Quando você compila sua versão de numeric.c e a carrega, a nova função que você está adicionando estará referenciando as funções e variáveis em sua biblioteca ao invés de usar aquelas no programa postgresql principal. Provavelmente está fazendo referência a estruturas de dados que não foram inicializadas corretamente, causando o travamento.
Eu recomendo que você comece com um arquivo em branco e copie apenas a função int2_avg_accum de numeric.c (renomeado como você fez). Se essa função estiver chamando outras funções no postgresql, ou referenciando variáveis, ela usará as funções e variáveis no binário postgresql principal, que é o que você deseja. Você pode #include o numeric.h original para obter as declarações de todas as funções externas.
Existem algumas outras diferenças entre como a função é definida como uma função interna e como ela precisa ser definida quando carregada como um módulo carregado dinamicamente:
-
Você precisava especificar que está usando a convenção de chamada V1 adicionando a macro:
PG_FUNCTION_INFO_V1(int2_avg_accum2);
Se faltar, isso também causará falhas de segmentação porque o postgresql assumirá as convenções de chamada da versão 0, que não correspondem à definição da função!
-
Como você indicou, você deve incluir o PG_MODOULE_MAGIC.
O arquivo completo, que funcionou para mim, é:
#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);
}
Compilado com:
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
Eu estava usando o Postgresql 9.2 no Centos 6. Você pode precisar ajustar seus caminhos de acordo com sua configuração.