That who has seen all my questions about triggers, may say
"Once again this guy ??!!!". I hope you don't think so.
I've created, compiled, linked and executed my self-made triggers,
but there is still a problem.
When I try to use the trigger by launching a "delete-query", I get this
message:
------------
PQexec() -- Request was sent to backend, but backend closed the channel
before responding.
This probably means the backend terminated abnormally before or while
processing the request.
------------
I guess the "PQexec" function is called by the "SPI_exec" function.
But where is the problem ???
_______________________________________
David Martinez Cuevas
Direccion General de Estadistica, UNAM
Tel. 622-60-80
E-mail david@estadistica.unam.mx
----------------------------------------
/*
* -- set of functions to define referential integrity
* constraints using general triggers.
*/
#include "executor/spi.h" /* this is what you need to work with SPI */
#include "commands/trigger.h" /* -"- and triggers */
#include <ctype.h> /* tolower () */
int cascada(void);
int
cascada()
{
Trigger *trigger;
char *relname; /* referencing relation name */
Relation rel; /* triggered relation */
HeapTuple trigtuple = NULL; /* tuple to being changed */
TupleDesc tupdesc; /* tuple description */
int ret;
int i;
char *cad;
char query[256],cad2[20];
/*
* Some checks first...
*/
/* Called by trigger manager ? */
if (!CurrentTriggerData)
elog(ERROR, "cascada: los triggers no han sido inicializados");
/* Should be called for ROW trigger */
if (TRIGGER_FIRED_FOR_STATEMENT(CurrentTriggerData->tg_event))
elog(ERROR, "cascada: no se pueden procesar eventos por statement");
/* Not should be called for INSERT */
if (TRIGGER_FIRED_BY_INSERT(CurrentTriggerData->tg_event))
elog(ERROR, "cascada: no se pueden procesar eventos de tipo insert");
/* Have to check tg_trigtuple - tuple being deleted */
trigtuple = CurrentTriggerData->tg_trigtuple;
if (TRIGGER_FIRED_BY_UPDATE(CurrentTriggerData->tg_event))
elog (ERROR, "cascada: no se pueden procesar eventos de tipo update");
if (TRIGGER_FIRED_BEFORE(CurrentTriggerData->tg_event))
elog (ERROR,"cascada: no se pueden procesar eventos de tipo before");
trigger = CurrentTriggerData->tg_trigger;
rel = CurrentTriggerData->tg_relation;
tupdesc = rel->rd_att;
relname = SPI_getrelname(rel);
/*
* Setting CurrentTriggerData to NULL prevents direct calls to trigger
* functions in queries. Normally, trigger functions have to be called
* by trigger manager code only.
*/
CurrentTriggerData = NULL;
elog (NOTICE,"Hasta aqui todo bien");
/* Connect to SPI manager */
if ((ret = SPI_connect()) < 0)
elog(ERROR, "cascada: SPI_connect regres� %d", ret);
sprintf (cad,"%s",SPI_getvalue(trigtuple,tupdesc,4));
elog (NOTICE,"La tupla a borrar es del tipo: %s",cad);
i = atoi(cad);
elog (NOTICE,"La tupla a borrar es del tipo: %d",i);
if ( (i<0) || (i>14) || (i==6))
elog (ERROR,"cascada: La tupla a borrar esta incorrecta");
if ( i < 6 )
{
switch (i)
{
case 1 : sprintf (cad2,"cuaderno");
break;
case 2 : sprintf (cad2,"software");
break;
case 3 : sprintf (cad2,"cartografico");
break;
case 4 : sprintf (cad2,"informereporte");
break;
case 5 : sprintf (cad2,"cartel");
break;
}
sprintf (query,"delete from %s where ProdEditorial = %s",cad2,SPI_getvalue(trigtuple,tupdesc,1));
}
else
{
sprintf (query,"delete from impresion where Prodeditorial = %s",SPI_getvalue(trigtuple,tupdesc,1));
}
elog (NOTICE,"Hasta aqui todo bien con el query: \n %s",query);
SPI_exec (query,0);
SPI_finish();
return (0);
}