Skip to content

Commit 7627154

Browse files
committed
Added: ttdummy() - variation of timetravel() function
for regress test.
1 parent 1777ba4 commit 7627154

File tree

2 files changed

+232
-3
lines changed

2 files changed

+232
-3
lines changed

src/test/regress/GNUmakefile

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
#
88
#
99
# IDENTIFICATION
10-
# $Header: /cvsroot/pgsql/src/test/regress/GNUmakefile,v 1.10 1997/09/11 09:13:27 vadim Exp $
10+
# $Header: /cvsroot/pgsql/src/test/regress/GNUmakefile,v 1.11 1997/09/24 08:35:07 vadim Exp $
1111
#
1212
#-------------------------------------------------------------------------
1313

@@ -43,7 +43,7 @@ endif
4343
all: $(INFILES)
4444
cd input; $(MAKE) all; cd ..
4545
cd output; $(MAKE) all; cd ..
46-
$(MAKE) -C ../../../contrib/spi REFINT_VERBOSE=1
46+
$(MAKE) -C ../../../contrib/spi REFINT_VERBOSE=1 refint$(DLSUFFIX)
4747

4848
#
4949
# run the test

src/test/regress/regress.c

Lines changed: 230 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* $Header: /cvsroot/pgsql/src/test/regress/regress.c,v 1.15 1997/09/18 20:22:54 momjian Exp $
2+
* $Header: /cvsroot/pgsql/src/test/regress/regress.c,v 1.16 1997/09/24 08:35:10 vadim Exp $
33
*/
44

55
#include <float.h> /* faked on sunos */
@@ -411,3 +411,232 @@ funny_dup17()
411411

412412
return (tuple);
413413
}
414+
415+
#include <ctype.h> /* tolower () */
416+
417+
HeapTuple ttdummy(void);
418+
int32 set_ttdummy(int32 on);
419+
420+
extern int4 nextval(struct varlena * seqin);
421+
422+
#define TTDUMMY_INFINITY 999999
423+
424+
static void *splan = NULL;
425+
static bool ttoff = false;
426+
427+
HeapTuple
428+
ttdummy()
429+
{
430+
Trigger *trigger; /* to get trigger name */
431+
char **args; /* arguments */
432+
int attnum[2]; /* fnumbers of start/stop columns */
433+
Datum oldon, oldoff;
434+
Datum newon, newoff;
435+
Datum *cvals; /* column values */
436+
char *cnulls; /* column nulls */
437+
char *relname; /* triggered relation name */
438+
Relation rel; /* triggered relation */
439+
HeapTuple trigtuple;
440+
HeapTuple newtuple = NULL;
441+
HeapTuple rettuple;
442+
TupleDesc tupdesc; /* tuple description */
443+
int natts; /* # of attributes */
444+
bool isnull; /* to know is some column NULL or not */
445+
int ret;
446+
int i;
447+
448+
if (!CurrentTriggerData)
449+
elog(WARN, "ttdummy: triggers are not initialized");
450+
if (TRIGGER_FIRED_FOR_STATEMENT(CurrentTriggerData->tg_event))
451+
elog(WARN, "ttdummy: can't process STATEMENT events");
452+
if (TRIGGER_FIRED_AFTER(CurrentTriggerData->tg_event))
453+
elog(WARN, "ttdummy: must be fired before event");
454+
if (TRIGGER_FIRED_BY_INSERT(CurrentTriggerData->tg_event))
455+
elog (WARN, "ttdummy: can't process INSERT event");
456+
if (TRIGGER_FIRED_BY_UPDATE(CurrentTriggerData->tg_event))
457+
newtuple = CurrentTriggerData->tg_newtuple;
458+
459+
trigtuple = CurrentTriggerData->tg_trigtuple;
460+
461+
rel = CurrentTriggerData->tg_relation;
462+
relname = SPI_getrelname(rel);
463+
464+
/* check if TT is OFF for this relation */
465+
if (ttoff) /* OFF - nothing to do */
466+
{
467+
pfree (relname);
468+
return ((newtuple != NULL) ? newtuple : trigtuple);
469+
}
470+
471+
trigger = CurrentTriggerData->tg_trigger;
472+
473+
if (trigger->tgnargs != 2)
474+
elog(WARN, "ttdummy (%s): invalid (!= 2) number of arguments %d",
475+
relname, trigger->tgnargs);
476+
477+
args = trigger->tgargs;
478+
tupdesc = rel->rd_att;
479+
natts = tupdesc->natts;
480+
481+
CurrentTriggerData = NULL;
482+
483+
for (i = 0; i < 2; i++ )
484+
{
485+
attnum[i] = SPI_fnumber (tupdesc, args[i]);
486+
if ( attnum[i] < 0 )
487+
elog(WARN, "ttdummy (%s): there is no attribute %s", relname, args[i]);
488+
if (SPI_gettypeid (tupdesc, attnum[i]) != INT4OID)
489+
elog(WARN, "ttdummy (%s): attributes %s and %s must be of abstime type",
490+
relname, args[0], args[1]);
491+
}
492+
493+
oldon = SPI_getbinval (trigtuple, tupdesc, attnum[0], &isnull);
494+
if (isnull)
495+
elog(WARN, "ttdummy (%s): %s must be NOT NULL", relname, args[0]);
496+
497+
oldoff = SPI_getbinval (trigtuple, tupdesc, attnum[1], &isnull);
498+
if (isnull)
499+
elog(WARN, "ttdummy (%s): %s must be NOT NULL", relname, args[1]);
500+
501+
if (newtuple != NULL) /* UPDATE */
502+
{
503+
newon = SPI_getbinval (newtuple, tupdesc, attnum[0], &isnull);
504+
if (isnull)
505+
elog(WARN, "ttdummy (%s): %s must be NOT NULL", relname, args[0]);
506+
newoff = SPI_getbinval (newtuple, tupdesc, attnum[1], &isnull);
507+
if (isnull)
508+
elog(WARN, "ttdummy (%s): %s must be NOT NULL", relname, args[1]);
509+
510+
if ( oldon != newon || oldoff != newoff )
511+
elog (WARN, "ttdummy (%s): you can't change %s and/or %s columns (use set_ttdummy)",
512+
relname, args[0], args[1]);
513+
514+
if ( newoff != TTDUMMY_INFINITY )
515+
{
516+
pfree (relname); /* allocated in upper executor context */
517+
return (NULL);
518+
}
519+
}
520+
else if (oldoff != TTDUMMY_INFINITY) /* DELETE */
521+
{
522+
pfree (relname);
523+
return (NULL);
524+
}
525+
526+
{
527+
struct varlena *seqname = textin ("ttdummy_seq");
528+
529+
newoff = nextval (seqname);
530+
pfree (seqname);
531+
}
532+
533+
/* Connect to SPI manager */
534+
if ((ret = SPI_connect()) < 0)
535+
elog(WARN, "ttdummy (%s): SPI_connect returned %d", relname, ret);
536+
537+
/* Fetch tuple values and nulls */
538+
cvals = (Datum *) palloc (natts * sizeof (Datum));
539+
cnulls = (char *) palloc (natts * sizeof (char));
540+
for (i = 0; i < natts; i++)
541+
{
542+
cvals[i] = SPI_getbinval ((newtuple != NULL) ? newtuple : trigtuple,
543+
tupdesc, i + 1, &isnull);
544+
cnulls[i] = (isnull) ? 'n' : ' ';
545+
}
546+
547+
/* change date column(s) */
548+
if (newtuple) /* UPDATE */
549+
{
550+
cvals[attnum[0] - 1] = newoff; /* start_date eq current date */
551+
cnulls[attnum[0] - 1] = ' ';
552+
cvals[attnum[1] - 1] = TTDUMMY_INFINITY; /* stop_date eq INFINITY */
553+
cnulls[attnum[1] - 1] = ' ';
554+
}
555+
else /* DELETE */
556+
{
557+
cvals[attnum[1] - 1] = newoff; /* stop_date eq current date */
558+
cnulls[attnum[1] - 1] = ' ';
559+
}
560+
561+
/* if there is no plan ... */
562+
if (splan == NULL)
563+
{
564+
void *pplan;
565+
Oid *ctypes;
566+
char sql[8192];
567+
568+
/* allocate ctypes for preparation */
569+
ctypes = (Oid *) palloc(natts * sizeof(Oid));
570+
571+
/*
572+
* Construct query:
573+
* INSERT INTO _relation_ VALUES ($1, ...)
574+
*/
575+
sprintf(sql, "INSERT INTO %s VALUES (", relname);
576+
for (i = 1; i <= natts; i++)
577+
{
578+
sprintf(sql + strlen(sql), "$%d%s",
579+
i, (i < natts) ? ", " : ")");
580+
ctypes[i - 1] = SPI_gettypeid(tupdesc, i);
581+
}
582+
583+
/* Prepare plan for query */
584+
pplan = SPI_prepare(sql, natts, ctypes);
585+
if (pplan == NULL)
586+
elog(WARN, "ttdummy (%s): SPI_prepare returned %d", relname, SPI_result);
587+
588+
pplan = SPI_saveplan(pplan);
589+
if (pplan == NULL)
590+
elog(WARN, "ttdummy (%s): SPI_saveplan returned %d", relname, SPI_result);
591+
592+
splan = pplan;
593+
}
594+
595+
ret = SPI_execp(splan, cvals, cnulls, 0);
596+
597+
if (ret < 0)
598+
elog(WARN, "ttdummy (%s): SPI_execp returned %d", relname, ret);
599+
600+
/* Tuple to return to upper Executor ... */
601+
if (newtuple) /* UPDATE */
602+
{
603+
HeapTuple tmptuple;
604+
605+
tmptuple = SPI_copytuple (trigtuple);
606+
rettuple = SPI_modifytuple (rel, tmptuple, 1, &(attnum[1]), &newoff, NULL);
607+
SPI_pfree (tmptuple);
608+
}
609+
else /* DELETE */
610+
rettuple = trigtuple;
611+
612+
SPI_finish(); /* don't forget say Bye to SPI mgr */
613+
614+
pfree (relname);
615+
616+
return (rettuple);
617+
}
618+
619+
int32
620+
set_ttdummy(int32 on)
621+
{
622+
623+
if (ttoff) /* OFF currently */
624+
{
625+
if (on == 0)
626+
return (0);
627+
628+
/* turn ON */
629+
ttoff = false;
630+
return (0);
631+
}
632+
633+
/* ON currently */
634+
if (on != 0)
635+
return (1);
636+
637+
/* turn OFF */
638+
ttoff = true;
639+
640+
return (1);
641+
642+
}

0 commit comments

Comments
 (0)