LCOV - code coverage report
Current view: top level - contrib/spi - insert_username.c (source / functions) Coverage Total Hit
Test: PostgreSQL 20devel Lines: 0.0 % 34 0
Test Date: 2026-07-03 19:57:34 Functions: 0.0 % 3 0
Legend: Lines:     hit not hit
Branches: + taken - not taken # not executed
Branches: 0.0 % 32 0

             Branch data     Line data    Source code
       1                 :             : /*
       2                 :             :  * contrib/spi/insert_username.c
       3                 :             :  *
       4                 :             :  * insert user name in response to a trigger
       5                 :             :  * usage:  insert_username (column_name)
       6                 :             :  */
       7                 :             : #include "postgres.h"
       8                 :             : 
       9                 :             : #include "access/htup_details.h"
      10                 :             : #include "catalog/pg_type.h"
      11                 :             : #include "commands/trigger.h"
      12                 :             : #include "executor/spi.h"
      13                 :             : #include "miscadmin.h"
      14                 :             : #include "utils/builtins.h"
      15                 :             : #include "utils/rel.h"
      16                 :             : 
      17                 :           0 : PG_MODULE_MAGIC_EXT(
      18                 :             :                     .name = "insert_username",
      19                 :             :                     .version = PG_VERSION
      20                 :             : );
      21                 :             : 
      22                 :           0 : PG_FUNCTION_INFO_V1(insert_username);
      23                 :             : 
      24                 :             : Datum
      25                 :           0 : insert_username(PG_FUNCTION_ARGS)
      26                 :             : {
      27                 :           0 :     TriggerData *trigdata = (TriggerData *) fcinfo->context;
      28                 :             :     Trigger    *trigger;        /* to get trigger name */
      29                 :             :     int         nargs;          /* # of arguments */
      30                 :             :     Datum       newval;         /* new value of column */
      31                 :             :     bool        newnull;        /* null flag */
      32                 :             :     char      **args;           /* arguments */
      33                 :             :     char       *relname;        /* triggered relation name */
      34                 :             :     Relation    rel;            /* triggered relation */
      35                 :           0 :     HeapTuple   rettuple = NULL;
      36                 :             :     TupleDesc   tupdesc;        /* tuple description */
      37                 :             :     int         attnum;
      38                 :             : 
      39                 :             :     /* sanity checks from autoinc.c */
      40   [ #  #  #  # ]:           0 :     if (!CALLED_AS_TRIGGER(fcinfo))
      41                 :             :         /* internal error */
      42         [ #  # ]:           0 :         elog(ERROR, "insert_username: not fired by trigger manager");
      43         [ #  # ]:           0 :     if (!TRIGGER_FIRED_FOR_ROW(trigdata->tg_event))
      44                 :             :         /* internal error */
      45         [ #  # ]:           0 :         elog(ERROR, "insert_username: must be fired for row");
      46         [ #  # ]:           0 :     if (!TRIGGER_FIRED_BEFORE(trigdata->tg_event))
      47                 :             :         /* internal error */
      48         [ #  # ]:           0 :         elog(ERROR, "insert_username: must be fired before event");
      49                 :             : 
      50         [ #  # ]:           0 :     if (TRIGGER_FIRED_BY_INSERT(trigdata->tg_event))
      51                 :           0 :         rettuple = trigdata->tg_trigtuple;
      52         [ #  # ]:           0 :     else if (TRIGGER_FIRED_BY_UPDATE(trigdata->tg_event))
      53                 :           0 :         rettuple = trigdata->tg_newtuple;
      54                 :             :     else
      55                 :             :         /* internal error */
      56         [ #  # ]:           0 :         elog(ERROR, "insert_username: cannot process DELETE events");
      57                 :             : 
      58                 :           0 :     rel = trigdata->tg_relation;
      59                 :           0 :     relname = SPI_getrelname(rel);
      60                 :             : 
      61                 :           0 :     trigger = trigdata->tg_trigger;
      62                 :             : 
      63                 :           0 :     nargs = trigger->tgnargs;
      64         [ #  # ]:           0 :     if (nargs != 1)
      65                 :             :         /* internal error */
      66         [ #  # ]:           0 :         elog(ERROR, "insert_username (%s): one argument was expected", relname);
      67                 :             : 
      68                 :           0 :     args = trigger->tgargs;
      69                 :           0 :     tupdesc = rel->rd_att;
      70                 :             : 
      71                 :           0 :     attnum = SPI_fnumber(tupdesc, args[0]);
      72                 :             : 
      73         [ #  # ]:           0 :     if (attnum <= 0)
      74         [ #  # ]:           0 :         ereport(ERROR,
      75                 :             :                 (errcode(ERRCODE_TRIGGERED_ACTION_EXCEPTION),
      76                 :             :                  errmsg("\"%s\" has no attribute \"%s\"", relname, args[0])));
      77                 :             : 
      78         [ #  # ]:           0 :     if (SPI_gettypeid(tupdesc, attnum) != TEXTOID)
      79         [ #  # ]:           0 :         ereport(ERROR,
      80                 :             :                 (errcode(ERRCODE_TRIGGERED_ACTION_EXCEPTION),
      81                 :             :                  errmsg("attribute \"%s\" of \"%s\" must be type TEXT",
      82                 :             :                         args[0], relname)));
      83                 :             : 
      84                 :             :     /* create fields containing name */
      85                 :           0 :     newval = CStringGetTextDatum(GetUserNameFromId(GetUserId(), false));
      86                 :           0 :     newnull = false;
      87                 :             : 
      88                 :             :     /* construct new tuple */
      89                 :           0 :     rettuple = heap_modify_tuple_by_cols(rettuple, tupdesc,
      90                 :             :                                          1, &attnum, &newval, &newnull);
      91                 :             : 
      92                 :           0 :     pfree(relname);
      93                 :             : 
      94                 :           0 :     return PointerGetDatum(rettuple);
      95                 :             : }
        

Generated by: LCOV version 2.0-1