LCOV - differential code coverage report
Current view: top level - contrib/pgrowlocks - pgrowlocks.c (source / functions) Coverage Total Hit UBC GNC CBC DCB
Current: Differential Code Coverage 16@8cea358b128 vs 17@8cea358b128 Lines: 90.7 % 108 98 10 2 96 2
Current Date: 2024-04-14 14:21:10 Functions: 100.0 % 3 3 1 2
Baseline: 16@8cea358b128 Branches: 69.8 % 53 37 16 37
Baseline Date: 2024-04-14 14:21:09 Line coverage date bins:
Legend: Lines: hit not hit | Branches: + taken - not taken # not executed (120,180] days: 50.0 % 2 1 1 1
(180,240] days: 100.0 % 2 2 2
(240..) days: 91.3 % 104 95 9 95
Function coverage date bins:
(240..) days: 100.0 % 3 3 1 2
Branch coverage date bins:
(120,180] days: 25.0 % 4 1 3 1
(240..) days: 73.5 % 49 36 13 36

 Age         Owner                    Branch data    TLA  Line data    Source code
                                  1                 :                : /*
                                  2                 :                :  * contrib/pgrowlocks/pgrowlocks.c
                                  3                 :                :  *
                                  4                 :                :  * Copyright (c) 2005-2006  Tatsuo Ishii
                                  5                 :                :  *
                                  6                 :                :  * Permission to use, copy, modify, and distribute this software and
                                  7                 :                :  * its documentation for any purpose, without fee, and without a
                                  8                 :                :  * written agreement is hereby granted, provided that the above
                                  9                 :                :  * copyright notice and this paragraph and the following two
                                 10                 :                :  * paragraphs appear in all copies.
                                 11                 :                :  *
                                 12                 :                :  * IN NO EVENT SHALL THE AUTHOR BE LIABLE TO ANY PARTY FOR DIRECT,
                                 13                 :                :  * INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES, INCLUDING
                                 14                 :                :  * LOST PROFITS, ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS
                                 15                 :                :  * DOCUMENTATION, EVEN IF THE UNIVERSITY OF CALIFORNIA HAS BEEN ADVISED
                                 16                 :                :  * OF THE POSSIBILITY OF SUCH DAMAGE.
                                 17                 :                :  *
                                 18                 :                :  * THE AUTHOR SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING, BUT NOT
                                 19                 :                :  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
                                 20                 :                :  * A PARTICULAR PURPOSE.  THE SOFTWARE PROVIDED HEREUNDER IS ON AN "AS
                                 21                 :                :  * IS" BASIS, AND THE AUTHOR HAS NO OBLIGATIONS TO PROVIDE MAINTENANCE,
                                 22                 :                :  * SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
                                 23                 :                :  */
                                 24                 :                : 
                                 25                 :                : #include "postgres.h"
                                 26                 :                : 
                                 27                 :                : #include "access/heapam.h"
                                 28                 :                : #include "access/multixact.h"
                                 29                 :                : #include "access/relscan.h"
                                 30                 :                : #include "access/tableam.h"
                                 31                 :                : #include "access/xact.h"
                                 32                 :                : #include "catalog/namespace.h"
                                 33                 :                : #include "catalog/pg_am_d.h"
                                 34                 :                : #include "catalog/pg_authid.h"
                                 35                 :                : #include "funcapi.h"
                                 36                 :                : #include "miscadmin.h"
                                 37                 :                : #include "storage/bufmgr.h"
                                 38                 :                : #include "storage/procarray.h"
                                 39                 :                : #include "utils/acl.h"
                                 40                 :                : #include "utils/builtins.h"
                                 41                 :                : #include "utils/rel.h"
                                 42                 :                : #include "utils/snapmgr.h"
                                 43                 :                : #include "utils/varlena.h"
                                 44                 :                : 
 6529 tgl@sss.pgh.pa.us          45                 :CBC           2 : PG_MODULE_MAGIC;
                                 46                 :                : 
 6566 ishii@postgresql.org       47                 :              2 : PG_FUNCTION_INFO_V1(pgrowlocks);
                                 48                 :                : 
                                 49                 :                : /* ----------
                                 50                 :                :  * pgrowlocks:
                                 51                 :                :  * returns tids of rows being locked
                                 52                 :                :  * ----------
                                 53                 :                :  */
                                 54                 :                : 
                                 55                 :                : #define NCHARS 32
                                 56                 :                : 
                                 57                 :                : #define     Atnum_tid       0
                                 58                 :                : #define     Atnum_xmax      1
                                 59                 :                : #define     Atnum_ismulti   2
                                 60                 :                : #define     Atnum_xids      3
                                 61                 :                : #define     Atnum_modes     4
                                 62                 :                : #define     Atnum_pids      5
                                 63                 :                : 
                                 64                 :                : Datum
                                 65                 :             12 : pgrowlocks(PG_FUNCTION_ARGS)
                                 66                 :                : {
 1490 tgl@sss.pgh.pa.us          67                 :             12 :     text       *relname = PG_GETARG_TEXT_PP(0);
                                 68                 :             12 :     ReturnSetInfo *rsinfo = (ReturnSetInfo *) fcinfo->resultinfo;
                                 69                 :                :     AttInMetadata *attinmeta;
                                 70                 :                :     Relation    rel;
                                 71                 :                :     RangeVar   *relrv;
                                 72                 :                :     TableScanDesc scan;
                                 73                 :                :     HeapScanDesc hscan;
                                 74                 :                :     HeapTuple   tuple;
                                 75                 :                :     AclResult   aclresult;
                                 76                 :                :     char      **values;
                                 77                 :                : 
  544 michael@paquier.xyz        78                 :             12 :     InitMaterializedSRF(fcinfo, 0);
                                 79                 :                : 
                                 80                 :                :     /* Access the table */
 1490 tgl@sss.pgh.pa.us          81                 :             12 :     relrv = makeRangeVarFromNameList(textToQualifiedNameList(relname));
                                 82                 :             12 :     rel = relation_openrv(relrv, AccessShareLock);
                                 83                 :                : 
                                 84         [ -  + ]:             12 :     if (rel->rd_rel->relkind == RELKIND_PARTITIONED_TABLE)
 1490 tgl@sss.pgh.pa.us          85         [ #  # ]:UBC           0 :         ereport(ERROR,
                                 86                 :                :                 (errcode(ERRCODE_WRONG_OBJECT_TYPE),
                                 87                 :                :                  errmsg("\"%s\" is a partitioned table",
                                 88                 :                :                         RelationGetRelationName(rel)),
                                 89                 :                :                  errdetail("Partitioned tables do not contain rows.")));
 1490 tgl@sss.pgh.pa.us          90         [ -  + ]:CBC          12 :     else if (rel->rd_rel->relkind != RELKIND_RELATION)
 1490 tgl@sss.pgh.pa.us          91         [ #  # ]:UBC           0 :         ereport(ERROR,
                                 92                 :                :                 (errcode(ERRCODE_WRONG_OBJECT_TYPE),
                                 93                 :                :                  errmsg("\"%s\" is not a table",
                                 94                 :                :                         RelationGetRelationName(rel))));
  166 drowley@postgresql.o       95         [ -  + ]:CBC          12 :     else if (rel->rd_rel->relam != HEAP_TABLE_AM_OID)
  166 drowley@postgresql.o       96         [ #  # ]:UBC           0 :         ereport(ERROR,
                                 97                 :                :                 (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
                                 98                 :                :                  errmsg("only heap AM is supported")));
                                 99                 :                : 
                                100                 :                :     /*
                                101                 :                :      * check permissions: must have SELECT on table or be in
                                102                 :                :      * pg_stat_scan_tables
                                103                 :                :      */
 1490 tgl@sss.pgh.pa.us         104                 :CBC          12 :     aclresult = pg_class_aclcheck(RelationGetRelid(rel), GetUserId(),
                                105                 :                :                                   ACL_SELECT);
                                106         [ -  + ]:             12 :     if (aclresult != ACLCHECK_OK)
  748 mail@joeconway.com        107                 :UBC           0 :         aclresult = has_privs_of_role(GetUserId(), ROLE_PG_STAT_SCAN_TABLES) ? ACLCHECK_OK : ACLCHECK_NO_PRIV;
                                108                 :                : 
 1490 tgl@sss.pgh.pa.us         109         [ -  + ]:CBC          12 :     if (aclresult != ACLCHECK_OK)
 1490 tgl@sss.pgh.pa.us         110                 :UBC           0 :         aclcheck_error(aclresult, get_relkind_objtype(rel->rd_rel->relkind),
                                111                 :              0 :                        RelationGetRelationName(rel));
                                112                 :                : 
                                113                 :                :     /* Scan the relation */
 1490 tgl@sss.pgh.pa.us         114                 :CBC          12 :     scan = table_beginscan(rel, GetActiveSnapshot(), 0, NULL);
                                115                 :             12 :     hscan = (HeapScanDesc) scan;
                                116                 :                : 
  768 michael@paquier.xyz       117                 :             12 :     attinmeta = TupleDescGetAttInMetadata(rsinfo->setDesc);
                                118                 :                : 
                                119                 :             12 :     values = (char **) palloc(rsinfo->setDesc->natts * sizeof(char *));
                                120                 :                : 
 6566 ishii@postgresql.org      121         [ +  + ]:             36 :     while ((tuple = heap_getnext(scan, ForwardScanDirection)) != NULL)
                                122                 :                :     {
                                123                 :                :         TM_Result   htsu;
                                124                 :                :         TransactionId xmax;
                                125                 :                :         uint16      infomask;
                                126                 :                : 
                                127                 :                :         /* must hold a buffer lock to call HeapTupleSatisfiesUpdate */
 1861 andres@anarazel.de        128                 :             24 :         LockBuffer(hscan->rs_cbuf, BUFFER_LOCK_SHARE);
                                129                 :                : 
 3919 rhaas@postgresql.org      130                 :             24 :         htsu = HeapTupleSatisfiesUpdate(tuple,
                                131                 :                :                                         GetCurrentCommandId(false),
                                132                 :                :                                         hscan->rs_cbuf);
 4099 alvherre@alvh.no-ip.      133                 :             24 :         xmax = HeapTupleHeaderGetRawXmax(tuple->t_data);
                                134                 :             24 :         infomask = tuple->t_data->t_infomask;
                                135                 :                : 
                                136                 :                :         /*
                                137                 :                :          * A tuple is locked if HTSU returns BeingModified.
                                138                 :                :          */
 1849 andres@anarazel.de        139         [ +  + ]:             24 :         if (htsu == TM_BeingModified)
                                140                 :                :         {
 4099 alvherre@alvh.no-ip.      141                 :             22 :             values[Atnum_tid] = (char *) DirectFunctionCall1(tidout,
                                142                 :                :                                                              PointerGetDatum(&tuple->t_self));
                                143                 :                : 
                                144                 :             22 :             values[Atnum_xmax] = palloc(NCHARS * sizeof(char));
  858 peter@eisentraut.org      145                 :             22 :             snprintf(values[Atnum_xmax], NCHARS, "%u", xmax);
 4099 alvherre@alvh.no-ip.      146         [ +  + ]:             22 :             if (infomask & HEAP_XMAX_IS_MULTI)
                                147                 :                :             {
                                148                 :                :                 MultiXactMember *members;
                                149                 :                :                 int         nmembers;
                                150                 :              8 :                 bool        first = true;
                                151                 :                :                 bool        allow_old;
                                152                 :                : 
                                153                 :              8 :                 values[Atnum_ismulti] = pstrdup("true");
                                154                 :                : 
 2851                           155   [ +  -  +  +  :              8 :                 allow_old = HEAP_LOCKED_UPGRADED(infomask);
                                              -  + ]
 3547                           156                 :              8 :                 nmembers = GetMultiXactIdMembers(xmax, &members, allow_old,
                                157                 :                :                                                  false);
 4099                           158         [ -  + ]:              8 :                 if (nmembers == -1)
                                159                 :                :                 {
 4099 alvherre@alvh.no-ip.      160                 :UBC           0 :                     values[Atnum_xids] = "{0}";
                                161                 :              0 :                     values[Atnum_modes] = "{transient upgrade status}";
                                162                 :              0 :                     values[Atnum_pids] = "{0}";
                                163                 :                :                 }
                                164                 :                :                 else
                                165                 :                :                 {
                                166                 :                :                     int         j;
                                167                 :                : 
 4099 alvherre@alvh.no-ip.      168                 :CBC           8 :                     values[Atnum_xids] = palloc(NCHARS * nmembers);
                                169                 :              8 :                     values[Atnum_modes] = palloc(NCHARS * nmembers);
                                170                 :              8 :                     values[Atnum_pids] = palloc(NCHARS * nmembers);
                                171                 :                : 
                                172                 :              8 :                     strcpy(values[Atnum_xids], "{");
                                173                 :              8 :                     strcpy(values[Atnum_modes], "{");
                                174                 :              8 :                     strcpy(values[Atnum_pids], "{");
                                175                 :                : 
                                176         [ +  + ]:             24 :                     for (j = 0; j < nmembers; j++)
                                177                 :                :                     {
                                178                 :                :                         char        buf[NCHARS];
                                179                 :                : 
                                180         [ +  + ]:             16 :                         if (!first)
                                181                 :                :                         {
                                182                 :              8 :                             strcat(values[Atnum_xids], ",");
                                183                 :              8 :                             strcat(values[Atnum_modes], ",");
                                184                 :              8 :                             strcat(values[Atnum_pids], ",");
                                185                 :                :                         }
  858 peter@eisentraut.org      186                 :             16 :                         snprintf(buf, NCHARS, "%u", members[j].xid);
 4099 alvherre@alvh.no-ip.      187                 :             16 :                         strcat(values[Atnum_xids], buf);
                                188   [ +  +  +  +  :             16 :                         switch (members[j].status)
                                           +  +  - ]
                                189                 :                :                         {
                                190                 :              1 :                             case MultiXactStatusUpdate:
                                191                 :              1 :                                 snprintf(buf, NCHARS, "Update");
                                192                 :              1 :                                 break;
                                193                 :              1 :                             case MultiXactStatusNoKeyUpdate:
                                194                 :              1 :                                 snprintf(buf, NCHARS, "No Key Update");
                                195                 :              1 :                                 break;
                                196                 :              2 :                             case MultiXactStatusForUpdate:
                                197                 :              2 :                                 snprintf(buf, NCHARS, "For Update");
                                198                 :              2 :                                 break;
                                199                 :              2 :                             case MultiXactStatusForNoKeyUpdate:
                                200                 :              2 :                                 snprintf(buf, NCHARS, "For No Key Update");
                                201                 :              2 :                                 break;
                                202                 :              2 :                             case MultiXactStatusForShare:
  201 bruce@momjian.us          203                 :GNC           2 :                                 snprintf(buf, NCHARS, "For Share");
 4099 alvherre@alvh.no-ip.      204                 :CBC           2 :                                 break;
                                205                 :              8 :                             case MultiXactStatusForKeyShare:
  201 bruce@momjian.us          206                 :GNC           8 :                                 snprintf(buf, NCHARS, "For Key Share");
 4099 alvherre@alvh.no-ip.      207                 :CBC           8 :                                 break;
                                208                 :                :                         }
                                209                 :             16 :                         strcat(values[Atnum_modes], buf);
                                210                 :             16 :                         snprintf(buf, NCHARS, "%d",
                                211                 :             16 :                                  BackendXidGetPid(members[j].xid));
                                212                 :             16 :                         strcat(values[Atnum_pids], buf);
                                213                 :                : 
                                214                 :             16 :                         first = false;
                                215                 :                :                     }
                                216                 :                : 
                                217                 :              8 :                     strcat(values[Atnum_xids], "}");
                                218                 :              8 :                     strcat(values[Atnum_modes], "}");
                                219                 :              8 :                     strcat(values[Atnum_pids], "}");
                                220                 :                :                 }
                                221                 :                :             }
                                222                 :                :             else
                                223                 :                :             {
                                224                 :             14 :                 values[Atnum_ismulti] = pstrdup("false");
                                225                 :                : 
                                226                 :             14 :                 values[Atnum_xids] = palloc(NCHARS * sizeof(char));
  858 peter@eisentraut.org      227                 :             14 :                 snprintf(values[Atnum_xids], NCHARS, "{%u}", xmax);
                                228                 :                : 
 4099 alvherre@alvh.no-ip.      229                 :             14 :                 values[Atnum_modes] = palloc(NCHARS);
                                230         [ +  + ]:             14 :                 if (infomask & HEAP_XMAX_LOCK_ONLY)
                                231                 :                :                 {
                                232         [ +  + ]:             12 :                     if (HEAP_XMAX_IS_SHR_LOCKED(infomask))
                                233                 :              2 :                         snprintf(values[Atnum_modes], NCHARS, "{For Share}");
                                234         [ +  + ]:             10 :                     else if (HEAP_XMAX_IS_KEYSHR_LOCKED(infomask))
                                235                 :              6 :                         snprintf(values[Atnum_modes], NCHARS, "{For Key Share}");
                                236         [ +  - ]:              4 :                     else if (HEAP_XMAX_IS_EXCL_LOCKED(infomask))
                                237                 :                :                     {
 4091                           238         [ +  + ]:              4 :                         if (tuple->t_data->t_infomask2 & HEAP_KEYS_UPDATED)
                                239                 :              2 :                             snprintf(values[Atnum_modes], NCHARS, "{For Update}");
                                240                 :                :                         else
                                241                 :              2 :                             snprintf(values[Atnum_modes], NCHARS, "{For No Key Update}");
                                242                 :                :                     }
                                243                 :                :                     else
                                244                 :                :                         /* neither keyshare nor exclusive bit it set */
 4099 alvherre@alvh.no-ip.      245                 :UBC           0 :                         snprintf(values[Atnum_modes], NCHARS,
                                246                 :                :                                  "{transient upgrade status}");
                                247                 :                :                 }
                                248                 :                :                 else
                                249                 :                :                 {
 4099 alvherre@alvh.no-ip.      250         [ +  + ]:CBC           2 :                     if (tuple->t_data->t_infomask2 & HEAP_KEYS_UPDATED)
                                251                 :              1 :                         snprintf(values[Atnum_modes], NCHARS, "{Update}");
                                252                 :                :                     else
 4091                           253                 :              1 :                         snprintf(values[Atnum_modes], NCHARS, "{No Key Update}");
                                254                 :                :                 }
                                255                 :                : 
 4099                           256                 :             14 :                 values[Atnum_pids] = palloc(NCHARS * sizeof(char));
                                257                 :             14 :                 snprintf(values[Atnum_pids], NCHARS, "{%d}",
                                258                 :                :                          BackendXidGetPid(xmax));
                                259                 :                :             }
                                260                 :                : 
 1861 andres@anarazel.de        261                 :             22 :             LockBuffer(hscan->rs_cbuf, BUFFER_LOCK_UNLOCK);
                                262                 :                : 
                                263                 :                :             /* build a tuple */
 6566 ishii@postgresql.org      264                 :             22 :             tuple = BuildTupleFromCStrings(attinmeta, values);
  768 michael@paquier.xyz       265                 :             22 :             tuplestore_puttuple(rsinfo->setResult, tuple);
                                266                 :                :         }
                                267                 :                :         else
                                268                 :                :         {
 1861 andres@anarazel.de        269                 :              2 :             LockBuffer(hscan->rs_cbuf, BUFFER_LOCK_UNLOCK);
                                270                 :                :         }
                                271                 :                :     }
                                272                 :                : 
                                273                 :             12 :     table_endscan(scan);
 1490 tgl@sss.pgh.pa.us         274                 :             12 :     table_close(rel, AccessShareLock);
                                275                 :             12 :     return (Datum) 0;
                                276                 :                : }
        

Generated by: LCOV version 2.1-beta2-3-g6141622