diff --git a/src/test/regress/GNUmakefile b/src/test/regress/GNUmakefile
index a4904b41190beb2aebdb7b632211ec01edc56fb2..8dbcdba58b8e5eb85d60312736020aa094132f4b 100644
--- a/src/test/regress/GNUmakefile
+++ b/src/test/regress/GNUmakefile
@@ -7,7 +7,7 @@
 #
 #
 # IDENTIFICATION
-#    $Header: /cvsroot/pgsql/src/test/regress/GNUmakefile,v 1.10 1997/09/11 09:13:27 vadim Exp $
+#    $Header: /cvsroot/pgsql/src/test/regress/GNUmakefile,v 1.11 1997/09/24 08:35:07 vadim Exp $
 #
 #-------------------------------------------------------------------------
 
@@ -43,7 +43,7 @@ endif
 all: $(INFILES)
 	cd input; $(MAKE) all; cd ..
 	cd output; $(MAKE) all; cd ..
-	$(MAKE) -C ../../../contrib/spi REFINT_VERBOSE=1
+	$(MAKE) -C ../../../contrib/spi REFINT_VERBOSE=1 refint$(DLSUFFIX)
 
 #
 # run the test
diff --git a/src/test/regress/regress.c b/src/test/regress/regress.c
index e602762df885a0e0ed02d82b5e0ff7fa52ce5caa..2e2eaa9e4fde3fa1822cfae864af12338d72c3f2 100644
--- a/src/test/regress/regress.c
+++ b/src/test/regress/regress.c
@@ -1,5 +1,5 @@
 /*
- * $Header: /cvsroot/pgsql/src/test/regress/regress.c,v 1.15 1997/09/18 20:22:54 momjian Exp $
+ * $Header: /cvsroot/pgsql/src/test/regress/regress.c,v 1.16 1997/09/24 08:35:10 vadim Exp $
  */
 
 #include <float.h>				/* faked on sunos */
@@ -411,3 +411,232 @@ funny_dup17()
 
 	return (tuple);
 }
+
+#include <ctype.h>				/* tolower () */
+
+HeapTuple		ttdummy(void);
+int32			set_ttdummy(int32 on);
+
+extern int4	nextval(struct varlena * seqin);
+
+#define TTDUMMY_INFINITY	999999
+
+static void    *splan = NULL;
+static bool		ttoff = false;
+
+HeapTuple
+ttdummy()
+{
+	Trigger    *trigger;		/* to get trigger name */
+	char	  **args;			/* arguments */
+	int			attnum[2];		/* fnumbers of start/stop columns */
+	Datum		oldon, oldoff;
+	Datum		newon, newoff;
+	Datum	   *cvals;			/* column values */
+	char	   *cnulls;			/* column nulls */
+	char	   *relname;		/* triggered relation name */
+	Relation	rel;			/* triggered relation */
+	HeapTuple	trigtuple;
+	HeapTuple	newtuple = NULL;
+	HeapTuple	rettuple;
+	TupleDesc	tupdesc;		/* tuple description */
+	int			natts;			/* # of attributes */
+	bool		isnull;			/* to know is some column NULL or not */
+	int			ret;
+	int			i;
+
+	if (!CurrentTriggerData)
+		elog(WARN, "ttdummy: triggers are not initialized");
+	if (TRIGGER_FIRED_FOR_STATEMENT(CurrentTriggerData->tg_event))
+		elog(WARN, "ttdummy: can't process STATEMENT events");
+	if (TRIGGER_FIRED_AFTER(CurrentTriggerData->tg_event))
+		elog(WARN, "ttdummy: must be fired before event");
+	if (TRIGGER_FIRED_BY_INSERT(CurrentTriggerData->tg_event))
+		elog (WARN, "ttdummy: can't process INSERT event");
+	if (TRIGGER_FIRED_BY_UPDATE(CurrentTriggerData->tg_event))
+		newtuple = CurrentTriggerData->tg_newtuple;
+	
+	trigtuple = CurrentTriggerData->tg_trigtuple;
+	
+	rel = CurrentTriggerData->tg_relation;
+	relname = SPI_getrelname(rel);
+	
+	/* check if TT is OFF for this relation */
+	if (ttoff)				/* OFF - nothing to do */
+	{
+		pfree (relname);
+		return ((newtuple != NULL) ? newtuple : trigtuple);
+	}
+	
+	trigger = CurrentTriggerData->tg_trigger;
+
+	if (trigger->tgnargs != 2)
+		elog(WARN, "ttdummy (%s): invalid (!= 2) number of arguments %d", 
+				relname, trigger->tgnargs);
+	
+	args = trigger->tgargs;
+	tupdesc = rel->rd_att;
+	natts = tupdesc->natts;
+	
+	CurrentTriggerData = NULL;
+	
+	for (i = 0; i < 2; i++ )
+	{
+		attnum[i] = SPI_fnumber (tupdesc, args[i]);
+		if ( attnum[i] < 0 )
+			elog(WARN, "ttdummy (%s): there is no attribute %s", relname, args[i]);
+		if (SPI_gettypeid (tupdesc, attnum[i]) != INT4OID)
+			elog(WARN, "ttdummy (%s): attributes %s and %s must be of abstime type", 
+					relname, args[0], args[1]);
+	}
+	
+	oldon = SPI_getbinval (trigtuple, tupdesc, attnum[0], &isnull);
+	if (isnull)
+		elog(WARN, "ttdummy (%s): %s must be NOT NULL", relname, args[0]);
+	
+	oldoff = SPI_getbinval (trigtuple, tupdesc, attnum[1], &isnull);
+	if (isnull)
+		elog(WARN, "ttdummy (%s): %s must be NOT NULL", relname, args[1]);
+	
+	if (newtuple != NULL)						/* UPDATE */
+	{
+		newon = SPI_getbinval (newtuple, tupdesc, attnum[0], &isnull);
+		if (isnull)
+			elog(WARN, "ttdummy (%s): %s must be NOT NULL", relname, args[0]);
+		newoff = SPI_getbinval (newtuple, tupdesc, attnum[1], &isnull);
+		if (isnull)
+			elog(WARN, "ttdummy (%s): %s must be NOT NULL", relname, args[1]);
+		
+		if ( oldon != newon || oldoff != newoff )
+			elog (WARN, "ttdummy (%s): you can't change %s and/or %s columns (use set_ttdummy)",
+					relname, args[0], args[1]);
+		
+		if ( newoff != TTDUMMY_INFINITY )
+		{
+			pfree (relname);	/* allocated in upper executor context */
+			return (NULL);
+		}
+	}
+	else if (oldoff != TTDUMMY_INFINITY)		/* DELETE */
+	{
+		pfree (relname);
+		return (NULL);
+	}
+	
+	{
+		struct varlena *seqname = textin ("ttdummy_seq");
+		
+		newoff = nextval (seqname);
+		pfree (seqname);
+	}
+	
+	/* Connect to SPI manager */
+	if ((ret = SPI_connect()) < 0)
+		elog(WARN, "ttdummy (%s): SPI_connect returned %d", relname, ret);
+	
+	/* Fetch tuple values and nulls */
+	cvals = (Datum *) palloc (natts * sizeof (Datum));
+	cnulls = (char *) palloc (natts * sizeof (char));
+	for (i = 0; i < natts; i++)
+	{
+		cvals[i] = SPI_getbinval ((newtuple != NULL) ? newtuple : trigtuple, 
+								  tupdesc, i + 1, &isnull);
+		cnulls[i] = (isnull) ? 'n' : ' ';
+	}
+	
+	/* change date column(s) */
+	if (newtuple)					/* UPDATE */
+	{
+		cvals[attnum[0] - 1] = newoff;			/* start_date eq current date */
+		cnulls[attnum[0] - 1] = ' ';
+		cvals[attnum[1] - 1] = TTDUMMY_INFINITY;	/* stop_date eq INFINITY */
+		cnulls[attnum[1] - 1] = ' ';
+	}
+	else							/* DELETE */
+	{
+		cvals[attnum[1] - 1] = newoff;			/* stop_date eq current date */
+		cnulls[attnum[1] - 1] = ' ';
+	}
+	
+	/* if there is no plan ... */
+	if (splan == NULL)
+	{
+		void	   *pplan;
+		Oid		   *ctypes;
+		char		sql[8192];
+		
+		/* allocate ctypes for preparation */
+		ctypes = (Oid *) palloc(natts * sizeof(Oid));
+		
+		/*
+		 * Construct query: 
+		 * 	INSERT INTO _relation_ VALUES ($1, ...)
+		 */
+		sprintf(sql, "INSERT INTO %s VALUES (", relname);
+		for (i = 1; i <= natts; i++)
+		{
+			sprintf(sql + strlen(sql), "$%d%s",
+				i, (i < natts) ? ", " : ")");
+			ctypes[i - 1] = SPI_gettypeid(tupdesc, i);
+		}
+		
+		/* Prepare plan for query */
+		pplan = SPI_prepare(sql, natts, ctypes);
+		if (pplan == NULL)
+			elog(WARN, "ttdummy (%s): SPI_prepare returned %d", relname, SPI_result);
+		
+		pplan = SPI_saveplan(pplan);
+		if (pplan == NULL)
+			elog(WARN, "ttdummy (%s): SPI_saveplan returned %d", relname, SPI_result);
+		
+		splan = pplan;
+	}
+	
+	ret = SPI_execp(splan, cvals, cnulls, 0);
+	
+	if (ret < 0)
+		elog(WARN, "ttdummy (%s): SPI_execp returned %d", relname, ret);
+	
+	/* Tuple to return to upper Executor ... */
+	if (newtuple)									/* UPDATE */
+	{
+		HeapTuple	tmptuple;
+		
+		tmptuple = SPI_copytuple (trigtuple);
+		rettuple = SPI_modifytuple (rel, tmptuple, 1, &(attnum[1]), &newoff, NULL);
+		SPI_pfree (tmptuple);
+	}
+	else											/* DELETE */
+		rettuple = trigtuple;
+	
+	SPI_finish();		/* don't forget say Bye to SPI mgr */
+	
+	pfree (relname);
+
+	return (rettuple);
+}
+
+int32
+set_ttdummy(int32 on)
+{
+	
+	if (ttoff)				/* OFF currently */
+	{
+		if (on == 0)
+			return (0);
+		
+		/* turn ON */
+		ttoff = false;
+		return (0);
+	}
+	
+	/* ON currently */
+	if (on != 0)
+		return (1);
+	
+	/* turn OFF */
+	ttoff = true;
+	
+	return (1);
+
+}