LCOV - differential code coverage report
Current view: top level - src/bin/pg_dump - common.c (source / functions) Coverage Total Hit UNC LBC UIC GBC GIC GNC CBC EUB ECB DUB DCB
Current: Differential Code Coverage HEAD vs 15 Lines: 96.6 % 381 368 2 5 6 3 181 45 139 9 183 1 41
Current Date: 2023-04-08 17:13:01 Functions: 100.0 % 25 25 24 1 21 4
Baseline: 15 Line coverage date bins:
Baseline Date: 2023-04-08 15:09:40 [..60] days: 93.9 % 33 31 2 2 28 1 1
Legend: Lines: hit not hit (60,120] days: 100.0 % 10 10 10
(180,240] days: 100.0 % 7 7 7
(240..) days: 96.7 % 331 320 5 6 3 179 138 9 178
Function coverage date bins:
[..60] days: 100.0 % 1 1 1
(240..) days: 53.3 % 45 24 24 21

 Age         Owner                  TLA  Line data    Source code
                                  1                 : /*-------------------------------------------------------------------------
                                  2                 :  *
                                  3                 :  * common.c
                                  4                 :  *  Catalog routines used by pg_dump; long ago these were shared
                                  5                 :  *  by another dump tool, but not anymore.
                                  6                 :  *
                                  7                 :  * Portions Copyright (c) 1996-2023, PostgreSQL Global Development Group
                                  8                 :  * Portions Copyright (c) 1994, Regents of the University of California
                                  9                 :  *
                                 10                 :  *
                                 11                 :  * IDENTIFICATION
                                 12                 :  *    src/bin/pg_dump/common.c
                                 13                 :  *
                                 14                 :  *-------------------------------------------------------------------------
                                 15                 :  */
                                 16                 : #include "postgres_fe.h"
                                 17                 : 
                                 18                 : #include <ctype.h>
                                 19                 : 
                                 20                 : #include "catalog/pg_class_d.h"
                                 21                 : #include "catalog/pg_collation_d.h"
                                 22                 : #include "catalog/pg_extension_d.h"
                                 23                 : #include "catalog/pg_namespace_d.h"
                                 24                 : #include "catalog/pg_operator_d.h"
                                 25                 : #include "catalog/pg_proc_d.h"
                                 26                 : #include "catalog/pg_publication_d.h"
                                 27                 : #include "catalog/pg_type_d.h"
                                 28                 : #include "common/hashfn.h"
                                 29                 : #include "fe_utils/string_utils.h"
                                 30                 : #include "pg_backup_archiver.h"
                                 31                 : #include "pg_backup_utils.h"
                                 32                 : #include "pg_dump.h"
                                 33                 : 
                                 34                 : /*
                                 35                 :  * Variables for mapping DumpId to DumpableObject
                                 36                 :  */
                                 37                 : static DumpableObject **dumpIdMap = NULL;
                                 38                 : static int  allocedDumpIds = 0;
                                 39                 : static DumpId lastDumpId = 0;   /* Note: 0 is InvalidDumpId */
                                 40                 : 
                                 41                 : /*
                                 42                 :  * Infrastructure for mapping CatalogId to DumpableObject
                                 43                 :  *
                                 44                 :  * We use a hash table generated by simplehash.h.  That infrastructure
                                 45                 :  * requires all the hash table entries to be the same size, and it also
                                 46                 :  * expects that it can move them around when resizing the table.  So we
                                 47                 :  * cannot make the DumpableObjects be elements of the hash table directly;
                                 48                 :  * instead, the hash table elements contain pointers to DumpableObjects.
                                 49                 :  *
                                 50                 :  * It turns out to be convenient to also use this data structure to map
                                 51                 :  * CatalogIds to owning extensions, if any.  Since extension membership
                                 52                 :  * data is read before creating most DumpableObjects, either one of dobj
                                 53                 :  * and ext could be NULL.
                                 54                 :  */
                                 55                 : typedef struct _catalogIdMapEntry
                                 56                 : {
                                 57                 :     CatalogId   catId;          /* the indexed CatalogId */
                                 58                 :     uint32      status;         /* hash status */
                                 59                 :     uint32      hashval;        /* hash code for the CatalogId */
                                 60                 :     DumpableObject *dobj;       /* the associated DumpableObject, if any */
                                 61                 :     ExtensionInfo *ext;         /* owning extension, if any */
                                 62                 : } CatalogIdMapEntry;
                                 63                 : 
                                 64                 : #define SH_PREFIX       catalogid
                                 65                 : #define SH_ELEMENT_TYPE CatalogIdMapEntry
                                 66                 : #define SH_KEY_TYPE     CatalogId
                                 67                 : #define SH_KEY          catId
                                 68                 : #define SH_HASH_KEY(tb, key)    hash_bytes((const unsigned char *) &(key), sizeof(CatalogId))
                                 69                 : #define SH_EQUAL(tb, a, b)      ((a).oid == (b).oid && (a).tableoid == (b).tableoid)
                                 70                 : #define SH_STORE_HASH
                                 71                 : #define SH_GET_HASH(tb, a) (a)->hashval
                                 72                 : #define SH_SCOPE        static inline
                                 73                 : #define SH_RAW_ALLOCATOR    pg_malloc0
                                 74                 : #define SH_DECLARE
                                 75                 : #define SH_DEFINE
                                 76                 : #include "lib/simplehash.h"
                                 77                 : 
                                 78                 : #define CATALOGIDHASH_INITIAL_SIZE  10000
                                 79                 : 
                                 80                 : static catalogid_hash *catalogIdHash = NULL;
                                 81                 : 
                                 82                 : static void flagInhTables(Archive *fout, TableInfo *tblinfo, int numTables,
                                 83                 :                           InhInfo *inhinfo, int numInherits);
                                 84                 : static void flagInhIndexes(Archive *fout, TableInfo *tblinfo, int numTables);
                                 85                 : static void flagInhAttrs(Archive *fout, DumpOptions *dopt, TableInfo *tblinfo,
                                 86                 :                          int numTables);
                                 87                 : static int  strInArray(const char *pattern, char **arr, int arr_size);
                                 88                 : static IndxInfo *findIndexByOid(Oid oid);
                                 89                 : 
                                 90                 : 
                                 91                 : /*
                                 92                 :  * getSchemaData
                                 93                 :  *    Collect information about all potentially dumpable objects
                                 94                 :  */
 4152 bruce                      95 ECB             : TableInfo *
 2643 tgl                        96 GIC         119 : getSchemaData(Archive *fout, int *numTablesPtr)
                                 97                 : {
                                 98                 :     TableInfo  *tblinfo;
                                 99                 :     ExtensionInfo *extinfo;
                                100                 :     InhInfo    *inhinfo;
                                101                 :     int         numTables;
                                102                 :     int         numTypes;
                                103                 :     int         numFuncs;
                                104                 :     int         numOperators;
                                105                 :     int         numCollations;
                                106                 :     int         numNamespaces;
                                107                 :     int         numExtensions;
                                108                 :     int         numPublications;
                                109                 :     int         numAggregates;
                                110                 :     int         numInherits;
                                111                 :     int         numRules;
                                112                 :     int         numProcLangs;
                                113                 :     int         numCasts;
                                114                 :     int         numTransforms;
                                115                 :     int         numAccessMethods;
                                116                 :     int         numOpclasses;
                                117                 :     int         numOpfamilies;
                                118                 :     int         numConversions;
                                119                 :     int         numTSParsers;
                                120                 :     int         numTSTemplates;
                                121                 :     int         numTSDicts;
                                122                 :     int         numTSConfigs;
                                123                 :     int         numForeignDataWrappers;
                                124                 :     int         numForeignServers;
                                125                 :     int         numDefaultACLs;
                                126                 :     int         numEventTriggers;
                                127                 : 
                                128                 :     /*
                                129                 :      * We must read extensions and extension membership info first, because
                                130                 :      * extension membership needs to be consultable during decisions about
                                131                 :      * whether other objects are to be dumped.
 2643 tgl                       132 ECB             :      */
 1469 peter                     133 CBC         119 :     pg_log_info("reading extensions");
 2643 tgl                       134 GIC         119 :     extinfo = getExtensions(fout, &numExtensions);
 2643 tgl                       135 ECB             : 
 1469 peter                     136 CBC         119 :     pg_log_info("identifying extension members");
 2643 tgl                       137 GIC         119 :     getExtensionMembership(fout, extinfo, numExtensions);
 2643 tgl                       138 ECB             : 
 1469 peter                     139 CBC         119 :     pg_log_info("reading schemas");
  534 tgl                       140 GIC         119 :     (void) getNamespaces(fout, &numNamespaces);
                                141                 : 
                                142                 :     /*
                                143                 :      * getTables should be done as soon as possible, so as to minimize the
                                144                 :      * window between starting our transaction and acquiring per-table locks.
                                145                 :      * However, we have to do getNamespaces first because the tables get
                                146                 :      * linked to their containing namespaces during getTables.
 4152 bruce                     147 ECB             :      */
 1469 peter                     148 CBC         119 :     pg_log_info("reading user-defined tables");
 2643 tgl                       149 GIC         119 :     tblinfo = getTables(fout, &numTables);
 4152 bruce                     150 ECB             : 
 4026 tgl                       151 GIC         118 :     getOwnedSeqs(fout, tblinfo, numTables);
 4026 tgl                       152 ECB             : 
 1469 peter                     153 CBC         118 :     pg_log_info("reading user-defined functions");
  534 tgl                       154 GIC         118 :     (void) getFuncs(fout, &numFuncs);
                                155                 : 
 4152 bruce                     156 ECB             :     /* this must be after getTables and getFuncs */
 1469 peter                     157 CBC         118 :     pg_log_info("reading user-defined types");
  534 tgl                       158 GIC         118 :     (void) getTypes(fout, &numTypes);
                                159                 : 
 4152 bruce                     160 ECB             :     /* this must be after getFuncs, too */
 1469 peter                     161 CBC         118 :     pg_log_info("reading procedural languages");
 4080 rhaas                     162 GIC         118 :     getProcLangs(fout, &numProcLangs);
 4152 bruce                     163 ECB             : 
 1469 peter                     164 CBC         118 :     pg_log_info("reading user-defined aggregate functions");
 2643 tgl                       165 GIC         118 :     getAggregates(fout, &numAggregates);
 4152 bruce                     166 ECB             : 
 1469 peter                     167 CBC         118 :     pg_log_info("reading user-defined operators");
  534 tgl                       168 GIC         118 :     (void) getOperators(fout, &numOperators);
 4152 bruce                     169 ECB             : 
 1469 peter                     170 CBC         118 :     pg_log_info("reading user-defined access methods");
 2573 alvherre                  171 GIC         118 :     getAccessMethods(fout, &numAccessMethods);
 2573 alvherre                  172 ECB             : 
 1469 peter                     173 CBC         118 :     pg_log_info("reading user-defined operator classes");
 4080 rhaas                     174 GIC         118 :     getOpclasses(fout, &numOpclasses);
 4152 bruce                     175 ECB             : 
 1469 peter                     176 CBC         118 :     pg_log_info("reading user-defined operator families");
 4080 rhaas                     177 GIC         118 :     getOpfamilies(fout, &numOpfamilies);
 4152 bruce                     178 ECB             : 
 1469 peter                     179 CBC         118 :     pg_log_info("reading user-defined text search parsers");
 4080 rhaas                     180 GIC         118 :     getTSParsers(fout, &numTSParsers);
 4152 bruce                     181 ECB             : 
 1469 peter                     182 CBC         118 :     pg_log_info("reading user-defined text search templates");
 4080 rhaas                     183 GIC         118 :     getTSTemplates(fout, &numTSTemplates);
 6026 tgl                       184 ECB             : 
 1469 peter                     185 CBC         118 :     pg_log_info("reading user-defined text search dictionaries");
 4080 rhaas                     186 GIC         118 :     getTSDictionaries(fout, &numTSDicts);
 4152 bruce                     187 ECB             : 
 1469 peter                     188 CBC         118 :     pg_log_info("reading user-defined text search configurations");
 4080 rhaas                     189 GIC         118 :     getTSConfigurations(fout, &numTSConfigs);
 4152 bruce                     190 ECB             : 
 1469 peter                     191 CBC         118 :     pg_log_info("reading user-defined foreign-data wrappers");
 4080 rhaas                     192 GIC         118 :     getForeignDataWrappers(fout, &numForeignDataWrappers);
 4152 bruce                     193 ECB             : 
 1469 peter                     194 CBC         118 :     pg_log_info("reading user-defined foreign servers");
 4080 rhaas                     195 GIC         118 :     getForeignServers(fout, &numForeignServers);
 4152 bruce                     196 ECB             : 
 1469 peter                     197 CBC         118 :     pg_log_info("reading default privileges");
 2643 tgl                       198 GIC         118 :     getDefaultACLs(fout, &numDefaultACLs);
 4152 bruce                     199 ECB             : 
 1469 peter                     200 CBC         118 :     pg_log_info("reading user-defined collations");
  534 tgl                       201 GIC         118 :     (void) getCollations(fout, &numCollations);
 4152 bruce                     202 ECB             : 
 1469 peter                     203 CBC         118 :     pg_log_info("reading user-defined conversions");
 4080 rhaas                     204 GIC         118 :     getConversions(fout, &numConversions);
 4152 bruce                     205 ECB             : 
 1469 peter                     206 CBC         118 :     pg_log_info("reading type casts");
 2643 tgl                       207 GIC         118 :     getCasts(fout, &numCasts);
 4152 bruce                     208 ECB             : 
 1469 peter                     209 CBC         118 :     pg_log_info("reading transforms");
 2905 peter_e                   210 GIC         118 :     getTransforms(fout, &numTransforms);
 2905 peter_e                   211 ECB             : 
 1469 peter                     212 CBC         118 :     pg_log_info("reading table inheritance information");
 4080 rhaas                     213 GIC         118 :     inhinfo = getInherits(fout, &numInherits);
 4152 bruce                     214 ECB             : 
 1469 peter                     215 CBC         118 :     pg_log_info("reading event triggers");
 3591 mail                      216 GIC         118 :     getEventTriggers(fout, &numEventTriggers);
                                217                 : 
 2643 tgl                       218 ECB             :     /* Identify extension configuration tables that should be dumped */
 1469 peter                     219 CBC         118 :     pg_log_info("finding extension tables");
 2643 tgl                       220 GIC         118 :     processExtensionTables(fout, extinfo, numExtensions);
                                221                 : 
 4152 bruce                     222 ECB             :     /* Link tables to parents, mark parents of target tables interesting */
 1469 peter                     223 CBC         118 :     pg_log_info("finding inheritance relationships");
 2064 rhaas                     224 GIC         118 :     flagInhTables(fout, tblinfo, numTables, inhinfo, numInherits);
 4152 bruce                     225 ECB             : 
 1469 peter                     226 CBC         118 :     pg_log_info("reading column info for interesting tables");
 2643 tgl                       227 GIC         118 :     getTableAttrs(fout, tblinfo, numTables);
 4152 bruce                     228 ECB             : 
 1469 peter                     229 CBC         118 :     pg_log_info("flagging inherited columns in subtables");
    2 alvherre                  230 GNC         118 :     flagInhAttrs(fout, fout->dopt, tblinfo, numTables);
 4152 bruce                     231 ECB             : 
   23 tgl                       232 CBC         118 :     pg_log_info("reading partitioning data");
   23 tgl                       233 GIC         118 :     getPartitioningInfo(fout);
   23 tgl                       234 ECB             : 
 1469 peter                     235 CBC         118 :     pg_log_info("reading indexes");
 4080 rhaas                     236 GIC         118 :     getIndexes(fout, tblinfo, numTables);
 4152 bruce                     237 ECB             : 
 1469 peter                     238 CBC         118 :     pg_log_info("flagging indexes in partitioned tables");
 1906 alvherre                  239 GIC         118 :     flagInhIndexes(fout, tblinfo, numTables);
 1906 alvherre                  240 ECB             : 
 1469 peter                     241 CBC         118 :     pg_log_info("reading extended statistics");
 1883 tgl                       242 GIC         118 :     getExtendedStatistics(fout);
 2207 alvherre                  243 ECB             : 
 1469 peter                     244 CBC         118 :     pg_log_info("reading constraints");
 4080 rhaas                     245 GIC         118 :     getConstraints(fout, tblinfo, numTables);
 4152 bruce                     246 ECB             : 
 1469 peter                     247 CBC         118 :     pg_log_info("reading triggers");
 4080 rhaas                     248 GIC         118 :     getTriggers(fout, tblinfo, numTables);
 4152 bruce                     249 ECB             : 
 1469 peter                     250 CBC         118 :     pg_log_info("reading rewrite rules");
 3591 mail                      251 GIC         118 :     getRules(fout, &numRules);
 3917 rhaas                     252 ECB             : 
 1469 peter                     253 CBC         118 :     pg_log_info("reading policies");
 3055 sfrost                    254 GIC         118 :     getPolicies(fout, tblinfo, numTables);
 3124 sfrost                    255 ECB             : 
 1469 peter                     256 CBC         118 :     pg_log_info("reading publications");
  534 tgl                       257 GIC         118 :     (void) getPublications(fout, &numPublications);
 2271 peter_e                   258 ECB             : 
  529 akapila                   259 CBC         118 :     pg_log_info("reading publication membership of tables");
 2271 peter_e                   260 GIC         118 :     getPublicationTables(fout, tblinfo, numTables);
 2271 peter_e                   261 ECB             : 
  529 akapila                   262 CBC         118 :     pg_log_info("reading publication membership of schemas");
  529 akapila                   263 GIC         118 :     getPublicationNamespaces(fout);
  529 akapila                   264 ECB             : 
 1469 peter                     265 CBC         118 :     pg_log_info("reading subscriptions");
 2271 peter_e                   266 GIC         118 :     getSubscriptions(fout);
 2271 peter_e                   267 ECB             : 
  532 tgl                       268 GIC         118 :     free(inhinfo);              /* not needed any longer */
  532 tgl                       269 ECB             : 
 4152 bruce                     270 CBC         118 :     *numTablesPtr = numTables;
 4152 bruce                     271 GIC         118 :     return tblinfo;
                                272                 : }
                                273                 : 
                                274                 : /* flagInhTables -
                                275                 :  *   Fill in parent link fields of tables for which we need that information,
                                276                 :  *   mark parents of target tables as interesting, and create
                                277                 :  *   TableAttachInfo objects for partitioned tables with appropriate
                                278                 :  *   dependency links.
                                279                 :  *
                                280                 :  * Note that only direct ancestors of targets are marked interesting.
                                281                 :  * This is sufficient; we don't much care whether they inherited their
                                282                 :  * attributes or not.
                                283                 :  *
                                284                 :  * modifies tblinfo
                                285                 :  */
 4152 bruce                     286 ECB             : static void
 2064 rhaas                     287 GIC         118 : flagInhTables(Archive *fout, TableInfo *tblinfo, int numTables,
                                288                 :               InhInfo *inhinfo, int numInherits)
 6026 tgl                       289 ECB             : {
   23 tgl                       290 GNC         118 :     TableInfo  *child = NULL;
                                291             118 :     TableInfo  *parent = NULL;
 4152 bruce                     292 ECB             :     int         i,
                                293                 :                 j;
                                294                 : 
                                295                 :     /*
                                296                 :      * Set up links from child tables to their parents.
                                297                 :      *
                                298                 :      * We used to attempt to skip this work for tables that are not to be
                                299                 :      * dumped; but the optimizable cases are rare in practice, and setting up
                                300                 :      * these links in bulk is cheaper than the old way.  (Note in particular
                                301                 :      * that it's very rare for a child to have more than one parent.)
                                302                 :      */
   23 tgl                       303 GNC        2272 :     for (i = 0; i < numInherits; i++)
                                304                 :     {
                                305                 :         /*
                                306                 :          * Skip a hashtable lookup if it's same table as last time.  This is
                                307                 :          * unlikely for the child, but less so for the parent.  (Maybe we
                                308                 :          * should ask the backend for a sorted array to make it more likely?
                                309                 :          * Not clear the sorting effort would be repaid, though.)
                                310                 :          */
                                311            2154 :         if (child == NULL ||
                                312            1543 :             child->dobj.catId.oid != inhinfo[i].inhrelid)
                                313                 :         {
                                314            2129 :             child = findTableByOid(inhinfo[i].inhrelid);
                                315                 : 
                                316                 :             /*
                                317                 :              * If we find no TableInfo, assume the pg_inherits entry is for a
                                318                 :              * partitioned index, which we don't need to track.
                                319                 :              */
                                320            2129 :             if (child == NULL)
                                321             607 :                 continue;
                                322                 :         }
                                323            1547 :         if (parent == NULL ||
                                324            1495 :             parent->dobj.catId.oid != inhinfo[i].inhparent)
                                325                 :         {
                                326             960 :             parent = findTableByOid(inhinfo[i].inhparent);
                                327             960 :             if (parent == NULL)
   23 tgl                       328 UNC           0 :                 pg_fatal("failed sanity check, parent OID %u of table \"%s\" (OID %u) not found",
                                329                 :                          inhinfo[i].inhparent,
                                330                 :                          child->dobj.name,
                                331                 :                          child->dobj.catId.oid);
                                332                 :         }
                                333                 :         /* Add this parent to the child's list of parents. */
   23 tgl                       334 GNC        1547 :         if (child->numParents > 0)
                                335              25 :             child->parents = pg_realloc_array(child->parents,
                                336                 :                                               TableInfo *,
                                337                 :                                               child->numParents + 1);
                                338                 :         else
                                339            1522 :             child->parents = pg_malloc_array(TableInfo *, 1);
                                340            1547 :         child->parents[child->numParents++] = parent;
                                341                 :     }
                                342                 : 
                                343                 :     /*
                                344                 :      * Now consider all child tables and mark parents interesting as needed.
                                345                 :      */
   23 tgl                       346 GIC       30474 :     for (i = 0; i < numTables; i++)
                                347                 :     {
                                348                 :         /*
 1809 tgl                       349 ECB             :          * If needed, mark the parents as interesting for getTableAttrs and
                                350                 :          * getIndexes.  We only need this for direct parents of dumpable
                                351                 :          * tables.
 1906 alvherre                  352 EUB             :          */
   23 tgl                       353 GNC       30356 :         if (tblinfo[i].dobj.dump)
                                354                 :         {
 2064 rhaas                     355 GIC       20412 :             int         numParents = tblinfo[i].numParents;
                                356           20412 :             TableInfo **parents = tblinfo[i].parents;
                                357                 : 
 2064 rhaas                     358 CBC       21915 :             for (j = 0; j < numParents; j++)
                                359            1503 :                 parents[j]->interesting = true;
                                360                 :         }
                                361                 : 
                                362                 :         /* Create TableAttachInfo object if needed */
   23 tgl                       363 GNC       30356 :         if ((tblinfo[i].dobj.dump & DUMP_COMPONENT_DEFINITION) &&
                                364            5139 :             tblinfo[i].ispartition)
  818 tgl                       365 ECB             :         {
                                366                 :             TableAttachInfo *attachinfo;
                                367                 : 
                                368                 :             /* With partitions there can only be one parent */
  818 tgl                       369 GIC        1166 :             if (tblinfo[i].numParents != 1)
  366 tgl                       370 UIC           0 :                 pg_fatal("invalid number of parents %d for table \"%s\"",
  366 tgl                       371 ECB             :                          tblinfo[i].numParents,
                                372                 :                          tblinfo[i].dobj.name);
                                373                 : 
  818 tgl                       374 GIC        1166 :             attachinfo = (TableAttachInfo *) palloc(sizeof(TableAttachInfo));
                                375            1166 :             attachinfo->dobj.objType = DO_TABLE_ATTACH;
                                376            1166 :             attachinfo->dobj.catId.tableoid = 0;
                                377            1166 :             attachinfo->dobj.catId.oid = 0;
  818 tgl                       378 CBC        1166 :             AssignDumpId(&attachinfo->dobj);
  818 tgl                       379 GIC        1166 :             attachinfo->dobj.name = pg_strdup(tblinfo[i].dobj.name);
  818 tgl                       380 CBC        1166 :             attachinfo->dobj.namespace = tblinfo[i].dobj.namespace;
                                381            1166 :             attachinfo->parentTbl = tblinfo[i].parents[0];
  818 tgl                       382 GIC        1166 :             attachinfo->partitionTbl = &tblinfo[i];
  818 tgl                       383 ECB             : 
                                384                 :             /*
                                385                 :              * We must state the DO_TABLE_ATTACH object's dependencies
                                386                 :              * explicitly, since it will not match anything in pg_depend.
                                387                 :              *
                                388                 :              * Give it dependencies on both the partition table and the parent
                                389                 :              * table, so that it will not be executed till both of those
                                390                 :              * exist.  (There's no need to care what order those are created
                                391                 :              * in.)
                                392                 :              */
  818 tgl                       393 GIC        1166 :             addObjectDependency(&attachinfo->dobj, tblinfo[i].dobj.dumpId);
  818 tgl                       394 CBC        1166 :             addObjectDependency(&attachinfo->dobj, tblinfo[i].parents[0]->dobj.dumpId);
  818 tgl                       395 EUB             :         }
                                396                 :     }
 6026 tgl                       397 GIC         118 : }
                                398                 : 
 1906 alvherre                  399 ECB             : /*
                                400                 :  * flagInhIndexes -
 1392 michael                   401                 :  *   Create IndexAttachInfo objects for partitioned indexes, and add
 1906 alvherre                  402                 :  *   appropriate dependency links.
                                403                 :  */
                                404                 : static void
 1906 alvherre                  405 CBC         118 : flagInhIndexes(Archive *fout, TableInfo tblinfo[], int numTables)
 1906 alvherre                  406 ECB             : {
 1809 tgl                       407                 :     int         i,
                                408                 :                 j;
                                409                 : 
 1906 alvherre                  410 GIC       30474 :     for (i = 0; i < numTables; i++)
                                411                 :     {
                                412           30356 :         if (!tblinfo[i].ispartition || tblinfo[i].numParents == 0)
                                413           29164 :             continue;
                                414                 : 
                                415            1192 :         Assert(tblinfo[i].numParents == 1);
                                416                 : 
  532 tgl                       417            1809 :         for (j = 0; j < tblinfo[i].numIndexes; j++)
 1906 alvherre                  418 ECB             :         {
 1906 alvherre                  419 CBC         617 :             IndxInfo   *index = &(tblinfo[i].indexes[j]);
                                420                 :             IndxInfo   *parentidx;
                                421                 :             IndexAttachInfo *attachinfo;
 1906 alvherre                  422 ECB             : 
 1906 alvherre                  423 GIC         617 :             if (index->parentidx == 0)
                                424              50 :                 continue;
                                425                 : 
  534 tgl                       426             567 :             parentidx = findIndexByOid(index->parentidx);
 1906 alvherre                  427             567 :             if (parentidx == NULL)
 1906 alvherre                  428 UIC           0 :                 continue;
                                429                 : 
  209 peter                     430 GNC         567 :             attachinfo = pg_malloc_object(IndexAttachInfo);
                                431                 : 
  532 tgl                       432 GIC         567 :             attachinfo->dobj.objType = DO_INDEX_ATTACH;
                                433             567 :             attachinfo->dobj.catId.tableoid = 0;
                                434             567 :             attachinfo->dobj.catId.oid = 0;
  532 tgl                       435 CBC         567 :             AssignDumpId(&attachinfo->dobj);
  532 tgl                       436 GIC         567 :             attachinfo->dobj.name = pg_strdup(index->dobj.name);
  532 tgl                       437 CBC         567 :             attachinfo->dobj.namespace = index->indextable->dobj.namespace;
                                438             567 :             attachinfo->parentIdx = parentidx;
  532 tgl                       439 GIC         567 :             attachinfo->partitionIdx = index;
 1906 alvherre                  440 ECB             : 
                                441                 :             /*
 1685 tgl                       442                 :              * We must state the DO_INDEX_ATTACH object's dependencies
                                443                 :              * explicitly, since it will not match anything in pg_depend.
                                444                 :              *
                                445                 :              * Give it dependencies on both the partition index and the parent
                                446                 :              * index, so that it will not be executed till both of those
                                447                 :              * exist.  (There's no need to care what order those are created
                                448                 :              * in.)
                                449                 :              *
                                450                 :              * In addition, give it dependencies on the indexes' underlying
                                451                 :              * tables.  This does nothing of great value so far as serial
                                452                 :              * restore ordering goes, but it ensures that a parallel restore
 1685 tgl                       453 EUB             :              * will not try to run the ATTACH concurrently with other
                                454                 :              * operations on those tables.
 1906 alvherre                  455 ECB             :              */
  532 tgl                       456 GIC         567 :             addObjectDependency(&attachinfo->dobj, index->dobj.dumpId);
  532 tgl                       457 CBC         567 :             addObjectDependency(&attachinfo->dobj, parentidx->dobj.dumpId);
                                458             567 :             addObjectDependency(&attachinfo->dobj,
 1685                           459             567 :                                 index->indextable->dobj.dumpId);
  532                           460             567 :             addObjectDependency(&attachinfo->dobj,
 1685                           461             567 :                                 parentidx->indextable->dobj.dumpId);
 1906 alvherre                  462 ECB             : 
 1270                           463                 :             /* keep track of the list of partitions in the parent index */
  532 tgl                       464 CBC         567 :             simple_ptr_list_append(&parentidx->partattaches, &attachinfo->dobj);
                                465                 :         }
                                466                 :     }
 1906 alvherre                  467 GIC         118 : }
                                468                 : 
                                469                 : /* flagInhAttrs -
                                470                 :  *   for each dumpable table in tblinfo, flag its inherited attributes
                                471                 :  *
                                472                 :  * What we need to do here is:
                                473                 :  *
                                474                 :  * - Detect child columns that inherit NOT NULL bits from their parents, so
                                475                 :  *   that we needn't specify that again for the child. (Versions >= 16 no
                                476                 :  *   longer need this.)
                                477                 :  *
                                478                 :  * - Detect child columns that have DEFAULT NULL when their parents had some
                                479                 :  *   non-null default.  In this case, we make up a dummy AttrDefInfo object so
                                480                 :  *   that we'll correctly emit the necessary DEFAULT NULL clause; otherwise
                                481                 :  *   the backend will apply an inherited default to the column.
  795 peter                     482 ECB             :  *
                                483                 :  * - Detect child columns that have a generation expression and all their
                                484                 :  *   parents also have the same generation expression, and if so suppress the
                                485                 :  *   child's expression.  The child will inherit the generation expression
                                486                 :  *   automatically, so there's no need to dump it.  This improves the dump's
                                487                 :  *   compatibility with pre-v16 servers, which didn't allow the child's
                                488                 :  *   expression to be given explicitly.  Exceptions: If it's a partition or
                                489                 :  *   we are in binary upgrade mode, we dump such expressions anyway because
                                490                 :  *   in those cases inherited tables are recreated standalone first and then
                                491                 :  *   reattached to the parent.  (See also the logic in dumpTableSchema().)
                                492                 :  *
                                493                 :  * modifies tblinfo
 4152 bruce                     494                 :  */
                                495                 : static void
    2 alvherre                  496 GNC         118 : flagInhAttrs(Archive *fout, DumpOptions *dopt, TableInfo *tblinfo, int numTables)
                                497                 : {
                                498                 :     int         i,
                                499                 :                 j,
                                500                 :                 k;
                                501                 : 
                                502                 :     /*
                                503                 :      * We scan the tables in OID order, since that's how tblinfo[] is sorted.
                                504                 :      * Hence we will typically visit parents before their children --- but
                                505                 :      * that is *not* guaranteed.  Thus this loop must be careful that it does
                                506                 :      * not alter table properties in a way that could change decisions made at
                                507                 :      * child tables during other iterations.
                                508                 :      */
 4152 bruce                     509 GIC       30474 :     for (i = 0; i < numTables; i++)
                                510                 :     {
                                511           30356 :         TableInfo  *tbinfo = &(tblinfo[i]);
                                512                 :         int         numParents;
                                513                 :         TableInfo **parents;
                                514                 : 
                                515                 :         /* Some kinds never have parents */
                                516           30356 :         if (tbinfo->relkind == RELKIND_SEQUENCE ||
 3689 kgrittn                   517           29911 :             tbinfo->relkind == RELKIND_VIEW ||
                                518           12993 :             tbinfo->relkind == RELKIND_MATVIEW)
 4152 bruce                     519           17763 :             continue;
                                520                 : 
                                521                 :         /* Don't bother computing anything for non-target tables, either */
                                522           12593 :         if (!tbinfo->dobj.dump)
                                523            1425 :             continue;
                                524                 : 
                                525           11168 :         numParents = tbinfo->numParents;
                                526           11168 :         parents = tbinfo->parents;
                                527                 : 
                                528           11168 :         if (numParents == 0)
                                529            9690 :             continue;           /* nothing to see here, move along */
 4152 bruce                     530 ECB             : 
                                531                 :         /* For each column, search for matching column names in parent(s) */
 4152 bruce                     532 GIC        5485 :         for (j = 0; j < tbinfo->numatts; j++)
                                533                 :         {
                                534                 :             bool        foundNotNull;   /* Attr was NOT NULL in a parent */
                                535                 :             bool        foundDefault;   /* Found a default in a parent */
                                536                 :             bool        foundSameGenerated; /* Found matching GENERATED */
                                537                 :             bool        foundDiffGenerated; /* Found non-matching GENERATED */
                                538                 : 
                                539                 :             /* no point in examining dropped columns */
 4076 tgl                       540            4007 :             if (tbinfo->attisdropped[j])
                                541             305 :                 continue;
                                542                 : 
                                543            3702 :             foundNotNull = false;
 4076 tgl                       544 CBC        3702 :             foundDefault = false;
   88 tgl                       545 GNC        3702 :             foundSameGenerated = false;
                                546            3702 :             foundDiffGenerated = false;
 4152 bruce                     547 CBC        7524 :             for (k = 0; k < numParents; k++)
                                548                 :             {
 4076 tgl                       549 GIC        3822 :                 TableInfo  *parent = parents[k];
                                550                 :                 int         inhAttrInd;
                                551                 : 
 4152 bruce                     552 CBC        3822 :                 inhAttrInd = strInArray(tbinfo->attnames[j],
 4152 bruce                     553 ECB             :                                         parent->attnames,
                                554                 :                                         parent->numatts);
 4076 tgl                       555 CBC        3822 :                 if (inhAttrInd >= 0)
                                556                 :                 {
   40 tgl                       557 GNC        3637 :                     AttrDefInfo *parentDef = parent->attrdefs[inhAttrInd];
                                558                 : 
 4152 bruce                     559 GIC        3637 :                     foundNotNull |= parent->notnull[inhAttrInd];
   40 tgl                       560 GNC        7654 :                     foundDefault |= (parentDef != NULL &&
                                561            3967 :                                      strcmp(parentDef->adef_expr, "NULL") != 0 &&
   88                           562             330 :                                      !parent->attgenerated[inhAttrInd]);
                                563            3637 :                     if (parent->attgenerated[inhAttrInd])
                                564                 :                     {
                                565                 :                         /* these pointer nullness checks are just paranoia */
   40                           566             128 :                         if (parentDef != NULL &&
   88                           567             122 :                             tbinfo->attrdefs[j] != NULL &&
   40                           568             122 :                             strcmp(parentDef->adef_expr,
   88                           569             122 :                                    tbinfo->attrdefs[j]->adef_expr) == 0)
                                570              97 :                             foundSameGenerated = true;
                                571                 :                         else
                                572              31 :                             foundDiffGenerated = true;
                                573                 :                     }
                                574                 :                 }
 4152 bruce                     575 ECB             :             }
                                576                 : 
                                577                 :             /* In versions < 16, remember if we found inherited NOT NULL */
    2 alvherre                  578 GNC        3702 :             if (fout->remoteVersion < 160000)
    2 alvherre                  579 UNC           0 :                 tbinfo->localNotNull[j] = !foundNotNull;
 4076 tgl                       580 ECB             : 
                                581                 :             /*
                                582                 :              * Manufacture a DEFAULT NULL clause if necessary.  This breaks
                                583                 :              * the advice given above to avoid changing state that might get
                                584                 :              * inspected in other loop iterations.  We prevent trouble by
                                585                 :              * having the foundDefault test above check whether adef_expr is
                                586                 :              * "NULL", so that it will reach the same conclusion before or
                                587                 :              * after this is done.
                                588                 :              */
 4076 tgl                       589 GIC        3702 :             if (foundDefault && tbinfo->attrdefs[j] == NULL)
 4152 bruce                     590 ECB             :             {
                                591                 :                 AttrDefInfo *attrDef;
                                592                 : 
  209 peter                     593 GNC          40 :                 attrDef = pg_malloc_object(AttrDefInfo);
 4076 tgl                       594 GIC          40 :                 attrDef->dobj.objType = DO_ATTRDEF;
                                595              40 :                 attrDef->dobj.catId.tableoid = 0;
                                596              40 :                 attrDef->dobj.catId.oid = 0;
                                597              40 :                 AssignDumpId(&attrDef->dobj);
 4076 tgl                       598 CBC          40 :                 attrDef->dobj.name = pg_strdup(tbinfo->dobj.name);
                                599              40 :                 attrDef->dobj.namespace = tbinfo->dobj.namespace;
 4076 tgl                       600 GIC          40 :                 attrDef->dobj.dump = tbinfo->dobj.dump;
 4076 tgl                       601 ECB             : 
 4076 tgl                       602 CBC          40 :                 attrDef->adtable = tbinfo;
                                603              40 :                 attrDef->adnum = j + 1;
                                604              40 :                 attrDef->adef_expr = pg_strdup("NULL");
 4076 tgl                       605 ECB             : 
                                606                 :                 /* Will column be dumped explicitly? */
 3099 alvherre                  607 CBC          40 :                 if (shouldPrintColumn(dopt, tbinfo, j))
                                608                 :                 {
 4076 tgl                       609 GIC          40 :                     attrDef->separate = false;
 4076 tgl                       610 ECB             :                     /* No dependency needed: NULL cannot have dependencies */
                                611                 :                 }
                                612                 :                 else
 4152 bruce                     613                 :                 {
                                614                 :                     /* column will be suppressed, print default separately */
 4076 tgl                       615 LBC           0 :                     attrDef->separate = true;
                                616                 :                     /* ensure it comes out after the table */
                                617               0 :                     addObjectDependency(&attrDef->dobj,
 4076 tgl                       618 ECB             :                                         tbinfo->dobj.dumpId);
 4152 bruce                     619                 :                 }
                                620                 : 
 4076 tgl                       621 CBC          40 :                 tbinfo->attrdefs[j] = attrDef;
                                622                 :             }
                                623                 : 
                                624                 :             /* No need to dump generation expression if it's inheritable */
   88 tgl                       625 GNC        3702 :             if (foundSameGenerated && !foundDiffGenerated &&
                                626              97 :                 !tbinfo->ispartition && !dopt->binary_upgrade)
   40                           627              86 :                 tbinfo->attrdefs[j]->dobj.dump = DUMP_COMPONENT_NONE;
 4152 bruce                     628 ECB             :         }
                                629                 :     }
 4152 bruce                     630 GIC         118 : }
 4152 bruce                     631 ECB             : 
                                632                 : /*
                                633                 :  * AssignDumpId
                                634                 :  *      Given a newly-created dumpable object, assign a dump ID,
                                635                 :  *      and enter the object into the lookup tables.
                                636                 :  *
                                637                 :  * The caller is expected to have filled in objType and catId,
 4152 bruce                     638 EUB             :  * but not any of the other standard fields of a DumpableObject.
                                639                 :  */
                                640                 : void
 4152 bruce                     641 GIC      510276 : AssignDumpId(DumpableObject *dobj)
                                642                 : {
                                643          510276 :     dobj->dumpId = ++lastDumpId;
                                644          510276 :     dobj->name = NULL;           /* must be set later */
                                645          510276 :     dobj->namespace = NULL;      /* may be set later */
 2559 sfrost                    646          510276 :     dobj->dump = DUMP_COMPONENT_ALL; /* default assumption */
  818 tgl                       647          510276 :     dobj->dump_contains = DUMP_COMPONENT_ALL;    /* default assumption */
  489 tgl                       648 ECB             :     /* All objects have definitions; we may set more components bits later */
  489 tgl                       649 GIC      510276 :     dobj->components = DUMP_COMPONENT_DEFINITION;
 4152 bruce                     650          510276 :     dobj->ext_member = false;    /* default assumption */
 1124 alvherre                  651          510276 :     dobj->depends_on_ext = false;    /* default assumption */
 4152 bruce                     652 CBC      510276 :     dobj->dependencies = NULL;
                                653          510276 :     dobj->nDeps = 0;
                                654          510276 :     dobj->allocDeps = 0;
 4152 bruce                     655 ECB             : 
  534 tgl                       656                 :     /* Add object to dumpIdMap[], enlarging that array if need be */
 4152 bruce                     657 CBC      510923 :     while (dobj->dumpId >= allocedDumpIds)
 4152 bruce                     658 ECB             :     {
                                659                 :         int         newAlloc;
                                660                 : 
 4152 bruce                     661 CBC         647 :         if (allocedDumpIds <= 0)
 4152 bruce                     662 ECB             :         {
 4152 bruce                     663 CBC         119 :             newAlloc = 256;
  209 peter                     664 GNC         119 :             dumpIdMap = pg_malloc_array(DumpableObject *, newAlloc);
 4152 bruce                     665 ECB             :         }
                                666                 :         else
                                667                 :         {
 4152 bruce                     668 GIC         528 :             newAlloc = allocedDumpIds * 2;
  209 peter                     669 GNC         528 :             dumpIdMap = pg_realloc_array(dumpIdMap, DumpableObject *, newAlloc);
                                670                 :         }
 4152 bruce                     671 GIC         647 :         memset(dumpIdMap + allocedDumpIds, 0,
 4152 bruce                     672 GBC         647 :                (newAlloc - allocedDumpIds) * sizeof(DumpableObject *));
 4152 bruce                     673 GIC         647 :         allocedDumpIds = newAlloc;
 4152 bruce                     674 EUB             :     }
 4152 bruce                     675 GIC      510276 :     dumpIdMap[dobj->dumpId] = dobj;
                                676                 : 
                                677                 :     /* If it has a valid CatalogId, enter it into the hash table */
  534 tgl                       678 CBC      510276 :     if (OidIsValid(dobj->catId.tableoid))
                                679                 :     {
                                680                 :         CatalogIdMapEntry *entry;
                                681                 :         bool        found;
  534 tgl                       682 ECB             : 
                                683                 :         /* Initialize CatalogId hash table if not done yet */
  534 tgl                       684 CBC      498767 :         if (catalogIdHash == NULL)
  534 tgl                       685 GIC         119 :             catalogIdHash = catalogid_create(CATALOGIDHASH_INITIAL_SIZE, NULL);
                                686                 : 
  534 tgl                       687 CBC      498767 :         entry = catalogid_insert(catalogIdHash, dobj->catId, &found);
  534 tgl                       688 GIC      498767 :         if (!found)
                                689                 :         {
                                690          498295 :             entry->dobj = NULL;
                                691          498295 :             entry->ext = NULL;
                                692                 :         }
                                693          498767 :         Assert(entry->dobj == NULL);
                                694          498767 :         entry->dobj = dobj;
                                695                 :     }
 4152 bruce                     696          510276 : }
                                697                 : 
 4152 bruce                     698 ECB             : /*
                                699                 :  * Assign a DumpId that's not tied to a DumpableObject.
                                700                 :  *
                                701                 :  * This is used when creating a "fixed" ArchiveEntry that doesn't need to
                                702                 :  * participate in the sorting logic.
                                703                 :  */
                                704                 : DumpId
 4152 bruce                     705 GIC        3626 : createDumpId(void)
 4152 bruce                     706 ECB             : {
 4152 bruce                     707 CBC        3626 :     return ++lastDumpId;
 4152 bruce                     708 ECB             : }
                                709                 : 
                                710                 : /*
                                711                 :  * Return the largest DumpId so far assigned
                                712                 :  */
                                713                 : DumpId
 4152 bruce                     714 CBC         898 : getMaxDumpId(void)
                                715                 : {
 4152 bruce                     716 GIC         898 :     return lastDumpId;
                                717                 : }
 4152 bruce                     718 ECB             : 
                                719                 : /*
                                720                 :  * Find a DumpableObject by dump ID
                                721                 :  *
                                722                 :  * Returns NULL for invalid ID
                                723                 :  */
                                724                 : DumpableObject *
 4152 bruce                     725 CBC    17510433 : findObjectByDumpId(DumpId dumpId)
 4152 bruce                     726 ECB             : {
 4152 bruce                     727 GIC    17510433 :     if (dumpId <= 0 || dumpId >= allocedDumpIds)
 4152 bruce                     728 LBC           0 :         return NULL;            /* out of range? */
 4152 bruce                     729 CBC    17510433 :     return dumpIdMap[dumpId];
 4152 bruce                     730 ECB             : }
                                731                 : 
                                732                 : /*
                                733                 :  * Find a DumpableObject by catalog ID
                                734                 :  *
                                735                 :  * Returns NULL for unknown ID
                                736                 :  */
                                737                 : DumpableObject *
 4152 bruce                     738 GIC     1545284 : findObjectByCatalogId(CatalogId catalogId)
                                739                 : {
                                740                 :     CatalogIdMapEntry *entry;
 4152 bruce                     741 ECB             : 
  534 tgl                       742 CBC     1545284 :     if (catalogIdHash == NULL)
  534 tgl                       743 UIC           0 :         return NULL;            /* no objects exist yet */
 4152 bruce                     744 ECB             : 
  534 tgl                       745 CBC     1545284 :     entry = catalogid_lookup(catalogIdHash, catalogId);
  534 tgl                       746 GIC     1545284 :     if (entry == NULL)
 4152 bruce                     747 CBC      410718 :         return NULL;
  534 tgl                       748         1134566 :     return entry->dobj;
                                749                 : }
 4152 bruce                     750 ECB             : 
                                751                 : /*
                                752                 :  * Build an array of pointers to all known dumpable objects
                                753                 :  *
                                754                 :  * This simply creates a modifiable copy of the internal map.
                                755                 :  */
                                756                 : void
 4152 bruce                     757 GIC         124 : getDumpableObjects(DumpableObject ***objs, int *numObjs)
                                758                 : {
                                759                 :     int         i,
                                760                 :                 j;
                                761                 : 
  209 peter                     762 GNC         124 :     *objs = pg_malloc_array(DumpableObject *, allocedDumpIds);
 4152 bruce                     763 CBC         124 :     j = 0;
 4152 bruce                     764 GIC      770048 :     for (i = 1; i < allocedDumpIds; i++)
                                765                 :     {
                                766          769924 :         if (dumpIdMap[i])
                                767          535191 :             (*objs)[j++] = dumpIdMap[i];
                                768                 :     }
                                769             124 :     *numObjs = j;
 4152 bruce                     770 CBC         124 : }
                                771                 : 
 4152 bruce                     772 ECB             : /*
                                773                 :  * Add a dependency link to a DumpableObject
                                774                 :  *
                                775                 :  * Note: duplicate dependencies are currently not eliminated
                                776                 :  */
                                777                 : void
 4152 bruce                     778 GIC      762922 : addObjectDependency(DumpableObject *dobj, DumpId refId)
                                779                 : {
                                780          762922 :     if (dobj->nDeps >= dobj->allocDeps)
 4152 bruce                     781 ECB             :     {
 4152 bruce                     782 GIC      113381 :         if (dobj->allocDeps <= 0)
 4152 bruce                     783 ECB             :         {
 4152 bruce                     784 GBC      110466 :             dobj->allocDeps = 16;
  209 peter                     785 GNC      110466 :             dobj->dependencies = pg_malloc_array(DumpId, dobj->allocDeps);
                                786                 :         }
                                787                 :         else
                                788                 :         {
 4152 bruce                     789 GIC        2915 :             dobj->allocDeps *= 2;
  209 peter                     790 GNC        2915 :             dobj->dependencies = pg_realloc_array(dobj->dependencies,
                                791                 :                                                   DumpId, dobj->allocDeps);
 4152 bruce                     792 ECB             :         }
                                793                 :     }
 4152 bruce                     794 GIC      762922 :     dobj->dependencies[dobj->nDeps++] = refId;
                                795          762922 : }
 4152 bruce                     796 ECB             : 
 4152 bruce                     797 EUB             : /*
                                798                 :  * Remove a dependency link from a DumpableObject
 4152 bruce                     799 ECB             :  *
                                800                 :  * If there are multiple links, all are removed
                                801                 :  */
                                802                 : void
 4152 bruce                     803 GIC       19405 : removeObjectDependency(DumpableObject *dobj, DumpId refId)
                                804                 : {
                                805                 :     int         i;
                                806           19405 :     int         j = 0;
                                807                 : 
                                808           90523 :     for (i = 0; i < dobj->nDeps; i++)
                                809                 :     {
                                810           71118 :         if (dobj->dependencies[i] != refId)
 4152 bruce                     811 CBC       50666 :             dobj->dependencies[j++] = dobj->dependencies[i];
                                812                 :     }
 4152 bruce                     813 GIC       19405 :     dobj->nDeps = j;
                                814           19405 : }
                                815                 : 
 4152 bruce                     816 ECB             : 
                                817                 : /*
                                818                 :  * findTableByOid
                                819                 :  *    finds the DumpableObject for the table with the given oid
                                820                 :  *    returns NULL if not found
                                821                 :  */
                                822                 : TableInfo *
 4152 bruce                     823 CBC       52146 : findTableByOid(Oid oid)
 4152 bruce                     824 ECB             : {
                                825                 :     CatalogId   catId;
                                826                 :     DumpableObject *dobj;
                                827                 : 
  534 tgl                       828 GIC       52146 :     catId.tableoid = RelationRelationId;
                                829           52146 :     catId.oid = oid;
                                830           52146 :     dobj = findObjectByCatalogId(catId);
                                831           52146 :     Assert(dobj == NULL || dobj->objType == DO_TABLE);
  534 tgl                       832 CBC       52146 :     return (TableInfo *) dobj;
                                833                 : }
  534 tgl                       834 ECB             : 
                                835                 : /*
                                836                 :  * findIndexByOid
                                837                 :  *    finds the DumpableObject for the index with the given oid
                                838                 :  *    returns NULL if not found
                                839                 :  */
                                840                 : static IndxInfo *
  534 tgl                       841 GIC         567 : findIndexByOid(Oid oid)
                                842                 : {
  534 tgl                       843 ECB             :     CatalogId   catId;
                                844                 :     DumpableObject *dobj;
                                845                 : 
  534 tgl                       846 GIC         567 :     catId.tableoid = RelationRelationId;
                                847             567 :     catId.oid = oid;
  534 tgl                       848 CBC         567 :     dobj = findObjectByCatalogId(catId);
                                849             567 :     Assert(dobj == NULL || dobj->objType == DO_INDEX);
  534 tgl                       850 GIC         567 :     return (IndxInfo *) dobj;
                                851                 : }
                                852                 : 
                                853                 : /*
                                854                 :  * findTypeByOid
                                855                 :  *    finds the DumpableObject for the type with the given oid
                                856                 :  *    returns NULL if not found
 4152 bruce                     857 ECB             :  */
                                858                 : TypeInfo *
 4152 bruce                     859 GIC       55269 : findTypeByOid(Oid oid)
 4152 bruce                     860 ECB             : {
                                861                 :     CatalogId   catId;
  534 tgl                       862                 :     DumpableObject *dobj;
                                863                 : 
  534 tgl                       864 CBC       55269 :     catId.tableoid = TypeRelationId;
                                865           55269 :     catId.oid = oid;
  534 tgl                       866 GIC       55269 :     dobj = findObjectByCatalogId(catId);
  534 tgl                       867 CBC       55269 :     Assert(dobj == NULL ||
  534 tgl                       868 ECB             :            dobj->objType == DO_TYPE || dobj->objType == DO_DUMMY_TYPE);
  534 tgl                       869 GIC       55269 :     return (TypeInfo *) dobj;
                                870                 : }
                                871                 : 
                                872                 : /*
                                873                 :  * findFuncByOid
                                874                 :  *    finds the DumpableObject for the function with the given oid
                                875                 :  *    returns NULL if not found
                                876                 :  */
 4152 bruce                     877 ECB             : FuncInfo *
 4152 bruce                     878 GIC         278 : findFuncByOid(Oid oid)
                                879                 : {
                                880                 :     CatalogId   catId;
                                881                 :     DumpableObject *dobj;
  534 tgl                       882 ECB             : 
  534 tgl                       883 CBC         278 :     catId.tableoid = ProcedureRelationId;
                                884             278 :     catId.oid = oid;
                                885             278 :     dobj = findObjectByCatalogId(catId);
                                886             278 :     Assert(dobj == NULL || dobj->objType == DO_FUNC);
  534 tgl                       887 GIC         278 :     return (FuncInfo *) dobj;
                                888                 : }
                                889                 : 
                                890                 : /*
                                891                 :  * findOprByOid
                                892                 :  *    finds the DumpableObject for the operator with the given oid
                                893                 :  *    returns NULL if not found
                                894                 :  */
 4152 bruce                     895 ECB             : OprInfo *
 4152 bruce                     896 GIC          25 : findOprByOid(Oid oid)
                                897                 : {
                                898                 :     CatalogId   catId;
                                899                 :     DumpableObject *dobj;
  534 tgl                       900 ECB             : 
  534 tgl                       901 CBC          25 :     catId.tableoid = OperatorRelationId;
                                902              25 :     catId.oid = oid;
                                903              25 :     dobj = findObjectByCatalogId(catId);
                                904              25 :     Assert(dobj == NULL || dobj->objType == DO_OPERATOR);
  534 tgl                       905 GIC          25 :     return (OprInfo *) dobj;
                                906                 : }
                                907                 : 
                                908                 : /*
                                909                 :  * findCollationByOid
                                910                 :  *    finds the DumpableObject for the collation with the given oid
                                911                 :  *    returns NULL if not found
                                912                 :  */
 4152 bruce                     913 ECB             : CollInfo *
 4152 bruce                     914 GIC          82 : findCollationByOid(Oid oid)
                                915                 : {
                                916                 :     CatalogId   catId;
                                917                 :     DumpableObject *dobj;
  534 tgl                       918 ECB             : 
  534 tgl                       919 CBC          82 :     catId.tableoid = CollationRelationId;
                                920              82 :     catId.oid = oid;
                                921              82 :     dobj = findObjectByCatalogId(catId);
  534 tgl                       922 GIC          82 :     Assert(dobj == NULL || dobj->objType == DO_COLLATION);
  534 tgl                       923 CBC          82 :     return (CollInfo *) dobj;
                                924                 : }
                                925                 : 
                                926                 : /*
                                927                 :  * findNamespaceByOid
                                928                 :  *    finds the DumpableObject for the namespace with the given oid
                                929                 :  *    returns NULL if not found
                                930                 :  */
                                931                 : NamespaceInfo *
 3971                           932          446460 : findNamespaceByOid(Oid oid)
                                933                 : {
                                934                 :     CatalogId   catId;
                                935                 :     DumpableObject *dobj;
                                936                 : 
  534                           937          446460 :     catId.tableoid = NamespaceRelationId;
                                938          446460 :     catId.oid = oid;
                                939          446460 :     dobj = findObjectByCatalogId(catId);
                                940          446460 :     Assert(dobj == NULL || dobj->objType == DO_NAMESPACE);
                                941          446460 :     return (NamespaceInfo *) dobj;
                                942                 : }
                                943                 : 
                                944                 : /*
                                945                 :  * findExtensionByOid
                                946                 :  *    finds the DumpableObject for the extension with the given oid
                                947                 :  *    returns NULL if not found
                                948                 :  */
                                949                 : ExtensionInfo *
 2643                           950             141 : findExtensionByOid(Oid oid)
                                951                 : {
                                952                 :     CatalogId   catId;
                                953                 :     DumpableObject *dobj;
                                954                 : 
  534                           955             141 :     catId.tableoid = ExtensionRelationId;
                                956             141 :     catId.oid = oid;
                                957             141 :     dobj = findObjectByCatalogId(catId);
                                958             141 :     Assert(dobj == NULL || dobj->objType == DO_EXTENSION);
                                959             141 :     return (ExtensionInfo *) dobj;
                                960                 : }
                                961                 : 
                                962                 : /*
                                963                 :  * findPublicationByOid
                                964                 :  *    finds the DumpableObject for the publication with the given oid
                                965                 :  *    returns NULL if not found
                                966                 :  */
                                967                 : PublicationInfo *
  815                           968             405 : findPublicationByOid(Oid oid)
                                969                 : {
                                970                 :     CatalogId   catId;
                                971                 :     DumpableObject *dobj;
                                972                 : 
  534                           973             405 :     catId.tableoid = PublicationRelationId;
                                974             405 :     catId.oid = oid;
                                975             405 :     dobj = findObjectByCatalogId(catId);
                                976             405 :     Assert(dobj == NULL || dobj->objType == DO_PUBLICATION);
                                977             405 :     return (PublicationInfo *) dobj;
                                978                 : }
                                979                 : 
                                980                 : 
                                981                 : /*
                                982                 :  * recordExtensionMembership
                                983                 :  *    Record that the object identified by the given catalog ID
                                984                 :  *    belongs to the given extension
                                985                 :  */
 2643 tgl                       986 ECB             : void
  534 tgl                       987 GIC         806 : recordExtensionMembership(CatalogId catId, ExtensionInfo *ext)
                                988                 : {
                                989                 :     CatalogIdMapEntry *entry;
                                990                 :     bool        found;
  534 tgl                       991 ECB             : 
                                992                 :     /* CatalogId hash table must exist, if we have an ExtensionInfo */
  534 tgl                       993 CBC         806 :     Assert(catalogIdHash != NULL);
  534 tgl                       994 ECB             : 
                                995                 :     /* Add reference to CatalogId hash */
  534 tgl                       996 GIC         806 :     entry = catalogid_insert(catalogIdHash, catId, &found);
                                997             806 :     if (!found)
                                998                 :     {
                                999             806 :         entry->dobj = NULL;
                               1000             806 :         entry->ext = NULL;
                               1001                 :     }
                               1002             806 :     Assert(entry->ext == NULL);
                               1003             806 :     entry->ext = ext;
 2643 tgl                      1004 CBC         806 : }
                               1005                 : 
                               1006                 : /*
                               1007                 :  * findOwningExtension
                               1008                 :  *    return owning extension for specified catalog ID, or NULL if none
 2643 tgl                      1009 ECB             :  */
                               1010                 : ExtensionInfo *
 2643 tgl                      1011 CBC      445511 : findOwningExtension(CatalogId catalogId)
 2643 tgl                      1012 ECB             : {
  534                          1013                 :     CatalogIdMapEntry *entry;
                               1014                 : 
  534 tgl                      1015 GIC      445511 :     if (catalogIdHash == NULL)
  534 tgl                      1016 UIC           0 :         return NULL;            /* no objects exist yet */
                               1017                 : 
  534 tgl                      1018 GIC      445511 :     entry = catalogid_lookup(catalogIdHash, catalogId);
                               1019          445511 :     if (entry == NULL)
  534 tgl                      1020 UIC           0 :         return NULL;
  534 tgl                      1021 GIC      445511 :     return entry->ext;
 2643 tgl                      1022 ECB             : }
                               1023                 : 
                               1024                 : 
 4152 bruce                    1025                 : /*
                               1026                 :  * parseOidArray
 4152 bruce                    1027 EUB             :  *    parse a string of numbers delimited by spaces into a character array
 4152 bruce                    1028 ECB             :  *
                               1029                 :  * Note: actually this is used for both Oids and potentially-signed
                               1030                 :  * attribute numbers.  This should cause no trouble, but we could split
                               1031                 :  * the function into two functions with different argument types if it does.
                               1032                 :  */
                               1033                 : 
                               1034                 : void
 4152 bruce                    1035 GIC        4619 : parseOidArray(const char *str, Oid *array, int arraysize)
                               1036                 : {
                               1037                 :     int         j,
                               1038                 :                 argNum;
                               1039                 :     char        temp[100];
                               1040                 :     char        s;
                               1041                 : 
 4152 bruce                    1042 CBC        4619 :     argNum = 0;
 4152 bruce                    1043 GIC        4619 :     j = 0;
                               1044                 :     for (;;)
                               1045                 :     {
                               1046           21735 :         s = *str++;
                               1047           21735 :         if (s == ' ' || s == '\0')
                               1048                 :         {
 4152 bruce                    1049 CBC        7366 :             if (j > 0)
 4152 bruce                    1050 ECB             :             {
 4152 bruce                    1051 GIC        7366 :                 if (argNum >= arraysize)
  366 tgl                      1052 UIC           0 :                     pg_fatal("could not parse numeric array \"%s\": too many numbers", str);
 4152 bruce                    1053 CBC        7366 :                 temp[j] = '\0';
                               1054            7366 :                 array[argNum++] = atooid(temp);
 4152 bruce                    1055 GIC        7366 :                 j = 0;
 4152 bruce                    1056 ECB             :             }
 4152 bruce                    1057 GIC        7366 :             if (s == '\0')
 4152 bruce                    1058 CBC        4619 :                 break;
 4152 bruce                    1059 EUB             :         }
 4152 bruce                    1060 ECB             :         else
                               1061                 :         {
 4152 bruce                    1062 CBC       14369 :             if (!(isdigit((unsigned char) s) || s == '-') ||
 4152 bruce                    1063 GIC       14369 :                 j >= sizeof(temp) - 1)
  366 tgl                      1064 LBC           0 :                 pg_fatal("could not parse numeric array \"%s\": invalid character in number", str);
 4152 bruce                    1065 CBC       14369 :             temp[j++] = s;
                               1066                 :         }
                               1067                 :     }
                               1068                 : 
                               1069            4619 :     while (argNum < arraysize)
 4152 bruce                    1070 LBC           0 :         array[argNum++] = InvalidOid;
 4152 bruce                    1071 GBC        4619 : }
 4152 bruce                    1072 ECB             : 
                               1073                 : 
                               1074                 : /*
                               1075                 :  * strInArray:
                               1076                 :  *    takes in a string and a string array and the number of elements in the
 4152 bruce                    1077 EUB             :  * string array.
 4152 bruce                    1078 ECB             :  *    returns the index if the string is somewhere in the array, -1 otherwise
                               1079                 :  */
                               1080                 : 
                               1081                 : static int
 4152 bruce                    1082 GIC        3822 : strInArray(const char *pattern, char **arr, int arr_size)
                               1083                 : {
                               1084                 :     int         i;
                               1085                 : 
                               1086            7771 :     for (i = 0; i < arr_size; i++)
                               1087                 :     {
                               1088            7586 :         if (strcmp(pattern, arr[i]) == 0)
 4152 bruce                    1089 CBC        3637 :             return i;
                               1090                 :     }
 4152 bruce                    1091 GIC         185 :     return -1;
                               1092                 : }
        

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