LCOV - differential code coverage report
Current view: top level - src/backend/bootstrap - bootstrap.c (source / functions) Coverage Total Hit UNC LBC UIC UBC GBC GIC GNC CBC EUB ECB DUB DCB
Current: Differential Code Coverage HEAD vs 15 Lines: 86.6 % 307 266 3 6 24 8 14 134 11 107 10 142 9 11
Current Date: 2023-04-08 17:13:01 Functions: 100.0 % 16 16 13 2 1 14
Baseline: 15 Line coverage date bins:
Baseline Date: 2023-04-08 15:09:40 (60,120] days: 70.0 % 10 7 3 7
Legend: Lines: hit not hit (120,180] days: 100.0 % 1 1 1
(180,240] days: 100.0 % 3 3 3
(240..) days: 87.0 % 293 255 6 24 8 14 134 107 10 142
Function coverage date bins:
(180,240] days: 100.0 % 1 1 1
(240..) days: 51.7 % 29 15 13 1 1 14

 Age         Owner                  TLA  Line data    Source code
                                  1                 : /*-------------------------------------------------------------------------
                                  2                 :  *
                                  3                 :  * bootstrap.c
                                  4                 :  *    routines to support running postgres in 'bootstrap' mode
                                  5                 :  *  bootstrap mode is used to create the initial template database
                                  6                 :  *
                                  7                 :  * Portions Copyright (c) 1996-2023, PostgreSQL Global Development Group
                                  8                 :  * Portions Copyright (c) 1994, Regents of the University of California
                                  9                 :  *
                                 10                 :  * IDENTIFICATION
                                 11                 :  *    src/backend/bootstrap/bootstrap.c
                                 12                 :  *
                                 13                 :  *-------------------------------------------------------------------------
                                 14                 :  */
                                 15                 : #include "postgres.h"
                                 16                 : 
                                 17                 : #include <unistd.h>
                                 18                 : #include <signal.h>
                                 19                 : 
                                 20                 : #include "access/genam.h"
                                 21                 : #include "access/heapam.h"
                                 22                 : #include "access/htup_details.h"
                                 23                 : #include "access/tableam.h"
                                 24                 : #include "access/toast_compression.h"
                                 25                 : #include "access/xact.h"
                                 26                 : #include "access/xlog_internal.h"
                                 27                 : #include "bootstrap/bootstrap.h"
                                 28                 : #include "catalog/index.h"
                                 29                 : #include "catalog/pg_collation.h"
                                 30                 : #include "catalog/pg_type.h"
                                 31                 : #include "common/link-canary.h"
                                 32                 : #include "libpq/pqsignal.h"
                                 33                 : #include "miscadmin.h"
                                 34                 : #include "nodes/makefuncs.h"
                                 35                 : #include "pg_getopt.h"
                                 36                 : #include "storage/bufmgr.h"
                                 37                 : #include "storage/bufpage.h"
                                 38                 : #include "storage/condition_variable.h"
                                 39                 : #include "storage/ipc.h"
                                 40                 : #include "storage/proc.h"
                                 41                 : #include "tcop/tcopprot.h"
                                 42                 : #include "utils/builtins.h"
                                 43                 : #include "utils/fmgroids.h"
                                 44                 : #include "utils/memutils.h"
                                 45                 : #include "utils/rel.h"
                                 46                 : #include "utils/relmapper.h"
                                 47                 : 
                                 48                 : uint32      bootstrap_data_checksum_version = 0;    /* No checksum */
                                 49                 : 
                                 50                 : 
                                 51                 : static void CheckerModeMain(void);
                                 52                 : static void bootstrap_signals(void);
                                 53                 : static Form_pg_attribute AllocateAttribute(void);
                                 54                 : static void populate_typ_list(void);
                                 55                 : static Oid  gettype(char *type);
                                 56                 : static void cleanup(void);
                                 57                 : 
                                 58                 : /* ----------------
                                 59                 :  *      global variables
                                 60                 :  * ----------------
                                 61                 :  */
                                 62                 : 
                                 63                 : Relation    boot_reldesc;       /* current relation descriptor */
                                 64                 : 
                                 65                 : Form_pg_attribute attrtypes[MAXATTR];   /* points to attribute info */
                                 66                 : int         numattr;            /* number of attributes for cur. rel */
                                 67                 : 
                                 68                 : 
                                 69                 : /*
                                 70                 :  * Basic information associated with each type.  This is used before
                                 71                 :  * pg_type is filled, so it has to cover the datatypes used as column types
                                 72                 :  * in the core "bootstrapped" catalogs.
                                 73                 :  *
                                 74                 :  *      XXX several of these input/output functions do catalog scans
                                 75                 :  *          (e.g., F_REGPROCIN scans pg_proc).  this obviously creates some
                                 76                 :  *          order dependencies in the catalog creation process.
                                 77                 :  */
                                 78                 : struct typinfo
                                 79                 : {
                                 80                 :     char        name[NAMEDATALEN];
                                 81                 :     Oid         oid;
                                 82                 :     Oid         elem;
                                 83                 :     int16       len;
                                 84                 :     bool        byval;
                                 85                 :     char        align;
                                 86                 :     char        storage;
                                 87                 :     Oid         collation;
                                 88                 :     Oid         inproc;
                                 89                 :     Oid         outproc;
                                 90                 : };
                                 91                 : 
                                 92                 : static const struct typinfo TypInfo[] = {
                                 93                 :     {"bool", BOOLOID, 0, 1, true, TYPALIGN_CHAR, TYPSTORAGE_PLAIN, InvalidOid,
                                 94                 :     F_BOOLIN, F_BOOLOUT},
                                 95                 :     {"bytea", BYTEAOID, 0, -1, false, TYPALIGN_INT, TYPSTORAGE_EXTENDED, InvalidOid,
                                 96                 :     F_BYTEAIN, F_BYTEAOUT},
                                 97                 :     {"char", CHAROID, 0, 1, true, TYPALIGN_CHAR, TYPSTORAGE_PLAIN, InvalidOid,
                                 98                 :     F_CHARIN, F_CHAROUT},
                                 99                 :     {"int2", INT2OID, 0, 2, true, TYPALIGN_SHORT, TYPSTORAGE_PLAIN, InvalidOid,
                                100                 :     F_INT2IN, F_INT2OUT},
                                101                 :     {"int4", INT4OID, 0, 4, true, TYPALIGN_INT, TYPSTORAGE_PLAIN, InvalidOid,
                                102                 :     F_INT4IN, F_INT4OUT},
                                103                 :     {"float4", FLOAT4OID, 0, 4, true, TYPALIGN_INT, TYPSTORAGE_PLAIN, InvalidOid,
                                104                 :     F_FLOAT4IN, F_FLOAT4OUT},
                                105                 :     {"name", NAMEOID, CHAROID, NAMEDATALEN, false, TYPALIGN_CHAR, TYPSTORAGE_PLAIN, C_COLLATION_OID,
                                106                 :     F_NAMEIN, F_NAMEOUT},
                                107                 :     {"regclass", REGCLASSOID, 0, 4, true, TYPALIGN_INT, TYPSTORAGE_PLAIN, InvalidOid,
                                108                 :     F_REGCLASSIN, F_REGCLASSOUT},
                                109                 :     {"regproc", REGPROCOID, 0, 4, true, TYPALIGN_INT, TYPSTORAGE_PLAIN, InvalidOid,
                                110                 :     F_REGPROCIN, F_REGPROCOUT},
                                111                 :     {"regtype", REGTYPEOID, 0, 4, true, TYPALIGN_INT, TYPSTORAGE_PLAIN, InvalidOid,
                                112                 :     F_REGTYPEIN, F_REGTYPEOUT},
                                113                 :     {"regrole", REGROLEOID, 0, 4, true, TYPALIGN_INT, TYPSTORAGE_PLAIN, InvalidOid,
                                114                 :     F_REGROLEIN, F_REGROLEOUT},
                                115                 :     {"regnamespace", REGNAMESPACEOID, 0, 4, true, TYPALIGN_INT, TYPSTORAGE_PLAIN, InvalidOid,
                                116                 :     F_REGNAMESPACEIN, F_REGNAMESPACEOUT},
                                117                 :     {"text", TEXTOID, 0, -1, false, TYPALIGN_INT, TYPSTORAGE_EXTENDED, DEFAULT_COLLATION_OID,
                                118                 :     F_TEXTIN, F_TEXTOUT},
                                119                 :     {"oid", OIDOID, 0, 4, true, TYPALIGN_INT, TYPSTORAGE_PLAIN, InvalidOid,
                                120                 :     F_OIDIN, F_OIDOUT},
                                121                 :     {"tid", TIDOID, 0, 6, false, TYPALIGN_SHORT, TYPSTORAGE_PLAIN, InvalidOid,
                                122                 :     F_TIDIN, F_TIDOUT},
                                123                 :     {"xid", XIDOID, 0, 4, true, TYPALIGN_INT, TYPSTORAGE_PLAIN, InvalidOid,
                                124                 :     F_XIDIN, F_XIDOUT},
                                125                 :     {"cid", CIDOID, 0, 4, true, TYPALIGN_INT, TYPSTORAGE_PLAIN, InvalidOid,
                                126                 :     F_CIDIN, F_CIDOUT},
                                127                 :     {"pg_node_tree", PG_NODE_TREEOID, 0, -1, false, TYPALIGN_INT, TYPSTORAGE_EXTENDED, DEFAULT_COLLATION_OID,
                                128                 :     F_PG_NODE_TREE_IN, F_PG_NODE_TREE_OUT},
                                129                 :     {"int2vector", INT2VECTOROID, INT2OID, -1, false, TYPALIGN_INT, TYPSTORAGE_PLAIN, InvalidOid,
                                130                 :     F_INT2VECTORIN, F_INT2VECTOROUT},
                                131                 :     {"oidvector", OIDVECTOROID, OIDOID, -1, false, TYPALIGN_INT, TYPSTORAGE_PLAIN, InvalidOid,
                                132                 :     F_OIDVECTORIN, F_OIDVECTOROUT},
                                133                 :     {"_int4", INT4ARRAYOID, INT4OID, -1, false, TYPALIGN_INT, TYPSTORAGE_EXTENDED, InvalidOid,
                                134                 :     F_ARRAY_IN, F_ARRAY_OUT},
                                135                 :     {"_text", 1009, TEXTOID, -1, false, TYPALIGN_INT, TYPSTORAGE_EXTENDED, DEFAULT_COLLATION_OID,
                                136                 :     F_ARRAY_IN, F_ARRAY_OUT},
                                137                 :     {"_oid", 1028, OIDOID, -1, false, TYPALIGN_INT, TYPSTORAGE_EXTENDED, InvalidOid,
                                138                 :     F_ARRAY_IN, F_ARRAY_OUT},
                                139                 :     {"_char", 1002, CHAROID, -1, false, TYPALIGN_INT, TYPSTORAGE_EXTENDED, InvalidOid,
                                140                 :     F_ARRAY_IN, F_ARRAY_OUT},
                                141                 :     {"_aclitem", 1034, ACLITEMOID, -1, false, TYPALIGN_INT, TYPSTORAGE_EXTENDED, InvalidOid,
                                142                 :     F_ARRAY_IN, F_ARRAY_OUT}
                                143                 : };
                                144                 : 
                                145                 : static const int n_types = sizeof(TypInfo) / sizeof(struct typinfo);
                                146                 : 
                                147                 : struct typmap
                                148                 : {                               /* a hack */
                                149                 :     Oid         am_oid;
                                150                 :     FormData_pg_type am_typ;
                                151                 : };
                                152                 : 
                                153                 : static List *Typ = NIL;         /* List of struct typmap* */
                                154                 : static struct typmap *Ap = NULL;
                                155                 : 
                                156                 : static Datum values[MAXATTR];   /* current row's attribute values */
                                157                 : static bool Nulls[MAXATTR];
                                158                 : 
                                159                 : static MemoryContext nogc = NULL;   /* special no-gc mem context */
                                160                 : 
                                161                 : /*
                                162                 :  *  At bootstrap time, we first declare all the indices to be built, and
                                163                 :  *  then build them.  The IndexList structure stores enough information
                                164                 :  *  to allow us to build the indices after they've been declared.
                                165                 :  */
                                166                 : 
                                167                 : typedef struct _IndexList
                                168                 : {
                                169                 :     Oid         il_heap;
                                170                 :     Oid         il_ind;
                                171                 :     IndexInfo  *il_info;
                                172                 :     struct _IndexList *il_next;
                                173                 : } IndexList;
                                174                 : 
                                175                 : static IndexList *ILHead = NULL;
                                176                 : 
                                177                 : 
                                178                 : /*
                                179                 :  * In shared memory checker mode, all we really want to do is create shared
                                180                 :  * memory and semaphores (just to prove we can do it with the current GUC
                                181                 :  * settings).  Since, in fact, that was already done by
                                182                 :  * CreateSharedMemoryAndSemaphores(), we have nothing more to do here.
                                183                 :  */
                                184                 : static void
 5877 alvherre                  185 CBC         610 : CheckerModeMain(void)
                                186                 : {
                                187             610 :     proc_exit(0);
                                188                 : }
                                189                 : 
                                190                 : /*
                                191                 :  *   The main entry point for running the backend in bootstrap mode
                                192                 :  *
                                193                 :  *   The bootstrap mode is used to initialize the template database.
                                194                 :  *   The bootstrap backend doesn't speak SQL, but instead expects
                                195                 :  *   commands in a special bootstrap language.
                                196                 :  *
                                197                 :  *   When check_only is true, startup is done only far enough to verify that
                                198                 :  *   the current configuration, particularly the passed in options pertaining
                                199                 :  *   to shared memory sizing, options work (or at least do not cause an error
                                200                 :  *   up to shared memory creation).
                                201                 :  */
                                202                 : void
  612 andres                    203             940 : BootstrapModeMain(int argc, char *argv[], bool check_only)
                                204                 : {
                                205                 :     int         i;
  613                           206             940 :     char       *progname = argv[0];
                                207                 :     int         flag;
                                208             940 :     char       *userDoption = NULL;
                                209                 : 
 5877 alvherre                  210             940 :     Assert(!IsUnderPostmaster);
                                211                 : 
  613 andres                    212             940 :     InitStandaloneProcess(argv[0]);
                                213                 : 
                                214                 :     /* Set defaults, to be overridden by explicit options below */
                                215             940 :     InitializeGUCOptions();
                                216                 : 
                                217                 :     /* an initial --boot or --check should be present */
  608                           218             940 :     Assert(argc > 1
                                219                 :            && (strcmp(argv[1], "--boot") == 0
                                220                 :                || strcmp(argv[1], "--check") == 0));
  613                           221             940 :     argv++;
                                222             940 :     argc--;
                                223                 : 
  612                           224            5031 :     while ((flag = getopt(argc, argv, "B:c:d:D:Fkr:X:-:")) != -1)
                                225                 :     {
  613                           226            4115 :         switch (flag)
                                227                 :         {
  613 andres                    228 UBC           0 :             case 'B':
                                229               0 :                 SetConfigOption("shared_buffers", optarg, PGC_POSTMASTER, PGC_S_ARGV);
                                230               0 :                 break;
  118 peter                     231 GNC        2868 :             case 'c':
                                232                 :             case '-':
                                233                 :                 {
                                234                 :                     char       *name,
                                235                 :                                *value;
                                236                 : 
                                237            2868 :                     ParseLongOption(optarg, &name, &value);
                                238            2868 :                     if (!value)
                                239                 :                     {
  118 peter                     240 UNC           0 :                         if (flag == '-')
                                241               0 :                             ereport(ERROR,
                                242                 :                                     (errcode(ERRCODE_SYNTAX_ERROR),
                                243                 :                                      errmsg("--%s requires a value",
                                244                 :                                             optarg)));
                                245                 :                         else
                                246               0 :                             ereport(ERROR,
                                247                 :                                     (errcode(ERRCODE_SYNTAX_ERROR),
                                248                 :                                      errmsg("-c %s requires a value",
                                249                 :                                             optarg)));
                                250                 :                     }
                                251                 : 
  118 peter                     252 GNC        2868 :                     SetConfigOption(name, value, PGC_POSTMASTER, PGC_S_ARGV);
                                253            2844 :                     pfree(name);
                                254            2844 :                     pfree(value);
                                255            2844 :                     break;
                                256                 :                 }
  613 andres                    257 LBC           0 :             case 'D':
  613 andres                    258 UIC           0 :                 userDoption = pstrdup(optarg);
                                259               0 :                 break;
                                260               0 :             case 'd':
                                261                 :                 {
                                262                 :                     /* Turn on debugging for the bootstrap process. */
  613 andres                    263 ECB             :                     char       *debugstr;
                                264                 : 
  613 andres                    265 UIC           0 :                     debugstr = psprintf("debug%s", optarg);
  613 andres                    266 UBC           0 :                     SetConfigOption("log_min_messages", debugstr,
  613 andres                    267 EUB             :                                     PGC_POSTMASTER, PGC_S_ARGV);
  613 andres                    268 UIC           0 :                     SetConfigOption("client_min_messages", debugstr,
                                269                 :                                     PGC_POSTMASTER, PGC_S_ARGV);
                                270               0 :                     pfree(debugstr);
                                271                 :                 }
  613 andres                    272 UBC           0 :                 break;
  613 andres                    273 GIC         940 :             case 'F':
                                274             940 :                 SetConfigOption("fsync", "false", PGC_POSTMASTER, PGC_S_ARGV);
                                275             940 :                 break;
                                276               1 :             case 'k':
                                277               1 :                 bootstrap_data_checksum_version = PG_DATA_CHECKSUM_VERSION;
  613 andres                    278 CBC           1 :                 break;
  613 andres                    279 LBC           0 :             case 'r':
                                280               0 :                 strlcpy(OutputFileName, optarg, MAXPGPATH);
                                281               0 :                 break;
  613 andres                    282 GIC         306 :             case 'X':
  613 andres                    283 EUB             :                 {
  613 andres                    284 GBC         306 :                     int         WalSegSz = strtoul(optarg, NULL, 0);
  613 andres                    285 EUB             : 
  613 andres                    286 GBC         306 :                     if (!IsValidWalSegSize(WalSegSz))
  613 andres                    287 UIC           0 :                         ereport(ERROR,
                                288                 :                                 (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
                                289                 :                                  errmsg("-X requires a power of two value between 1 MB and 1 GB")));
  613 andres                    290 GIC         306 :                     SetConfigOption("wal_segment_size", optarg, PGC_INTERNAL,
  305 tgl                       291 EUB             :                                     PGC_S_DYNAMIC_DEFAULT);
  613 andres                    292                 :                 }
  613 andres                    293 GIC         306 :                 break;
  613 andres                    294 UBC           0 :             default:
  613 andres                    295 UIC           0 :                 write_stderr("Try \"%s --help\" for more information.\n",
  613 andres                    296 EUB             :                              progname);
  613 andres                    297 UIC           0 :                 proc_exit(1);
                                298                 :                 break;
                                299                 :         }
                                300                 :     }
  613 andres                    301 ECB             : 
  613 andres                    302 GIC         916 :     if (argc != optind)
  613 andres                    303 EUB             :     {
  613 andres                    304 UBC           0 :         write_stderr("%s: invalid command-line arguments\n", progname);
  613 andres                    305 UIC           0 :         proc_exit(1);
                                306                 :     }
                                307                 : 
  613 andres                    308 ECB             :     /* Acquire configuration parameters */
  613 andres                    309 GBC         916 :     if (!SelectConfigFiles(userDoption, progname))
  613 andres                    310 UIC           0 :         proc_exit(1);
                                311                 : 
                                312                 :     /*
                                313                 :      * Validate we have been given a reasonable-looking DataDir and change
                                314                 :      * into it
  613 andres                    315 ECB             :      */
  613 andres                    316 CBC         915 :     checkDataDir();
  613 andres                    317 GIC         915 :     ChangeToDataDir();
  613 andres                    318 ECB             : 
  613 andres                    319 GIC         915 :     CreateDataDirLockFile(false);
  613 andres                    320 ECB             : 
  613 andres                    321 CBC         915 :     SetProcessingMode(BootstrapProcessing);
  613 andres                    322 GIC         915 :     IgnoreSystemIndexes = true;
  613 andres                    323 ECB             : 
  613 andres                    324 GIC         915 :     InitializeMaxBackends();
  613 andres                    325 ECB             : 
  612 andres                    326 GIC         915 :     CreateSharedMemoryAndSemaphores();
                                327                 : 
                                328                 :     /*
                                329                 :      * XXX: It might make sense to move this into its own function at some
                                330                 :      * point. Right now it seems like it'd cause more code duplication than
                                331                 :      * it's worth.
  613 andres                    332 ECB             :      */
  612 andres                    333 GIC         915 :     if (check_only)
  613 andres                    334 ECB             :     {
  613 andres                    335 CBC         610 :         SetProcessingMode(NormalProcessing);
  613 andres                    336 GBC         610 :         CheckerModeMain();
  613 andres                    337 UIC           0 :         abort();
                                338                 :     }
                                339                 : 
                                340                 :     /*
                                341                 :      * Do backend-like initialization for bootstrap mode
  612 andres                    342 ECB             :      */
  612 andres                    343 GIC         305 :     InitProcess();
  612 andres                    344 ECB             : 
  612 andres                    345 GIC         305 :     BaseInit();
  612 andres                    346 ECB             : 
  613 andres                    347 CBC         305 :     bootstrap_signals();
  613 andres                    348 GIC         305 :     BootStrapXLOG();
                                349                 : 
                                350                 :     /*
                                351                 :      * To ensure that src/common/link-canary.c is linked into the backend, we
                                352                 :      * must call it from somewhere.  Here is as good as anywhere.
 1673 tgl                       353 ECB             :      */
 1673 tgl                       354 GBC         305 :     if (pg_link_canary_is_frontend())
 1673 tgl                       355 UIC           0 :         elog(ERROR, "backend is incorrectly linked to frontend functions");
 1673 tgl                       356 ECB             : 
  258 tgl                       357 GIC         305 :     InitPostgres(NULL, InvalidOid, NULL, InvalidOid, false, false, NULL);
                                358                 : 
 7208 tgl                       359 ECB             :     /* Initialize stuff for bootstrap-file processing */
 9345 bruce                     360 GIC       12505 :     for (i = 0; i < MAXATTR; i++)
 9345 bruce                     361 ECB             :     {
 7032 neilc                     362 CBC       12200 :         attrtypes[i] = NULL;
 5271 tgl                       363 GIC       12200 :         Nulls[i] = false;
                                364                 :     }
                                365                 : 
                                366                 :     /*
                                367                 :      * Process bootstrap input.
 9345 bruce                     368 ECB             :      */
 2186 tgl                       369 CBC         305 :     StartTransactionCommand();
 6242                           370             305 :     boot_yyparse();
 2186 tgl                       371 GIC         305 :     CommitTransactionCommand();
                                372                 : 
                                373                 :     /*
                                374                 :      * We should now know about all mapped relations, so it's okay to write
                                375                 :      * out the initial relation mapping files.
 4809 tgl                       376 ECB             :      */
 4809 tgl                       377 GIC         305 :     RelationMapFinishBootstrap();
                                378                 : 
 7208 tgl                       379 ECB             :     /* Clean up and exit */
 9345 bruce                     380 CBC         305 :     cleanup();
 5877 alvherre                  381 GIC         305 :     proc_exit(0);
                                382                 : }
                                383                 : 
                                384                 : 
                                385                 : /* ----------------------------------------------------------------
                                386                 :  *                      misc functions
                                387                 :  * ----------------------------------------------------------------
                                388                 :  */
                                389                 : 
                                390                 : /*
                                391                 :  * Set up signal handling for a bootstrap process
                                392                 :  */
 6889 tgl                       393 ECB             : static void
 6889 tgl                       394 GIC         305 : bootstrap_signals(void)
 6889 tgl                       395 ECB             : {
 3008 andres                    396 GIC         305 :     Assert(!IsUnderPostmaster);
                                397                 : 
                                398                 :     /*
                                399                 :      * We don't actually need any non-default signal handling in bootstrap
                                400                 :      * mode; "curl up and die" is a sufficient response for all these cases.
                                401                 :      * Let's set that handling explicitly, as documentation if nothing else.
 1426 tgl                       402 ECB             :      */
 1426 tgl                       403 CBC         305 :     pqsignal(SIGHUP, SIG_DFL);
                                404             305 :     pqsignal(SIGINT, SIG_DFL);
                                405             305 :     pqsignal(SIGTERM, SIG_DFL);
                                406             305 :     pqsignal(SIGQUIT, SIG_DFL);
 6889 tgl                       407 GIC         305 : }
                                408                 : 
                                409                 : /* ----------------------------------------------------------------
                                410                 :  *              MANUAL BACKEND INTERACTIVE INTERFACE COMMANDS
                                411                 :  * ----------------------------------------------------------------
                                412                 :  */
                                413                 : 
                                414                 : /* ----------------
                                415                 :  *      boot_openrel
                                416                 :  *
                                417                 :  * Execute BKI OPEN command.
                                418                 :  * ----------------
                                419                 :  */
 9770 scrappy                   420 ECB             : void
 9770 scrappy                   421 GIC       18300 : boot_openrel(char *relname)
                                422                 : {
                                423                 :     int         i;
 9345 bruce                     424 ECB             : 
 6569 tgl                       425 GBC       18300 :     if (strlen(relname) >= NAMEDATALEN)
 9173 bruce                     426 UIC           0 :         relname[NAMEDATALEN - 1] = '\0';
                                427                 : 
                                428                 :     /*
                                429                 :      * pg_type must be filled before any OPEN command is executed, hence we
                                430                 :      * can now populate Typ if we haven't yet.
  946 tgl                       431 ECB             :      */
  746 tomas.vondra              432 GBC       18300 :     if (Typ == NIL)
  746 tomas.vondra              433 UIC           0 :         populate_typ_list();
 9345 bruce                     434 ECB             : 
 7652 tgl                       435 GBC       18300 :     if (boot_reldesc != NULL)
 9345 bruce                     436 UIC           0 :         closerel(NULL);
 9345 bruce                     437 ECB             : 
 7201 tgl                       438 GIC       18300 :     elog(DEBUG4, "open relation %s, attrsize %d",
                                439                 :          relname, (int) ATTRIBUTE_FIXED_PART_SIZE);
 9345 bruce                     440 ECB             : 
 1539 andres                    441 CBC       18300 :     boot_reldesc = table_openrv(makeRangeVar(NULL, relname, -1), NoLock);
 1828 teodor                    442           18300 :     numattr = RelationGetNumberOfAttributes(boot_reldesc);
 9345 bruce                     443 GIC      163480 :     for (i = 0; i < numattr; i++)
 9345 bruce                     444 ECB             :     {
 9345 bruce                     445 GBC      145180 :         if (attrtypes[i] == NULL)
 9345 bruce                     446 LBC           0 :             attrtypes[i] = AllocateAttribute();
 9345 bruce                     447 CBC      145180 :         memmove((char *) attrtypes[i],
 2058 andres                    448 GIC      145180 :                 (char *) TupleDescAttr(boot_reldesc->rd_att, i),
                                449                 :                 ATTRIBUTE_FIXED_PART_SIZE);
                                450                 : 
 9345 bruce                     451 ECB             :         {
 8986 bruce                     452 GIC      145180 :             Form_pg_attribute at = attrtypes[i];
 9345 bruce                     453 ECB             : 
 7257 bruce                     454 GIC      145180 :             elog(DEBUG4, "create attribute %d name %s len %d num %d type %u",
                                455                 :                  i, NameStr(at->attname), at->attlen, at->attnum,
                                456                 :                  at->atttypid);
                                457                 :         }
 9345 bruce                     458 ECB             :     }
 9770 scrappy                   459 GIC       18300 : }
                                460                 : 
                                461                 : /* ----------------
                                462                 :  *      closerel
                                463                 :  * ----------------
                                464                 :  */
 9770 scrappy                   465 ECB             : void
  201 pg                        466 GNC       19520 : closerel(char *relname)
 9770 scrappy                   467 ECB             : {
  201 pg                        468 GNC       19520 :     if (relname)
 9345 bruce                     469 ECB             :     {
 7652 tgl                       470 GIC       19520 :         if (boot_reldesc)
 9345 bruce                     471 ECB             :         {
  201 pg                        472 GNC       19520 :             if (strcmp(RelationGetRelationName(boot_reldesc), relname) != 0)
 7201 tgl                       473 UIC           0 :                 elog(ERROR, "close of %s when %s was expected",
                                474                 :                      relname, RelationGetRelationName(boot_reldesc));
                                475                 :         }
 9345 bruce                     476 EUB             :         else
 7201 tgl                       477 UIC           0 :             elog(ERROR, "close of %s before any relation was opened",
                                478                 :                  relname);
                                479                 :     }
 9345 bruce                     480 ECB             : 
 7652 tgl                       481 GBC       19520 :     if (boot_reldesc == NULL)
 8002 peter_e                   482 UIC           0 :         elog(ERROR, "no open relation to close");
                                483                 :     else
 9345 bruce                     484 ECB             :     {
 6569 tgl                       485 GIC       19520 :         elog(DEBUG4, "close relation %s",
 6569 tgl                       486 ECB             :              RelationGetRelationName(boot_reldesc));
 1539 andres                    487 CBC       19520 :         table_close(boot_reldesc, NoLock);
 7032 neilc                     488 GIC       19520 :         boot_reldesc = NULL;
 9345 bruce                     489 ECB             :     }
 9770 scrappy                   490 GIC       19520 : }
                                491                 : 
                                492                 : 
                                493                 : 
                                494                 : /* ----------------
                                495                 :  * DEFINEATTR()
                                496                 :  *
                                497                 :  * define a <field,type> pair
                                498                 :  * if there are n fields in a relation to be created, this routine
                                499                 :  * will be called n times
                                500                 :  * ----------------
                                501                 :  */
 9770 scrappy                   502 ECB             : void
 2969 andres                    503 GIC      182085 : DefineAttr(char *name, char *type, int attnum, int nullness)
                                504                 : {
                                505                 :     Oid         typeoid;
 9345 bruce                     506 ECB             : 
 7652 tgl                       507 GIC      182085 :     if (boot_reldesc != NULL)
 9345 bruce                     508 EUB             :     {
 7201 tgl                       509 UBC           0 :         elog(WARNING, "no open relations allowed with CREATE command");
 6569 tgl                       510 UIC           0 :         closerel(NULL);
                                511                 :     }
 9345 bruce                     512 ECB             : 
 7032 neilc                     513 CBC      182085 :     if (attrtypes[attnum] == NULL)
 9345 bruce                     514           10065 :         attrtypes[attnum] = AllocateAttribute();
 5190 tgl                       515 GIC      182085 :     MemSet(attrtypes[attnum], 0, ATTRIBUTE_FIXED_PART_SIZE);
 7555 tgl                       516 ECB             : 
 7555 tgl                       517 CBC      182085 :     namestrcpy(&attrtypes[attnum]->attname, name);
 7257 bruce                     518          182085 :     elog(DEBUG4, "column %s %s", NameStr(attrtypes[attnum]->attname), type);
 1363 michael                   519 GIC      182085 :     attrtypes[attnum]->attnum = attnum + 1;
 7555 tgl                       520 ECB             : 
 7555 tgl                       521 GIC      182085 :     typeoid = gettype(type);
 7555 tgl                       522 ECB             : 
  746 tomas.vondra              523 GIC      182085 :     if (Typ != NIL)
 9345 bruce                     524 ECB             :     {
 9345 bruce                     525 CBC      155550 :         attrtypes[attnum]->atttypid = Ap->am_oid;
 6585 tgl                       526          155550 :         attrtypes[attnum]->attlen = Ap->am_typ.typlen;
 9345 bruce                     527          155550 :         attrtypes[attnum]->attbyval = Ap->am_typ.typbyval;
 8994                           528          155550 :         attrtypes[attnum]->attalign = Ap->am_typ.typalign;
  686 tgl                       529          155550 :         attrtypes[attnum]->attstorage = Ap->am_typ.typstorage;
  682                           530          155550 :         attrtypes[attnum]->attcompression = InvalidCompressionMethod;
 4443 peter_e                   531 GIC      155550 :         attrtypes[attnum]->attcollation = Ap->am_typ.typcollation;
 7033 tgl                       532 ECB             :         /* if an array type, assume 1-dimensional attribute */
 7033 tgl                       533 CBC      155550 :         if (Ap->am_typ.typelem != InvalidOid && Ap->am_typ.typlen < 0)
 7033 tgl                       534 GIC       14640 :             attrtypes[attnum]->attndims = 1;
 7033 tgl                       535 ECB             :         else
 7033 tgl                       536 GIC      140910 :             attrtypes[attnum]->attndims = 0;
                                537                 :     }
                                538                 :     else
 9345 bruce                     539 ECB             :     {
 6947 tgl                       540 CBC       26535 :         attrtypes[attnum]->atttypid = TypInfo[typeoid].oid;
 6585                           541           26535 :         attrtypes[attnum]->attlen = TypInfo[typeoid].len;
 6947                           542           26535 :         attrtypes[attnum]->attbyval = TypInfo[typeoid].byval;
                                543           26535 :         attrtypes[attnum]->attalign = TypInfo[typeoid].align;
  686                           544           26535 :         attrtypes[attnum]->attstorage = TypInfo[typeoid].storage;
  682                           545           26535 :         attrtypes[attnum]->attcompression = InvalidCompressionMethod;
 4443 peter_e                   546 GIC       26535 :         attrtypes[attnum]->attcollation = TypInfo[typeoid].collation;
 7033 tgl                       547 ECB             :         /* if an array type, assume 1-dimensional attribute */
 6585 tgl                       548 CBC       26535 :         if (TypInfo[typeoid].elem != InvalidOid &&
                                549            4270 :             attrtypes[attnum]->attlen < 0)
 7033 tgl                       550 GIC        3355 :             attrtypes[attnum]->attndims = 1;
 7033 tgl                       551 ECB             :         else
 7033 tgl                       552 GIC       23180 :             attrtypes[attnum]->attndims = 0;
                                553                 :     }
                                554                 : 
                                555                 :     /*
                                556                 :      * If a system catalog column is collation-aware, force it to use C
                                557                 :      * collation, so that its behavior is independent of the database's
                                558                 :      * collation.  This is essential to allow template0 to be cloned with a
                                559                 :      * different database collation.
 1573 tgl                       560 ECB             :      */
 1573 tgl                       561 CBC      182085 :     if (OidIsValid(attrtypes[attnum]->attcollation))
 1573 tgl                       562 GIC       30195 :         attrtypes[attnum]->attcollation = C_COLLATION_OID;
 1573 tgl                       563 ECB             : 
 7033 tgl                       564 CBC      182085 :     attrtypes[attnum]->attstattarget = -1;
 9193 bruce                     565          182085 :     attrtypes[attnum]->attcacheoff = -1;
 9192                           566          182085 :     attrtypes[attnum]->atttypmod = -1;
 7504 tgl                       567 GIC      182085 :     attrtypes[attnum]->attislocal = true;
 7522 bruce                     568 ECB             : 
 2969 andres                    569 GIC      182085 :     if (nullness == BOOTCOL_NULL_FORCE_NOT_NULL)
 2969 andres                    570 ECB             :     {
 2969 andres                    571 GIC       10370 :         attrtypes[attnum]->attnotnull = true;
 2969 andres                    572 ECB             :     }
 2969 andres                    573 GIC      171715 :     else if (nullness == BOOTCOL_NULL_FORCE_NULL)
 2969 andres                    574 ECB             :     {
 2969 andres                    575 GIC         610 :         attrtypes[attnum]->attnotnull = false;
                                576                 :     }
                                577                 :     else
 7555 tgl                       578 ECB             :     {
 2969 andres                    579 GIC      171105 :         Assert(nullness == BOOTCOL_NULL_AUTO);
                                580                 : 
                                581                 :         /*
                                582                 :          * Mark as "not null" if type is fixed-width and prior columns are
                                583                 :          * likewise fixed-width and not-null.  This corresponds to case where
                                584                 :          * column can be accessed directly via C struct declaration.
 2969 andres                    585 ECB             :          */
  992 tgl                       586 GIC      171105 :         if (attrtypes[attnum]->attlen > 0)
                                587                 :         {
                                588                 :             int         i;
                                589                 : 
 2969 andres                    590 ECB             :             /* check earlier attributes */
 2969 andres                    591 GIC     1019005 :             for (i = 0; i < attnum; i++)
 2969 andres                    592 ECB             :             {
  992 tgl                       593 CBC      874130 :                 if (attrtypes[i]->attlen <= 0 ||
  992 tgl                       594 GIC      873215 :                     !attrtypes[i]->attnotnull)
                                595                 :                     break;
 2969 andres                    596 ECB             :             }
 2969 andres                    597 CBC      145790 :             if (i == attnum)
 2969 andres                    598 GIC      144875 :                 attrtypes[attnum]->attnotnull = true;
                                599                 :         }
 7555 tgl                       600 ECB             :     }
 9770 scrappy                   601 GIC      182085 : }
                                602                 : 
                                603                 : 
                                604                 : /* ----------------
                                605                 :  *      InsertOneTuple
                                606                 :  *
                                607                 :  * If objectid is not zero, it is a specific OID to assign to the tuple.
                                608                 :  * Otherwise, an OID will be assigned (if necessary) by heap_insert.
                                609                 :  * ----------------
                                610                 :  */
 9770 scrappy                   611 ECB             : void
 1601 andres                    612 GIC     3215615 : InsertOneTuple(void)
                                613                 : {
                                614                 :     HeapTuple   tuple;
                                615                 :     TupleDesc   tupDesc;
                                616                 :     int         i;
 9345 bruce                     617 ECB             : 
 1601 andres                    618 GIC     3215615 :     elog(DEBUG4, "inserting row with %d columns", numattr);
 9345 bruce                     619 ECB             : 
 1601 andres                    620 CBC     3215615 :     tupDesc = CreateTupleDesc(numattr, attrtypes);
 5271 tgl                       621         3215615 :     tuple = heap_form_tuple(tupDesc, values, Nulls);
 7568 bruce                     622 GIC     3215615 :     pfree(tupDesc);             /* just free's tupDesc, not the attrtypes */
 7524 tgl                       623 ECB             : 
 7628 tgl                       624 CBC     3215615 :     simple_heap_insert(boot_reldesc, tuple);
 8515 JanWieck                  625         3215615 :     heap_freetuple(tuple);
 7257 bruce                     626 GIC     3215615 :     elog(DEBUG4, "row inserted");
                                627                 : 
                                628                 :     /*
                                629                 :      * Reset null markers for next tuple
 9345 bruce                     630 ECB             :      */
 9345 bruce                     631 CBC    50904500 :     for (i = 0; i < numattr; i++)
 5271 tgl                       632        47688885 :         Nulls[i] = false;
 9770 scrappy                   633 GIC     3215615 : }
                                634                 : 
                                635                 : /* ----------------
                                636                 :  *      InsertOneValue
                                637                 :  * ----------------
                                638                 :  */
 9770 scrappy                   639 ECB             : void
 7912 tgl                       640 GIC    38343072 : InsertOneValue(char *value, int i)
                                641                 : {
                                642                 :     Oid         typoid;
                                643                 :     int16       typlen;
                                644                 :     bool        typbyval;
                                645                 :     char        typalign;
                                646                 :     char        typdelim;
                                647                 :     Oid         typioparam;
                                648                 :     Oid         typinput;
                                649                 :     Oid         typoutput;
 9345 bruce                     650 ECB             : 
  163 peter                     651 GNC    38343072 :     Assert(i >= 0 && i < MAXATTR);
 8002 peter_e                   652 ECB             : 
 7201 tgl                       653 GIC    38343072 :     elog(DEBUG4, "inserting column %d value \"%s\"", i, value);
 9345 bruce                     654 ECB             : 
 2058 andres                    655 GIC    38343072 :     typoid = TupleDescAttr(boot_reldesc->rd_att, i)->atttypid;
 6881 tgl                       656 ECB             : 
 6081 tgl                       657 GIC    38343072 :     boot_get_type_io_data(typoid,
                                658                 :                           &typlen, &typbyval, &typalign,
                                659                 :                           &typdelim, &typioparam,
                                660                 :                           &typinput, &typoutput);
 6081 tgl                       661 ECB             : 
 6214 tgl                       662 GIC    38343072 :     values[i] = OidInputFunctionCall(typinput, value, typioparam, -1);
                                663                 : 
                                664                 :     /*
                                665                 :      * We use ereport not elog here so that parameters aren't evaluated unless
                                666                 :      * the message is going to be printed, which generally it isn't
 3444 tgl                       667 ECB             :      */
 3444 tgl                       668 GIC    38343072 :     ereport(DEBUG4,
                                669                 :             (errmsg_internal("inserted -> %s",
 3444 tgl                       670 ECB             :                              OidOutputFunctionCall(typoutput, values[i]))));
 9770 scrappy                   671 GIC    38343072 : }
                                672                 : 
                                673                 : /* ----------------
                                674                 :  *      InsertOneNull
                                675                 :  * ----------------
                                676                 :  */
 9770 scrappy                   677 ECB             : void
 9770 scrappy                   678 GIC     9345813 : InsertOneNull(int i)
 9770 scrappy                   679 ECB             : {
 7257 bruce                     680 CBC     9345813 :     elog(DEBUG4, "inserting column %d NULL", i);
 4233 peter_e                   681         9345813 :     Assert(i >= 0 && i < MAXATTR);
 2058 andres                    682 GBC     9345813 :     if (TupleDescAttr(boot_reldesc->rd_att, i)->attnotnull)
 2126 tgl                       683 UIC           0 :         elog(ERROR,
                                684                 :              "NULL value specified for not-null column \"%s\" of relation \"%s\"",
                                685                 :              NameStr(TupleDescAttr(boot_reldesc->rd_att, i)->attname),
 2126 tgl                       686 ECB             :              RelationGetRelationName(boot_reldesc));
 8349 tgl                       687 CBC     9345813 :     values[i] = PointerGetDatum(NULL);
 5271                           688         9345813 :     Nulls[i] = true;
 9770 scrappy                   689 GIC     9345813 : }
                                690                 : 
                                691                 : /* ----------------
                                692                 :  *      cleanup
                                693                 :  * ----------------
                                694                 :  */
 9364 bruce                     695 ECB             : static void
 7256 tgl                       696 GIC         305 : cleanup(void)
 9770 scrappy                   697 ECB             : {
 7555 tgl                       698 GBC         305 :     if (boot_reldesc != NULL)
 7555 tgl                       699 LBC           0 :         closerel(NULL);
 9770 scrappy                   700 GIC         305 : }
                                701                 : 
                                702                 : /* ----------------
                                703                 :  *      populate_typ_list
                                704                 :  *
                                705                 :  * Load the Typ list by reading pg_type.
                                706                 :  * ----------------
                                707                 :  */
  946 tgl                       708 ECB             : static void
  746 tomas.vondra              709 GIC         610 : populate_typ_list(void)
                                710                 : {
                                711                 :     Relation    rel;
                                712                 :     TableScanDesc scan;
                                713                 :     HeapTuple   tup;
                                714                 :     MemoryContext old;
  946 tgl                       715 ECB             : 
  746 tomas.vondra              716 GIC         610 :     Assert(Typ == NIL);
  946 tgl                       717 ECB             : 
  946 tgl                       718 CBC         610 :     rel = table_open(TypeRelationId, NoLock);
                                719             610 :     scan = table_beginscan_catalog(rel, 0, NULL);
  746 tomas.vondra              720             610 :     old = MemoryContextSwitchTo(TopMemoryContext);
  946 tgl                       721 GIC      128100 :     while ((tup = heap_getnext(scan, ForwardScanDirection)) != NULL)
  946 tgl                       722 ECB             :     {
  946 tgl                       723 GIC      127490 :         Form_pg_type typForm = (Form_pg_type) GETSTRUCT(tup);
                                724                 :         struct typmap *newtyp;
  946 tgl                       725 ECB             : 
  746 tomas.vondra              726 CBC      127490 :         newtyp = (struct typmap *) palloc(sizeof(struct typmap));
  746 tomas.vondra              727 GIC      127490 :         Typ = lappend(Typ, newtyp);
  746 tomas.vondra              728 ECB             : 
  746 tomas.vondra              729 CBC      127490 :         newtyp->am_oid = typForm->oid;
  746 tomas.vondra              730 GIC      127490 :         memcpy(&newtyp->am_typ, typForm, sizeof(newtyp->am_typ));
  946 tgl                       731 ECB             :     }
  746 tomas.vondra              732 CBC         610 :     MemoryContextSwitchTo(old);
  946 tgl                       733             610 :     table_endscan(scan);
                                734             610 :     table_close(rel, NoLock);
  946 tgl                       735 GIC         610 : }
                                736                 : 
                                737                 : /* ----------------
                                738                 :  *      gettype
                                739                 :  *
                                740                 :  * NB: this is really ugly; it will return an integer index into TypInfo[],
                                741                 :  * and not an OID at all, until the first reference to a type not known in
                                742                 :  * TypInfo[].  At that point it will read and cache pg_type in Typ,
                                743                 :  * and subsequently return a real OID (and set the global pointer Ap to
                                744                 :  * point at the found row in Typ).  So caller must check whether Typ is
                                745                 :  * still NIL to determine what the return value is!
                                746                 :  * ----------------
                                747                 :  */
 8994 bruce                     748 ECB             : static Oid
 9770 scrappy                   749 GIC      182390 : gettype(char *type)
 9770 scrappy                   750 ECB             : {
  746 tomas.vondra              751 GIC      182390 :     if (Typ != NIL)
                                752                 :     {
                                753                 :         ListCell   *lc;
  946 tgl                       754 ECB             : 
  697 tgl                       755 GIC     2974360 :         foreach(lc, Typ)
 9345 bruce                     756 ECB             :         {
  746 tomas.vondra              757 GIC     2974055 :             struct typmap *app = lfirst(lc);
  697 tgl                       758 ECB             : 
  746 tomas.vondra              759 GIC     2974055 :             if (strncmp(NameStr(app->am_typ.typname), type, NAMEDATALEN) == 0)
 9345 bruce                     760 ECB             :             {
  746 tomas.vondra              761 CBC      155245 :                 Ap = app;
  746 tomas.vondra              762 GIC      155245 :                 return app->am_oid;
                                763                 :             }
                                764                 :         }
                                765                 : 
                                766                 :         /*
                                767                 :          * The type wasn't known; reload the pg_type contents and check again
                                768                 :          * to handle composite types, added since last populating the list.
                                769                 :          */
  746 tomas.vondra              770 ECB             : 
  746 tomas.vondra              771 CBC         305 :         list_free_deep(Typ);
                                772             305 :         Typ = NIL;
  746 tomas.vondra              773 GIC         305 :         populate_typ_list();
                                774                 : 
                                775                 :         /*
                                776                 :          * Calling gettype would result in infinite recursion for types
                                777                 :          * missing in pg_type, so just repeat the lookup.
  746 tomas.vondra              778 ECB             :          */
  697 tgl                       779 GIC       68015 :         foreach(lc, Typ)
  746 tomas.vondra              780 ECB             :         {
  746 tomas.vondra              781 GIC       68015 :             struct typmap *app = lfirst(lc);
  697 tgl                       782 ECB             : 
  746 tomas.vondra              783 GIC       68015 :             if (strncmp(NameStr(app->am_typ.typname), type, NAMEDATALEN) == 0)
  746 tomas.vondra              784 ECB             :             {
  746 tomas.vondra              785 CBC         305 :                 Ap = app;
  746 tomas.vondra              786 GIC         305 :                 return app->am_oid;
                                787                 :             }
                                788                 :         }
                                789                 :     }
                                790                 :     else
                                791                 :     {
                                792                 :         int         i;
  946 tgl                       793 ECB             : 
 7654 tgl                       794 GIC      252845 :         for (i = 0; i < n_types; i++)
 9345 bruce                     795 ECB             :         {
 6947 tgl                       796 CBC      252540 :             if (strncmp(type, TypInfo[i].name, NAMEDATALEN) == 0)
 8986 bruce                     797 GIC       26535 :                 return i;
                                798                 :         }
  946 tgl                       799 ECB             :         /* Not in TypInfo, so we'd better be able to read pg_type now */
 7257 bruce                     800 CBC         305 :         elog(DEBUG4, "external type: %s", type);
  746 tomas.vondra              801             305 :         populate_typ_list();
 8986 bruce                     802 GIC         305 :         return gettype(type);
 9345 bruce                     803 EUB             :     }
 7201 tgl                       804 UIC           0 :     elog(ERROR, "unrecognized type \"%s\"", type);
                                805                 :     /* not reached, here to make compiler happy */
                                806                 :     return 0;
                                807                 : }
                                808                 : 
                                809                 : /* ----------------
                                810                 :  *      boot_get_type_io_data
                                811                 :  *
                                812                 :  * Obtain type I/O information at bootstrap time.  This intentionally has
                                813                 :  * almost the same API as lsyscache.c's get_type_io_data, except that
                                814                 :  * we only support obtaining the typinput and typoutput routines, not
                                815                 :  * the binary I/O routines.  It is exported so that array_in and array_out
                                816                 :  * can be made to work during early bootstrap.
                                817                 :  * ----------------
                                818                 :  */
 6081 tgl                       819 ECB             : void
 6081 tgl                       820 GIC    38460802 : boot_get_type_io_data(Oid typid,
                                821                 :                       int16 *typlen,
                                822                 :                       bool *typbyval,
                                823                 :                       char *typalign,
                                824                 :                       char *typdelim,
                                825                 :                       Oid *typioparam,
                                826                 :                       Oid *typinput,
                                827                 :                       Oid *typoutput)
 6081 tgl                       828 ECB             : {
  746 tomas.vondra              829 GIC    38460802 :     if (Typ != NIL)
                                830                 :     {
 6081 tgl                       831 ECB             :         /* We have the boot-time contents of pg_type, so use it */
  746 tomas.vondra              832 GIC    15426592 :         struct typmap *ap = NULL;
                                833                 :         ListCell   *lc;
  746 tomas.vondra              834 ECB             : 
  697 tgl                       835 GIC   136466120 :         foreach(lc, Typ)
  746 tomas.vondra              836 ECB             :         {
  746 tomas.vondra              837 CBC   136466120 :             ap = lfirst(lc);
                                838       136466120 :             if (ap->am_oid == typid)
  746 tomas.vondra              839 GIC    15426592 :                 break;
                                840                 :         }
  746 tomas.vondra              841 ECB             : 
  746 tomas.vondra              842 GBC    15426592 :         if (!ap || ap->am_oid != typid)
 6081 tgl                       843 UIC           0 :             elog(ERROR, "type OID %u not found in Typ list", typid);
 6081 tgl                       844 ECB             : 
 6081 tgl                       845 CBC    15426592 :         *typlen = ap->am_typ.typlen;
                                846        15426592 :         *typbyval = ap->am_typ.typbyval;
                                847        15426592 :         *typalign = ap->am_typ.typalign;
 6081 tgl                       848 GIC    15426592 :         *typdelim = ap->am_typ.typdelim;
                                849                 : 
 6081 tgl                       850 ECB             :         /* XXX this logic must match getTypeIOParam() */
 6081 tgl                       851 CBC    15426592 :         if (OidIsValid(ap->am_typ.typelem))
 6081 tgl                       852 GIC      440115 :             *typioparam = ap->am_typ.typelem;
 6081 tgl                       853 ECB             :         else
 6081 tgl                       854 GIC    14986477 :             *typioparam = typid;
 6081 tgl                       855 ECB             : 
 6081 tgl                       856 CBC    15426592 :         *typinput = ap->am_typ.typinput;
 6081 tgl                       857 GIC    15426592 :         *typoutput = ap->am_typ.typoutput;
                                858                 :     }
                                859                 :     else
                                860                 :     {
                                861                 :         /* We don't have pg_type yet, so use the hard-wired TypInfo array */
                                862                 :         int         typeindex;
 6081 tgl                       863 ECB             : 
 6081 tgl                       864 GIC   183928420 :         for (typeindex = 0; typeindex < n_types; typeindex++)
 6081 tgl                       865 ECB             :         {
 6081 tgl                       866 CBC   183928420 :             if (TypInfo[typeindex].oid == typid)
 6081 tgl                       867 GIC    23034210 :                 break;
 6081 tgl                       868 ECB             :         }
 6081 tgl                       869 GBC    23034210 :         if (typeindex >= n_types)
 6081 tgl                       870 UIC           0 :             elog(ERROR, "type OID %u not found in TypInfo", typid);
 6081 tgl                       871 ECB             : 
 6081 tgl                       872 CBC    23034210 :         *typlen = TypInfo[typeindex].len;
                                873        23034210 :         *typbyval = TypInfo[typeindex].byval;
 6081 tgl                       874 GIC    23034210 :         *typalign = TypInfo[typeindex].align;
 6081 tgl                       875 ECB             :         /* We assume typdelim is ',' for all boot-time types */
 6081 tgl                       876 GIC    23034210 :         *typdelim = ',';
                                877                 : 
 6081 tgl                       878 ECB             :         /* XXX this logic must match getTypeIOParam() */
 6081 tgl                       879 CBC    23034210 :         if (OidIsValid(TypInfo[typeindex].elem))
 6081 tgl                       880 GIC     2182885 :             *typioparam = TypInfo[typeindex].elem;
 6081 tgl                       881 ECB             :         else
 6081 tgl                       882 GIC    20851325 :             *typioparam = typid;
 6081 tgl                       883 ECB             : 
 6081 tgl                       884 CBC    23034210 :         *typinput = TypInfo[typeindex].inproc;
 6081 tgl                       885 GIC    23034210 :         *typoutput = TypInfo[typeindex].outproc;
 6081 tgl                       886 ECB             :     }
 6081 tgl                       887 GIC    38460802 : }
                                888                 : 
                                889                 : /* ----------------
                                890                 :  *      AllocateAttribute
                                891                 :  *
                                892                 :  * Note: bootstrap never sets any per-column ACLs, so we only need
                                893                 :  * ATTRIBUTE_FIXED_PART_SIZE space per attribute.
                                894                 :  * ----------------
                                895                 :  */
 7555 tgl                       896 ECB             : static Form_pg_attribute
 7555 tgl                       897 GIC       10065 : AllocateAttribute(void)
 9770 scrappy                   898 ECB             : {
 2413 tgl                       899 CBC       10065 :     return (Form_pg_attribute)
 2413 tgl                       900 GIC       10065 :         MemoryContextAllocZero(TopMemoryContext, ATTRIBUTE_FIXED_PART_SIZE);
                                901                 : }
                                902                 : 
                                903                 : /*
                                904                 :  *  index_register() -- record an index that has been set up for building
                                905                 :  *                      later.
                                906                 :  *
                                907                 :  *      At bootstrap time, we define a bunch of indexes on system catalogs.
                                908                 :  *      We postpone actually building the indexes until just before we're
                                909                 :  *      finished with initialization, however.  This is because the indexes
                                910                 :  *      themselves have catalog entries, and those have to be included in the
                                911                 :  *      indexes on those catalogs.  Doing it in two phases is the simplest
                                912                 :  *      way of making sure the indexes have the right contents at the end.
                                913                 :  */
 9770 scrappy                   914 ECB             : void
 7684 tgl                       915 GIC       48800 : index_register(Oid heap,
                                916                 :                Oid ind,
                                917                 :                IndexInfo *indexInfo)
                                918                 : {
                                919                 :     IndexList  *newind;
                                920                 :     MemoryContext oldcxt;
                                921                 : 
                                922                 :     /*
                                923                 :      * XXX mao 10/31/92 -- don't gc index reldescs, associated info at
                                924                 :      * bootstrap time.  we'll declare the indexes now, but want to create them
                                925                 :      * later.
                                926                 :      */
 9345 bruce                     927 ECB             : 
 8320 tgl                       928 CBC       48800 :     if (nogc == NULL)
 7032 neilc                     929 GIC         305 :         nogc = AllocSetContextCreate(NULL,
                                930                 :                                      "BootstrapNoGC",
                                931                 :                                      ALLOCSET_DEFAULT_SIZES);
 9345 bruce                     932 ECB             : 
 8320 tgl                       933 GIC       48800 :     oldcxt = MemoryContextSwitchTo(nogc);
 9345 bruce                     934 ECB             : 
 9345 bruce                     935 CBC       48800 :     newind = (IndexList *) palloc(sizeof(IndexList));
 7684 tgl                       936           48800 :     newind->il_heap = heap;
                                937           48800 :     newind->il_ind = ind;
 8304 tgl                       938 GIC       48800 :     newind->il_info = (IndexInfo *) palloc(sizeof(IndexInfo));
 9345 bruce                     939 ECB             : 
 8304 tgl                       940 GIC       48800 :     memcpy(newind->il_info, indexInfo, sizeof(IndexInfo));
 7256 tgl                       941 ECB             :     /* expressions will likely be null, but may as well copy it */
 2222 peter_e                   942 CBC       97600 :     newind->il_info->ii_Expressions =
 7256 tgl                       943           48800 :         copyObject(indexInfo->ii_Expressions);
 7256 tgl                       944 GIC       48800 :     newind->il_info->ii_ExpressionsState = NIL;
 7937 tgl                       945 ECB             :     /* predicate will likely be null, but may as well copy it */
 2222 peter_e                   946 CBC       97600 :     newind->il_info->ii_Predicate =
 7937 tgl                       947           48800 :         copyObject(indexInfo->ii_Predicate);
 2217 andres                    948 GIC       48800 :     newind->il_info->ii_PredicateState = NULL;
 4871 tgl                       949 ECB             :     /* no exclusion constraints at bootstrap time, so no need to copy */
 4871 tgl                       950 CBC       48800 :     Assert(indexInfo->ii_ExclusionOps == NULL);
                                951           48800 :     Assert(indexInfo->ii_ExclusionProcs == NULL);
 4871 tgl                       952 GIC       48800 :     Assert(indexInfo->ii_ExclusionStrats == NULL);
 8331 tgl                       953 ECB             : 
 9345 bruce                     954 CBC       48800 :     newind->il_next = ILHead;
 9345 bruce                     955 GIC       48800 :     ILHead = newind;
 9345 bruce                     956 ECB             : 
 9345 bruce                     957 CBC       48800 :     MemoryContextSwitchTo(oldcxt);
 9770 scrappy                   958 GIC       48800 : }
                                959                 : 
                                960                 : 
                                961                 : /*
                                962                 :  * build_indices -- fill in all the indexes registered earlier
                                963                 :  */
 9770 scrappy                   964 ECB             : void
 7032 neilc                     965 GIC         305 : build_indices(void)
 9770 scrappy                   966 ECB             : {
 7032 neilc                     967 GIC       49105 :     for (; ILHead != NULL; ILHead = ILHead->il_next)
                                968                 :     {
                                969                 :         Relation    heap;
                                970                 :         Relation    ind;
                                971                 : 
 6096 tgl                       972 ECB             :         /* need not bother with locks during bootstrap */
 1539 andres                    973 CBC       48800 :         heap = table_open(ILHead->il_heap, NoLock);
 6096 tgl                       974 GIC       48800 :         ind = index_open(ILHead->il_ind, NoLock);
 8397 bruce                     975 ECB             : 
 1536 michael                   976 GIC       48800 :         index_build(heap, ind, ILHead->il_info, false, false);
 9345 bruce                     977 ECB             : 
 6096 tgl                       978 CBC       48800 :         index_close(ind, NoLock);
 1539 andres                    979 GIC       48800 :         table_close(heap, NoLock);
 9345 bruce                     980 ECB             :     }
 9770 scrappy                   981 GIC         305 : }
        

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