LCOV - differential code coverage report
Current view: top level - contrib/spi - autoinc.c (source / functions) Coverage Total Hit UBC CBC
Current: Differential Code Coverage HEAD vs 15 Lines: 87.7 % 57 50 7 50
Current Date: 2023-04-08 17:13:01 Functions: 100.0 % 3 3 3
Baseline: 15 Line coverage date bins:
Baseline Date: 2023-04-08 15:09:40 (240..) days: 87.7 % 57 50 7 50
Legend: Lines: hit not hit Function coverage date bins:
(240..) days: 100.0 % 3 3 3

 Age         Owner                  TLA  Line data    Source code
                                  1                 : /*
                                  2                 :  * contrib/spi/autoinc.c
                                  3                 :  */
                                  4                 : #include "postgres.h"
                                  5                 : 
                                  6                 : #include "access/htup_details.h"
                                  7                 : #include "catalog/pg_type.h"
                                  8                 : #include "commands/sequence.h"
                                  9                 : #include "commands/trigger.h"
                                 10                 : #include "executor/spi.h"
                                 11                 : #include "utils/builtins.h"
                                 12                 : #include "utils/rel.h"
                                 13                 : 
 6158 tgl                        14 CBC           6 : PG_MODULE_MAGIC;
                                 15                 : 
 8175                            16               7 : PG_FUNCTION_INFO_V1(autoinc);
                                 17                 : 
                                 18                 : Datum
 8350                            19              36 : autoinc(PG_FUNCTION_ARGS)
                                 20                 : {
                                 21              36 :     TriggerData *trigdata = (TriggerData *) fcinfo->context;
                                 22                 :     Trigger    *trigger;        /* to get trigger name */
                                 23                 :     int         nargs;          /* # of arguments */
                                 24                 :     int        *chattrs;        /* attnums of attributes to change */
 9320 vadim4o                    25              36 :     int         chnattrs = 0;   /* # of above */
                                 26                 :     Datum      *newvals;        /* vals of above */
                                 27                 :     bool       *newnulls;       /* null flags for above */
                                 28                 :     char      **args;           /* arguments */
                                 29                 :     char       *relname;        /* triggered relation name */
                                 30                 :     Relation    rel;            /* triggered relation */
                                 31              36 :     HeapTuple   rettuple = NULL;
                                 32                 :     TupleDesc   tupdesc;        /* tuple description */
                                 33                 :     bool        isnull;
                                 34                 :     int         i;
                                 35                 : 
 8350 tgl                        36              36 :     if (!CALLED_AS_TRIGGER(fcinfo))
                                 37                 :         /* internal error */
 7199 tgl                        38 UBC           0 :         elog(ERROR, "not fired by trigger manager");
 4566 tgl                        39 CBC          36 :     if (!TRIGGER_FIRED_FOR_ROW(trigdata->tg_event))
                                 40                 :         /* internal error */
 4566 tgl                        41 UBC           0 :         elog(ERROR, "must be fired for row");
 4566 tgl                        42 CBC          36 :     if (!TRIGGER_FIRED_BEFORE(trigdata->tg_event))
                                 43                 :         /* internal error */
 7199 tgl                        44 UBC           0 :         elog(ERROR, "must be fired before event");
                                 45                 : 
 8350 tgl                        46 CBC          36 :     if (TRIGGER_FIRED_BY_INSERT(trigdata->tg_event))
                                 47              18 :         rettuple = trigdata->tg_trigtuple;
                                 48              18 :     else if (TRIGGER_FIRED_BY_UPDATE(trigdata->tg_event))
                                 49              18 :         rettuple = trigdata->tg_newtuple;
                                 50                 :     else
                                 51                 :         /* internal error */
 5911 bruce                      52 UBC           0 :         elog(ERROR, "cannot process DELETE events");
                                 53                 : 
 8350 tgl                        54 CBC          36 :     rel = trigdata->tg_relation;
 9320 vadim4o                    55              36 :     relname = SPI_getrelname(rel);
                                 56                 : 
 8350 tgl                        57              36 :     trigger = trigdata->tg_trigger;
                                 58                 : 
 9320 vadim4o                    59              36 :     nargs = trigger->tgnargs;
                                 60              36 :     if (nargs <= 0 || nargs % 2 != 0)
                                 61                 :         /* internal error */
 9224 bruce                      62 UBC           0 :         elog(ERROR, "autoinc (%s): even number gt 0 of arguments was expected", relname);
                                 63                 : 
 9320 vadim4o                    64 CBC          36 :     args = trigger->tgargs;
                                 65              36 :     tupdesc = rel->rd_att;
                                 66                 : 
 9173 bruce                      67              36 :     chattrs = (int *) palloc(nargs / 2 * sizeof(int));
                                 68              36 :     newvals = (Datum *) palloc(nargs / 2 * sizeof(Datum));
 2343 tgl                        69              36 :     newnulls = (bool *) palloc(nargs / 2 * sizeof(bool));
                                 70                 : 
 9173 bruce                      71              72 :     for (i = 0; i < nargs;)
                                 72                 :     {
                                 73              36 :         int         attnum = SPI_fnumber(tupdesc, args[i]);
                                 74                 :         int32       val;
                                 75                 :         Datum       seqname;
                                 76                 : 
 2343 tgl                        77              36 :         if (attnum <= 0)
 7199 tgl                        78 UBC           0 :             ereport(ERROR,
                                 79                 :                     (errcode(ERRCODE_TRIGGERED_ACTION_EXCEPTION),
                                 80                 :                      errmsg("\"%s\" has no attribute \"%s\"",
                                 81                 :                             relname, args[i])));
                                 82                 : 
 9173 bruce                      83 CBC          36 :         if (SPI_gettypeid(tupdesc, attnum) != INT4OID)
 7199 tgl                        84 UBC           0 :             ereport(ERROR,
                                 85                 :                     (errcode(ERRCODE_TRIGGERED_ACTION_EXCEPTION),
                                 86                 :                      errmsg("attribute \"%s\" of \"%s\" must be type INT4",
                                 87                 :                             args[i], relname)));
                                 88                 : 
 9173 bruce                      89 CBC          36 :         val = DatumGetInt32(SPI_getbinval(rettuple, tupdesc, attnum, &isnull));
                                 90                 : 
 9320 vadim4o                    91              36 :         if (!isnull && val != 0)
                                 92                 :         {
                                 93              27 :             i += 2;
                                 94              27 :             continue;
                                 95                 :         }
                                 96                 : 
                                 97               9 :         i++;
                                 98               9 :         chattrs[chnattrs] = attnum;
 5493 tgl                        99               9 :         seqname = CStringGetTextDatum(args[i]);
 8313                           100               9 :         newvals[chnattrs] = DirectFunctionCall1(nextval, seqname);
                                101                 :         /* nextval now returns int64; coerce down to int32 */
 7906                           102               9 :         newvals[chnattrs] = Int32GetDatum((int32) DatumGetInt64(newvals[chnattrs]));
 9173 bruce                     103               9 :         if (DatumGetInt32(newvals[chnattrs]) == 0)
                                104                 :         {
 8313 tgl                       105               3 :             newvals[chnattrs] = DirectFunctionCall1(nextval, seqname);
 7906                           106               3 :             newvals[chnattrs] = Int32GetDatum((int32) DatumGetInt64(newvals[chnattrs]));
                                107                 :         }
 2343                           108               9 :         newnulls[chnattrs] = false;
 2219 noah                      109               9 :         pfree(DatumGetTextPP(seqname));
 9320 vadim4o                   110               9 :         chnattrs++;
                                111               9 :         i++;
                                112                 :     }
                                113                 : 
                                114              36 :     if (chnattrs > 0)
                                115                 :     {
 2343 tgl                       116               9 :         rettuple = heap_modify_tuple_by_cols(rettuple, tupdesc,
                                117                 :                                              chnattrs, chattrs,
                                118                 :                                              newvals, newnulls);
                                119                 :     }
                                120                 : 
 9173 bruce                     121              36 :     pfree(relname);
                                122              36 :     pfree(chattrs);
                                123              36 :     pfree(newvals);
 2343 tgl                       124              36 :     pfree(newnulls);
                                125                 : 
 8350                           126              36 :     return PointerGetDatum(rettuple);
                                127                 : }
        

Generated by: LCOV version v1.16-55-g56c0a2a