pg.ddx.io  pgsql-interfaces@postgresql.org mailing list archive  
help / color / mirror / Atom feed
From: fabrizio picca <fabrizio.picca@gmail.com>
To: pgsql-interfaces@postgresql.org
Subject: help needed on SPI_modifytuple.
Date: Mon, 12 Sep 2005 16:17:33 +0200
Message-ID: <1532344d050912071740e7c5d9@mail.gmail.com> (raw)

I'm trying to sipmply modify a tuple before it will be inserted in the db.
The problem is that when it try to insert the modified tuple with
SPI_modifytuple all i get is a SPI_ERROR_ARGUMENT negative (-6) .
Could someone help me? i'm reallygoing crazy.



What i did is just a fire-before C trigger that acts like this:

#include <postgres.h>
#include <executor/spi.h>       /* this is what you need to work with SPI */
#include <commands/trigger.h>   /* ... and triggers */
#include <string.h>
#include <utils/builtins.h>

extern Datum trgupdana(PG_FUNCTION_ARGS);
char *checkFieldData(char *);

PG_FUNCTION_INFO_V1(trgupdana);

Datum
trgupdana(PG_FUNCTION_ARGS)
{
    TriggerData *trigdata = (TriggerData *) fcinfo->context;
    TupleDesc   tupdesc;
    HeapTuple   rettuple,
    		oldtuple,
    		newtuple;
    char        *rs1,*rs2,*rs3,*relname;
    int         ret, i,j;
    bool        isnull;
    Relation    rel;

     /* make sure it's called as a trigger at all */
    if (!CALLED_AS_TRIGGER(fcinfo)) elog(ERROR, "trgchkneg: not called
by trigger manager\n");

    if (TRIGGER_FIRED_BEFORE(trigdata->tg_event) &&
TRIGGER_FIRED_FOR_ROW(trigdata->tg_event)) //trigger fires when called
for rows and before updating
    {
        tupdesc = trigdata->tg_relation->rd_att; 
        oldtuple =  trigdata->tg_trigtuple; 
	newtuple = trigdata->tg_newtuple; 
 	rettuple=NULL;
	rel = trigdata->tg_relation;
	relname= SPI_getrelname(rel);
		
	if ((ret = SPI_connect()) < 0)                               // SPI
manager initialization
		elog(NOTICE, "trgCheckNeg : SPI_connect returned: %d",  ret);
		      
        rs1=SPI_getvalue(oldtuple,tupdesc,5);
        rs2=SPI_getvalue(oldtuple,tupdesc,6);
      
	elog(NOTICE,"%s,%s",rs1,rs2);
	
        int attnum;
        Datum new_value;
        
	rs3=(char*) malloc(80);
        sprintf(rs3,"");
	
	if(rs1[strlen(rs1)-1]=='&'){
           rs3=strncat(rs3,rs1,strlen(rs1)-1);
	   rs3=strcat(rs3,"E ");
	} 
	else if(rs1[strlen(rs1)-1]==',')
	{
	   rs3=strncat(rs3,rs1,strlen(rs1)-1);
	   rs3=strcat(rs3,", ");
	} else {
	   rs3=rs1;	
	}
        
        elog(NOTICE,"1:%s",rs3);	
	
	if(strlen(rs2)!=0){
	   rs3=strcat(rs3,rs2);
	}
	
	elog(NOTICE,"2:%s",rs3);
	
	new_value=DirectFunctionCall1(textin,PointerGetDatum(checkFieldData(rs3)));
	
        attnum=SPI_fnumber(tupdesc,"ARGSL1");
       
        if(rel==NULL) elog(NOTICE,"rel NULL");
	if(&attnum==NULL) elog(NOTICE,"attnum NULL");
	if(&new_value==NULL) elog(NOTICE,"new_value NULL");
	if(&isnull==NULL) elog(NOTICE,"isnull NULL");
		
        rettuple=SPI_modifytuple(rel,newtuple,1,&attnum,&new_value,&isnull);
	if(rettuple==NULL){
		elog(ERROR,"trgupdana (%s):%d returned by
SPI_modifytuple",relname,SPI_result);
	}
	return PointerGetDatum(rettuple);
    }
    return PointerGetDatum(oldtuple);
}

char *checkFieldData(char *valueToCheck){
	int i=0;
	for(i=0;i<strlen(valueToCheck);i++)
	{
		if(valueToCheck[i]=='&') valueToCheck[i]='E';
		else if(valueToCheck[i]=='\'') valueToCheck[i]=96;
	}
        
	return(valueToCheck);
}




--
http://www.fabpicca.net



view thread (3+ messages)  latest in thread

Message-ID: <1532344d050912071740e7c5d9@mail.gmail.com>
Permalink:  ../1532344d050912071740e7c5d9@mail.gmail.com/
Also on:    postgresql.org/message-id/1532344d050912071740e7c5d9@mail.gmail.com

 · 

reply

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Reply to all the recipients using the --to and --cc options:
  reply via email

  To: pgsql-interfaces@postgresql.org
  Cc: fabrizio.picca@gmail.com
  Subject: Re: help needed on SPI_modifytuple.
  In-Reply-To: <1532344d050912071740e7c5d9@mail.gmail.com>

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

This inbox is served by DDX for PostgreSQL; see mirroring instructions
for how to clone and mirror all data and code used for this inbox