Thread: Problem with trigger function in C
I'm new at this and I apologize if I got the wrong list, but I'm trying to write a trigger function in C which is linked in with libxqilla and is supposed to run an xquery against some xml we have stored in a column. I find that when the function is entered fcinfo is null, which causes a segfault. I copied the example trigger function from the documentation at http://www.postgresql.org/docs/8.3/static/trigger-example.html. I added some debug output to tell that fcinfo is null. I built the function by copying the makefile in the contrib directory for the xml2 demo and modifying it a bit. Here's what I wound up with: --- start --- MODULE_big = xqueryTrigger PG_CPPFLAGS = -I$(libpq_srcdir) OBJS = xqueryTrigger.o DATA = libxqueryTrigger.so SHLIB_LINK = -L/usr/local/lib -lxqilla -lxerces-c-3.0 -lcrypto -lssl ifdef USE_PGXS PG_CONFIG = pg_config PGXS := $(shell $(PG_CONFIG) --pgxs) include $(PGXS) else subdir = contrib/xml2 top_builddir = ../.. include $(top_builddir)/src/Makefile.global include $(top_srcdir)/contrib/contrib-global.mk endif --- stop --- Here's the trigger function (or at least as far as it gets) --- start --- #include "postgres.h" #include "executor/spi.h" /* this is what you need to work with SPI */ #include "commands/trigger.h" /* ... and triggers */ #include <fmgr.h> #ifdef PG_MODULE_MAGIC PG_MODULE_MAGIC; #endif typedef void*(*memFunc)(unsigned int sz); extern int runQuery(const char *qry, const char *xml, char **result, memFunc allocator); extern Datum xqueryTrigger(PG_FUNCTION_ARGS); PG_FUNCTION_INFO_V1(xqueryTrigger); void *memAllocator(unsigned int); Datum xquerytrigger(PG_FUNCTION_ARGS); void *memAllocator(unsigned int sz) { return palloc(sz); } Datum xquerytrigger(PG_FUNCTION_ARGS) { TriggerData *trigdata; TupleDesc tupdesc; HeapTuple rettuple; char *when; bool checknull; bool isnull; int ret, i; char *status; elog(INFO, "Entering xquerytrigger()"); elog(INFO, "getting TriggerData..."); elog(INFO, "fcinfo = %p", fcinfo); elog(INFO, "fcinfo->context = %p", fcinfo->context); trigdata = (TriggerData *) fcinfo->context; --- stop --- Any advice would be appreciated. Thanks Joe
"Joe Halpin" <jhalpin100@gmail.com> writes: > I'm new at this and I apologize if I got the wrong list, but I'm > trying to write a trigger function in C which is linked in with > libxqilla and is supposed to run an xquery against some xml we have > stored in a column. I find that when the function is entered fcinfo is > null, which causes a segfault. AFAIK the only way fcinfo would be null is if PG didn't think that the function was V1 call convention. I see that you do have the PG_FUNCTION_INFO_V1 macro in there, which eliminates the most obvious explanation. Are you sure that the SQL-level CREATE FUNCTION command references this function name and not some other one? regards, tom lane
Sorry I forgot to add that part. Here's how I did that: sn=# create function xqueryTrigger() returns trigger as '/usr/local/lib/postgresql/xqueryTrigger.so' language c; CREATE FUNCTION sn=# create trigger tbefore before insert or update on at_xparam for each row execute procedure xquerytrigger(); CREATE TRIGGER Is the function name case sensitive? I had originally named it xqueryTrigger, but after some error messages which referenced "xquerytrigger" I renamed it to be all lower case. Thanks Joe On Tue, Oct 28, 2008 at 3:01 PM, Tom Lane <tgl@sss.pgh.pa.us> wrote: > "Joe Halpin" <jhalpin100@gmail.com> writes: >> I'm new at this and I apologize if I got the wrong list, but I'm >> trying to write a trigger function in C which is linked in with >> libxqilla and is supposed to run an xquery against some xml we have >> stored in a column. I find that when the function is entered fcinfo is >> null, which causes a segfault. > > AFAIK the only way fcinfo would be null is if PG didn't think that the > function was V1 call convention. I see that you do have the > PG_FUNCTION_INFO_V1 macro in there, which eliminates the most obvious > explanation. Are you sure that the SQL-level CREATE FUNCTION command > references this function name and not some other one? > > regards, tom lane >
"Joe Halpin" <jhalpin100@gmail.com> writes: > Sorry I forgot to add that part. Here's how I did that: > sn=# create function xqueryTrigger() returns trigger as > '/usr/local/lib/postgresql/xqueryTrigger.so' language c; > CREATE FUNCTION > Is the function name case sensitive? Well, if you don't quote it then it's forced to all lower case, same as any other SQL identifier. ... and that is the problem, because your function's C name is xquerytrigger but the V1 macro says xqueryTrigger. I must be blind today :-(. Get that all in sync and you should be good. regards, tom lane