diff options
Diffstat (limited to 'contrib')
-rw-r--r-- | contrib/fulltextindex/README | 3 | ||||
-rw-r--r-- | contrib/fulltextindex/fti.c | 46 | ||||
-rw-r--r-- | contrib/fulltextindex/fticopy | 2 | ||||
-rw-r--r-- | contrib/lo/lo.c | 32 | ||||
-rw-r--r-- | contrib/lo/lo.sql.in | 4 | ||||
-rw-r--r-- | contrib/noupdate/noup.c | 46 | ||||
-rw-r--r-- | contrib/noupdate/noup.source | 2 | ||||
-rw-r--r-- | contrib/spi/autoinc.c | 32 | ||||
-rw-r--r-- | contrib/spi/autoinc.source | 2 | ||||
-rw-r--r-- | contrib/spi/insert_username.c | 31 | ||||
-rw-r--r-- | contrib/spi/insert_username.source | 2 | ||||
-rw-r--r-- | contrib/spi/moddatetime.c | 42 | ||||
-rw-r--r-- | contrib/spi/moddatetime.source | 2 | ||||
-rw-r--r-- | contrib/spi/refint.c | 84 | ||||
-rw-r--r-- | contrib/spi/refint.source | 4 | ||||
-rw-r--r-- | contrib/spi/timetravel.c | 65 | ||||
-rw-r--r-- | contrib/spi/timetravel.source | 4 |
17 files changed, 186 insertions, 217 deletions
diff --git a/contrib/fulltextindex/README b/contrib/fulltextindex/README index 36d611cf32d..06850f7493d 100644 --- a/contrib/fulltextindex/README +++ b/contrib/fulltextindex/README @@ -56,7 +56,8 @@ sub-string will fit. The create the function that contains the trigger:: - create function fti() returns opaque as '/path/to/fti.so' language 'C'; + create function fti() returns opaque as + '/path/to/fti.so' language 'newC'; And finally define the trigger on the 'cds' table: diff --git a/contrib/fulltextindex/fti.c b/contrib/fulltextindex/fti.c index 0291a48a274..aa5f066897c 100644 --- a/contrib/fulltextindex/fti.c +++ b/contrib/fulltextindex/fti.c @@ -17,7 +17,7 @@ Example: create function fti() returns opaque as -'/home/boekhold/src/postgresql-6.2/contrib/fti/fti.so' language 'c'; +'/home/boekhold/src/postgresql-6.2/contrib/fti/fti.so' language 'newC'; create table title_fti (string varchar(25), id oid); create index title_fti_idx on title_fti (string); @@ -61,11 +61,11 @@ select p.* from product p, title_fti f1, title_fti f2 where that can build the final query automatigally? */ -HeapTuple fti(void); -char *breakup(char *, char *); -bool is_stopword(char *); +extern Datum fti(PG_FUNCTION_ARGS); +static char *breakup(char *, char *); +static bool is_stopword(char *); -bool new_tuple = false; +static bool new_tuple = false; /* THIS LIST MUST BE IN SORTED ORDER, A BINARY SEARCH IS USED!!!! */ @@ -93,9 +93,10 @@ static int nDeletePlans = 0; static EPlan *find_plan(char *ident, EPlan ** eplan, int *nplans); /***********************************************************************/ -HeapTuple -fti() +Datum +fti(PG_FUNCTION_ARGS) { + TriggerData *trigdata = (TriggerData *) fcinfo->context; Trigger *trigger; /* to get trigger name */ int nargs; /* # of arguments */ char **args; /* arguments */ @@ -119,32 +120,29 @@ fti() * function\n"); fflush(debug); */ - if (!CurrentTriggerData) - elog(ERROR, "Full Text Indexing: triggers are not initialized"); - if (TRIGGER_FIRED_FOR_STATEMENT(CurrentTriggerData->tg_event)) + if (!CALLED_AS_TRIGGER(fcinfo)) + elog(ERROR, "Full Text Indexing: not fired by trigger manager"); + if (TRIGGER_FIRED_FOR_STATEMENT(trigdata->tg_event)) elog(ERROR, "Full Text Indexing: can't process STATEMENT events"); - if (TRIGGER_FIRED_BEFORE(CurrentTriggerData->tg_event)) + if (TRIGGER_FIRED_BEFORE(trigdata->tg_event)) elog(ERROR, "Full Text Indexing: must be fired AFTER event"); - if (TRIGGER_FIRED_BY_INSERT(CurrentTriggerData->tg_event)) + if (TRIGGER_FIRED_BY_INSERT(trigdata->tg_event)) isinsert = true; - if (TRIGGER_FIRED_BY_UPDATE(CurrentTriggerData->tg_event)) + if (TRIGGER_FIRED_BY_UPDATE(trigdata->tg_event)) { isdelete = true; isinsert = true; } - if (TRIGGER_FIRED_BY_DELETE(CurrentTriggerData->tg_event)) + if (TRIGGER_FIRED_BY_DELETE(trigdata->tg_event)) isdelete = true; - trigger = CurrentTriggerData->tg_trigger; - rel = CurrentTriggerData->tg_relation; + trigger = trigdata->tg_trigger; + rel = trigdata->tg_relation; relname = SPI_getrelname(rel); - rettuple = CurrentTriggerData->tg_trigtuple; + rettuple = trigdata->tg_trigtuple; if (isdelete && isinsert) /* is an UPDATE */ - rettuple = CurrentTriggerData->tg_newtuple; - - CurrentTriggerData = NULL; /* invalidate 'normal' calls to this - * function */ + rettuple = trigdata->tg_newtuple; if ((ret = SPI_connect()) < 0) elog(ERROR, "Full Text Indexing: SPI_connect failed, returned %d\n", ret); @@ -289,10 +287,10 @@ fti() } SPI_finish(); - return (rettuple); + return PointerGetDatum(rettuple); } -char * +static char * breakup(char *string, char *substring) { static char *last_start; @@ -342,7 +340,7 @@ breakup(char *string, char *substring) } /* copied from src/backend/parser/keywords.c and adjusted for our situation*/ -bool +static bool is_stopword(char *text) { char **StopLow; /* for list of stop-words */ diff --git a/contrib/fulltextindex/fticopy b/contrib/fulltextindex/fticopy index 02bf057e94a..6b6d68e4900 100644 --- a/contrib/fulltextindex/fticopy +++ b/contrib/fulltextindex/fticopy @@ -29,7 +29,7 @@ # # create function fti() returns opaque as # '/path/to/fti/file/fti.so' -# language 'C'; +# language 'newC'; # # create trigger my_fti_trigger after update or insert or delete # on mytable diff --git a/contrib/lo/lo.c b/contrib/lo/lo.c index 3b0c1e26142..497952fdbab 100644 --- a/contrib/lo/lo.c +++ b/contrib/lo/lo.c @@ -1,7 +1,7 @@ /* * PostgreSQL type definitions for managed LargeObjects. * - * $Id: lo.c,v 1.2 1999/05/25 16:05:45 momjian Exp $ + * $Id: lo.c,v 1.3 2000/05/29 01:59:02 tgl Exp $ * */ @@ -37,7 +37,7 @@ Blob *lo_in(char *str); /* Create from String */ char *lo_out(Blob * addr);/* Output oid as String */ Oid lo_oid(Blob * addr);/* Return oid as an oid */ Blob *lo(Oid oid); /* Return Blob based on oid */ -HeapTuple lo_manage(void); /* Trigger handler */ +Datum lo_manage(PG_FUNCTION_ARGS); /* Trigger handler */ /* * This creates a large object, and set's its OID to the value in the @@ -139,9 +139,10 @@ lo(Oid oid) /* * This handles the trigger that protects us from orphaned large objects */ -HeapTuple -lo_manage(void) +Datum +lo_manage(PG_FUNCTION_ARGS) { + TriggerData *trigdata = (TriggerData *) fcinfo->context; int attnum; /* attribute number to monitor */ char **args; /* Args containing attr name */ TupleDesc tupdesc; /* Tuple Descriptor */ @@ -150,28 +151,25 @@ lo_manage(void) HeapTuple newtuple = NULL;/* The new value for tuple */ HeapTuple trigtuple; /* The original value of tuple */ - if (!CurrentTriggerData) - elog(ERROR, "lo: triggers are not initialized"); + if (!CALLED_AS_TRIGGER(fcinfo)) + elog(ERROR, "lo: not fired by trigger manager"); /* - * Fetch some values from CurrentTriggerData + * Fetch some values from trigdata */ - newtuple = CurrentTriggerData->tg_newtuple; - trigtuple = CurrentTriggerData->tg_trigtuple; - tupdesc = CurrentTriggerData->tg_relation->rd_att; - args = CurrentTriggerData->tg_trigger->tgargs; + newtuple = trigdata->tg_newtuple; + trigtuple = trigdata->tg_trigtuple; + tupdesc = trigdata->tg_relation->rd_att; + args = trigdata->tg_trigger->tgargs; /* tuple to return to Executor */ - if (TRIGGER_FIRED_BY_UPDATE(CurrentTriggerData->tg_event)) + if (TRIGGER_FIRED_BY_UPDATE(trigdata->tg_event)) rettuple = newtuple; else rettuple = trigtuple; /* Are we deleting the row? */ - isdelete = TRIGGER_FIRED_BY_DELETE(CurrentTriggerData->tg_event); - - /* Were done with it */ - CurrentTriggerData = NULL; + isdelete = TRIGGER_FIRED_BY_DELETE(trigdata->tg_event); /* Get the column were interested in */ attnum = SPI_fnumber(tupdesc, args[0]); @@ -214,5 +212,5 @@ lo_manage(void) } } - return (rettuple); + return PointerGetDatum(rettuple); } diff --git a/contrib/lo/lo.sql.in b/contrib/lo/lo.sql.in index 291c93315ad..869f5ccc545 100644 --- a/contrib/lo/lo.sql.in +++ b/contrib/lo/lo.sql.in @@ -1,7 +1,7 @@ -- -- PostgreSQL code for LargeObjects -- --- $Id: lo.sql.in,v 1.1 1998/06/16 07:07:11 momjian Exp $ +-- $Id: lo.sql.in,v 1.2 2000/05/29 01:59:02 tgl Exp $ -- load '_OBJWD_/lo_DLSUFFIX_'; @@ -47,7 +47,7 @@ create function lo(oid) create function lo_manage() returns opaque as '_OBJWD_/lo_DLSUFFIX_' - language 'c'; + language 'newC'; -- This allows us to map lo to oid -- diff --git a/contrib/noupdate/noup.c b/contrib/noupdate/noup.c index ecbbd3d5ed2..5035e127be8 100644 --- a/contrib/noupdate/noup.c +++ b/contrib/noupdate/noup.c @@ -6,7 +6,7 @@ #include "commands/trigger.h" /* -"- and triggers */ #include <ctype.h> /* tolower () */ -HeapTuple noup(void); +extern Datum noup(PG_FUNCTION_ARGS); /* * noup () -- revoke permission on column @@ -16,9 +16,10 @@ HeapTuple noup(void); * EXECUTE PROCEDURE noup ('col'). */ -HeapTuple /* have to return HeapTuple to Executor */ -noup() +Datum +noup(PG_FUNCTION_ARGS) { + TriggerData *trigdata = (TriggerData *) fcinfo->context; Trigger *trigger; /* to get trigger name */ int nargs; /* # of args specified in CREATE TRIGGER */ char **args; /* arguments: column names and table name */ @@ -36,42 +37,35 @@ noup() */ /* Called by trigger manager ? */ - if (!CurrentTriggerData) - elog(WARN, "noup: triggers are not initialized"); + if (!CALLED_AS_TRIGGER(fcinfo)) + elog(ERROR, "noup: not fired by trigger manager"); /* Should be called for ROW trigger */ - if (TRIGGER_FIRED_FOR_STATEMENT(CurrentTriggerData->tg_event)) - elog(WARN, "noup: can't process STATEMENT events"); + if (TRIGGER_FIRED_FOR_STATEMENT(trigdata->tg_event)) + elog(ERROR, "noup: can't process STATEMENT events"); /* Not should be called for INSERT */ - if (TRIGGER_FIRED_BY_INSERT(CurrentTriggerData->tg_event)) - elog(WARN, "noup: can't process INSERT events"); + if (TRIGGER_FIRED_BY_INSERT(trigdata->tg_event)) + elog(ERROR, "noup: can't process INSERT events"); /* Not should be called for DELETE */ - else if (TRIGGER_FIRED_BY_DELETE(CurrentTriggerData->tg_event)) - elog(WARN, "noup: can't process DELETE events"); + else if (TRIGGER_FIRED_BY_DELETE(trigdata->tg_event)) + elog(ERROR, "noup: can't process DELETE events"); /* check new Tuple */ - tuple = CurrentTriggerData->tg_newtuple; + tuple = trigdata->tg_newtuple; - trigger = CurrentTriggerData->tg_trigger; + trigger = trigdata->tg_trigger; nargs = trigger->tgnargs; args = trigger->tgargs; nkeys = nargs; - rel = CurrentTriggerData->tg_relation; + rel = trigdata->tg_relation; tupdesc = rel->rd_att; - /* - * 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; - /* Connect to SPI manager */ if ((ret = SPI_connect()) < 0) - elog(WARN, "noup: SPI_connect returned %d", ret); + elog(ERROR, "noup: SPI_connect returned %d", ret); /* * We use SPI plan preparation feature, so allocate space to place key @@ -87,7 +81,7 @@ noup() /* Bad guys may give us un-existing column in CREATE TRIGGER */ if (fnumber < 0) - elog(WARN, "noup: there is no attribute %s in relation %s", + elog(ERROR, "noup: there is no attribute %s in relation %s", args[i], SPI_getrelname(rel)); /* Well, get binary (in internal format) value of column */ @@ -99,13 +93,13 @@ noup() if (!isnull) { - elog(WARN, "%s: update not allowed", args[i]); + elog(NOTICE, "%s: update not allowed", args[i]); SPI_finish(); - return NULL; + return PointerGetDatum(NULL); } } SPI_finish(); - return (tuple); + return PointerGetDatum(tuple); } diff --git a/contrib/noupdate/noup.source b/contrib/noupdate/noup.source index 0aa875d51e4..a1917a31209 100644 --- a/contrib/noupdate/noup.source +++ b/contrib/noupdate/noup.source @@ -3,5 +3,5 @@ DROP FUNCTION noup (); CREATE FUNCTION noup () RETURNS opaque AS '_OBJWD_/noup_DLSUFFIX_' - LANGUAGE 'c' + LANGUAGE 'newC' ; diff --git a/contrib/spi/autoinc.c b/contrib/spi/autoinc.c index c7caf3c842c..33cce457236 100644 --- a/contrib/spi/autoinc.c +++ b/contrib/spi/autoinc.c @@ -2,13 +2,13 @@ #include "executor/spi.h" /* this is what you need to work with SPI */ #include "commands/trigger.h" /* -"- and triggers */ -HeapTuple autoinc(void); - +extern Datum autoinc(PG_FUNCTION_ARGS); extern int4 nextval(struct varlena * seqin); -HeapTuple -autoinc() +Datum +autoinc(PG_FUNCTION_ARGS) { + TriggerData *trigdata = (TriggerData *) fcinfo->context; Trigger *trigger; /* to get trigger name */ int nargs; /* # of arguments */ int *chattrs; /* attnums of attributes to change */ @@ -22,24 +22,24 @@ autoinc() bool isnull; int i; - if (!CurrentTriggerData) - elog(ERROR, "autoinc: triggers are not initialized"); - if (TRIGGER_FIRED_FOR_STATEMENT(CurrentTriggerData->tg_event)) + if (!CALLED_AS_TRIGGER(fcinfo)) + elog(ERROR, "autoinc: not fired by trigger manager"); + if (TRIGGER_FIRED_FOR_STATEMENT(trigdata->tg_event)) elog(ERROR, "autoinc: can't process STATEMENT events"); - if (TRIGGER_FIRED_AFTER(CurrentTriggerData->tg_event)) + if (TRIGGER_FIRED_AFTER(trigdata->tg_event)) elog(ERROR, "autoinc: must be fired before event"); - if (TRIGGER_FIRED_BY_INSERT(CurrentTriggerData->tg_event)) - rettuple = CurrentTriggerData->tg_trigtuple; - else if (TRIGGER_FIRED_BY_UPDATE(CurrentTriggerData->tg_event)) - rettuple = CurrentTriggerData->tg_newtuple; + if (TRIGGER_FIRED_BY_INSERT(trigdata->tg_event)) + rettuple = trigdata->tg_trigtuple; + else if (TRIGGER_FIRED_BY_UPDATE(trigdata->tg_event)) + rettuple = trigdata->tg_newtuple; else elog(ERROR, "autoinc: can't process DELETE events"); - rel = CurrentTriggerData->tg_relation; + rel = trigdata->tg_relation; relname = SPI_getrelname(rel); - trigger = CurrentTriggerData->tg_trigger; + trigger = trigdata->tg_trigger; nargs = trigger->tgnargs; if (nargs <= 0 || nargs % 2 != 0) @@ -48,8 +48,6 @@ autoinc() args = trigger->tgargs; tupdesc = rel->rd_att; - CurrentTriggerData = NULL; - chattrs = (int *) palloc(nargs / 2 * sizeof(int)); newvals = (Datum *) palloc(nargs / 2 * sizeof(Datum)); @@ -96,5 +94,5 @@ autoinc() pfree(chattrs); pfree(newvals); - return (rettuple); + return PointerGetDatum(rettuple); } diff --git a/contrib/spi/autoinc.source b/contrib/spi/autoinc.source index ff7dec87c63..3423ec92ebe 100644 --- a/contrib/spi/autoinc.source +++ b/contrib/spi/autoinc.source @@ -3,4 +3,4 @@ DROP FUNCTION autoinc(); CREATE FUNCTION autoinc() RETURNS opaque AS '_OBJWD_/autoinc_DLSUFFIX_' - LANGUAGE 'c'; + LANGUAGE 'newC'; diff --git a/contrib/spi/insert_username.c b/contrib/spi/insert_username.c index b53d5e40884..61b41500845 100644 --- a/contrib/spi/insert_username.c +++ b/contrib/spi/insert_username.c @@ -10,11 +10,12 @@ #include "commands/trigger.h" /* -"- and triggers */ #include "miscadmin.h" /* for GetPgUserName() */ -HeapTuple insert_username(void); +extern Datum insert_username(PG_FUNCTION_ARGS); -HeapTuple -insert_username() +Datum +insert_username(PG_FUNCTION_ARGS) { + TriggerData *trigdata = (TriggerData *) fcinfo->context; Trigger *trigger; /* to get trigger name */ int nargs; /* # of arguments */ Datum newval; /* new value of column */ @@ -26,24 +27,24 @@ insert_username() int attnum; /* sanity checks from autoinc.c */ - if (!CurrentTriggerData) - elog(ERROR, "insert_username: triggers are not initialized"); - if (TRIGGER_FIRED_FOR_STATEMENT(CurrentTriggerData->tg_event)) + if (!CALLED_AS_TRIGGER(fcinfo)) + elog(ERROR, "insert_username: not fired by trigger manager"); + if (TRIGGER_FIRED_FOR_STATEMENT(trigdata->tg_event)) elog(ERROR, "insert_username: can't process STATEMENT events"); - if (TRIGGER_FIRED_AFTER(CurrentTriggerData->tg_event)) + if (TRIGGER_FIRED_AFTER(trigdata->tg_event)) elog(ERROR, "insert_username: must be fired before event"); - if (TRIGGER_FIRED_BY_INSERT(CurrentTriggerData->tg_event)) - rettuple = CurrentTriggerData->tg_trigtuple; - else if (TRIGGER_FIRED_BY_UPDATE(CurrentTriggerData->tg_event)) - rettuple = CurrentTriggerData->tg_newtuple; + if (TRIGGER_FIRED_BY_INSERT(trigdata->tg_event)) + rettuple = trigdata->tg_trigtuple; + else if (TRIGGER_FIRED_BY_UPDATE(trigdata->tg_event)) + rettuple = trigdata->tg_newtuple; else elog(ERROR, "insert_username: can't process DELETE events"); - rel = CurrentTriggerData->tg_relation; + rel = trigdata->tg_relation; relname = SPI_getrelname(rel); - trigger = CurrentTriggerData->tg_trigger; + trigger = trigdata->tg_trigger; nargs = trigger->tgnargs; if (nargs != 1) @@ -52,8 +53,6 @@ insert_username() args = trigger->tgargs; tupdesc = rel->rd_att; - CurrentTriggerData = NULL; - attnum = SPI_fnumber(tupdesc, args[0]); if (attnum < 0) @@ -73,5 +72,5 @@ insert_username() pfree(relname); - return (rettuple); + return PointerGetDatum(rettuple); } diff --git a/contrib/spi/insert_username.source b/contrib/spi/insert_username.source index 573d9aba0ad..4b7a684305f 100644 --- a/contrib/spi/insert_username.source +++ b/contrib/spi/insert_username.source @@ -3,4 +3,4 @@ DROP FUNCTION insert_username(); CREATE FUNCTION insert_username() RETURNS opaque AS '_OBJWD_/insert_username_DLSUFFIX_' - LANGUAGE 'c'; + LANGUAGE 'newC'; diff --git a/contrib/spi/moddatetime.c b/contrib/spi/moddatetime.c index 39c3ddf0f2f..6405f3fb9b8 100644 --- a/contrib/spi/moddatetime.c +++ b/contrib/spi/moddatetime.c @@ -8,18 +8,19 @@ a modification datetime stamp in a record when that record is UPDATEd. Credits This is 95%+ based on autoinc.c, which I used as a starting point as I do not really know what I am doing. I also had help from -Jan Wieck <jwieck@debis.com> who told me about the datetime_in("now") function. +Jan Wieck <jwieck@debis.com> who told me about the timestamp_in("now") function. OH, me, I'm Terry Mackintosh <terry@terrym.com> */ #include "executor/spi.h" /* this is what you need to work with SPI */ #include "commands/trigger.h" /* -"- and triggers */ -HeapTuple moddatetime(void); +extern Datum moddatetime(PG_FUNCTION_ARGS); -HeapTuple -moddatetime() +Datum +moddatetime(PG_FUNCTION_ARGS) { + TriggerData *trigdata = (TriggerData *) fcinfo->context; Trigger *trigger; /* to get trigger name */ int nargs; /* # of arguments */ int attnum; /* positional number of field to change */ @@ -30,26 +31,26 @@ moddatetime() HeapTuple rettuple = NULL; TupleDesc tupdesc; /* tuple description */ - if (!CurrentTriggerData) - elog(ERROR, "moddatetime: triggers are not initialized."); + if (!CALLED_AS_TRIGGER(fcinfo)) + elog(ERROR, "moddatetime: not fired by trigger manager."); - if (TRIGGER_FIRED_FOR_STATEMENT(CurrentTriggerData->tg_event)) + if (TRIGGER_FIRED_FOR_STATEMENT(trigdata->tg_event)) elog(ERROR, "moddatetime: can't process STATEMENT events."); - if (TRIGGER_FIRED_AFTER(CurrentTriggerData->tg_event)) + if (TRIGGER_FIRED_AFTER(trigdata->tg_event)) elog(ERROR, "moddatetime: must be fired before event."); - if (TRIGGER_FIRED_BY_INSERT(CurrentTriggerData->tg_event)) + if (TRIGGER_FIRED_BY_INSERT(trigdata->tg_event)) elog(ERROR, "moddatetime: must be fired before event."); - else if (TRIGGER_FIRED_BY_UPDATE(CurrentTriggerData->tg_event)) - rettuple = CurrentTriggerData->tg_newtuple; + else if (TRIGGER_FIRED_BY_UPDATE(trigdata->tg_event)) + rettuple = trigdata->tg_newtuple; else elog(ERROR, "moddatetime: can't process DELETE events."); - rel = CurrentTriggerData->tg_relation; + rel = trigdata->tg_relation; relname = SPI_getrelname(rel); - trigger = CurrentTriggerData->tg_trigger; + trigger = trigdata->tg_trigger; nargs = trigger->tgnargs; @@ -60,11 +61,8 @@ moddatetime() /* must be the field layout? */ tupdesc = rel->rd_att; - /* Why do this? */ - CurrentTriggerData = NULL; - /* Get the current datetime. */ - newdt = datetime_in("now"); + newdt = (Datum) timestamp_in("now"); /* * This gets the position in the turple of the field we want. args[0] @@ -82,12 +80,12 @@ moddatetime() args[0]); /* - * OK, this is where we make sure the datetime field that we are - * modifying is really a datetime field. Hay, error checking, what a + * OK, this is where we make sure the timestamp field that we are + * modifying is really a timestamp field. Hay, error checking, what a * novel idea !-) */ - if (SPI_gettypeid(tupdesc, attnum) != DATETIMEOID) - elog(ERROR, "moddatetime (%s): attribute %s must be of DATETIME type", + if (SPI_gettypeid(tupdesc, attnum) != TIMESTAMPOID) + elog(ERROR, "moddatetime (%s): attribute %s must be of TIMESTAMP type", relname, args[0]); /* 1 is the number of items in the arrays attnum and newdt. @@ -106,5 +104,5 @@ moddatetime() /* Clean up */ pfree(relname); - return (rettuple); + return PointerGetDatum(rettuple); } diff --git a/contrib/spi/moddatetime.source b/contrib/spi/moddatetime.source index 26906a3f333..2aafedb38b2 100644 --- a/contrib/spi/moddatetime.source +++ b/contrib/spi/moddatetime.source @@ -3,4 +3,4 @@ DROP FUNCTION moddatetime(); CREATE FUNCTION moddatetime() RETURNS opaque AS '_OBJWD_/moddatetime_DLSUFFIX_' - LANGUAGE 'c'; + LANGUAGE 'newC'; diff --git a/contrib/spi/refint.c b/contrib/spi/refint.c index 1062592e6ff..4bbe761573b 100644 --- a/contrib/spi/refint.c +++ b/contrib/spi/refint.c @@ -8,10 +8,8 @@ #include <ctype.h> /* tolower () */ - - -HeapTuple check_primary_key(void); -HeapTuple check_foreign_key(void); +extern Datum check_primary_key(PG_FUNCTION_ARGS); +extern Datum check_foreign_key(PG_FUNCTION_ARGS); typedef struct @@ -38,9 +36,10 @@ static EPlan *find_plan(char *ident, EPlan ** eplan, int *nplans); * check_primary_key ('Fkey1', 'Fkey2', 'Ptable', 'Pkey1', 'Pkey2'). */ -HeapTuple /* have to return HeapTuple to Executor */ -check_primary_key() +Datum +check_primary_key(PG_FUNCTION_ARGS) { + TriggerData *trigdata = (TriggerData *) fcinfo->context; Trigger *trigger; /* to get trigger name */ int nargs; /* # of args specified in CREATE TRIGGER */ char **args; /* arguments: column names and table name */ @@ -57,33 +56,35 @@ check_primary_key() int ret; int i; - /* - * Some checks first... - */ #ifdef DEBUG_QUERY elog(NOTICE, "Check_primary_key Enter Function"); #endif + + /* + * Some checks first... + */ + /* Called by trigger manager ? */ - if (!CurrentTriggerData) - elog(ERROR, "check_primary_key: triggers are not initialized"); + if (!CALLED_AS_TRIGGER(fcinfo)) + elog(ERROR, "check_primary_key: not fired by trigger manager"); /* Should be called for ROW trigger */ - if (TRIGGER_FIRED_FOR_STATEMENT(CurrentTriggerData->tg_event)) + if (TRIGGER_FIRED_FOR_STATEMENT(trigdata->tg_event)) elog(ERROR, "check_primary_key: can't process STATEMENT events"); /* If INSERTion then must check Tuple to being inserted */ - if (TRIGGER_FIRED_BY_INSERT(CurrentTriggerData->tg_event)) - tuple = CurrentTriggerData->tg_trigtuple; + if (TRIGGER_FIRED_BY_INSERT(trigdata->tg_event)) + tuple = trigdata->tg_trigtuple; /* Not should be called for DELETE */ - else if (TRIGGER_FIRED_BY_DELETE(CurrentTriggerData->tg_event)) + else if (TRIGGER_FIRED_BY_DELETE(trigdata->tg_event)) elog(ERROR, "check_primary_key: can't process DELETE events"); /* If UPDATion the must check new Tuple, not old one */ else - tuple = CurrentTriggerData->tg_newtuple; + tuple = trigdata->tg_newtuple; - trigger = CurrentTriggerData->tg_trigger; + trigger = trigdata->tg_trigger; nargs = trigger->tgnargs; args = trigger->tgargs; @@ -92,16 +93,9 @@ check_primary_key() nkeys = nargs / 2; relname = args[nkeys]; - rel = CurrentTriggerData->tg_relation; + rel = trigdata->tg_relation; tupdesc = rel->rd_att; - /* - * 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; - /* Connect to SPI manager */ if ((ret = SPI_connect()) < 0) elog(ERROR, "check_primary_key: SPI_connect returned %d", ret); @@ -145,7 +139,7 @@ check_primary_key() if (isnull) { SPI_finish(); - return (tuple); + return PointerGetDatum(tuple); } if (plan->nplans <= 0) /* Get typeId of column */ @@ -207,7 +201,7 @@ check_primary_key() SPI_finish(); - return (tuple); + return PointerGetDatum(tuple); } /* @@ -222,9 +216,10 @@ check_primary_key() * 'Ftable1', 'Fkey11', 'Fkey12', 'Ftable2', 'Fkey21', 'Fkey22'). */ -HeapTuple /* have to return HeapTuple to Executor */ -check_foreign_key() +Datum +check_foreign_key(PG_FUNCTION_ARGS) { + TriggerData *trigdata = (TriggerData *) fcinfo->context; Trigger *trigger; /* to get trigger name */ int nargs; /* # of args specified in CREATE TRIGGER */ char **args; /* arguments: as described above */ @@ -258,19 +253,19 @@ check_foreign_key() */ /* Called by trigger manager ? */ - if (!CurrentTriggerData) - elog(ERROR, "check_foreign_key: triggers are not initialized"); + if (!CALLED_AS_TRIGGER(fcinfo)) + elog(ERROR, "check_foreign_key: not fired by trigger manager"); /* Should be called for ROW trigger */ - if (TRIGGER_FIRED_FOR_STATEMENT(CurrentTriggerData->tg_event)) + if (TRIGGER_FIRED_FOR_STATEMENT(trigdata->tg_event)) elog(ERROR, "check_foreign_key: can't process STATEMENT events"); /* Not should be called for INSERT */ - if (TRIGGER_FIRED_BY_INSERT(CurrentTriggerData->tg_event)) + if (TRIGGER_FIRED_BY_INSERT(trigdata->tg_event)) elog(ERROR, "check_foreign_key: can't process INSERT events"); /* Have to check tg_trigtuple - tuple being deleted */ - trigtuple = CurrentTriggerData->tg_trigtuple; + trigtuple = trigdata->tg_trigtuple; /* * But if this is UPDATE then we have to return tg_newtuple. Also, if @@ -278,12 +273,12 @@ check_foreign_key() * do. */ is_update = 0; - if (TRIGGER_FIRED_BY_UPDATE(CurrentTriggerData->tg_event)) + if (TRIGGER_FIRED_BY_UPDATE(trigdata->tg_event)) { - newtuple = CurrentTriggerData->tg_newtuple; + newtuple = trigdata->tg_newtuple; is_update = 1; } - trigger = CurrentTriggerData->tg_trigger; + trigger = trigdata->tg_trigger; nargs = trigger->tgnargs; args = trigger->tgargs; @@ -304,16 +299,9 @@ check_foreign_key() elog(ERROR, "check_foreign_key: invalid number of arguments %d for %d references", nargs + 2, nrefs); - rel = CurrentTriggerData->tg_relation; + rel = trigdata->tg_relation; tupdesc = rel->rd_att; - /* - * 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; - /* Connect to SPI manager */ if ((ret = SPI_connect()) < 0) elog(ERROR, "check_foreign_key: SPI_connect returned %d", ret); @@ -364,7 +352,7 @@ check_foreign_key() if (isnull) { SPI_finish(); - return ((newtuple == NULL) ? trigtuple : newtuple); + return PointerGetDatum((newtuple == NULL) ? trigtuple : newtuple); } /* @@ -527,7 +515,7 @@ check_foreign_key() if (newtuple != NULL && isequal) { SPI_finish(); - return (newtuple); + return PointerGetDatum(newtuple); } /* @@ -571,7 +559,7 @@ check_foreign_key() SPI_finish(); - return ((newtuple == NULL) ? trigtuple : newtuple); + return PointerGetDatum((newtuple == NULL) ? trigtuple : newtuple); } static EPlan * diff --git a/contrib/spi/refint.source b/contrib/spi/refint.source index 16745bb771b..04323446617 100644 --- a/contrib/spi/refint.source +++ b/contrib/spi/refint.source @@ -4,11 +4,11 @@ DROP FUNCTION check_foreign_key (); CREATE FUNCTION check_primary_key () RETURNS opaque AS '_OBJWD_/refint_DLSUFFIX_' - LANGUAGE 'c' + LANGUAGE 'newC' ; CREATE FUNCTION check_foreign_key () RETURNS opaque AS '_OBJWD_/refint_DLSUFFIX_' - LANGUAGE 'c' + LANGUAGE 'newC' ; diff --git a/contrib/spi/timetravel.c b/contrib/spi/timetravel.c index 89d3f13e41f..92c2ba92cf1 100644 --- a/contrib/spi/timetravel.c +++ b/contrib/spi/timetravel.c @@ -10,8 +10,8 @@ #define ABSTIMEOID 702 /* it should be in pg_type.h */ AbsoluteTime currabstime(void); -HeapTuple timetravel(void); -int32 set_timetravel(Name relname, int32 on); +Datum timetravel(PG_FUNCTION_ARGS); +Datum set_timetravel(PG_FUNCTION_ARGS); typedef struct { @@ -47,9 +47,10 @@ static EPlan *find_plan(char *ident, EPlan ** eplan, int *nplans); * timetravel ('date_on', 'date_off'). */ -HeapTuple /* have to return HeapTuple to Executor */ -timetravel() +Datum +timetravel(PG_FUNCTION_ARGS) { + TriggerData *trigdata = (TriggerData *) fcinfo->context; Trigger *trigger; /* to get trigger name */ char **args; /* arguments */ int attnum[2]; /* fnumbers of start/stop columns */ @@ -78,27 +79,27 @@ timetravel() */ /* Called by trigger manager ? */ - if (!CurrentTriggerData) - elog(ERROR, "timetravel: triggers are not initialized"); + if (!CALLED_AS_TRIGGER(fcinfo)) + elog(ERROR, "timetravel: not fired by trigger manager"); /* Should be called for ROW trigger */ - if (TRIGGER_FIRED_FOR_STATEMENT(CurrentTriggerData->tg_event)) + if (TRIGGER_FIRED_FOR_STATEMENT(trigdata->tg_event)) elog(ERROR, "timetravel: can't process STATEMENT events"); /* Should be called BEFORE */ - if (TRIGGER_FIRED_AFTER(CurrentTriggerData->tg_event)) + if (TRIGGER_FIRED_AFTER(trigdata->tg_event)) elog(ERROR, "timetravel: must be fired before event"); /* INSERT ? */ - if (TRIGGER_FIRED_BY_INSERT(CurrentTriggerData->tg_event)) + if (TRIGGER_FIRED_BY_INSERT(trigdata->tg_event)) isinsert = true; - if (TRIGGER_FIRED_BY_UPDATE(CurrentTriggerData->tg_event)) - newtuple = CurrentTriggerData->tg_newtuple; + if (TRIGGER_FIRED_BY_UPDATE(trigdata->tg_event)) + newtuple = trigdata->tg_newtuple; - trigtuple = CurrentTriggerData->tg_trigtuple; + trigtuple = trigdata->tg_trigtuple; - rel = CurrentTriggerData->tg_relation; + rel = trigdata->tg_relation; relname = SPI_getrelname(rel); /* check if TT is OFF for this relation */ @@ -108,10 +109,10 @@ timetravel() if (i < nTTOff) /* OFF - nothing to do */ { pfree(relname); - return ((newtuple != NULL) ? newtuple : trigtuple); + return PointerGetDatum((newtuple != NULL) ? newtuple : trigtuple); } - trigger = CurrentTriggerData->tg_trigger; + trigger = trigdata->tg_trigger; if (trigger->tgnargs != 2) elog(ERROR, "timetravel (%s): invalid (!= 2) number of arguments %d", @@ -121,13 +122,6 @@ timetravel() tupdesc = rel->rd_att; natts = tupdesc->natts; - /* - * 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; - for (i = 0; i < 2; i++) { attnum[i] = SPI_fnumber(tupdesc, args[i]); @@ -175,11 +169,11 @@ timetravel() pfree(relname); if (chnattrs <= 0) - return (trigtuple); + return PointerGetDatum(trigtuple); rettuple = SPI_modifytuple(rel, trigtuple, chnattrs, chattrs, newvals, NULL); - return (rettuple); + return PointerGetDatum(rettuple); } oldon = SPI_getbinval(trigtuple, tupdesc, attnum[0], &isnull); @@ -210,13 +204,13 @@ timetravel() if (newoff != NOEND_ABSTIME) { pfree(relname); /* allocated in upper executor context */ - return (NULL); + return PointerGetDatum(NULL); } } else if (oldoff != NOEND_ABSTIME) /* DELETE */ { pfree(relname); - return (NULL); + return PointerGetDatum(NULL); } newoff = GetCurrentAbsoluteTime(); @@ -325,16 +319,18 @@ timetravel() pfree(relname); - return (rettuple); + return PointerGetDatum(rettuple); } /* - * set_timetravel () -- + * set_timetravel (relname, on) -- * turn timetravel for specified relation ON/OFF */ -int32 -set_timetravel(Name relname, int32 on) +Datum +set_timetravel(PG_FUNCTION_ARGS) { + Name relname = PG_GETARG_NAME(0); + int32 on = PG_GETARG_INT32(1); char *rname; char *d; char *s; @@ -347,7 +343,7 @@ set_timetravel(Name relname, int32 on) if (i < nTTOff) /* OFF currently */ { if (on == 0) - return (0); + PG_RETURN_INT32(0); /* turn ON */ free(TTOff[i]); @@ -360,12 +356,12 @@ set_timetravel(Name relname, int32 on) TTOff = realloc(TTOff, (nTTOff - 1) * sizeof(char *)); } nTTOff--; - return (0); + PG_RETURN_INT32(0); } /* ON currently */ if (on != 0) - return (1); + PG_RETURN_INT32(1); /* turn OFF */ if (nTTOff == 0) @@ -380,8 +376,7 @@ set_timetravel(Name relname, int32 on) pfree(rname); nTTOff++; - return (1); - + PG_RETURN_INT32(1); } AbsoluteTime diff --git a/contrib/spi/timetravel.source b/contrib/spi/timetravel.source index 5de63d3821b..8012cb93c20 100644 --- a/contrib/spi/timetravel.source +++ b/contrib/spi/timetravel.source @@ -4,9 +4,9 @@ DROP FUNCTION set_timetravel(name, int4); CREATE FUNCTION timetravel() RETURNS opaque AS '_OBJWD_/timetravel_DLSUFFIX_' - LANGUAGE 'c'; + LANGUAGE 'newC'; CREATE FUNCTION set_timetravel(name, int4) RETURNS int4 AS '_OBJWD_/timetravel_DLSUFFIX_' - LANGUAGE 'c'; + LANGUAGE 'newC' WITH (isStrict); |