Added: ttdummy() - variation of timetravel() function
authorVadim B. Mikheev
Wed, 24 Sep 1997 08:35:10 +0000 (08:35 +0000)
committerVadim B. Mikheev
Wed, 24 Sep 1997 08:35:10 +0000 (08:35 +0000)
for regress test.

src/test/regress/GNUmakefile
src/test/regress/regress.c

index a4904b41190beb2aebdb7b632211ec01edc56fb2..8dbcdba58b8e5eb85d60312736020aa094132f4b 100644 (file)
@@ -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
index e602762df885a0e0ed02d82b5e0ff7fa52ce5caa..2e2eaa9e4fde3fa1822cfae864af12338d72c3f2 100644 (file)
@@ -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              /* faked on sunos */
@@ -411,3 +411,232 @@ funny_dup17()
 
    return (tuple);
 }
+
+#include              /* 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);
+
+}