|
Home > Archive > PostgreSQL SQL > December 2006 > Proper way of iterating over the column names in a trigger function.
You are viewing an archived Text-only version of the thread.
To view this thread in it's original format and/or if you want to reply to
this thread please [click here]
| Author |
Proper way of iterating over the column names in a trigger function.
|
|
| Rajesh Kumar Mallah 2006-12-06, 7:18 pm |
| Hi,
I am trying to interate over column names of a table on which a C trigger
function is called on UPDATE/DELETE and INSERT. SPI function
char * SPI_fname(TupleDesc rowdesc, int colnumber)
is being used. looks like the function is returning column names like
"........pg.dropped.2........" for deleted colnumbers. My question is
what is the proper way for iterating over column names of a table using
SPI_* functions.
(sorry for bad english)
SQL transcript:
-----------------------
tradein_clients=> UPDATE public.test set x=10;
NOTICE: no of column : 2
NOTICE: colname: x
NOTICE: colname: y
UPDATE 1
tradein_clients=> ALTER TABLE public.test add z int;
ALTER TABLE
tradein_clients=> UPDATE public.test set x=10;
NOTICE: no of column : 3
NOTICE: colname: x
NOTICE: colname: y
NOTICE: colname: z
UPDATE 1
tradein_clients=> ALTER TABLE public.test DROP y;
ALTER TABLE
tradein_clients=> UPDATE public.test set x=10;
NOTICE: no of column : 2
NOTICE: colname: x
NOTICE: colname: ........pg.dropped.2........
UPDATE 1
tradein_clients=>
i am pasting the minial code based on
http://www.postgresql.org/docs/8.1/...er-example.html
--------------------------------------------------------------------------------------------------
#include "postgres.h"
#include "executor/spi.h"
#include "commands/trigger.h"
extern Datum trigf(PG_FUNCTION_AR
GS);
static int get_no_columns(char *table_name, char *table_nspname);
PG_FUNCTION_INFO_V1(
trigf);
Datum
trigf(PG_FUNCTION_AR
GS)
{
TriggerData *trigdata = (TriggerData *) fcinfo->context;
TupleDesc tupdesc;
HeapTuple rettuple;
char
*source_table,*sourc
e_table_nspname , *col_name ;
int ret,ncolumns, i ;
/* make sure it's called as a trigger at all */
if (!CALLED_AS_TRIGGER(
fcinfo))
elog(ERROR, "trigf: not called by trigger manager");
/* tuple to return to executor */
if (TRIGGER_FIRED_BY_UP
DATE(trigdata->tg_event))
rettuple = trigdata->tg_newtuple;
else
rettuple = trigdata->tg_trigtuple;
tupdesc = trigdata->tg_relation->rd_att;
/* connect to SPI manager */
if ((ret = SPI_connect()) < 0)
elog(INFO, "trigf : SPI_connect returned %d", ret);
source_table = SPI_getrelname(trigd
ata->tg_relation);
source_table_nspname
= SPI_getnspname(trigd
ata->tg_relation);
ncolumns = get_no_columns( source_table,source_
table_nspname );
elog(NOTICE, "no of column : %d" , ncolumns);
for (i = 1; i <= ncolumns ; i++)
{
col_name = SPI_fname(tupdesc, i);
elog (NOTICE , "colname: %s" , col_name);
}
SPI_finish();
return PointerGetDatum(rett
uple);
}
static int
get_no_columns(char *table_name,char *table_nspname )
{
char query[512];
int ret;
int ncolumns = -1;
snprintf(query, 511,
"SELECT COUNT(pg_attribute.attname) AS a FROM
pg_class, pg_attribute , pg_namespace WHERE pg_class.relname='%s' and
pg_namespace.nspname='%s' AND pg_attribute.attnum > 0 AND
pg_attribute.attrelid=pg_class.oid and
pg_class. relnamespace=pg_name
space.oid and attisdropped is false" ,
table_name,
table_nspname
);
if ((ret = SPI_exec(query, 0)) < 0)
{
elog(ERROR, "get_no_columnss: could not get number of columns from
relation %s.%s ret: %d",
table_nspname , table_name , ret );
}
if (SPI_processed > 0)
{
/* this is a old code which is not using DatumGetInt64 , sorry for that :(
if its a mistake. */
ncolumns =
DatumGetInt32(Direct
FunctionCall1
(int4in,
CStringGetDatum(SPI_
getvalue
(SPI_tuptable->
vals[0], SPI_tuptable->tupdesc, 1))));
if (ncolumns < 1)
{
elog(ERROR, "get_no_columns: relation %s.%s does not exist",
table_nspname, table_name);
}
}
else
{
elog(ERROR,
"get_no_columns: could not get number columns in relation %s.%s",
table_nspname , table_name);
}
return (ncolumns);
}
------------------------------ end of code
------------------------------------------------
---------------------------(end of broadcast)---------------------------
TIP 5: don't forget to increase your free space map settings
| |
| Tom Lane 2006-12-06, 7:18 pm |
| "Rajesh Kumar Mallah" <mallah.rajesh@gmail.com> writes:
> what is the proper way for iterating over column names of a table using
> SPI_* functions.
You need to pay attention to the attisdropped field of the TupleDesc
entries.
regards, tom lane
---------------------------(end of broadcast)---------------------------
TIP 9: In versions below 8.0, the planner will ignore your desire to
choose an index scan if your joining column's datatypes do not
match
|
|
|
|
|