En tu caso, tu función devuelve un número variable de elementos y no veo que reserves memoria para ellos de forma variable , puedes mirar el código de la función del enlace https://github.com/postgres/postgres/blob/master/src/tutorial/funcs.c#L89-L103 y que te guíe en la reserva de memoria y ampliación de la misma cuando los resultados de la consulta son variables.
Un saludo El mar, 27 ago 2024 a las 1:52, Fernando Magariños (<mancha.at...@gmail.com>) escribió: > > Hola, para la versión 9 de PostgreSQL escribí varias funciones en C que > eran invocadas desde SQL. Al compilarlas para la versión 15, tengo el > problema mencionado en el Asunto del mensaje: al ejecutar cualquiera de > ellas, termina la ejecución del servidor por el segmentation fault: > > 2024-08-26 16:30:02.801 CST [1177]LOG: server process (PID 10357) was > terminated by signal 11: Segmentation fault > 2024-08-26 16:30:02.801 CST [1177]DETAIL: Failed process was running: > select nombre, apeuno, apedos, entnac, sexo, fecnac, '0'::text as hm, > crea_curp(nombre::text, apeuno::text, apedos::text, entnac::integer, > sexo::text, fecnac::text, '0'::text) from mini_retrapo limit 18; > 2024-08-26 16:30:02.801 CST [1177]LOG: terminating any other active > server processes > 2024-08-26 16:30:02.802 CST prueba_extensiones mancha [13868]FATAL: the > database system is in recovery mode > 2024-08-26 16:30:02.808 CST [1177]LOG: all server processes terminated; > reinitializing > 2024-08-26 16:30:03.052 CST [13869]LOG: database system was > interrupted; last known up at 2024-08-26 16:29:55 CST > 2024-08-26 16:30:10.351 CST [13869]LOG: database system was not > properly shut down; automatic recovery in progress > > Hice unas pruebas y llegué a la conclusión que el problema se manifiesta > dependiendo del número de registros seleccionados o del número de > argumentos que recibe la función. > > El texto del ejemplo minimo: > > #include <string.h> > #include <stdlib.h> > #include <stdio.h> > #include <string.h> > #include <regex.h> > #include <locale.h> > #include <regex.h> > #include "postgres.h" > #include "executor/executor.h" > #include "utils/builtins.h" > #include "fmgr.h" > > PG_MODULE_MAGIC; > void _PG_init(void); > void _PG_fini(void); > Datum c_crea_curp (PG_FUNCTION_ARGS); > > #define DBUG 1 > > PG_FUNCTION_INFO_V1(c_crea_curp); > > Datum c_crea_curp(PG_FUNCTION_ARGS) > { > char *nombre, *apepat, *apemat, *sexo, *fecnac, *lahm; > char salida[2048]; > int laent; > nombre = text_to_cstring(PG_GETARG_TEXT_PP(0)); > apepat = text_to_cstring(PG_GETARG_TEXT_PP(1)); > apemat = text_to_cstring(PG_GETARG_TEXT_PP(2)); > laent = PG_GETARG_INT32(3); > sexo = text_to_cstring(PG_GETARG_TEXT_PP(4)); > fecnac = text_to_cstring(PG_GETARG_TEXT_PP(5)); > lahm = text_to_cstring(PG_GETARG_TEXT_PP(6)); > sprintf(salida, "%s|%s|%s|%d|%s|%s|%s", nombre, apepat, > apemat, laent, sexo, fecnac, lahm); > elog(NOTICE, "entrada:>%s<>%s<>%s<>%d<>%s<>%s<>%s<", > nombre, apepat, apemat, laent, sexo, fecnac, lahm); > PG_RETURN_TEXT_P(CStringGetTextDatum(salida)); > } > > Al momento de cargarlo y ejecutarlo, si lo hago sobre 8 registros, lo hace > sin problema, pero si lo hago sobre 28 ya aroja el seg fault. > > mancha@duanne:~/trabajo/Padrinos$ psql prueba_extensiones > psql (15.7) > Type "help" for help. > > prueba_extensiones=# create or replace function crea_curp (text, text, > text, integer, text, text, text) returns text as > '/home/mancha/lib/inicio_curp.so', 'c_crea_curp' language c IMMUTABLE; > CREATE FUNCTION > prueba_extensiones=# select nombre, apeuno, apedos, entnac, sexo, fecnac, > '0'::text as hm, crea_curp(nombre::text, apeuno::text, apedos::text, > entnac::integer, sexo::text, fecnac::text, '0'::text) from mini_retrapo > limit 8; > NOTICE: entrada:>LUZ<>FLORES<>GARCIA<>30<>M<>1929-12-25<>0< > NOTICE: entrada:>ROSA MARIA<>FRANCO<>LOA<>9<>M<>1971-04-19<>0< > NOTICE: entrada:>ALFREDO<>FRANCO<>PEREZ<>9<>H<>1978-01-16<>0< > NOTICE: entrada:>MATEO<>FARIAS<>RUIZ<>16<>H<>2015-07-05<>0< > NOTICE: entrada:>BELEN<>FABIAN<>SORIANO<>9<>M<>2018-07-29<>0< > NOTICE: entrada:>RAUL<>FRANCO<>ROMO<>14<>H<>1948-07-19<>0< > NOTICE: entrada:>LAURA<>FABIAN<>NERI<>21<>M<>1992-02-19<>0< > NOTICE: entrada:>DAFNE<>FELIX<>AYALA<>25<>M<>2016-10-09<>0< > nombre | apeuno | apedos | entnac | sexo | fecnac | hm | > crea_curp > > ------------+--------+---------+--------+------+------------+----+---------------------------------------- > LUZ | FLORES | GARCIA | 30 | M | 1929-12-25 | 0 | > LUZ|FLORES|GARCIA|30|M|1929-12-25|0 > ROSA MARIA | FRANCO | LOA | 9 | M | 1971-04-19 | 0 | ROSA > MARIA|FRANCO|LOA|9|M|1971-04-19|0 > ALFREDO | FRANCO | PEREZ | 9 | H | 1978-01-16 | 0 | > ALFREDO|FRANCO|PEREZ|9|H|1978-01-16|0 > MATEO | FARIAS | RUIZ | 16 | H | 2015-07-05 | 0 | > MATEO|FARIAS|RUIZ|16|H|2015-07-05|0 > BELEN | FABIAN | SORIANO | 9 | M | 2018-07-29 | 0 | > BELEN|FABIAN|SORIANO|9|M|2018-07-29|0 > RAUL | FRANCO | ROMO | 14 | H | 1948-07-19 | 0 | > RAUL|FRANCO|ROMO|14|H|1948-07-19|0 > LAURA | FABIAN | NERI | 21 | M | 1992-02-19 | 0 | > LAURA|FABIAN|NERI|21|M|1992-02-19|0 > DAFNE | FELIX | AYALA | 25 | M | 2016-10-09 | 0 | > DAFNE|FELIX|AYALA|25|M|2016-10-09|0 > (8 rows) > > prueba_extensiones=# select nombre, apeuno, apedos, entnac, sexo, fecnac, > '0'::text as hm, crea_curp(nombre::text, apeuno::text, apedos::text, > entnac::integer, sexo::text, fecnac::text, '0'::text) from mini_retrapo > limit 28; > NOTICE: entrada:>LUZ<>FLORES<>GARCIA<>30<>M<>1929-12-25<>0< > NOTICE: entrada:>ROSA MARIA<>FRANCO<>LOA<>9<>M<>1971-04-19<>0< > NOTICE: entrada:>ALFREDO<>FRANCO<>PEREZ<>9<>H<>1978-01-16<>0< > NOTICE: entrada:>MATEO<>FARIAS<>RUIZ<>16<>H<>2015-07-05<>0< > NOTICE: entrada:>BELEN<>FABIAN<>SORIANO<>9<>M<>2018-07-29<>0< > NOTICE: entrada:>RAUL<>FRANCO<>ROMO<>14<>H<>1948-07-19<>0< > NOTICE: entrada:>LAURA<>FABIAN<>NERI<>21<>M<>1992-02-19<>0< > NOTICE: entrada:>DAFNE<>FELIX<>AYALA<>25<>M<>2016-10-09<>0< > NOTICE: entrada:>JUANA<>FERIA<>PEREZ<>20<>M<>1997-08-25<>0< > server closed the connection unexpectedly > This probably means the server terminated abnormally > before or while processing the request. > The connection to the server was lost. Attempting reset: Failed. > The connection to the server was lost. Attempting reset: Failed. > !?> \q > > Ahora bien, si comento la lectura de los ultimos 5 argumentos: > > Datum c_crea_curp(PG_FUNCTION_ARGS) > { > char *nombre, *apepat/* , *apemat, *sexo, *fecnac, *lahm */; > char salida[2048]; > /* int laent; */ > nombre = text_to_cstring(PG_GETARG_TEXT_PP(0)); > apepat = text_to_cstring(PG_GETARG_TEXT_PP(1)); > /* apemat = text_to_cstring(PG_GETARG_TEXT_PP(2)); */ > /* laent = PG_GETARG_INT32(3); */ > /* sexo = text_to_cstring(PG_GETARG_TEXT_PP(4)); */ > /* fecnac = text_to_cstring(PG_GETARG_TEXT_PP(5)); */ > /* lahm = text_to_cstring(PG_GETARG_TEXT_PP(6)); */ > /* sprintf(salida, "%s|%s|%s|%d|%s|%s|%s", nombre, apepat, */ > /* apemat, laent, sexo, fecnac, lahm); */ > /* elog(NOTICE, "entrada:>%s<>%s<>%s<>%d<>%s<>%s<>%s<", */ > /* nombre, apepat, apemat, laent, sexo, fecnac, lahm); */ > sprintf(salida, "%s|%s", nombre, apepat); > PG_RETURN_TEXT_P(CStringGetTextDatum(salida)); > } > > Entonces la función hace lo esperado para los 71 millones de registros. > > nombre | > apeuno | apedos | entnac | sexo | > fecnac | hm | crea_curp > > > ----------------------------------------------------+----------------------------------------+----------------------------+--------+------+------------+----+------------------------------------------------------------------------------------------ > LUZ | FLORES > | GARCIA | 30 | M | 1929-12-25 > | 0 | LUZ|FLORES > ROSA MARIA | FRANCO > | LOA | 9 | M | 1971-04-19 > | 0 | ROSA MARIA|FRANCO > . > . > . > > > También hice pruebas sin hacer el sprintf y regresando de la función con > PG_RETURN_NULL(); > y funciona bien si leo sólo dos argumentos o si uso los siete funciona > limitando el select a 8 registros. > > Revisé el código de postgresql-15.7/backend/replication/slotfuncs.c, > postgresql-15.7/test/regress/regress.c y los ejemplos contenidos en > postgresql-15.7/src/tutorial > > El Makefile es: > > MODULES = complex funcs inicio_curp > DATA_built = advanced.sql basics.sql complex.sql funcs.sql syscat.sql > > ifdef NO_PGXS > subdir = src/tutorial > top_builddir = ../.. > include $(top_builddir)/src/Makefile.global > include $(top_srcdir)/src/makefiles/pgxs.mk > else > PG_CONFIG = pg_config > PGXS := $(shell $(PG_CONFIG) --pgxs) > include $(PGXS) > endif > > %.sql: %.source > rm -f $@; \ > C=`pwd`; \ > sed -e "s:_OBJWD_:$$C:g" < $< > $@ > > Tomado del directorio postgresql-15.7/src/tutorial y la salida del make > es: > > -*- mode: compilation; default-directory: > "~/trabajo/Padrinos/postgresql-15.7/src/tutorial/" -*- > Compilation started at Mon Aug 26 17:19:31 > > make -k > gcc -Wall -Wmissing-prototypes -Wpointer-arith > -Wdeclaration-after-statement -Werror=vla -Wendif-labels > -Wmissing-format-attribute -Wimplicit-fallthrough=3 -Wformat-security > -fno-strict-aliasing -fwrapv -fexcess-precision=standard > -Wno-format-truncation -fmessage-length=0 -grecord-gcc-switches -O2 -Wall > -D_FORTIFY_SOURCE=2 -fstack-protector-strong -funwind-tables > -fasynchronous-unwind-tables -fstack-clash-protection -g -fPIC -I. -I./ > -I/usr/include/pgsql/server -I/usr/include/pgsql/internal -D_GNU_SOURCE > -I/usr/include/libxml2 -c -o inicio_curp.o inicio_curp.c > gcc -Wall -Wmissing-prototypes -Wpointer-arith > -Wdeclaration-after-statement -Werror=vla -Wendif-labels > -Wmissing-format-attribute -Wimplicit-fallthrough=3 -Wformat-security > -fno-strict-aliasing -fwrapv -fexcess-precision=standard > -Wno-format-truncation -fmessage-length=0 -grecord-gcc-switches -O2 -Wall > -D_FORTIFY_SOURCE=2 -fstack-protector-strong -funwind-tables > -fasynchronous-unwind-tables -fstack-clash-protection -g -fPIC > inicio_curp.o -L/usr/lib/postgresql15/lib64 -L/usr/lib64 -Wl,--as-needed > -shared -o inicio_curp.so > /usr/bin/clang -Wno-ignored-attributes -fno-strict-aliasing -fwrapv > -Wno-unused-command-line-argument -O2 -I. -I./ -I/usr/include/pgsql/server > -I/usr/include/pgsql/internal -D_GNU_SOURCE -I/usr/include/libxml2 > -flto=thin -emit-llvm -c -o inicio_curp.bc inicio_curp.c > > Compilation finished at Mon Aug 26 17:19:32 > > ¿Alguna idea de lo que estoy haciendo mal o si se trata de un bug de > aparición reciente? > > Agradezco la atención y los comentarios que presten a éste mensaje. > > -- > Saludos. > > /* Los nombres, endidad de nacimiento y fecha de nacimiento de los > registros mostrados son ficticios */ > > >