mirror of
https://github.com/postgres/postgres.git
synced 2025-07-30 11:03:19 +03:00
Error message editing in contrib (mostly by Joe Conway --- thanks Joe!)
This commit is contained in:
@ -25,18 +25,22 @@ autoinc(PG_FUNCTION_ARGS)
|
||||
int i;
|
||||
|
||||
if (!CALLED_AS_TRIGGER(fcinfo))
|
||||
elog(ERROR, "autoinc: not fired by trigger manager");
|
||||
/* internal error */
|
||||
elog(ERROR, "not fired by trigger manager");
|
||||
if (TRIGGER_FIRED_FOR_STATEMENT(trigdata->tg_event))
|
||||
elog(ERROR, "autoinc: can't process STATEMENT events");
|
||||
/* internal error */
|
||||
elog(ERROR, "can't process STATEMENT events");
|
||||
if (TRIGGER_FIRED_AFTER(trigdata->tg_event))
|
||||
elog(ERROR, "autoinc: must be fired before event");
|
||||
/* internal error */
|
||||
elog(ERROR, "must be fired before event");
|
||||
|
||||
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");
|
||||
/* internal error */
|
||||
elog(ERROR, "can't process DELETE events");
|
||||
|
||||
rel = trigdata->tg_relation;
|
||||
relname = SPI_getrelname(rel);
|
||||
@ -45,6 +49,7 @@ autoinc(PG_FUNCTION_ARGS)
|
||||
|
||||
nargs = trigger->tgnargs;
|
||||
if (nargs <= 0 || nargs % 2 != 0)
|
||||
/* internal error */
|
||||
elog(ERROR, "autoinc (%s): even number gt 0 of arguments was expected", relname);
|
||||
|
||||
args = trigger->tgargs;
|
||||
@ -60,11 +65,16 @@ autoinc(PG_FUNCTION_ARGS)
|
||||
Datum seqname;
|
||||
|
||||
if (attnum < 0)
|
||||
elog(ERROR, "autoinc (%s): there is no attribute %s",
|
||||
relname, args[i]);
|
||||
ereport(ERROR,
|
||||
(errcode(ERRCODE_TRIGGERED_ACTION_EXCEPTION),
|
||||
errmsg("\"%s\" has no attribute \"%s\"",
|
||||
relname, args[i])));
|
||||
|
||||
if (SPI_gettypeid(tupdesc, attnum) != INT4OID)
|
||||
elog(ERROR, "autoinc (%s): attribute %s must be of INT4 type",
|
||||
relname, args[i]);
|
||||
ereport(ERROR,
|
||||
(errcode(ERRCODE_TRIGGERED_ACTION_EXCEPTION),
|
||||
errmsg("attribute \"%s\" of \"%s\" must be type INT4",
|
||||
args[i], relname)));
|
||||
|
||||
val = DatumGetInt32(SPI_getbinval(rettuple, tupdesc, attnum, &isnull));
|
||||
|
||||
@ -95,6 +105,7 @@ autoinc(PG_FUNCTION_ARGS)
|
||||
{
|
||||
rettuple = SPI_modifytuple(rel, rettuple, chnattrs, chattrs, newvals, NULL);
|
||||
if (rettuple == NULL)
|
||||
/* internal error */
|
||||
elog(ERROR, "autoinc (%s): %d returned by SPI_modifytuple",
|
||||
relname, SPI_result);
|
||||
}
|
||||
|
@ -30,10 +30,13 @@ insert_username(PG_FUNCTION_ARGS)
|
||||
|
||||
/* sanity checks from autoinc.c */
|
||||
if (!CALLED_AS_TRIGGER(fcinfo))
|
||||
/* internal error */
|
||||
elog(ERROR, "insert_username: not fired by trigger manager");
|
||||
if (TRIGGER_FIRED_FOR_STATEMENT(trigdata->tg_event))
|
||||
/* internal error */
|
||||
elog(ERROR, "insert_username: can't process STATEMENT events");
|
||||
if (TRIGGER_FIRED_AFTER(trigdata->tg_event))
|
||||
/* internal error */
|
||||
elog(ERROR, "insert_username: must be fired before event");
|
||||
|
||||
if (TRIGGER_FIRED_BY_INSERT(trigdata->tg_event))
|
||||
@ -41,6 +44,7 @@ insert_username(PG_FUNCTION_ARGS)
|
||||
else if (TRIGGER_FIRED_BY_UPDATE(trigdata->tg_event))
|
||||
rettuple = trigdata->tg_newtuple;
|
||||
else
|
||||
/* internal error */
|
||||
elog(ERROR, "insert_username: can't process DELETE events");
|
||||
|
||||
rel = trigdata->tg_relation;
|
||||
@ -50,6 +54,7 @@ insert_username(PG_FUNCTION_ARGS)
|
||||
|
||||
nargs = trigger->tgnargs;
|
||||
if (nargs != 1)
|
||||
/* internal error */
|
||||
elog(ERROR, "insert_username (%s): one argument was expected", relname);
|
||||
|
||||
args = trigger->tgargs;
|
||||
@ -58,10 +63,15 @@ insert_username(PG_FUNCTION_ARGS)
|
||||
attnum = SPI_fnumber(tupdesc, args[0]);
|
||||
|
||||
if (attnum < 0)
|
||||
elog(ERROR, "insert_username (%s): there is no attribute %s", relname, args[0]);
|
||||
ereport(ERROR,
|
||||
(errcode(ERRCODE_TRIGGERED_ACTION_EXCEPTION),
|
||||
errmsg("\"%s\" has no attribute \"%s\"", relname, args[0])));
|
||||
|
||||
if (SPI_gettypeid(tupdesc, attnum) != TEXTOID)
|
||||
elog(ERROR, "insert_username (%s): attribute %s must be of TEXT type",
|
||||
relname, args[0]);
|
||||
ereport(ERROR,
|
||||
(errcode(ERRCODE_TRIGGERED_ACTION_EXCEPTION),
|
||||
errmsg("attribute \"%s\" of \"%s\" must be type TEXT",
|
||||
args[0], relname)));
|
||||
|
||||
/* create fields containing name */
|
||||
newval = DirectFunctionCall1(textin,
|
||||
@ -70,7 +80,8 @@ insert_username(PG_FUNCTION_ARGS)
|
||||
/* construct new tuple */
|
||||
rettuple = SPI_modifytuple(rel, rettuple, 1, &attnum, &newval, NULL);
|
||||
if (rettuple == NULL)
|
||||
elog(ERROR, "insert_username (%s): %d returned by SPI_modifytuple",
|
||||
/* internal error */
|
||||
elog(ERROR, "insert_username (\"%s\"): %d returned by SPI_modifytuple",
|
||||
relname, SPI_result);
|
||||
|
||||
pfree(relname);
|
||||
|
@ -34,20 +34,25 @@ moddatetime(PG_FUNCTION_ARGS)
|
||||
TupleDesc tupdesc; /* tuple description */
|
||||
|
||||
if (!CALLED_AS_TRIGGER(fcinfo))
|
||||
elog(ERROR, "moddatetime: not fired by trigger manager.");
|
||||
/* internal error */
|
||||
elog(ERROR, "moddatetime: not fired by trigger manager");
|
||||
|
||||
if (TRIGGER_FIRED_FOR_STATEMENT(trigdata->tg_event))
|
||||
elog(ERROR, "moddatetime: can't process STATEMENT events.");
|
||||
/* internal error */
|
||||
elog(ERROR, "moddatetime: can't process STATEMENT events");
|
||||
|
||||
if (TRIGGER_FIRED_AFTER(trigdata->tg_event))
|
||||
elog(ERROR, "moddatetime: must be fired before event.");
|
||||
/* internal error */
|
||||
elog(ERROR, "moddatetime: must be fired before event");
|
||||
|
||||
if (TRIGGER_FIRED_BY_INSERT(trigdata->tg_event))
|
||||
elog(ERROR, "moddatetime: must be fired before event.");
|
||||
/* internal error */
|
||||
elog(ERROR, "moddatetime: must be fired before event");
|
||||
else if (TRIGGER_FIRED_BY_UPDATE(trigdata->tg_event))
|
||||
rettuple = trigdata->tg_newtuple;
|
||||
else
|
||||
elog(ERROR, "moddatetime: can't process DELETE events.");
|
||||
/* internal error */
|
||||
elog(ERROR, "moddatetime: can't process DELETE events");
|
||||
|
||||
rel = trigdata->tg_relation;
|
||||
relname = SPI_getrelname(rel);
|
||||
@ -57,7 +62,8 @@ moddatetime(PG_FUNCTION_ARGS)
|
||||
nargs = trigger->tgnargs;
|
||||
|
||||
if (nargs != 1)
|
||||
elog(ERROR, "moddatetime (%s): A single argument was expected.", relname);
|
||||
/* internal error */
|
||||
elog(ERROR, "moddatetime (%s): A single argument was expected", relname);
|
||||
|
||||
args = trigger->tgargs;
|
||||
/* must be the field layout? */
|
||||
@ -81,8 +87,10 @@ moddatetime(PG_FUNCTION_ARGS)
|
||||
* even exits. The above function must return -1 if name not found?
|
||||
*/
|
||||
if (attnum < 0)
|
||||
elog(ERROR, "moddatetime (%s): there is no attribute %s", relname,
|
||||
args[0]);
|
||||
ereport(ERROR,
|
||||
(errcode(ERRCODE_TRIGGERED_ACTION_EXCEPTION),
|
||||
errmsg("\"%s\" has no attribute \"%s\"",
|
||||
relname, args[0])));
|
||||
|
||||
/*
|
||||
* OK, this is where we make sure the timestamp field that we are
|
||||
@ -90,8 +98,10 @@ moddatetime(PG_FUNCTION_ARGS)
|
||||
* novel idea !-)
|
||||
*/
|
||||
if (SPI_gettypeid(tupdesc, attnum) != TIMESTAMPOID)
|
||||
elog(ERROR, "moddatetime (%s): attribute %s must be of TIMESTAMP type",
|
||||
relname, args[0]);
|
||||
ereport(ERROR,
|
||||
(errcode(ERRCODE_TRIGGERED_ACTION_EXCEPTION),
|
||||
errmsg("attribute \"%s\" of \"%s\" must be type TIMESTAMP",
|
||||
args[0], relname)));
|
||||
|
||||
/* 1 is the number of items in the arrays attnum and newdt.
|
||||
attnum is the positional number of the field to be updated.
|
||||
@ -103,6 +113,7 @@ moddatetime(PG_FUNCTION_ARGS)
|
||||
rettuple = SPI_modifytuple(rel, rettuple, 1, &attnum, &newdt, NULL);
|
||||
|
||||
if (rettuple == NULL)
|
||||
/* internal error */
|
||||
elog(ERROR, "moddatetime (%s): %d returned by SPI_modifytuple",
|
||||
relname, SPI_result);
|
||||
|
||||
|
@ -59,7 +59,7 @@ check_primary_key(PG_FUNCTION_ARGS)
|
||||
int i;
|
||||
|
||||
#ifdef DEBUG_QUERY
|
||||
elog(DEBUG4, "Check_primary_key Enter Function");
|
||||
elog(DEBUG4, "check_primary_key: Enter Function");
|
||||
#endif
|
||||
|
||||
/*
|
||||
@ -68,10 +68,12 @@ check_primary_key(PG_FUNCTION_ARGS)
|
||||
|
||||
/* Called by trigger manager ? */
|
||||
if (!CALLED_AS_TRIGGER(fcinfo))
|
||||
/* internal error */
|
||||
elog(ERROR, "check_primary_key: not fired by trigger manager");
|
||||
|
||||
/* Should be called for ROW trigger */
|
||||
if (TRIGGER_FIRED_FOR_STATEMENT(trigdata->tg_event))
|
||||
/* internal error */
|
||||
elog(ERROR, "check_primary_key: can't process STATEMENT events");
|
||||
|
||||
/* If INSERTion then must check Tuple to being inserted */
|
||||
@ -80,6 +82,7 @@ check_primary_key(PG_FUNCTION_ARGS)
|
||||
|
||||
/* Not should be called for DELETE */
|
||||
else if (TRIGGER_FIRED_BY_DELETE(trigdata->tg_event))
|
||||
/* internal error */
|
||||
elog(ERROR, "check_primary_key: can't process DELETE events");
|
||||
|
||||
/* If UPDATion the must check new Tuple, not old one */
|
||||
@ -91,6 +94,7 @@ check_primary_key(PG_FUNCTION_ARGS)
|
||||
args = trigger->tgargs;
|
||||
|
||||
if (nargs % 2 != 1) /* odd number of arguments! */
|
||||
/* internal error */
|
||||
elog(ERROR, "check_primary_key: odd number of arguments should be specified");
|
||||
|
||||
nkeys = nargs / 2;
|
||||
@ -100,6 +104,7 @@ check_primary_key(PG_FUNCTION_ARGS)
|
||||
|
||||
/* Connect to SPI manager */
|
||||
if ((ret = SPI_connect()) < 0)
|
||||
/* internal error */
|
||||
elog(ERROR, "check_primary_key: SPI_connect returned %d", ret);
|
||||
|
||||
/*
|
||||
@ -127,8 +132,10 @@ check_primary_key(PG_FUNCTION_ARGS)
|
||||
|
||||
/* Bad guys may give us un-existing column in CREATE TRIGGER */
|
||||
if (fnumber < 0)
|
||||
elog(ERROR, "check_primary_key: there is no attribute %s in relation %s",
|
||||
args[i], SPI_getrelname(rel));
|
||||
ereport(ERROR,
|
||||
(errcode(ERRCODE_UNDEFINED_COLUMN),
|
||||
errmsg("there is no attribute \"%s\" in relation \"%s\"",
|
||||
args[i], SPI_getrelname(rel))));
|
||||
|
||||
/* Well, get binary (in internal format) value of column */
|
||||
kvals[i] = SPI_getbinval(tuple, tupdesc, fnumber, &isnull);
|
||||
@ -170,6 +177,7 @@ check_primary_key(PG_FUNCTION_ARGS)
|
||||
/* Prepare plan for query */
|
||||
pplan = SPI_prepare(sql, nkeys, argtypes);
|
||||
if (pplan == NULL)
|
||||
/* internal error */
|
||||
elog(ERROR, "check_primary_key: SPI_prepare returned %d", SPI_result);
|
||||
|
||||
/*
|
||||
@ -179,6 +187,7 @@ check_primary_key(PG_FUNCTION_ARGS)
|
||||
*/
|
||||
pplan = SPI_saveplan(pplan);
|
||||
if (pplan == NULL)
|
||||
/* internal error */
|
||||
elog(ERROR, "check_primary_key: SPI_saveplan returned %d", SPI_result);
|
||||
plan->splan = (void **) malloc(sizeof(void *));
|
||||
*(plan->splan) = pplan;
|
||||
@ -192,14 +201,17 @@ check_primary_key(PG_FUNCTION_ARGS)
|
||||
/* we have no NULLs - so we pass ^^^^ here */
|
||||
|
||||
if (ret < 0)
|
||||
/* internal error */
|
||||
elog(ERROR, "check_primary_key: SPI_execp returned %d", ret);
|
||||
|
||||
/*
|
||||
* If there are no tuples returned by SELECT then ...
|
||||
*/
|
||||
if (SPI_processed == 0)
|
||||
elog(ERROR, "%s: tuple references non-existing key in %s",
|
||||
trigger->tgname, relname);
|
||||
ereport(ERROR,
|
||||
(errcode(ERRCODE_TRIGGERED_ACTION_EXCEPTION),
|
||||
errmsg("tuple references non-existent key"),
|
||||
errdetail("Trigger \"%s\" found tuple referencing non-existent key in \"%s\".", trigger->tgname, relname)));
|
||||
|
||||
SPI_finish();
|
||||
|
||||
@ -249,7 +261,7 @@ check_foreign_key(PG_FUNCTION_ARGS)
|
||||
r;
|
||||
|
||||
#ifdef DEBUG_QUERY
|
||||
elog(DEBUG4, "Check_foreign_key Enter Function");
|
||||
elog(DEBUG4, "check_foreign_key: Enter Function");
|
||||
#endif
|
||||
|
||||
/*
|
||||
@ -258,14 +270,17 @@ check_foreign_key(PG_FUNCTION_ARGS)
|
||||
|
||||
/* Called by trigger manager ? */
|
||||
if (!CALLED_AS_TRIGGER(fcinfo))
|
||||
/* internal error */
|
||||
elog(ERROR, "check_foreign_key: not fired by trigger manager");
|
||||
|
||||
/* Should be called for ROW trigger */
|
||||
if (TRIGGER_FIRED_FOR_STATEMENT(trigdata->tg_event))
|
||||
/* internal error */
|
||||
elog(ERROR, "check_foreign_key: can't process STATEMENT events");
|
||||
|
||||
/* Not should be called for INSERT */
|
||||
if (TRIGGER_FIRED_BY_INSERT(trigdata->tg_event))
|
||||
/* internal error */
|
||||
elog(ERROR, "check_foreign_key: can't process INSERT events");
|
||||
|
||||
/* Have to check tg_trigtuple - tuple being deleted */
|
||||
@ -288,18 +303,22 @@ check_foreign_key(PG_FUNCTION_ARGS)
|
||||
|
||||
if (nargs < 5) /* nrefs, action, key, Relation, key - at
|
||||
* least */
|
||||
/* internal error */
|
||||
elog(ERROR, "check_foreign_key: too short %d (< 5) list of arguments", nargs);
|
||||
|
||||
nrefs = pg_atoi(args[0], sizeof(int), 0);
|
||||
if (nrefs < 1)
|
||||
/* internal error */
|
||||
elog(ERROR, "check_foreign_key: %d (< 1) number of references specified", nrefs);
|
||||
action = tolower((unsigned char) *(args[1]));
|
||||
if (action != 'r' && action != 'c' && action != 's')
|
||||
/* internal error */
|
||||
elog(ERROR, "check_foreign_key: invalid action %s", args[1]);
|
||||
nargs -= 2;
|
||||
args += 2;
|
||||
nkeys = (nargs - nrefs) / (nrefs + 1);
|
||||
if (nkeys <= 0 || nargs != (nrefs + nkeys * (nrefs + 1)))
|
||||
/* internal error */
|
||||
elog(ERROR, "check_foreign_key: invalid number of arguments %d for %d references",
|
||||
nargs + 2, nrefs);
|
||||
|
||||
@ -308,6 +327,7 @@ check_foreign_key(PG_FUNCTION_ARGS)
|
||||
|
||||
/* Connect to SPI manager */
|
||||
if ((ret = SPI_connect()) < 0)
|
||||
/* internal error */
|
||||
elog(ERROR, "check_foreign_key: SPI_connect returned %d", ret);
|
||||
|
||||
/*
|
||||
@ -331,6 +351,7 @@ check_foreign_key(PG_FUNCTION_ARGS)
|
||||
* else - check that we have exactly nrefs plan(s) ready
|
||||
*/
|
||||
else if (plan->nplans != nrefs)
|
||||
/* internal error */
|
||||
elog(ERROR, "%s: check_foreign_key: # of plans changed in meantime",
|
||||
trigger->tgname);
|
||||
|
||||
@ -342,8 +363,10 @@ check_foreign_key(PG_FUNCTION_ARGS)
|
||||
|
||||
/* Bad guys may give us un-existing column in CREATE TRIGGER */
|
||||
if (fnumber < 0)
|
||||
elog(ERROR, "check_foreign_key: there is no attribute %s in relation %s",
|
||||
args[i], SPI_getrelname(rel));
|
||||
ereport(ERROR,
|
||||
(errcode(ERRCODE_UNDEFINED_COLUMN),
|
||||
errmsg("there is no attribute \"%s\" in relation \"%s\"",
|
||||
args[i], SPI_getrelname(rel))));
|
||||
|
||||
/* Well, get binary (in internal format) value of column */
|
||||
kvals[i] = SPI_getbinval(trigtuple, tupdesc, fnumber, &isnull);
|
||||
@ -371,6 +394,7 @@ check_foreign_key(PG_FUNCTION_ARGS)
|
||||
|
||||
/* this shouldn't happen! SPI_ERROR_NOOUTFUNC ? */
|
||||
if (oldval == NULL)
|
||||
/* internal error */
|
||||
elog(ERROR, "check_foreign_key: SPI_getvalue returned %d", SPI_result);
|
||||
newval = SPI_getvalue(newtuple, tupdesc, fnumber);
|
||||
if (newval == NULL || strcmp(oldval, newval) != 0)
|
||||
@ -453,7 +477,7 @@ check_foreign_key(PG_FUNCTION_ARGS)
|
||||
strcmp(type, "date") && strcmp(type, "timestamp")) == 0)
|
||||
is_char_type = 1;
|
||||
#ifdef DEBUG_QUERY
|
||||
elog(DEBUG4, "Check_foreign_key Debug value %s type %s %d",
|
||||
elog(DEBUG4, "check_foreign_key Debug value %s type %s %d",
|
||||
nv, type, is_char_type);
|
||||
#endif
|
||||
|
||||
@ -504,6 +528,7 @@ check_foreign_key(PG_FUNCTION_ARGS)
|
||||
/* Prepare plan for query */
|
||||
pplan = SPI_prepare(sql, nkeys, argtypes);
|
||||
if (pplan == NULL)
|
||||
/* internal error */
|
||||
elog(ERROR, "check_foreign_key: SPI_prepare returned %d", SPI_result);
|
||||
|
||||
/*
|
||||
@ -513,6 +538,7 @@ check_foreign_key(PG_FUNCTION_ARGS)
|
||||
*/
|
||||
pplan = SPI_saveplan(pplan);
|
||||
if (pplan == NULL)
|
||||
/* internal error */
|
||||
elog(ERROR, "check_foreign_key: SPI_saveplan returned %d", SPI_result);
|
||||
|
||||
plan->splan[r] = pplan;
|
||||
@ -521,7 +547,7 @@ check_foreign_key(PG_FUNCTION_ARGS)
|
||||
}
|
||||
plan->nplans = nrefs;
|
||||
#ifdef DEBUG_QUERY
|
||||
elog(DEBUG4, "Check_foreign_key Debug Query is : %s ", sql);
|
||||
elog(DEBUG4, "check_foreign_key Debug Query is : %s ", sql);
|
||||
#endif
|
||||
}
|
||||
|
||||
@ -553,22 +579,26 @@ check_foreign_key(PG_FUNCTION_ARGS)
|
||||
/* we have no NULLs - so we pass ^^^^ here */
|
||||
|
||||
if (ret < 0)
|
||||
elog(ERROR, "check_foreign_key: SPI_execp returned %d", ret);
|
||||
ereport(ERROR,
|
||||
(errcode(ERRCODE_TRIGGERED_ACTION_EXCEPTION),
|
||||
errmsg("SPI_execp returned %d", ret)));
|
||||
|
||||
/* If action is 'R'estrict ... */
|
||||
if (action == 'r')
|
||||
{
|
||||
/* If there is tuple returned by SELECT then ... */
|
||||
if (SPI_processed > 0)
|
||||
elog(ERROR, "%s: tuple referenced in %s",
|
||||
trigger->tgname, relname);
|
||||
ereport(ERROR,
|
||||
(errcode(ERRCODE_TRIGGERED_ACTION_EXCEPTION),
|
||||
errmsg("\"%s\": tuple is referenced in \"%s\"",
|
||||
trigger->tgname, relname)));
|
||||
}
|
||||
else
|
||||
{
|
||||
#ifdef REFINT_VERBOSE
|
||||
elog(NOTICE, "%s: %d tuple(s) of %s are %s",
|
||||
trigger->tgname, SPI_processed, relname,
|
||||
(action == 'c') ? "deleted" : "setted to null");
|
||||
(action == 'c') ? "deleted" : "set to null");
|
||||
#endif
|
||||
}
|
||||
args += nkeys + 1; /* to the next relation */
|
||||
|
@ -82,14 +82,17 @@ timetravel(PG_FUNCTION_ARGS)
|
||||
|
||||
/* Called by trigger manager ? */
|
||||
if (!CALLED_AS_TRIGGER(fcinfo))
|
||||
/* internal error */
|
||||
elog(ERROR, "timetravel: not fired by trigger manager");
|
||||
|
||||
/* Should be called for ROW trigger */
|
||||
if (TRIGGER_FIRED_FOR_STATEMENT(trigdata->tg_event))
|
||||
/* internal error */
|
||||
elog(ERROR, "timetravel: can't process STATEMENT events");
|
||||
|
||||
/* Should be called BEFORE */
|
||||
if (TRIGGER_FIRED_AFTER(trigdata->tg_event))
|
||||
/* internal error */
|
||||
elog(ERROR, "timetravel: must be fired before event");
|
||||
|
||||
/* INSERT ? */
|
||||
@ -117,6 +120,7 @@ timetravel(PG_FUNCTION_ARGS)
|
||||
trigger = trigdata->tg_trigger;
|
||||
|
||||
if (trigger->tgnargs != 2)
|
||||
/* internal error */
|
||||
elog(ERROR, "timetravel (%s): invalid (!= 2) number of arguments %d",
|
||||
relname, trigger->tgnargs);
|
||||
|
||||
@ -128,10 +132,15 @@ timetravel(PG_FUNCTION_ARGS)
|
||||
{
|
||||
attnum[i] = SPI_fnumber(tupdesc, args[i]);
|
||||
if (attnum[i] < 0)
|
||||
elog(ERROR, "timetravel (%s): there is no attribute %s", relname, args[i]);
|
||||
ereport(ERROR,
|
||||
(errcode(ERRCODE_TRIGGERED_ACTION_EXCEPTION),
|
||||
errmsg("\"%s\" has no attribute \"%s\"",
|
||||
relname, args[i])));
|
||||
if (SPI_gettypeid(tupdesc, attnum[i]) != ABSTIMEOID)
|
||||
elog(ERROR, "timetravel (%s): attributes %s and %s must be of abstime type",
|
||||
relname, args[0], args[1]);
|
||||
ereport(ERROR,
|
||||
(errcode(ERRCODE_TRIGGERED_ACTION_EXCEPTION),
|
||||
errmsg("attribute \"%s\" of \"%s\" must be type ABSTIME",
|
||||
args[i], relname)));
|
||||
}
|
||||
|
||||
if (isinsert) /* INSERT */
|
||||
@ -153,8 +162,10 @@ timetravel(PG_FUNCTION_ARGS)
|
||||
{
|
||||
if ((chnattrs == 0 && DatumGetInt32(oldon) >= NOEND_ABSTIME) ||
|
||||
(chnattrs > 0 && DatumGetInt32(newvals[0]) >= NOEND_ABSTIME))
|
||||
elog(ERROR, "timetravel (%s): %s ge %s",
|
||||
relname, args[0], args[1]);
|
||||
ereport(ERROR,
|
||||
(errcode(ERRCODE_TRIGGERED_ACTION_EXCEPTION),
|
||||
errmsg("timetravel (%s): %s ge %s",
|
||||
relname, args[0], args[1])));
|
||||
newvals[chnattrs] = NOEND_ABSTIME;
|
||||
chattrs[chnattrs] = attnum[1];
|
||||
chnattrs++;
|
||||
@ -165,8 +176,10 @@ timetravel(PG_FUNCTION_ARGS)
|
||||
DatumGetInt32(oldoff)) ||
|
||||
(chnattrs > 0 && DatumGetInt32(newvals[0]) >=
|
||||
DatumGetInt32(oldoff)))
|
||||
elog(ERROR, "timetravel (%s): %s ge %s",
|
||||
relname, args[0], args[1]);
|
||||
ereport(ERROR,
|
||||
(errcode(ERRCODE_TRIGGERED_ACTION_EXCEPTION),
|
||||
errmsg("timetravel (%s): %s ge %s",
|
||||
relname, args[0], args[1])));
|
||||
}
|
||||
|
||||
pfree(relname);
|
||||
@ -180,11 +193,16 @@ timetravel(PG_FUNCTION_ARGS)
|
||||
|
||||
oldon = SPI_getbinval(trigtuple, tupdesc, attnum[0], &isnull);
|
||||
if (isnull)
|
||||
elog(ERROR, "timetravel (%s): %s must be NOT NULL", relname, args[0]);
|
||||
|
||||
ereport(ERROR,
|
||||
(errcode(ERRCODE_NULL_VALUE_NOT_ALLOWED),
|
||||
errmsg("\"%s\" must be NOT NULL in \"%s\"",
|
||||
args[0],relname)));
|
||||
oldoff = SPI_getbinval(trigtuple, tupdesc, attnum[1], &isnull);
|
||||
if (isnull)
|
||||
elog(ERROR, "timetravel (%s): %s must be NOT NULL", relname, args[1]);
|
||||
ereport(ERROR,
|
||||
(errcode(ERRCODE_NULL_VALUE_NOT_ALLOWED),
|
||||
errmsg("\"%s\" must be NOT NULL in \"%s\"",
|
||||
args[1],relname)));
|
||||
|
||||
/*
|
||||
* If DELETE/UPDATE of tuple with stop_date neq INFINITY then say
|
||||
@ -194,14 +212,23 @@ timetravel(PG_FUNCTION_ARGS)
|
||||
{
|
||||
newon = SPI_getbinval(newtuple, tupdesc, attnum[0], &isnull);
|
||||
if (isnull)
|
||||
elog(ERROR, "timetravel (%s): %s must be NOT NULL", relname, args[0]);
|
||||
ereport(ERROR,
|
||||
(errcode(ERRCODE_NULL_VALUE_NOT_ALLOWED),
|
||||
errmsg("\"%s\" must be NOT NULL in \"%s\"",
|
||||
args[0],relname)));
|
||||
newoff = SPI_getbinval(newtuple, tupdesc, attnum[1], &isnull);
|
||||
if (isnull)
|
||||
elog(ERROR, "timetravel (%s): %s must be NOT NULL", relname, args[1]);
|
||||
ereport(ERROR,
|
||||
(errcode(ERRCODE_NULL_VALUE_NOT_ALLOWED),
|
||||
errmsg("\"%s\" must be NOT NULL in \"%s\"",
|
||||
args[1],relname)));
|
||||
|
||||
if (oldon != newon || oldoff != newoff)
|
||||
elog(ERROR, "timetravel (%s): you can't change %s and/or %s columns (use set_timetravel)",
|
||||
relname, args[0], args[1]);
|
||||
ereport(ERROR,
|
||||
(errcode(ERRCODE_TRIGGERED_ACTION_EXCEPTION),
|
||||
errmsg("cannot change columns \"%s\" or \"%s\" in \"%s\"",
|
||||
args[0], args[1], relname),
|
||||
errhint("Use set_timetravel() instead.")));
|
||||
|
||||
if (newoff != NOEND_ABSTIME)
|
||||
{
|
||||
@ -219,6 +246,7 @@ timetravel(PG_FUNCTION_ARGS)
|
||||
|
||||
/* Connect to SPI manager */
|
||||
if ((ret = SPI_connect()) < 0)
|
||||
/* internal error */
|
||||
elog(ERROR, "timetravel (%s): SPI_connect returned %d", relname, ret);
|
||||
|
||||
/* Fetch tuple values and nulls */
|
||||
@ -277,6 +305,7 @@ timetravel(PG_FUNCTION_ARGS)
|
||||
/* Prepare plan for query */
|
||||
pplan = SPI_prepare(sql, natts, ctypes);
|
||||
if (pplan == NULL)
|
||||
/* internal error */
|
||||
elog(ERROR, "timetravel (%s): SPI_prepare returned %d", relname, SPI_result);
|
||||
|
||||
/*
|
||||
@ -286,6 +315,7 @@ timetravel(PG_FUNCTION_ARGS)
|
||||
*/
|
||||
pplan = SPI_saveplan(pplan);
|
||||
if (pplan == NULL)
|
||||
/* internal error */
|
||||
elog(ERROR, "timetravel (%s): SPI_saveplan returned %d", relname, SPI_result);
|
||||
|
||||
plan->splan = pplan;
|
||||
@ -297,6 +327,7 @@ timetravel(PG_FUNCTION_ARGS)
|
||||
ret = SPI_execp(plan->splan, cvals, cnulls, 0);
|
||||
|
||||
if (ret < 0)
|
||||
/* internal error */
|
||||
elog(ERROR, "timetravel (%s): SPI_execp returned %d", relname, ret);
|
||||
|
||||
/* Tuple to return to upper Executor ... */
|
||||
|
Reference in New Issue
Block a user