Clean up the loose ends in selectivity estimation left by my patch for semi
[PostgreSQL.git] / contrib / spi / insert_username.c
blob133131d74c67e096dd2bfe7951388afa3b9c9027
1 /*
2 * insert_username.c
3 * $Modified: Thu Oct 16 08:13:42 1997 by brook $
4 * $PostgreSQL$
6 * insert user name in response to a trigger
7 * usage: insert_username (column_name)
8 */
10 #include "executor/spi.h" /* this is what you need to work with SPI */
11 #include "commands/trigger.h" /* -"- and triggers */
12 #include "miscadmin.h" /* for GetUserName() */
14 PG_MODULE_MAGIC;
16 extern Datum insert_username(PG_FUNCTION_ARGS);
18 PG_FUNCTION_INFO_V1(insert_username);
20 Datum
21 insert_username(PG_FUNCTION_ARGS)
23 TriggerData *trigdata = (TriggerData *) fcinfo->context;
24 Trigger *trigger; /* to get trigger name */
25 int nargs; /* # of arguments */
26 Datum newval; /* new value of column */
27 char **args; /* arguments */
28 char *relname; /* triggered relation name */
29 Relation rel; /* triggered relation */
30 HeapTuple rettuple = NULL;
31 TupleDesc tupdesc; /* tuple description */
32 int attnum;
34 /* sanity checks from autoinc.c */
35 if (!CALLED_AS_TRIGGER(fcinfo))
36 /* internal error */
37 elog(ERROR, "insert_username: not fired by trigger manager");
38 if (TRIGGER_FIRED_FOR_STATEMENT(trigdata->tg_event))
39 /* internal error */
40 elog(ERROR, "insert_username: cannot process STATEMENT events");
41 if (TRIGGER_FIRED_AFTER(trigdata->tg_event))
42 /* internal error */
43 elog(ERROR, "insert_username: must be fired before event");
45 if (TRIGGER_FIRED_BY_INSERT(trigdata->tg_event))
46 rettuple = trigdata->tg_trigtuple;
47 else if (TRIGGER_FIRED_BY_UPDATE(trigdata->tg_event))
48 rettuple = trigdata->tg_newtuple;
49 else
50 /* internal error */
51 elog(ERROR, "insert_username: cannot process DELETE events");
53 rel = trigdata->tg_relation;
54 relname = SPI_getrelname(rel);
56 trigger = trigdata->tg_trigger;
58 nargs = trigger->tgnargs;
59 if (nargs != 1)
60 /* internal error */
61 elog(ERROR, "insert_username (%s): one argument was expected", relname);
63 args = trigger->tgargs;
64 tupdesc = rel->rd_att;
66 attnum = SPI_fnumber(tupdesc, args[0]);
68 if (attnum < 0)
69 ereport(ERROR,
70 (errcode(ERRCODE_TRIGGERED_ACTION_EXCEPTION),
71 errmsg("\"%s\" has no attribute \"%s\"", relname, args[0])));
73 if (SPI_gettypeid(tupdesc, attnum) != TEXTOID)
74 ereport(ERROR,
75 (errcode(ERRCODE_TRIGGERED_ACTION_EXCEPTION),
76 errmsg("attribute \"%s\" of \"%s\" must be type TEXT",
77 args[0], relname)));
79 /* create fields containing name */
80 newval = CStringGetTextDatum(GetUserNameFromId(GetUserId()));
82 /* construct new tuple */
83 rettuple = SPI_modifytuple(rel, rettuple, 1, &attnum, &newval, NULL);
84 if (rettuple == NULL)
85 /* internal error */
86 elog(ERROR, "insert_username (\"%s\"): %d returned by SPI_modifytuple",
87 relname, SPI_result);
89 pfree(relname);
91 return PointerGetDatum(rettuple);