aboutsummaryrefslogtreecommitdiff
path: root/contrib
diff options
context:
space:
mode:
Diffstat (limited to 'contrib')
-rw-r--r--contrib/fulltextindex/README3
-rw-r--r--contrib/fulltextindex/fti.c46
-rw-r--r--contrib/fulltextindex/fticopy2
-rw-r--r--contrib/lo/lo.c32
-rw-r--r--contrib/lo/lo.sql.in4
-rw-r--r--contrib/noupdate/noup.c46
-rw-r--r--contrib/noupdate/noup.source2
-rw-r--r--contrib/spi/autoinc.c32
-rw-r--r--contrib/spi/autoinc.source2
-rw-r--r--contrib/spi/insert_username.c31
-rw-r--r--contrib/spi/insert_username.source2
-rw-r--r--contrib/spi/moddatetime.c42
-rw-r--r--contrib/spi/moddatetime.source2
-rw-r--r--contrib/spi/refint.c84
-rw-r--r--contrib/spi/refint.source4
-rw-r--r--contrib/spi/timetravel.c65
-rw-r--r--contrib/spi/timetravel.source4
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);