LCOV - differential code coverage report
Current view: top level - src/backend/utils/adt - amutils.c (source / functions) Coverage Total Hit UNC LBC UIC UBC GBC GIC GNC CBC EUB ECB DCB
Current: Differential Code Coverage HEAD vs 15 Lines: 88.0 % 158 139 1 3 9 6 2 58 1 78 11 56 2
Current Date: 2023-04-08 17:13:01 Functions: 85.7 % 7 6 1 4 1 1 1 4
Baseline: 15 Line coverage date bins:
Baseline Date: 2023-04-08 15:09:40 [..60] days: 100.0 % 1 1 1
Legend: Lines: hit not hit (180,240] days: 0.0 % 1 0 1
(240..) days: 88.5 % 156 138 3 9 6 2 58 78 11 56
Function coverage date bins:
(240..) days: 50.0 % 12 6 1 4 1 1 1 4

 Age         Owner                  TLA  Line data    Source code
                                  1                 : /*-------------------------------------------------------------------------
                                  2                 :  *
                                  3                 :  * amutils.c
                                  4                 :  *    SQL-level APIs related to index access methods.
                                  5                 :  *
                                  6                 :  * Copyright (c) 2016-2023, PostgreSQL Global Development Group
                                  7                 :  *
                                  8                 :  *
                                  9                 :  * IDENTIFICATION
                                 10                 :  *    src/backend/utils/adt/amutils.c
                                 11                 :  *
                                 12                 :  *-------------------------------------------------------------------------
                                 13                 :  */
                                 14                 : #include "postgres.h"
                                 15                 : 
                                 16                 : #include "access/amapi.h"
                                 17                 : #include "access/htup_details.h"
                                 18                 : #include "catalog/pg_class.h"
                                 19                 : #include "catalog/pg_index.h"
                                 20                 : #include "utils/builtins.h"
                                 21                 : #include "utils/syscache.h"
                                 22                 : 
                                 23                 : 
                                 24                 : /* Convert string property name to enum, for efficiency */
                                 25                 : struct am_propname
                                 26                 : {
                                 27                 :     const char *name;
                                 28                 :     IndexAMProperty prop;
                                 29                 : };
                                 30                 : 
                                 31                 : static const struct am_propname am_propnames[] =
                                 32                 : {
                                 33                 :     {
                                 34                 :         "asc", AMPROP_ASC
                                 35                 :     },
                                 36                 :     {
                                 37                 :         "desc", AMPROP_DESC
                                 38                 :     },
                                 39                 :     {
                                 40                 :         "nulls_first", AMPROP_NULLS_FIRST
                                 41                 :     },
                                 42                 :     {
                                 43                 :         "nulls_last", AMPROP_NULLS_LAST
                                 44                 :     },
                                 45                 :     {
                                 46                 :         "orderable", AMPROP_ORDERABLE
                                 47                 :     },
                                 48                 :     {
                                 49                 :         "distance_orderable", AMPROP_DISTANCE_ORDERABLE
                                 50                 :     },
                                 51                 :     {
                                 52                 :         "returnable", AMPROP_RETURNABLE
                                 53                 :     },
                                 54                 :     {
                                 55                 :         "search_array", AMPROP_SEARCH_ARRAY
                                 56                 :     },
                                 57                 :     {
                                 58                 :         "search_nulls", AMPROP_SEARCH_NULLS
                                 59                 :     },
                                 60                 :     {
                                 61                 :         "clusterable", AMPROP_CLUSTERABLE
                                 62                 :     },
                                 63                 :     {
                                 64                 :         "index_scan", AMPROP_INDEX_SCAN
                                 65                 :     },
                                 66                 :     {
                                 67                 :         "bitmap_scan", AMPROP_BITMAP_SCAN
                                 68                 :     },
                                 69                 :     {
                                 70                 :         "backward_scan", AMPROP_BACKWARD_SCAN
                                 71                 :     },
                                 72                 :     {
                                 73                 :         "can_order", AMPROP_CAN_ORDER
                                 74                 :     },
                                 75                 :     {
                                 76                 :         "can_unique", AMPROP_CAN_UNIQUE
                                 77                 :     },
                                 78                 :     {
                                 79                 :         "can_multi_col", AMPROP_CAN_MULTI_COL
                                 80                 :     },
                                 81                 :     {
                                 82                 :         "can_exclude", AMPROP_CAN_EXCLUDE
                                 83                 :     },
                                 84                 :     {
                                 85                 :         "can_include", AMPROP_CAN_INCLUDE
                                 86                 :     },
                                 87                 : };
                                 88                 : 
                                 89                 : static IndexAMProperty
 2430 tgl                        90 CBC         894 : lookup_prop_name(const char *name)
                                 91                 : {
                                 92                 :     int         i;
                                 93                 : 
                                 94            8547 :     for (i = 0; i < lengthof(am_propnames); i++)
                                 95                 :     {
                                 96            8451 :         if (pg_strcasecmp(am_propnames[i].name, name) == 0)
                                 97             798 :             return am_propnames[i].prop;
                                 98                 :     }
                                 99                 : 
                                100                 :     /* We do not throw an error, so that AMs can define their own properties */
                                101              96 :     return AMPROP_UNKNOWN;
                                102                 : }
                                103                 : 
                                104                 : /*
                                105                 :  * Common code for properties that are just bit tests of indoptions.
                                106                 :  *
                                107                 :  * tuple: the pg_index heaptuple
                                108                 :  * attno: identify the index column to test the indoptions of.
                                109                 :  * guard: if false, a boolean false result is forced (saves code in caller).
                                110                 :  * iopt_mask: mask for interesting indoption bit.
                                111                 :  * iopt_expect: value for a "true" result (should be 0 or iopt_mask).
                                112                 :  *
                                113                 :  * Returns false to indicate a NULL result (for "unknown/inapplicable"),
                                114                 :  * otherwise sets *res to the boolean value to return.
                                115                 :  */
                                116                 : static bool
 1827 rhodiumtoad               117             168 : test_indoption(HeapTuple tuple, int attno, bool guard,
                                118                 :                int16 iopt_mask, int16 iopt_expect,
                                119                 :                bool *res)
                                120                 : {
                                121                 :     Datum       datum;
                                122                 :     int2vector *indoption;
                                123                 :     int16       indoption_val;
 2430 tgl                       124 ECB             : 
 2430 tgl                       125 GIC         168 :     if (!guard)
 2430 tgl                       126 ECB             :     {
 2430 tgl                       127 CBC          84 :         *res = false;
 2430 tgl                       128 GIC          84 :         return true;
                                129                 :     }
 2430 tgl                       130 ECB             : 
   15 dgustafsson               131 GNC          84 :     datum = SysCacheGetAttrNotNull(INDEXRELID, tuple, Anum_pg_index_indoption);
                                132                 : 
 2430 tgl                       133 CBC          84 :     indoption = ((int2vector *) DatumGetPointer(datum));
 2430 tgl                       134 GIC          84 :     indoption_val = indoption->values[attno - 1];
 2430 tgl                       135 ECB             : 
 2430 tgl                       136 GIC          84 :     *res = (indoption_val & iopt_mask) == iopt_expect;
                                137                 : 
                                138              84 :     return true;
                                139                 : }
                                140                 : 
                                141                 : 
                                142                 : /*
                                143                 :  * Test property of an index AM, index, or index column.
                                144                 :  *
                                145                 :  * This is common code for different SQL-level funcs, so the amoid and
                                146                 :  * index_oid parameters are mutually exclusive; we look up the amoid from the
                                147                 :  * index_oid if needed, or if no index oid is given, we're looking at AM-wide
 2430 tgl                       148 ECB             :  * properties.
                                149                 :  */
                                150                 : static Datum
 2430 tgl                       151 GIC         894 : indexam_property(FunctionCallInfo fcinfo,
 2430 tgl                       152 ECB             :                  const char *propname,
                                153                 :                  Oid amoid, Oid index_oid, int attno)
                                154                 : {
 2430 tgl                       155 GIC         894 :     bool        res = false;
                                156             894 :     bool        isnull = false;
                                157             894 :     int         natts = 0;
                                158                 :     IndexAMProperty prop;
 2430 tgl                       159 ECB             :     IndexAmRoutine *routine;
                                160                 : 
                                161                 :     /* Try to convert property name to enum (no error if not known) */
 2430 tgl                       162 CBC         894 :     prop = lookup_prop_name(propname);
                                163                 : 
                                164                 :     /* If we have an index OID, look up the AM, and get # of columns too */
 2430 tgl                       165 GIC         894 :     if (OidIsValid(index_oid))
                                166                 :     {
 2430 tgl                       167 ECB             :         HeapTuple   tuple;
                                168                 :         Form_pg_class rd_rel;
                                169                 : 
 2430 tgl                       170 GBC         672 :         Assert(!OidIsValid(amoid));
 2430 tgl                       171 CBC         672 :         tuple = SearchSysCache1(RELOID, ObjectIdGetDatum(index_oid));
                                172             672 :         if (!HeapTupleIsValid(tuple))
 2430 tgl                       173 UBC           0 :             PG_RETURN_NULL();
 2430 tgl                       174 GIC         672 :         rd_rel = (Form_pg_class) GETSTRUCT(tuple);
 1906 alvherre                  175 GBC         672 :         if (rd_rel->relkind != RELKIND_INDEX &&
 1906 alvherre                  176 UBC           0 :             rd_rel->relkind != RELKIND_PARTITIONED_INDEX)
                                177                 :         {
 2430 tgl                       178 LBC           0 :             ReleaseSysCache(tuple);
                                179               0 :             PG_RETURN_NULL();
 2430 tgl                       180 ECB             :         }
 2430 tgl                       181 GIC         672 :         amoid = rd_rel->relam;
                                182             672 :         natts = rd_rel->relnatts;
                                183             672 :         ReleaseSysCache(tuple);
                                184                 :     }
                                185                 : 
                                186                 :     /*
                                187                 :      * At this point, either index_oid == InvalidOid or it's a valid index
                                188                 :      * OID. Also, after this test and the one below, either attno == 0 for
 1827 rhodiumtoad               189 ECB             :      * index-wide or AM-wide tests, or it's a valid column number in a valid
 1827 rhodiumtoad               190 EUB             :      * index.
                                191                 :      */
 2430 tgl                       192 GIC         894 :     if (attno < 0 || attno > natts)
 2430 tgl                       193 UIC           0 :         PG_RETURN_NULL();
                                194                 : 
 2430 tgl                       195 ECB             :     /*
                                196                 :      * Get AM information.  If we don't have a valid AM OID, return NULL.
 2430 tgl                       197 EUB             :      */
 2430 tgl                       198 GIC         894 :     routine = GetIndexAmRoutineByAmId(amoid, true);
                                199             894 :     if (routine == NULL)
 2430 tgl                       200 UIC           0 :         PG_RETURN_NULL();
                                201                 : 
                                202                 :     /*
 2430 tgl                       203 ECB             :      * If there's an AM property routine, give it a chance to override the
                                204                 :      * generic logic.  Proceed if it returns false.
                                205                 :      */
 2430 tgl                       206 GIC        1599 :     if (routine->amproperty &&
 2430 tgl                       207 CBC         705 :         routine->amproperty(index_oid, attno, prop, propname,
 2430 tgl                       208 EUB             :                             &res, &isnull))
 2430 tgl                       209 ECB             :     {
 2430 tgl                       210 GIC          33 :         if (isnull)
 2430 tgl                       211 UIC           0 :             PG_RETURN_NULL();
 2430 tgl                       212 CBC          33 :         PG_RETURN_BOOL(res);
                                213                 :     }
                                214                 : 
 2430 tgl                       215 GIC         861 :     if (attno > 0)
 2430 tgl                       216 ECB             :     {
                                217                 :         HeapTuple   tuple;
                                218                 :         Form_pg_index rd_index;
 1827 rhodiumtoad               219 GIC         435 :         bool        iskey = true;
                                220                 : 
                                221                 :         /*
                                222                 :          * Handle column-level properties. Many of these need the pg_index row
 1827 rhodiumtoad               223 ECB             :          * (which we also need to use to check for nonkey atts) so we fetch
                                224                 :          * that first.
 1827 rhodiumtoad               225 EUB             :          */
 1827 rhodiumtoad               226 CBC         435 :         tuple = SearchSysCache1(INDEXRELID, ObjectIdGetDatum(index_oid));
 1827 rhodiumtoad               227 GIC         435 :         if (!HeapTupleIsValid(tuple))
 1827 rhodiumtoad               228 LBC           0 :             PG_RETURN_NULL();
 1827 rhodiumtoad               229 CBC         435 :         rd_index = (Form_pg_index) GETSTRUCT(tuple);
                                230                 : 
                                231             435 :         Assert(index_oid == rd_index->indexrelid);
 1827 rhodiumtoad               232 GIC         435 :         Assert(attno > 0 && attno <= rd_index->indnatts);
                                233                 : 
                                234             435 :         isnull = true;
                                235                 : 
                                236                 :         /*
                                237                 :          * If amcaninclude, we might be looking at an attno for a nonkey
 1827 rhodiumtoad               238 ECB             :          * column, for which we (generically) assume that most properties are
                                239                 :          * null.
                                240                 :          */
 1827 rhodiumtoad               241 GIC         435 :         if (routine->amcaninclude
 1827 rhodiumtoad               242 CBC         345 :             && attno > rd_index->indnkeyatts)
 1827 rhodiumtoad               243 GIC          42 :             iskey = false;
 1827 rhodiumtoad               244 ECB             : 
 2430 tgl                       245 CBC         435 :         switch (prop)
 2430 tgl                       246 ECB             :         {
 2430 tgl                       247 GIC          48 :             case AMPROP_ASC:
 1827 rhodiumtoad               248 CBC          90 :                 if (iskey &&
                                249              42 :                     test_indoption(tuple, attno, routine->amcanorder,
                                250                 :                                    INDOPTION_DESC, 0, &res))
                                251              42 :                     isnull = false;
                                252              48 :                 break;
 2430 tgl                       253 ECB             : 
 2430 tgl                       254 GIC          48 :             case AMPROP_DESC:
 1827 rhodiumtoad               255 CBC          90 :                 if (iskey &&
                                256              42 :                     test_indoption(tuple, attno, routine->amcanorder,
                                257                 :                                    INDOPTION_DESC, INDOPTION_DESC, &res))
                                258              42 :                     isnull = false;
                                259              48 :                 break;
 2430 tgl                       260 ECB             : 
 2430 tgl                       261 GIC          48 :             case AMPROP_NULLS_FIRST:
 1827 rhodiumtoad               262 CBC          90 :                 if (iskey &&
                                263              42 :                     test_indoption(tuple, attno, routine->amcanorder,
                                264                 :                                    INDOPTION_NULLS_FIRST, INDOPTION_NULLS_FIRST, &res))
                                265              42 :                     isnull = false;
                                266              48 :                 break;
 2430 tgl                       267 ECB             : 
 2430 tgl                       268 GIC          48 :             case AMPROP_NULLS_LAST:
 1827 rhodiumtoad               269 CBC          90 :                 if (iskey &&
                                270              42 :                     test_indoption(tuple, attno, routine->amcanorder,
                                271                 :                                    INDOPTION_NULLS_FIRST, 0, &res))
                                272              42 :                     isnull = false;
 1827 rhodiumtoad               273 GIC          48 :                 break;
                                274                 : 
 2430 tgl                       275              48 :             case AMPROP_ORDERABLE:
                                276                 : 
 1827 rhodiumtoad               277 ECB             :                 /*
                                278                 :                  * generic assumption is that nonkey columns are not orderable
                                279                 :                  */
 1827 rhodiumtoad               280 GIC          48 :                 res = iskey ? routine->amcanorder : false;
 1827 rhodiumtoad               281 CBC          48 :                 isnull = false;
 1827 rhodiumtoad               282 GIC          48 :                 break;
                                283                 : 
 2430 tgl                       284              24 :             case AMPROP_DISTANCE_ORDERABLE:
                                285                 : 
                                286                 :                 /*
                                287                 :                  * The conditions for whether a column is distance-orderable
                                288                 :                  * are really up to the AM (at time of writing, only GiST
                                289                 :                  * supports it at all). The planner has its own idea based on
                                290                 :                  * whether it finds an operator with amoppurpose 'o', but
                                291                 :                  * getting there from just the index column type seems like a
                                292                 :                  * lot of work. So instead we expect the AM to handle this in
                                293                 :                  * its amproperty routine. The generic result is to return
                                294                 :                  * false if the AM says it never supports this, or if this is
 1809 tgl                       295 ECB             :                  * a nonkey column, and null otherwise (meaning we don't
                                296                 :                  * know).
 2430                           297                 :                  */
 1827 rhodiumtoad               298 CBC          24 :                 if (!iskey || !routine->amcanorderbyop)
                                299                 :                 {
                                300              24 :                     res = false;
 1827 rhodiumtoad               301 GIC          24 :                     isnull = false;
 1827 rhodiumtoad               302 ECB             :                 }
 1827 rhodiumtoad               303 GIC          24 :                 break;
                                304                 : 
 2430 tgl                       305              15 :             case AMPROP_RETURNABLE:
 2430 tgl                       306 ECB             : 
 1827 rhodiumtoad               307                 :                 /* note that we ignore iskey for this property */
                                308                 : 
 1827 rhodiumtoad               309 CBC          15 :                 isnull = false;
 1827 rhodiumtoad               310 GIC          15 :                 res = false;
                                311                 : 
                                312              15 :                 if (routine->amcanreturn)
                                313                 :                 {
                                314                 :                     /*
                                315                 :                      * If possible, the AM should handle this test in its
 1809 tgl                       316 ECB             :                      * amproperty function without opening the rel. But this
                                317                 :                      * is the generic fallback if it does not.
 1827 rhodiumtoad               318                 :                      */
 2430 tgl                       319 CBC           6 :                     Relation    indexrel = index_open(index_oid, AccessShareLock);
                                320                 : 
                                321               6 :                     res = index_can_return(indexrel, attno);
 2430 tgl                       322 GIC           6 :                     index_close(indexrel, AccessShareLock);
 2430 tgl                       323 ECB             :                 }
 1827 rhodiumtoad               324 CBC          15 :                 break;
                                325                 : 
 2430 tgl                       326              27 :             case AMPROP_SEARCH_ARRAY:
 1827 rhodiumtoad               327              27 :                 if (iskey)
                                328                 :                 {
                                329              27 :                     res = routine->amsearcharray;
 1827 rhodiumtoad               330 GIC          27 :                     isnull = false;
 1827 rhodiumtoad               331 ECB             :                 }
 1827 rhodiumtoad               332 CBC          27 :                 break;
                                333                 : 
 2430 tgl                       334              27 :             case AMPROP_SEARCH_NULLS:
 1827 rhodiumtoad               335              27 :                 if (iskey)
                                336                 :                 {
                                337              27 :                     res = routine->amsearchnulls;
 1827 rhodiumtoad               338 GIC          27 :                     isnull = false;
 1827 rhodiumtoad               339 ECB             :                 }
 1827 rhodiumtoad               340 CBC          27 :                 break;
                                341                 : 
 2430 tgl                       342 GIC         102 :             default:
 1827 rhodiumtoad               343 CBC         102 :                 break;
                                344                 :         }
 1827 rhodiumtoad               345 ECB             : 
 1827 rhodiumtoad               346 CBC         435 :         ReleaseSysCache(tuple);
 1827 rhodiumtoad               347 ECB             : 
 1827 rhodiumtoad               348 GIC         435 :         if (!isnull)
                                349             309 :             PG_RETURN_BOOL(res);
 1827 rhodiumtoad               350 CBC         126 :         PG_RETURN_NULL();
                                351                 :     }
                                352                 : 
 2430 tgl                       353 GIC         426 :     if (OidIsValid(index_oid))
                                354                 :     {
                                355                 :         /*
                                356                 :          * Handle index-level properties.  Currently, these only depend on the
 2430 tgl                       357 ECB             :          * AM, but that might not be true forever, so we make users name an
                                358                 :          * index not just an AM.
                                359                 :          */
 2430 tgl                       360 CBC         204 :         switch (prop)
                                361                 :         {
                                362              24 :             case AMPROP_CLUSTERABLE:
                                363              24 :                 PG_RETURN_BOOL(routine->amclusterable);
                                364                 : 
                                365              24 :             case AMPROP_INDEX_SCAN:
                                366              24 :                 PG_RETURN_BOOL(routine->amgettuple ? true : false);
                                367                 : 
                                368              24 :             case AMPROP_BITMAP_SCAN:
                                369              24 :                 PG_RETURN_BOOL(routine->amgetbitmap ? true : false);
                                370                 : 
                                371              24 :             case AMPROP_BACKWARD_SCAN:
                                372              24 :                 PG_RETURN_BOOL(routine->amcanbackward);
                                373                 : 
 2430 tgl                       374 GIC         108 :             default:
                                375             108 :                 PG_RETURN_NULL();
                                376                 :         }
                                377                 :     }
                                378                 : 
                                379                 :     /*
 2430 tgl                       380 ECB             :      * Handle AM-level properties (those that control what you can say in
                                381                 :      * CREATE INDEX).
                                382                 :      */
 2430 tgl                       383 CBC         222 :     switch (prop)
                                384                 :     {
                                385              24 :         case AMPROP_CAN_ORDER:
                                386              24 :             PG_RETURN_BOOL(routine->amcanorder);
                                387                 : 
                                388              24 :         case AMPROP_CAN_UNIQUE:
                                389              24 :             PG_RETURN_BOOL(routine->amcanunique);
                                390                 : 
                                391              24 :         case AMPROP_CAN_MULTI_COL:
                                392              24 :             PG_RETURN_BOOL(routine->amcanmulticol);
                                393                 : 
                                394              24 :         case AMPROP_CAN_EXCLUDE:
                                395              24 :             PG_RETURN_BOOL(routine->amgettuple ? true : false);
                                396                 : 
 1827 rhodiumtoad               397              24 :         case AMPROP_CAN_INCLUDE:
                                398              24 :             PG_RETURN_BOOL(routine->amcaninclude);
                                399                 : 
 2430 tgl                       400 GIC         102 :         default:
                                401             102 :             PG_RETURN_NULL();
                                402                 :     }
                                403                 : }
                                404                 : 
                                405                 : /*
 2430 tgl                       406 ECB             :  * Test property of an AM specified by AM OID
                                407                 :  */
                                408                 : Datum
 2430 tgl                       409 CBC         222 : pg_indexam_has_property(PG_FUNCTION_ARGS)
                                410                 : {
                                411             222 :     Oid         amoid = PG_GETARG_OID(0);
 2430 tgl                       412 GIC         222 :     char       *propname = text_to_cstring(PG_GETARG_TEXT_PP(1));
                                413                 : 
                                414             222 :     return indexam_property(fcinfo, propname, amoid, InvalidOid, 0);
                                415                 : }
                                416                 : 
                                417                 : /*
 2430 tgl                       418 ECB             :  * Test property of an index specified by index OID
                                419                 :  */
                                420                 : Datum
 2430 tgl                       421 CBC         204 : pg_index_has_property(PG_FUNCTION_ARGS)
                                422                 : {
                                423             204 :     Oid         relid = PG_GETARG_OID(0);
 2430 tgl                       424 GIC         204 :     char       *propname = text_to_cstring(PG_GETARG_TEXT_PP(1));
                                425                 : 
                                426             204 :     return indexam_property(fcinfo, propname, InvalidOid, relid, 0);
                                427                 : }
                                428                 : 
                                429                 : /*
 2430 tgl                       430 ECB             :  * Test property of an index column specified by index OID and column number
                                431                 :  */
                                432                 : Datum
 2430 tgl                       433 CBC         468 : pg_index_column_has_property(PG_FUNCTION_ARGS)
 2430 tgl                       434 ECB             : {
 2430 tgl                       435 GIC         468 :     Oid         relid = PG_GETARG_OID(0);
                                436             468 :     int32       attno = PG_GETARG_INT32(1);
 2430 tgl                       437 CBC         468 :     char       *propname = text_to_cstring(PG_GETARG_TEXT_PP(2));
 2430 tgl                       438 EUB             : 
                                439                 :     /* Reject attno 0 immediately, so that attno > 0 identifies this case */
 2430 tgl                       440 CBC         468 :     if (attno <= 0)
 2430 tgl                       441 UIC           0 :         PG_RETURN_NULL();
                                442                 : 
 2430 tgl                       443 GIC         468 :     return indexam_property(fcinfo, propname, InvalidOid, relid, attno);
                                444                 : }
                                445                 : 
                                446                 : /*
                                447                 :  * Return the name of the given phase, as used for progress reporting by the
 1468 alvherre                  448 EUB             :  * given AM.
                                449                 :  */
                                450                 : Datum
 1468 alvherre                  451 UBC           0 : pg_indexam_progress_phasename(PG_FUNCTION_ARGS)
                                452                 : {
 1468 alvherre                  453 UIC           0 :     Oid         amoid = PG_GETARG_OID(0);
                                454               0 :     int32       phasenum = PG_GETARG_INT32(1);
 1468 alvherre                  455 EUB             :     IndexAmRoutine *routine;
                                456                 :     char       *name;
                                457                 : 
 1468 alvherre                  458 UIC           0 :     routine = GetIndexAmRoutineByAmId(amoid, true);
 1468 alvherre                  459 UBC           0 :     if (routine == NULL || !routine->ambuildphasename)
                                460               0 :         PG_RETURN_NULL();
 1468 alvherre                  461 EUB             : 
 1468 alvherre                  462 UIC           0 :     name = routine->ambuildphasename(phasenum);
 1468 alvherre                  463 UBC           0 :     if (!name)
 1468 alvherre                  464 UIC           0 :         PG_RETURN_NULL();
                                465                 : 
  224 peter                     466 UNC           0 :     PG_RETURN_DATUM(CStringGetTextDatum(name));
                                467                 : }
        

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