LCOV - differential code coverage report
Current view: top level - contrib/pageinspect - brinfuncs.c (source / functions) Coverage Total Hit UBC CBC
Current: c70b6db34ffeab48beef1fb4ce61bcad3772b8dd vs 06473f5a344df8c9594ead90a609b86f6724cff8 Lines: 86.5 % 171 148 23 148
Current Date: 2025-09-06 07:49:51 +0900 Functions: 100.0 % 9 9 9
Baseline: lcov-20250906-005545-baseline Branches: 67.1 % 85 57 28 57
Baseline Date: 2025-09-05 08:21:35 +0100 Line coverage date bins:
Legend: Lines:     hit not hit
Branches: + taken - not taken # not executed
(30,360] days: 100.0 % 2 2 2
(360..) days: 86.4 % 169 146 23 146
Function coverage date bins:
(360..) days: 100.0 % 9 9 9
Branch coverage date bins:
(30,360] days: 75.0 % 4 3 1 3
(360..) days: 66.7 % 81 54 27 54

 Age         Owner                    Branch data    TLA  Line data    Source code
                                  1                 :                : /*
                                  2                 :                :  * brinfuncs.c
                                  3                 :                :  *      Functions to investigate BRIN indexes
                                  4                 :                :  *
                                  5                 :                :  * Copyright (c) 2014-2025, PostgreSQL Global Development Group
                                  6                 :                :  *
                                  7                 :                :  * IDENTIFICATION
                                  8                 :                :  *      contrib/pageinspect/brinfuncs.c
                                  9                 :                :  */
                                 10                 :                : #include "postgres.h"
                                 11                 :                : 
                                 12                 :                : #include "access/brin_internal.h"
                                 13                 :                : #include "access/brin_page.h"
                                 14                 :                : #include "access/brin_tuple.h"
                                 15                 :                : #include "access/htup_details.h"
                                 16                 :                : #include "catalog/pg_am_d.h"
                                 17                 :                : #include "catalog/pg_type.h"
                                 18                 :                : #include "funcapi.h"
                                 19                 :                : #include "lib/stringinfo.h"
                                 20                 :                : #include "miscadmin.h"
                                 21                 :                : #include "pageinspect.h"
                                 22                 :                : #include "utils/builtins.h"
                                 23                 :                : #include "utils/lsyscache.h"
                                 24                 :                : #include "utils/rel.h"
                                 25                 :                : 
 3956 alvherre@alvh.no-ip.       26                 :CBC           7 : PG_FUNCTION_INFO_V1(brin_page_type);
                                 27                 :             31 : PG_FUNCTION_INFO_V1(brin_page_items);
                                 28                 :              8 : PG_FUNCTION_INFO_V1(brin_metapage_info);
                                 29                 :              7 : PG_FUNCTION_INFO_V1(brin_revmap_data);
                                 30                 :                : 
                                 31                 :                : #define IS_BRIN(r) ((r)->rd_rel->relam == BRIN_AM_OID)
                                 32                 :                : 
                                 33                 :                : typedef struct brin_column_state
                                 34                 :                : {
                                 35                 :                :     int         nstored;
                                 36                 :                :     FmgrInfo    outputFn[FLEXIBLE_ARRAY_MEMBER];
                                 37                 :                : } brin_column_state;
                                 38                 :                : 
                                 39                 :                : 
                                 40                 :                : static Page verify_brin_page(bytea *raw_page, uint16 type,
                                 41                 :                :                              const char *strtype);
                                 42                 :                : 
                                 43                 :                : Datum
                                 44                 :              5 : brin_page_type(PG_FUNCTION_ARGS)
                                 45                 :                : {
                                 46                 :              5 :     bytea      *raw_page = PG_GETARG_BYTEA_P(0);
                                 47                 :                :     Page        page;
                                 48                 :                :     char       *type;
                                 49                 :                : 
 3449                            50         [ -  + ]:              5 :     if (!superuser())
 3449 alvherre@alvh.no-ip.       51         [ #  # ]:UBC           0 :         ereport(ERROR,
                                 52                 :                :                 (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
                                 53                 :                :                  errmsg("must be superuser to use raw page functions")));
                                 54                 :                : 
 1270 michael@paquier.xyz        55                 :CBC           5 :     page = get_page_from_raw(raw_page);
                                 56                 :                : 
 1241                            57         [ +  + ]:              5 :     if (PageIsNew(page))
                                 58                 :              1 :         PG_RETURN_NULL();
                                 59                 :                : 
                                 60                 :                :     /* verify the special space has the expected size */
 1259                            61         [ +  + ]:              4 :     if (PageGetSpecialSize(page) != MAXALIGN(sizeof(BrinSpecialSpace)))
 1213 tgl@sss.pgh.pa.us          62         [ +  - ]:              1 :         ereport(ERROR,
                                 63                 :                :                 (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
                                 64                 :                :                  errmsg("input page is not a valid %s page", "BRIN"),
                                 65                 :                :                  errdetail("Expected special size %d, got %d.",
                                 66                 :                :                            (int) MAXALIGN(sizeof(BrinSpecialSpace)),
                                 67                 :                :                            (int) PageGetSpecialSize(page))));
                                 68                 :                : 
 3833 alvherre@alvh.no-ip.       69   [ +  +  +  - ]:              3 :     switch (BrinPageType(page))
                                 70                 :                :     {
 3956                            71                 :              1 :         case BRIN_PAGETYPE_META:
                                 72                 :              1 :             type = "meta";
                                 73                 :              1 :             break;
                                 74                 :              1 :         case BRIN_PAGETYPE_REVMAP:
                                 75                 :              1 :             type = "revmap";
                                 76                 :              1 :             break;
                                 77                 :              1 :         case BRIN_PAGETYPE_REGULAR:
                                 78                 :              1 :             type = "regular";
                                 79                 :              1 :             break;
 3956 alvherre@alvh.no-ip.       80                 :UBC           0 :         default:
 3833                            81                 :              0 :             type = psprintf("unknown (%02x)", BrinPageType(page));
 3956                            82                 :              0 :             break;
                                 83                 :                :     }
                                 84                 :                : 
 3956 alvherre@alvh.no-ip.       85                 :CBC           3 :     PG_RETURN_TEXT_P(cstring_to_text(type));
                                 86                 :                : }
                                 87                 :                : 
                                 88                 :                : /*
                                 89                 :                :  * Verify that the given bytea contains a BRIN page of the indicated page
                                 90                 :                :  * type, or die in the attempt.  A pointer to the page is returned.
                                 91                 :                :  */
                                 92                 :                : static Page
                                 93                 :             45 : verify_brin_page(bytea *raw_page, uint16 type, const char *strtype)
                                 94                 :                : {
 1270 michael@paquier.xyz        95                 :             45 :     Page        page = get_page_from_raw(raw_page);
                                 96                 :                : 
 1241                            97         [ +  + ]:             45 :     if (PageIsNew(page))
                                 98                 :              3 :         return page;
                                 99                 :                : 
                                100                 :                :     /* verify the special space has the expected size */
 1259                           101         [ +  + ]:             42 :     if (PageGetSpecialSize(page) != MAXALIGN(sizeof(BrinSpecialSpace)))
 1213 tgl@sss.pgh.pa.us         102         [ +  - ]:              3 :         ereport(ERROR,
                                103                 :                :                 (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
                                104                 :                :                  errmsg("input page is not a valid %s page", "BRIN"),
                                105                 :                :                  errdetail("Expected special size %d, got %d.",
                                106                 :                :                            (int) MAXALIGN(sizeof(BrinSpecialSpace)),
                                107                 :                :                            (int) PageGetSpecialSize(page))));
                                108                 :                : 
                                109                 :                :     /* verify the special space says this page is what we want */
 3833 alvherre@alvh.no-ip.      110         [ +  + ]:             39 :     if (BrinPageType(page) != type)
 3956                           111         [ +  - ]:              2 :         ereport(ERROR,
                                112                 :                :                 (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
                                113                 :                :                  errmsg("page is not a BRIN page of type \"%s\"", strtype),
                                114                 :                :                  errdetail("Expected special type %08x, got %08x.",
                                115                 :                :                            type, BrinPageType(page))));
                                116                 :                : 
                                117                 :             37 :     return page;
                                118                 :                : }
                                119                 :                : 
                                120                 :                : /* Number of output arguments (columns) for brin_page_items() */
                                121                 :                : #define BRIN_PAGE_ITEMS_V1_12   8
                                122                 :                : 
                                123                 :                : /*
                                124                 :                :  * Extract all item values from a BRIN index page
                                125                 :                :  *
                                126                 :                :  * Usage: SELECT * FROM brin_page_items(get_raw_page('idx', 1), 'idx'::regclass);
                                127                 :                :  */
                                128                 :                : Datum
                                129                 :             28 : brin_page_items(PG_FUNCTION_ARGS)
                                130                 :                : {
 3677                           131                 :             28 :     bytea      *raw_page = PG_GETARG_BYTEA_P(0);
                                132                 :             28 :     Oid         indexRelid = PG_GETARG_OID(1);
                                133                 :             28 :     ReturnSetInfo *rsinfo = (ReturnSetInfo *) fcinfo->resultinfo;
                                134                 :                :     Relation    indexRel;
                                135                 :                :     brin_column_state **columns;
                                136                 :                :     BrinDesc   *bdesc;
                                137                 :                :     BrinMemTuple *dtup;
                                138                 :                :     Page        page;
                                139                 :                :     OffsetNumber offset;
                                140                 :                :     AttrNumber  attno;
                                141                 :                :     bool        unusedItem;
                                142                 :                : 
 3956                           143         [ -  + ]:             28 :     if (!superuser())
 3956 alvherre@alvh.no-ip.      144         [ #  # ]:UBC           0 :         ereport(ERROR,
                                145                 :                :                 (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
                                146                 :                :                  errmsg("must be superuser to use raw page functions")));
                                147                 :                : 
 1054 michael@paquier.xyz       148                 :CBC          28 :     InitMaterializedSRF(fcinfo, 0);
                                149                 :                : 
                                150                 :                :     /*
                                151                 :                :      * Version 1.12 added a new output column for the empty range flag. But as
                                152                 :                :      * it was added in the middle, it may cause crashes with function
                                153                 :                :      * definitions from older versions of the extension.
                                154                 :                :      *
                                155                 :                :      * There is no way to reliably avoid the problems created by the old
                                156                 :                :      * function definition at this point, so insist that the user update the
                                157                 :                :      * extension.
                                158                 :                :      */
  263 tomas.vondra@postgre      159         [ +  + ]:             28 :     if (rsinfo->setDesc->natts < BRIN_PAGE_ITEMS_V1_12)
                                160         [ +  - ]:              1 :         ereport(ERROR,
                                161                 :                :                 (errcode(ERRCODE_INVALID_FUNCTION_DEFINITION),
                                162                 :                :                  errmsg("function has wrong number of declared columns"),
                                163                 :                :                  errhint("To resolve the problem, update the \"pageinspect\" extension to the latest version.")));
                                164                 :                : 
 3677 alvherre@alvh.no-ip.      165                 :             27 :     indexRel = index_open(indexRelid, AccessShareLock);
                                166                 :                : 
 1270 michael@paquier.xyz       167         [ +  + ]:             27 :     if (!IS_BRIN(indexRel))
                                168         [ +  - ]:              1 :         ereport(ERROR,
                                169                 :                :                 (errcode(ERRCODE_WRONG_OBJECT_TYPE),
                                170                 :                :                  errmsg("\"%s\" is not a %s index",
                                171                 :                :                         RelationGetRelationName(indexRel), "BRIN")));
                                172                 :                : 
 3677 alvherre@alvh.no-ip.      173                 :             26 :     bdesc = brin_build_desc(indexRel);
                                174                 :                : 
                                175                 :                :     /* minimally verify the page we got */
                                176                 :             26 :     page = verify_brin_page(raw_page, BRIN_PAGETYPE_REGULAR, "regular");
                                177                 :                : 
 1241 michael@paquier.xyz       178         [ +  + ]:             25 :     if (PageIsNew(page))
                                179                 :                :     {
                                180                 :              1 :         brin_free_desc(bdesc);
                                181                 :              1 :         index_close(indexRel, AccessShareLock);
                                182                 :              1 :         PG_RETURN_NULL();
                                183                 :                :     }
                                184                 :                : 
                                185                 :                :     /*
                                186                 :                :      * Initialize output functions for all indexed datatypes; simplifies
                                187                 :                :      * calling them later.
                                188                 :                :      */
 3677 alvherre@alvh.no-ip.      189                 :             24 :     columns = palloc(sizeof(brin_column_state *) * RelationGetDescr(indexRel)->natts);
                                190         [ +  + ]:             72 :     for (attno = 1; attno <= bdesc->bd_tupdesc->natts; attno++)
                                191                 :                :     {
                                192                 :                :         Oid         output;
                                193                 :                :         bool        isVarlena;
                                194                 :                :         BrinOpcInfo *opcinfo;
                                195                 :                :         int         i;
                                196                 :                :         brin_column_state *column;
                                197                 :                : 
                                198                 :             48 :         opcinfo = bdesc->bd_info[attno - 1];
                                199                 :             48 :         column = palloc(offsetof(brin_column_state, outputFn) +
                                200                 :             48 :                         sizeof(FmgrInfo) * opcinfo->oi_nstored);
                                201                 :                : 
                                202                 :             48 :         column->nstored = opcinfo->oi_nstored;
                                203         [ +  + ]:            128 :         for (i = 0; i < opcinfo->oi_nstored; i++)
                                204                 :                :         {
                                205                 :             80 :             getTypeOutputInfo(opcinfo->oi_typcache[i]->type_id, &output, &isVarlena);
                                206                 :             80 :             fmgr_info(output, &column->outputFn[i]);
                                207                 :                :         }
                                208                 :                : 
                                209                 :             48 :         columns[attno - 1] = column;
                                210                 :                :     }
                                211                 :                : 
                                212                 :             24 :     offset = FirstOffsetNumber;
                                213                 :             24 :     unusedItem = false;
                                214                 :             24 :     dtup = NULL;
                                215                 :                :     for (;;)
 3956                           216                 :            612 :     {
                                217                 :                :         Datum       values[8];
  841 tomas.vondra@postgre      218                 :            636 :         bool        nulls[8] = {0};
                                219                 :                : 
                                220                 :                :         /*
                                221                 :                :          * This loop is called once for every attribute of every tuple in the
                                222                 :                :          * page.  At the start of a tuple, we get a NULL dtup; that's our
                                223                 :                :          * signal for obtaining and decoding the next one.  If that's not the
                                224                 :                :          * case, we output the next attribute.
                                225                 :                :          */
 3677 alvherre@alvh.no-ip.      226         [ +  + ]:            636 :         if (dtup == NULL)
                                227                 :                :         {
                                228                 :                :             ItemId      itemId;
                                229                 :                : 
                                230                 :                :             /* verify item status: if there's no data, we can't decode */
                                231                 :            180 :             itemId = PageGetItemId(page, offset);
 3956                           232         [ +  - ]:            180 :             if (ItemIdIsUsed(itemId))
                                233                 :                :             {
 3677                           234                 :            180 :                 dtup = brin_deform_tuple(bdesc,
 2999 tgl@sss.pgh.pa.us         235                 :            180 :                                          (BrinTuple *) PageGetItem(page, itemId),
                                236                 :                :                                          NULL);
 3677 alvherre@alvh.no-ip.      237                 :            180 :                 attno = 1;
                                238                 :            180 :                 unusedItem = false;
                                239                 :                :             }
                                240                 :                :             else
 3677 alvherre@alvh.no-ip.      241                 :UBC           0 :                 unusedItem = true;
                                242                 :                :         }
                                243                 :                :         else
 3677 alvherre@alvh.no-ip.      244                 :CBC         456 :             attno++;
                                245                 :                : 
                                246         [ -  + ]:            636 :         if (unusedItem)
                                247                 :                :         {
 3677 alvherre@alvh.no-ip.      248                 :UBC           0 :             values[0] = UInt16GetDatum(offset);
 3956                           249                 :              0 :             nulls[1] = true;
                                250                 :              0 :             nulls[2] = true;
                                251                 :              0 :             nulls[3] = true;
                                252                 :              0 :             nulls[4] = true;
                                253                 :              0 :             nulls[5] = true;
                                254                 :              0 :             nulls[6] = true;
  841 tomas.vondra@postgre      255                 :              0 :             nulls[7] = true;
                                256                 :                :         }
                                257                 :                :         else
                                258                 :                :         {
 3677 alvherre@alvh.no-ip.      259                 :CBC         636 :             int         att = attno - 1;
                                260                 :                : 
                                261                 :            636 :             values[0] = UInt16GetDatum(offset);
 1278 michael@paquier.xyz       262      [ +  -  - ]:            636 :             switch (TupleDescAttr(rsinfo->setDesc, 1)->atttypid)
                                263                 :                :             {
 1691 peter@eisentraut.org      264                 :            636 :                 case INT8OID:
                                265                 :            636 :                     values[1] = Int64GetDatum((int64) dtup->bt_blkno);
                                266                 :            636 :                     break;
 1691 peter@eisentraut.org      267                 :UBC           0 :                 case INT4OID:
                                268                 :                :                     /* support for old extension version */
                                269                 :              0 :                     values[1] = UInt32GetDatum(dtup->bt_blkno);
                                270                 :              0 :                     break;
                                271                 :              0 :                 default:
                                272         [ #  # ]:              0 :                     elog(ERROR, "incorrect output types");
                                273                 :                :             }
 3677 alvherre@alvh.no-ip.      274                 :CBC         636 :             values[2] = UInt16GetDatum(attno);
                                275                 :            636 :             values[3] = BoolGetDatum(dtup->bt_columns[att].bv_allnulls);
                                276                 :            636 :             values[4] = BoolGetDatum(dtup->bt_columns[att].bv_hasnulls);
                                277                 :            636 :             values[5] = BoolGetDatum(dtup->bt_placeholder);
  841 tomas.vondra@postgre      278                 :            636 :             values[6] = BoolGetDatum(dtup->bt_empty_range);
 3677 alvherre@alvh.no-ip.      279         [ +  + ]:            636 :             if (!dtup->bt_columns[att].bv_allnulls)
                                280                 :                :             {
                                281                 :            526 :                 BrinValues *bvalues = &dtup->bt_columns[att];
                                282                 :                :                 StringInfoData s;
                                283                 :                :                 bool        first;
                                284                 :                :                 int         i;
                                285                 :                : 
 3956                           286                 :            526 :                 initStringInfo(&s);
                                287                 :            526 :                 appendStringInfoChar(&s, '{');
                                288                 :                : 
                                289                 :            526 :                 first = true;
 3677                           290         [ +  + ]:           1330 :                 for (i = 0; i < columns[att]->nstored; i++)
                                291                 :                :                 {
                                292                 :                :                     char       *val;
                                293                 :                : 
 3956                           294         [ +  + ]:            804 :                     if (!first)
                                295                 :            278 :                         appendStringInfoString(&s, " .. ");
                                296                 :            804 :                     first = false;
 3677                           297                 :            804 :                     val = OutputFunctionCall(&columns[att]->outputFn[i],
 3956                           298                 :            804 :                                              bvalues->bv_values[i]);
                                299                 :            804 :                     appendStringInfoString(&s, val);
                                300                 :            804 :                     pfree(val);
                                301                 :                :                 }
                                302                 :            526 :                 appendStringInfoChar(&s, '}');
                                303                 :                : 
  841 tomas.vondra@postgre      304                 :            526 :                 values[7] = CStringGetTextDatum(s.data);
 3956 alvherre@alvh.no-ip.      305                 :            526 :                 pfree(s.data);
                                306                 :                :             }
                                307                 :                :             else
                                308                 :                :             {
  841 tomas.vondra@postgre      309                 :            110 :                 nulls[7] = true;
                                310                 :                :             }
                                311                 :                :         }
                                312                 :                : 
 1278 michael@paquier.xyz       313                 :            636 :         tuplestore_putvalues(rsinfo->setResult, rsinfo->setDesc, values, nulls);
                                314                 :                : 
                                315                 :                :         /*
                                316                 :                :          * If the item was unused, jump straight to the next one; otherwise,
                                317                 :                :          * the only cleanup needed here is to set our signal to go to the next
                                318                 :                :          * tuple in the following iteration, by freeing the current one.
                                319                 :                :          */
 3677 alvherre@alvh.no-ip.      320         [ -  + ]:            636 :         if (unusedItem)
 3677 alvherre@alvh.no-ip.      321                 :UBC           0 :             offset = OffsetNumberNext(offset);
 3677 alvherre@alvh.no-ip.      322         [ +  + ]:CBC         636 :         else if (attno >= bdesc->bd_tupdesc->natts)
                                323                 :                :         {
                                324                 :            180 :             pfree(dtup);
                                325                 :            180 :             dtup = NULL;
                                326                 :            180 :             offset = OffsetNumberNext(offset);
                                327                 :                :         }
                                328                 :                : 
                                329                 :                :         /*
                                330                 :                :          * If we're beyond the end of the page, we're done.
                                331                 :                :          */
                                332         [ +  + ]:            636 :         if (offset > PageGetMaxOffsetNumber(page))
                                333                 :             24 :             break;
                                334                 :                :     }
                                335                 :                : 
                                336                 :             24 :     brin_free_desc(bdesc);
                                337                 :             24 :     index_close(indexRel, AccessShareLock);
                                338                 :                : 
                                339                 :             24 :     return (Datum) 0;
                                340                 :                : }
                                341                 :                : 
                                342                 :                : Datum
 3956                           343                 :             15 : brin_metapage_info(PG_FUNCTION_ARGS)
                                344                 :                : {
                                345                 :             15 :     bytea      *raw_page = PG_GETARG_BYTEA_P(0);
                                346                 :                :     Page        page;
                                347                 :                :     BrinMetaPageData *meta;
                                348                 :                :     TupleDesc   tupdesc;
                                349                 :                :     Datum       values[4];
 1148 peter@eisentraut.org      350                 :             15 :     bool        nulls[4] = {0};
                                351                 :                :     HeapTuple   htup;
                                352                 :                : 
 3449 alvherre@alvh.no-ip.      353         [ -  + ]:             15 :     if (!superuser())
 3449 alvherre@alvh.no-ip.      354         [ #  # ]:UBC           0 :         ereport(ERROR,
                                355                 :                :                 (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
                                356                 :                :                  errmsg("must be superuser to use raw page functions")));
                                357                 :                : 
 3956 alvherre@alvh.no-ip.      358                 :CBC          15 :     page = verify_brin_page(raw_page, BRIN_PAGETYPE_META, "metapage");
                                359                 :                : 
 1241 michael@paquier.xyz       360         [ +  + ]:             13 :     if (PageIsNew(page))
                                361                 :              1 :         PG_RETURN_NULL();
                                362                 :                : 
                                363                 :                :     /* Build a tuple descriptor for our result type */
 3956 alvherre@alvh.no-ip.      364         [ -  + ]:             12 :     if (get_call_result_type(fcinfo, NULL, &tupdesc) != TYPEFUNC_COMPOSITE)
 3956 alvherre@alvh.no-ip.      365         [ #  # ]:UBC           0 :         elog(ERROR, "return type must be a row type");
 3956 alvherre@alvh.no-ip.      366                 :CBC          12 :     tupdesc = BlessTupleDesc(tupdesc);
                                367                 :                : 
                                368                 :                :     /* Extract values from the metapage */
                                369                 :             12 :     meta = (BrinMetaPageData *) PageGetContents(page);
                                370                 :             12 :     values[0] = CStringGetTextDatum(psprintf("0x%08X", meta->brinMagic));
                                371                 :             12 :     values[1] = Int32GetDatum(meta->brinVersion);
                                372                 :             12 :     values[2] = Int32GetDatum(meta->pagesPerRange);
                                373                 :             12 :     values[3] = Int64GetDatum(meta->lastRevmapPage);
                                374                 :                : 
                                375                 :             12 :     htup = heap_form_tuple(tupdesc, values, nulls);
                                376                 :                : 
                                377                 :             12 :     PG_RETURN_DATUM(HeapTupleGetDatum(htup));
                                378                 :                : }
                                379                 :                : 
                                380                 :                : /*
                                381                 :                :  * Return the TID array stored in a BRIN revmap page
                                382                 :                :  */
                                383                 :                : Datum
                                384                 :           1364 : brin_revmap_data(PG_FUNCTION_ARGS)
                                385                 :                : {
                                386                 :                :     struct
                                387                 :                :     {
                                388                 :                :         ItemPointerData *tids;
                                389                 :                :         int         idx;
                                390                 :                :     }          *state;
                                391                 :                :     FuncCallContext *fctx;
                                392                 :                : 
                                393         [ -  + ]:           1364 :     if (!superuser())
 3956 alvherre@alvh.no-ip.      394         [ #  # ]:UBC           0 :         ereport(ERROR,
                                395                 :                :                 (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
                                396                 :                :                  errmsg("must be superuser to use raw page functions")));
                                397                 :                : 
 3956 alvherre@alvh.no-ip.      398         [ +  + ]:CBC        1364 :     if (SRF_IS_FIRSTCALL())
                                399                 :                :     {
                                400                 :              4 :         bytea      *raw_page = PG_GETARG_BYTEA_P(0);
                                401                 :                :         MemoryContext mctx;
                                402                 :                :         Page        page;
                                403                 :                : 
                                404                 :                :         /* create a function context for cross-call persistence */
                                405                 :              4 :         fctx = SRF_FIRSTCALL_INIT();
                                406                 :                : 
                                407                 :                :         /* switch to memory context appropriate for multiple function calls */
                                408                 :              4 :         mctx = MemoryContextSwitchTo(fctx->multi_call_memory_ctx);
                                409                 :                : 
                                410                 :                :         /* minimally verify the page we got */
 1270 michael@paquier.xyz       411                 :              4 :         page = verify_brin_page(raw_page, BRIN_PAGETYPE_REVMAP, "revmap");
                                412                 :                : 
 1241                           413         [ +  + ]:              2 :         if (PageIsNew(page))
                                414                 :                :         {
                                415                 :              1 :             MemoryContextSwitchTo(mctx);
                                416                 :              1 :             PG_RETURN_NULL();
                                417                 :                :         }
                                418                 :                : 
 3956 alvherre@alvh.no-ip.      419                 :              1 :         state = palloc(sizeof(*state));
                                420                 :              1 :         state->tids = ((RevmapContents *) PageGetContents(page))->rm_tids;
                                421                 :              1 :         state->idx = 0;
                                422                 :                : 
                                423                 :              1 :         fctx->user_fctx = state;
                                424                 :                : 
                                425                 :              1 :         MemoryContextSwitchTo(mctx);
                                426                 :                :     }
                                427                 :                : 
                                428                 :           1361 :     fctx = SRF_PERCALL_SETUP();
                                429                 :           1361 :     state = fctx->user_fctx;
                                430                 :                : 
                                431         [ +  + ]:           1361 :     if (state->idx < REVMAP_PAGE_MAXITEMS)
                                432                 :           1360 :         SRF_RETURN_NEXT(fctx, PointerGetDatum(&state->tids[state->idx++]));
                                433                 :                : 
                                434                 :              1 :     SRF_RETURN_DONE(fctx);
                                435                 :                : }
        

Generated by: LCOV version 2.4-beta