LCOV - code coverage report
Current view: top level - src/test/modules/dummy_index_am - dummy_index_am.c (source / functions) Coverage Total Hit
Test: Code coverage Lines: 0.0 % 85 0
Test Date: 2026-01-26 10:56:24 Functions: 0.0 % 17 0
Legend: Lines:     hit not hit

            Line data    Source code
       1              : /*-------------------------------------------------------------------------
       2              :  *
       3              :  * dummy_index_am.c
       4              :  *              Index AM template main file.
       5              :  *
       6              :  * Portions Copyright (c) 1996-2026, PostgreSQL Global Development Group
       7              :  * Portions Copyright (c) 1994, Regents of the University of California
       8              :  *
       9              :  * IDENTIFICATION
      10              :  *        src/test/modules/dummy_index_am/dummy_index_am.c
      11              :  *
      12              :  *-------------------------------------------------------------------------
      13              :  */
      14              : #include "postgres.h"
      15              : 
      16              : #include "access/amapi.h"
      17              : #include "access/reloptions.h"
      18              : #include "catalog/index.h"
      19              : #include "commands/vacuum.h"
      20              : #include "nodes/pathnodes.h"
      21              : 
      22            0 : PG_MODULE_MAGIC;
      23              : 
      24              : /* parse table for fillRelOptions */
      25              : static relopt_parse_elt di_relopt_tab[8];
      26              : 
      27              : /* Kind of relation options for dummy index */
      28              : static relopt_kind di_relopt_kind;
      29              : 
      30              : typedef enum DummyAmEnum
      31              : {
      32              :         DUMMY_AM_ENUM_ONE,
      33              :         DUMMY_AM_ENUM_TWO,
      34              : }                       DummyAmEnum;
      35              : 
      36              : /* Dummy index options */
      37              : typedef struct DummyIndexOptions
      38              : {
      39              :         int32           vl_len_;                /* varlena header (do not touch directly!) */
      40              :         int                     option_int;
      41              :         double          option_real;
      42              :         bool            option_bool;
      43              :         pg_ternary      option_ternary_1;
      44              :         DummyAmEnum option_enum;
      45              :         int                     option_string_val_offset;
      46              :         int                     option_string_null_offset;
      47              : }                       DummyIndexOptions;
      48              : 
      49              : static relopt_enum_elt_def dummyAmEnumValues[] =
      50              : {
      51              :         {"one", DUMMY_AM_ENUM_ONE},
      52              :         {"two", DUMMY_AM_ENUM_TWO},
      53              :         {(const char *) NULL}           /* list terminator */
      54              : };
      55              : 
      56              : /* Handler for index AM */
      57            0 : PG_FUNCTION_INFO_V1(dihandler);
      58              : 
      59              : /*
      60              :  * Validation function for string relation options.
      61              :  */
      62              : static void
      63            0 : validate_string_option(const char *value)
      64              : {
      65            0 :         ereport(NOTICE,
      66              :                         (errmsg("new option value for string parameter %s",
      67              :                                         value ? value : "NULL")));
      68            0 : }
      69              : 
      70              : /*
      71              :  * This function creates a full set of relation option types,
      72              :  * with various patterns.
      73              :  */
      74              : static void
      75            0 : create_reloptions_table(void)
      76              : {
      77            0 :         int                     i = 0;
      78              : 
      79            0 :         di_relopt_kind = add_reloption_kind();
      80              : 
      81            0 :         add_int_reloption(di_relopt_kind, "option_int",
      82              :                                           "Integer option for dummy_index_am",
      83              :                                           10, -10, 100, AccessExclusiveLock);
      84            0 :         di_relopt_tab[i].optname = "option_int";
      85            0 :         di_relopt_tab[i].opttype = RELOPT_TYPE_INT;
      86            0 :         di_relopt_tab[i].offset = offsetof(DummyIndexOptions, option_int);
      87            0 :         i++;
      88              : 
      89            0 :         add_real_reloption(di_relopt_kind, "option_real",
      90              :                                            "Real option for dummy_index_am",
      91              :                                            3.1415, -10, 100, AccessExclusiveLock);
      92            0 :         di_relopt_tab[i].optname = "option_real";
      93            0 :         di_relopt_tab[i].opttype = RELOPT_TYPE_REAL;
      94            0 :         di_relopt_tab[i].offset = offsetof(DummyIndexOptions, option_real);
      95            0 :         i++;
      96              : 
      97            0 :         add_bool_reloption(di_relopt_kind, "option_bool",
      98              :                                            "Boolean option for dummy_index_am",
      99              :                                            true, AccessExclusiveLock);
     100            0 :         di_relopt_tab[i].optname = "option_bool";
     101            0 :         di_relopt_tab[i].opttype = RELOPT_TYPE_BOOL;
     102            0 :         di_relopt_tab[i].offset = offsetof(DummyIndexOptions, option_bool);
     103            0 :         i++;
     104              : 
     105            0 :         add_ternary_reloption(di_relopt_kind, "option_ternary_1",
     106              :                                                   "One ternary option for dummy_index_am",
     107              :                                                   AccessExclusiveLock);
     108            0 :         di_relopt_tab[i].optname = "option_ternary_1";
     109            0 :         di_relopt_tab[i].opttype = RELOPT_TYPE_TERNARY;
     110            0 :         di_relopt_tab[i].offset = offsetof(DummyIndexOptions, option_ternary_1);
     111            0 :         i++;
     112              : 
     113            0 :         add_enum_reloption(di_relopt_kind, "option_enum",
     114              :                                            "Enum option for dummy_index_am",
     115              :                                            dummyAmEnumValues,
     116              :                                            DUMMY_AM_ENUM_ONE,
     117              :                                            "Valid values are \"one\" and \"two\".",
     118              :                                            AccessExclusiveLock);
     119            0 :         di_relopt_tab[i].optname = "option_enum";
     120            0 :         di_relopt_tab[i].opttype = RELOPT_TYPE_ENUM;
     121            0 :         di_relopt_tab[i].offset = offsetof(DummyIndexOptions, option_enum);
     122            0 :         i++;
     123              : 
     124            0 :         add_string_reloption(di_relopt_kind, "option_string_val",
     125              :                                                  "String option for dummy_index_am with non-NULL default",
     126              :                                                  "DefaultValue", &validate_string_option,
     127              :                                                  AccessExclusiveLock);
     128            0 :         di_relopt_tab[i].optname = "option_string_val";
     129            0 :         di_relopt_tab[i].opttype = RELOPT_TYPE_STRING;
     130            0 :         di_relopt_tab[i].offset = offsetof(DummyIndexOptions,
     131              :                                                                            option_string_val_offset);
     132            0 :         i++;
     133              : 
     134              :         /*
     135              :          * String option for dummy_index_am with NULL default, and without
     136              :          * description.
     137              :          */
     138            0 :         add_string_reloption(di_relopt_kind, "option_string_null",
     139              :                                                  NULL,  /* description */
     140              :                                                  NULL, &validate_string_option,
     141              :                                                  AccessExclusiveLock);
     142            0 :         di_relopt_tab[i].optname = "option_string_null";
     143            0 :         di_relopt_tab[i].opttype = RELOPT_TYPE_STRING;
     144            0 :         di_relopt_tab[i].offset = offsetof(DummyIndexOptions,
     145              :                                                                            option_string_null_offset);
     146            0 :         i++;
     147            0 : }
     148              : 
     149              : 
     150              : /*
     151              :  * Build a new index.
     152              :  */
     153              : static IndexBuildResult *
     154            0 : dibuild(Relation heap, Relation index, IndexInfo *indexInfo)
     155              : {
     156            0 :         IndexBuildResult *result;
     157              : 
     158            0 :         result = palloc_object(IndexBuildResult);
     159              : 
     160              :         /* let's pretend that no tuples were scanned */
     161            0 :         result->heap_tuples = 0;
     162              :         /* and no index tuples were created (that is true) */
     163            0 :         result->index_tuples = 0;
     164              : 
     165            0 :         return result;
     166            0 : }
     167              : 
     168              : /*
     169              :  * Build an empty index for the initialization fork.
     170              :  */
     171              : static void
     172            0 : dibuildempty(Relation index)
     173              : {
     174              :         /* No need to build an init fork for a dummy index */
     175            0 : }
     176              : 
     177              : /*
     178              :  * Insert new tuple to index AM.
     179              :  */
     180              : static bool
     181            0 : diinsert(Relation index, Datum *values, bool *isnull,
     182              :                  ItemPointer ht_ctid, Relation heapRel,
     183              :                  IndexUniqueCheck checkUnique,
     184              :                  bool indexUnchanged,
     185              :                  IndexInfo *indexInfo)
     186              : {
     187              :         /* nothing to do */
     188            0 :         return false;
     189              : }
     190              : 
     191              : /*
     192              :  * Bulk deletion of all index entries pointing to a set of table tuples.
     193              :  */
     194              : static IndexBulkDeleteResult *
     195            0 : dibulkdelete(IndexVacuumInfo *info, IndexBulkDeleteResult *stats,
     196              :                          IndexBulkDeleteCallback callback, void *callback_state)
     197              : {
     198              :         /*
     199              :          * There is nothing to delete.  Return NULL as there is nothing to pass to
     200              :          * amvacuumcleanup.
     201              :          */
     202            0 :         return NULL;
     203              : }
     204              : 
     205              : /*
     206              :  * Post-VACUUM cleanup for index AM.
     207              :  */
     208              : static IndexBulkDeleteResult *
     209            0 : divacuumcleanup(IndexVacuumInfo *info, IndexBulkDeleteResult *stats)
     210              : {
     211              :         /* Index has not been modified, so returning NULL is fine */
     212            0 :         return NULL;
     213              : }
     214              : 
     215              : /*
     216              :  * Estimate cost of index AM.
     217              :  */
     218              : static void
     219            0 : dicostestimate(PlannerInfo *root, IndexPath *path, double loop_count,
     220              :                            Cost *indexStartupCost, Cost *indexTotalCost,
     221              :                            Selectivity *indexSelectivity, double *indexCorrelation,
     222              :                            double *indexPages)
     223              : {
     224              :         /* Tell planner to never use this index! */
     225            0 :         *indexStartupCost = 1.0e10;
     226            0 :         *indexTotalCost = 1.0e10;
     227              : 
     228              :         /* Do not care about the rest */
     229            0 :         *indexSelectivity = 1;
     230            0 :         *indexCorrelation = 0;
     231            0 :         *indexPages = 1;
     232            0 : }
     233              : 
     234              : /*
     235              :  * Parse relation options for index AM, returning a DummyIndexOptions
     236              :  * structure filled with option values.
     237              :  */
     238              : static bytea *
     239            0 : dioptions(Datum reloptions, bool validate)
     240              : {
     241            0 :         return (bytea *) build_reloptions(reloptions, validate,
     242            0 :                                                                           di_relopt_kind,
     243              :                                                                           sizeof(DummyIndexOptions),
     244              :                                                                           di_relopt_tab, lengthof(di_relopt_tab));
     245              : }
     246              : 
     247              : /*
     248              :  * Validator for index AM.
     249              :  */
     250              : static bool
     251            0 : divalidate(Oid opclassoid)
     252              : {
     253              :         /* Index is dummy so we are happy with any opclass */
     254            0 :         return true;
     255              : }
     256              : 
     257              : /*
     258              :  * Begin scan of index AM.
     259              :  */
     260              : static IndexScanDesc
     261            0 : dibeginscan(Relation r, int nkeys, int norderbys)
     262              : {
     263            0 :         IndexScanDesc scan;
     264              : 
     265              :         /* Let's pretend we are doing something */
     266            0 :         scan = RelationGetIndexScan(r, nkeys, norderbys);
     267            0 :         return scan;
     268            0 : }
     269              : 
     270              : /*
     271              :  * Rescan of index AM.
     272              :  */
     273              : static void
     274            0 : direscan(IndexScanDesc scan, ScanKey scankey, int nscankeys,
     275              :                  ScanKey orderbys, int norderbys)
     276              : {
     277              :         /* nothing to do */
     278            0 : }
     279              : 
     280              : /*
     281              :  * End scan of index AM.
     282              :  */
     283              : static void
     284            0 : diendscan(IndexScanDesc scan)
     285              : {
     286              :         /* nothing to do */
     287            0 : }
     288              : 
     289              : /*
     290              :  * Index AM handler function: returns IndexAmRoutine with access method
     291              :  * parameters and callbacks.
     292              :  */
     293              : Datum
     294            0 : dihandler(PG_FUNCTION_ARGS)
     295              : {
     296              :         static const IndexAmRoutine amroutine = {
     297              :                 .type = T_IndexAmRoutine,
     298              :                 .amstrategies = 0,
     299              :                 .amsupport = 1,
     300              :                 .amcanorder = false,
     301              :                 .amcanorderbyop = false,
     302              :                 .amcanhash = false,
     303              :                 .amconsistentequality = false,
     304              :                 .amconsistentordering = false,
     305              :                 .amcanbackward = false,
     306              :                 .amcanunique = false,
     307              :                 .amcanmulticol = false,
     308              :                 .amoptionalkey = false,
     309              :                 .amsearcharray = false,
     310              :                 .amsearchnulls = false,
     311              :                 .amstorage = false,
     312              :                 .amclusterable = false,
     313              :                 .ampredlocks = false,
     314              :                 .amcanparallel = false,
     315              :                 .amcanbuildparallel = false,
     316              :                 .amcaninclude = false,
     317              :                 .amusemaintenanceworkmem = false,
     318              :                 .amsummarizing = false,
     319              :                 .amparallelvacuumoptions = VACUUM_OPTION_NO_PARALLEL,
     320              :                 .amkeytype = InvalidOid,
     321              : 
     322              :                 .ambuild = dibuild,
     323              :                 .ambuildempty = dibuildempty,
     324              :                 .aminsert = diinsert,
     325              :                 .ambulkdelete = dibulkdelete,
     326              :                 .amvacuumcleanup = divacuumcleanup,
     327              :                 .amcanreturn = NULL,
     328              :                 .amcostestimate = dicostestimate,
     329              :                 .amgettreeheight = NULL,
     330              :                 .amoptions = dioptions,
     331              :                 .amproperty = NULL,
     332              :                 .ambuildphasename = NULL,
     333              :                 .amvalidate = divalidate,
     334              :                 .ambeginscan = dibeginscan,
     335              :                 .amrescan = direscan,
     336              :                 .amgettuple = NULL,
     337              :                 .amgetbitmap = NULL,
     338              :                 .amendscan = diendscan,
     339              :                 .ammarkpos = NULL,
     340              :                 .amrestrpos = NULL,
     341              :                 .amestimateparallelscan = NULL,
     342              :                 .aminitparallelscan = NULL,
     343              :                 .amparallelrescan = NULL,
     344              :         };
     345              : 
     346            0 :         PG_RETURN_POINTER(&amroutine);
     347              : }
     348              : 
     349              : void
     350            0 : _PG_init(void)
     351              : {
     352            0 :         create_reloptions_table();
     353            0 : }
        

Generated by: LCOV version 2.3.2-1