LCOV - differential code coverage report
Current view: top level - contrib/pageinspect - brinfuncs.c (source / functions) Coverage Total Hit UBC GBC CBC
Current: Differential Code Coverage 16@8cea358b128 vs 17@8cea358b128 Lines: 86.4 % 169 146 23 1 145
Current Date: 2024-04-14 14:21:10 Functions: 100.0 % 9 9 9
Baseline: 16@8cea358b128 Branches: 66.7 % 81 54 27 2 52
Baseline Date: 2024-04-14 14:21:09 Line coverage date bins:
Legend: Lines: hit not hit | Branches: + taken - not taken # not executed (240..) days: 86.4 % 169 146 23 1 145
Function coverage date bins:
(240..) days: 100.0 % 9 9 9
Branch coverage date bins:
(240..) days: 66.7 % 81 54 27 2 52

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

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