summaryrefslogtreecommitdiff
path: root/contrib/spi/autoinc.c
diff options
context:
space:
mode:
Diffstat (limited to 'contrib/spi/autoinc.c')
-rw-r--r--contrib/spi/autoinc.c107
1 files changed, 0 insertions, 107 deletions
diff --git a/contrib/spi/autoinc.c b/contrib/spi/autoinc.c
deleted file mode 100644
index 92d3e97c220..00000000000
--- a/contrib/spi/autoinc.c
+++ /dev/null
@@ -1,107 +0,0 @@
-
-#include "executor/spi.h" /* this is what you need to work with SPI */
-#include "commands/trigger.h" /* -"- and triggers */
-#include "commands/sequence.h" /* for nextval() */
-
-extern Datum autoinc(PG_FUNCTION_ARGS);
-
-PG_FUNCTION_INFO_V1(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 */
- int chnattrs = 0; /* # of above */
- Datum *newvals; /* vals of above */
- char **args; /* arguments */
- char *relname; /* triggered relation name */
- Relation rel; /* triggered relation */
- HeapTuple rettuple = NULL;
- TupleDesc tupdesc; /* tuple description */
- bool isnull;
- int i;
-
- 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(trigdata->tg_event))
- elog(ERROR, "autoinc: 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");
-
- rel = trigdata->tg_relation;
- relname = SPI_getrelname(rel);
-
- trigger = trigdata->tg_trigger;
-
- nargs = trigger->tgnargs;
- if (nargs <= 0 || nargs % 2 != 0)
- elog(ERROR, "autoinc (%s): even number gt 0 of arguments was expected", relname);
-
- args = trigger->tgargs;
- tupdesc = rel->rd_att;
-
- chattrs = (int *) palloc(nargs / 2 * sizeof(int));
- newvals = (Datum *) palloc(nargs / 2 * sizeof(Datum));
-
- for (i = 0; i < nargs;)
- {
- int attnum = SPI_fnumber(tupdesc, args[i]);
- int32 val;
- Datum seqname;
-
- if (attnum < 0)
- elog(ERROR, "autoinc (%s): there is 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]);
-
- val = DatumGetInt32(SPI_getbinval(rettuple, tupdesc, attnum, &isnull));
-
- if (!isnull && val != 0)
- {
- i += 2;
- continue;
- }
-
- i++;
- chattrs[chnattrs] = attnum;
- seqname = DirectFunctionCall1(textin,
- CStringGetDatum(args[i]));
- newvals[chnattrs] = DirectFunctionCall1(nextval, seqname);
- /* nextval now returns int64; coerce down to int32 */
- newvals[chnattrs] = Int32GetDatum((int32) DatumGetInt64(newvals[chnattrs]));
- if (DatumGetInt32(newvals[chnattrs]) == 0)
- {
- newvals[chnattrs] = DirectFunctionCall1(nextval, seqname);
- newvals[chnattrs] = Int32GetDatum((int32) DatumGetInt64(newvals[chnattrs]));
- }
- pfree(DatumGetTextP(seqname));
- chnattrs++;
- i++;
- }
-
- if (chnattrs > 0)
- {
- rettuple = SPI_modifytuple(rel, rettuple, chnattrs, chattrs, newvals, NULL);
- if (rettuple == NULL)
- elog(ERROR, "autoinc (%s): %d returned by SPI_modifytuple",
- relname, SPI_result);
- }
-
- pfree(relname);
- pfree(chattrs);
- pfree(newvals);
-
- return PointerGetDatum(rettuple);
-}