LCOV - differential code coverage report
Current view: top level - src/test/modules/dummy_index_am - dummy_index_am.c (source / functions) Coverage Total Hit UIC UBC GIC GNC CBC EUB ECB
Current: Differential Code Coverage HEAD vs 15 Lines: 78.0 % 109 85 22 2 26 1 58 22 27
Current Date: 2023-04-08 15:15:32 Functions: 47.1 % 17 8 9 7 1 9 7
Baseline: 15
Baseline Date: 2023-04-08 15:09:40
Legend: Lines: hit not hit

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

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