#include "nodes/execnodes.h"
Go to the source code of this file.
Defines | |
#define | MAXATTR 40 |
Functions | |
void | AuxiliaryProcessMain (int argc, char *argv[]) __attribute__((noreturn)) |
void | err_out (void) |
void | closerel (char *name) |
void | boot_openrel (char *name) |
void | DefineAttr (char *name, char *type, int attnum) |
void | InsertOneTuple (Oid objectid) |
void | InsertOneValue (char *value, int i) |
void | InsertOneNull (int i) |
char * | MapArrayTypeName (char *s) |
void | index_register (Oid heap, Oid ind, IndexInfo *indexInfo) |
void | build_indices (void) |
void | boot_get_type_io_data (Oid typid, int16 *typlen, bool *typbyval, char *typalign, char *typdelim, Oid *typioparam, Oid *typinput, Oid *typoutput) |
int | boot_yyparse (void) |
int | boot_yylex (void) |
void | boot_yyerror (const char *str) |
Variables | |
Relation | boot_reldesc |
Form_pg_attribute | attrtypes [MAXATTR] |
int | numattr |
#define MAXATTR 40 |
Definition at line 24 of file bootstrap.h.
Referenced by InsertOneNull(), and InsertOneValue().
void AuxiliaryProcessMain | ( | int | argc, | |
char * | argv[] | |||
) |
Definition at line 192 of file bootstrap.c.
References Assert, BackgroundWriterMain(), BaseInit(), BgWriterProcess, bootstrap_data_checksum_version, bootstrap_signals(), BootstrapModeMain(), BootstrapProcess, BootstrapProcessing, BootStrapXLOG(), ChangeToDataDir(), CheckerModeMain(), CheckerProcess, CheckpointerMain(), CheckpointerProcess, CreateDataDirLockFile(), DataDir, elog, ereport, errcode(), errmsg(), ERROR, FATAL, find_my_exec(), free, getopt(), IgnoreSystemIndexes, init_ps_display(), InitAuxiliaryProcess(), InitBufferPoolBackend(), InitializeGUCOptions(), InitializeMaxBackends(), InitXLOGAccess(), IsUnderPostmaster, MaxBackends, MAXPGPATH, MemoryContextInit(), my_exec_path, MyAuxProcType, MyProcPid, MyStartTime, name, NormalProcessing, NULL, on_shmem_exit(), optarg, optind, OutputFileName, palloc(), PANIC, ParseLongOption(), pfree(), PGC_POSTMASTER, PGC_S_ARGV, proc_exit(), ProcSignalInit(), progname, SelectConfigFiles(), SetConfigOption(), SetProcessingMode, ShutdownAuxiliaryProcess(), StartupProcess, StartupProcessMain(), strlcpy(), userDoption, ValidatePgVersion(), value, WalReceiverMain(), WalReceiverProcess, WalWriterMain(), WalWriterProcess, and write_stderr.
Referenced by main(), and StartChildProcess().
{ char *progname = argv[0]; int flag; char *userDoption = NULL; /* * initialize globals */ MyProcPid = getpid(); MyStartTime = time(NULL); /* * Fire up essential subsystems: error and memory management * * If we are running under the postmaster, this is done already. */ if (!IsUnderPostmaster) MemoryContextInit(); /* Compute paths, if we didn't inherit them from postmaster */ if (my_exec_path[0] == '\0') { if (find_my_exec(progname, my_exec_path) < 0) elog(FATAL, "%s: could not locate my own executable path", progname); } /* * process command arguments */ /* Set defaults, to be overriden by explicit options below */ if (!IsUnderPostmaster) InitializeGUCOptions(); /* Ignore the initial --boot argument, if present */ if (argc > 1 && strcmp(argv[1], "--boot") == 0) { argv++; argc--; } /* If no -x argument, we are a CheckerProcess */ MyAuxProcType = CheckerProcess; while ((flag = getopt(argc, argv, "B:c:d:D:Fkr:x:-:")) != -1) { switch (flag) { case 'B': SetConfigOption("shared_buffers", optarg, PGC_POSTMASTER, PGC_S_ARGV); break; case 'D': userDoption = strdup(optarg); break; case 'd': { /* Turn on debugging for the bootstrap process. */ char *debugstr = palloc(strlen("debug") + strlen(optarg) + 1); sprintf(debugstr, "debug%s", optarg); SetConfigOption("log_min_messages", debugstr, PGC_POSTMASTER, PGC_S_ARGV); SetConfigOption("client_min_messages", debugstr, PGC_POSTMASTER, PGC_S_ARGV); pfree(debugstr); } break; case 'F': SetConfigOption("fsync", "false", PGC_POSTMASTER, PGC_S_ARGV); break; case 'k': bootstrap_data_checksum_version = PG_DATA_CHECKSUM_VERSION; break; case 'r': strlcpy(OutputFileName, optarg, MAXPGPATH); break; case 'x': MyAuxProcType = atoi(optarg); break; case 'c': case '-': { char *name, *value; ParseLongOption(optarg, &name, &value); if (!value) { if (flag == '-') ereport(ERROR, (errcode(ERRCODE_SYNTAX_ERROR), errmsg("--%s requires a value", optarg))); else ereport(ERROR, (errcode(ERRCODE_SYNTAX_ERROR), errmsg("-c %s requires a value", optarg))); } SetConfigOption(name, value, PGC_POSTMASTER, PGC_S_ARGV); free(name); if (value) free(value); break; } default: write_stderr("Try \"%s --help\" for more information.\n", progname); proc_exit(1); break; } } if (argc != optind) { write_stderr("%s: invalid command-line arguments\n", progname); proc_exit(1); } /* * Identify myself via ps */ if (IsUnderPostmaster) { const char *statmsg; switch (MyAuxProcType) { case StartupProcess: statmsg = "startup process"; break; case BgWriterProcess: statmsg = "writer process"; break; case CheckpointerProcess: statmsg = "checkpointer process"; break; case WalWriterProcess: statmsg = "wal writer process"; break; case WalReceiverProcess: statmsg = "wal receiver process"; break; default: statmsg = "??? process"; break; } init_ps_display(statmsg, "", "", ""); } /* Acquire configuration parameters, unless inherited from postmaster */ if (!IsUnderPostmaster) { if (!SelectConfigFiles(userDoption, progname)) proc_exit(1); } /* Validate we have been given a reasonable-looking DataDir */ Assert(DataDir); ValidatePgVersion(DataDir); /* Change into DataDir (if under postmaster, should be done already) */ if (!IsUnderPostmaster) ChangeToDataDir(); /* If standalone, create lockfile for data directory */ if (!IsUnderPostmaster) CreateDataDirLockFile(false); SetProcessingMode(BootstrapProcessing); IgnoreSystemIndexes = true; /* Initialize MaxBackends (if under postmaster, was done already) */ if (!IsUnderPostmaster) InitializeMaxBackends(); BaseInit(); /* * When we are an auxiliary process, we aren't going to do the full * InitPostgres pushups, but there are a couple of things that need to get * lit up even in an auxiliary process. */ if (IsUnderPostmaster) { /* * Create a PGPROC so we can use LWLocks. In the EXEC_BACKEND case, * this was already done by SubPostmasterMain(). */ #ifndef EXEC_BACKEND InitAuxiliaryProcess(); #endif /* * Assign the ProcSignalSlot for an auxiliary process. Since it * doesn't have a BackendId, the slot is statically allocated based on * the auxiliary process type (MyAuxProcType). Backends use slots * indexed in the range from 1 to MaxBackends (inclusive), so we use * MaxBackends + AuxProcType + 1 as the index of the slot for an * auxiliary process. * * This will need rethinking if we ever want more than one of a * particular auxiliary process type. */ ProcSignalInit(MaxBackends + MyAuxProcType + 1); /* finish setting up bufmgr.c */ InitBufferPoolBackend(); /* register a shutdown callback for LWLock cleanup */ on_shmem_exit(ShutdownAuxiliaryProcess, 0); } /* * XLOG operations */ SetProcessingMode(NormalProcessing); switch (MyAuxProcType) { case CheckerProcess: /* don't set signals, they're useless here */ CheckerModeMain(); proc_exit(1); /* should never return */ case BootstrapProcess: bootstrap_signals(); BootStrapXLOG(); BootstrapModeMain(); proc_exit(1); /* should never return */ case StartupProcess: /* don't set signals, startup process has its own agenda */ StartupProcessMain(); proc_exit(1); /* should never return */ case BgWriterProcess: /* don't set signals, bgwriter has its own agenda */ BackgroundWriterMain(); proc_exit(1); /* should never return */ case CheckpointerProcess: /* don't set signals, checkpointer has its own agenda */ CheckpointerMain(); proc_exit(1); /* should never return */ case WalWriterProcess: /* don't set signals, walwriter has its own agenda */ InitXLOGAccess(); WalWriterMain(); proc_exit(1); /* should never return */ case WalReceiverProcess: /* don't set signals, walreceiver has its own agenda */ WalReceiverMain(); proc_exit(1); /* should never return */ default: elog(PANIC, "unrecognized process type: %d", (int) MyAuxProcType); proc_exit(1); } }
void boot_get_type_io_data | ( | Oid | typid, | |
int16 * | typlen, | |||
bool * | typbyval, | |||
char * | typalign, | |||
char * | typdelim, | |||
Oid * | typioparam, | |||
Oid * | typinput, | |||
Oid * | typoutput | |||
) |
Definition at line 959 of file bootstrap.c.
References typinfo::align, typmap::am_oid, typmap::am_typ, typinfo::byval, typinfo::elem, elog, ERROR, typinfo::inproc, typinfo::len, n_types, NULL, OidIsValid, and typinfo::outproc.
Referenced by get_type_io_data(), and InsertOneValue().
{ if (Typ != NULL) { /* We have the boot-time contents of pg_type, so use it */ struct typmap **app; struct typmap *ap; app = Typ; while (*app && (*app)->am_oid != typid) ++app; ap = *app; if (ap == NULL) elog(ERROR, "type OID %u not found in Typ list", typid); *typlen = ap->am_typ.typlen; *typbyval = ap->am_typ.typbyval; *typalign = ap->am_typ.typalign; *typdelim = ap->am_typ.typdelim; /* XXX this logic must match getTypeIOParam() */ if (OidIsValid(ap->am_typ.typelem)) *typioparam = ap->am_typ.typelem; else *typioparam = typid; *typinput = ap->am_typ.typinput; *typoutput = ap->am_typ.typoutput; } else { /* We don't have pg_type yet, so use the hard-wired TypInfo array */ int typeindex; for (typeindex = 0; typeindex < n_types; typeindex++) { if (TypInfo[typeindex].oid == typid) break; } if (typeindex >= n_types) elog(ERROR, "type OID %u not found in TypInfo", typid); *typlen = TypInfo[typeindex].len; *typbyval = TypInfo[typeindex].byval; *typalign = TypInfo[typeindex].align; /* We assume typdelim is ',' for all boot-time types */ *typdelim = ','; /* XXX this logic must match getTypeIOParam() */ if (OidIsValid(TypInfo[typeindex].elem)) *typioparam = TypInfo[typeindex].elem; else *typioparam = typid; *typinput = TypInfo[typeindex].inproc; *typoutput = TypInfo[typeindex].outproc; } }
void boot_openrel | ( | char * | name | ) |
Definition at line 599 of file bootstrap.c.
References ALLOC, AllocateAttribute(), typmap::am_oid, ATTRIBUTE_FIXED_PART_SIZE, tupleDesc::attrs, attrtypes, closerel(), DEBUG4, elog, ForwardScanDirection, GETSTRUCT, heap_beginscan(), heap_close, heap_endscan(), heap_getnext(), heap_open(), heap_openrv(), HeapTupleGetOid, i, makeRangeVar(), memmove, NAMEDATALEN, NameStr, NoLock, NULL, numattr, RelationData::rd_att, RelationData::rd_rel, SnapshotNow, and TypeRelationId.
{ int i; struct typmap **app; Relation rel; HeapScanDesc scan; HeapTuple tup; if (strlen(relname) >= NAMEDATALEN) relname[NAMEDATALEN - 1] = '\0'; if (Typ == NULL) { /* We can now load the pg_type data */ rel = heap_open(TypeRelationId, NoLock); scan = heap_beginscan(rel, SnapshotNow, 0, NULL); i = 0; while ((tup = heap_getnext(scan, ForwardScanDirection)) != NULL) ++i; heap_endscan(scan); app = Typ = ALLOC(struct typmap *, i + 1); while (i-- > 0) *app++ = ALLOC(struct typmap, 1); *app = NULL; scan = heap_beginscan(rel, SnapshotNow, 0, NULL); app = Typ; while ((tup = heap_getnext(scan, ForwardScanDirection)) != NULL) { (*app)->am_oid = HeapTupleGetOid(tup); memcpy((char *) &(*app)->am_typ, (char *) GETSTRUCT(tup), sizeof((*app)->am_typ)); app++; } heap_endscan(scan); heap_close(rel, NoLock); } if (boot_reldesc != NULL) closerel(NULL); elog(DEBUG4, "open relation %s, attrsize %d", relname, (int) ATTRIBUTE_FIXED_PART_SIZE); boot_reldesc = heap_openrv(makeRangeVar(NULL, relname, -1), NoLock); numattr = boot_reldesc->rd_rel->relnatts; for (i = 0; i < numattr; i++) { if (attrtypes[i] == NULL) attrtypes[i] = AllocateAttribute(); memmove((char *) attrtypes[i], (char *) boot_reldesc->rd_att->attrs[i], ATTRIBUTE_FIXED_PART_SIZE); { Form_pg_attribute at = attrtypes[i]; elog(DEBUG4, "create attribute %d name %s len %d num %d type %u", i, NameStr(at->attname), at->attlen, at->attnum, at->atttypid); } } }
void boot_yyerror | ( | const char * | str | ) |
int boot_yylex | ( | void | ) |
int boot_yyparse | ( | void | ) |
Referenced by BootstrapModeMain().
void build_indices | ( | void | ) |
Definition at line 1143 of file bootstrap.c.
References heap_close, heap_open(), _IndexList::il_heap, _IndexList::il_ind, _IndexList::il_info, _IndexList::il_next, index_build(), index_close(), index_open(), and NoLock.
{ for (; ILHead != NULL; ILHead = ILHead->il_next) { Relation heap; Relation ind; /* need not bother with locks during bootstrap */ heap = heap_open(ILHead->il_heap, NoLock); ind = index_open(ILHead->il_ind, NoLock); index_build(heap, ind, ILHead->il_info, false, false); index_close(ind, NoLock); heap_close(heap, NoLock); } }
void closerel | ( | char * | name | ) |
Definition at line 668 of file bootstrap.c.
References DEBUG4, elog, ERROR, heap_close, NoLock, NULL, and RelationGetRelationName.
Referenced by boot_openrel(), cleanup(), and DefineAttr().
{ if (name) { if (boot_reldesc) { if (strcmp(RelationGetRelationName(boot_reldesc), name) != 0) elog(ERROR, "close of %s when %s was expected", name, RelationGetRelationName(boot_reldesc)); } else elog(ERROR, "close of %s before any relation was opened", name); } if (boot_reldesc == NULL) elog(ERROR, "no open relation to close"); else { elog(DEBUG4, "close relation %s", RelationGetRelationName(boot_reldesc)); heap_close(boot_reldesc, NoLock); boot_reldesc = NULL; } }
void DefineAttr | ( | char * | name, | |
char * | type, | |||
int | attnum | |||
) |
Definition at line 705 of file bootstrap.c.
References typinfo::align, AllocateAttribute(), typmap::am_oid, typmap::am_typ, ATTRIBUTE_FIXED_PART_SIZE, attrtypes, typinfo::byval, closerel(), typinfo::collation, DEBUG4, elog, gettype(), i, InvalidOid, typinfo::len, MARKNOTNULL, MemSet, NameStr, namestrcpy(), NULL, typinfo::oid, typinfo::storage, and WARNING.
{ Oid typeoid; if (boot_reldesc != NULL) { elog(WARNING, "no open relations allowed with CREATE command"); closerel(NULL); } if (attrtypes[attnum] == NULL) attrtypes[attnum] = AllocateAttribute(); MemSet(attrtypes[attnum], 0, ATTRIBUTE_FIXED_PART_SIZE); namestrcpy(&attrtypes[attnum]->attname, name); elog(DEBUG4, "column %s %s", NameStr(attrtypes[attnum]->attname), type); attrtypes[attnum]->attnum = attnum + 1; /* fillatt */ typeoid = gettype(type); if (Typ != NULL) { attrtypes[attnum]->atttypid = Ap->am_oid; attrtypes[attnum]->attlen = Ap->am_typ.typlen; attrtypes[attnum]->attbyval = Ap->am_typ.typbyval; attrtypes[attnum]->attstorage = Ap->am_typ.typstorage; attrtypes[attnum]->attalign = Ap->am_typ.typalign; attrtypes[attnum]->attcollation = Ap->am_typ.typcollation; /* if an array type, assume 1-dimensional attribute */ if (Ap->am_typ.typelem != InvalidOid && Ap->am_typ.typlen < 0) attrtypes[attnum]->attndims = 1; else attrtypes[attnum]->attndims = 0; } else { attrtypes[attnum]->atttypid = TypInfo[typeoid].oid; attrtypes[attnum]->attlen = TypInfo[typeoid].len; attrtypes[attnum]->attbyval = TypInfo[typeoid].byval; attrtypes[attnum]->attstorage = TypInfo[typeoid].storage; attrtypes[attnum]->attalign = TypInfo[typeoid].align; attrtypes[attnum]->attcollation = TypInfo[typeoid].collation; /* if an array type, assume 1-dimensional attribute */ if (TypInfo[typeoid].elem != InvalidOid && attrtypes[attnum]->attlen < 0) attrtypes[attnum]->attndims = 1; else attrtypes[attnum]->attndims = 0; } attrtypes[attnum]->attstattarget = -1; attrtypes[attnum]->attcacheoff = -1; attrtypes[attnum]->atttypmod = -1; attrtypes[attnum]->attislocal = true; /* * Mark as "not null" if type is fixed-width and prior columns are too. * This corresponds to case where column can be accessed directly via C * struct declaration. * * oidvector and int2vector are also treated as not-nullable, even though * they are no longer fixed-width. */ #define MARKNOTNULL(att) \ ((att)->attlen > 0 || \ (att)->atttypid == OIDVECTOROID || \ (att)->atttypid == INT2VECTOROID) if (MARKNOTNULL(attrtypes[attnum])) { int i; for (i = 0; i < attnum; i++) { if (!MARKNOTNULL(attrtypes[i])) break; } if (i == attnum) attrtypes[attnum]->attnotnull = true; } }
void err_out | ( | void | ) |
Definition at line 1091 of file bootstrap.c.
References ALLOCSET_DEFAULT_INITSIZE, ALLOCSET_DEFAULT_MAXSIZE, ALLOCSET_DEFAULT_MINSIZE, AllocSetContextCreate(), Assert, copyObject(), IndexInfo::ii_ExclusionOps, IndexInfo::ii_ExclusionProcs, IndexInfo::ii_ExclusionStrats, IndexInfo::ii_Expressions, IndexInfo::ii_ExpressionsState, IndexInfo::ii_Predicate, IndexInfo::ii_PredicateState, _IndexList::il_heap, _IndexList::il_ind, _IndexList::il_info, _IndexList::il_next, MemoryContextSwitchTo(), NULL, and palloc().
Referenced by index_create().
{ IndexList *newind; MemoryContext oldcxt; /* * XXX mao 10/31/92 -- don't gc index reldescs, associated info at * bootstrap time. we'll declare the indexes now, but want to create them * later. */ if (nogc == NULL) nogc = AllocSetContextCreate(NULL, "BootstrapNoGC", ALLOCSET_DEFAULT_MINSIZE, ALLOCSET_DEFAULT_INITSIZE, ALLOCSET_DEFAULT_MAXSIZE); oldcxt = MemoryContextSwitchTo(nogc); newind = (IndexList *) palloc(sizeof(IndexList)); newind->il_heap = heap; newind->il_ind = ind; newind->il_info = (IndexInfo *) palloc(sizeof(IndexInfo)); memcpy(newind->il_info, indexInfo, sizeof(IndexInfo)); /* expressions will likely be null, but may as well copy it */ newind->il_info->ii_Expressions = (List *) copyObject(indexInfo->ii_Expressions); newind->il_info->ii_ExpressionsState = NIL; /* predicate will likely be null, but may as well copy it */ newind->il_info->ii_Predicate = (List *) copyObject(indexInfo->ii_Predicate); newind->il_info->ii_PredicateState = NIL; /* no exclusion constraints at bootstrap time, so no need to copy */ Assert(indexInfo->ii_ExclusionOps == NULL); Assert(indexInfo->ii_ExclusionProcs == NULL); Assert(indexInfo->ii_ExclusionStrats == NULL); newind->il_next = ILHead; ILHead = newind; MemoryContextSwitchTo(oldcxt); }
void InsertOneNull | ( | int | i | ) |
void InsertOneTuple | ( | Oid | objectid | ) |
Definition at line 796 of file bootstrap.c.
References attrtypes, CreateTupleDesc(), DEBUG4, elog, heap_form_tuple(), heap_freetuple(), HeapTupleSetOid, i, numattr, pfree(), RelationGetForm, and simple_heap_insert().
{ HeapTuple tuple; TupleDesc tupDesc; int i; elog(DEBUG4, "inserting row oid %u, %d columns", objectid, numattr); tupDesc = CreateTupleDesc(numattr, RelationGetForm(boot_reldesc)->relhasoids, attrtypes); tuple = heap_form_tuple(tupDesc, values, Nulls); if (objectid != (Oid) 0) HeapTupleSetOid(tuple, objectid); pfree(tupDesc); /* just free's tupDesc, not the attrtypes */ simple_heap_insert(boot_reldesc, tuple); heap_freetuple(tuple); elog(DEBUG4, "row inserted"); /* * Reset null markers for next tuple */ for (i = 0; i < numattr; i++) Nulls[i] = false; }
void InsertOneValue | ( | char * | value, | |
int | i | |||
) |
Definition at line 828 of file bootstrap.c.
References AssertArg, tupleDesc::attrs, boot_get_type_io_data(), DEBUG4, elog, MAXATTR, OidInputFunctionCall(), OidOutputFunctionCall(), pfree(), and RelationData::rd_att.
{ Oid typoid; int16 typlen; bool typbyval; char typalign; char typdelim; Oid typioparam; Oid typinput; Oid typoutput; char *prt; AssertArg(i >= 0 && i < MAXATTR); elog(DEBUG4, "inserting column %d value \"%s\"", i, value); typoid = boot_reldesc->rd_att->attrs[i]->atttypid; boot_get_type_io_data(typoid, &typlen, &typbyval, &typalign, &typdelim, &typioparam, &typinput, &typoutput); values[i] = OidInputFunctionCall(typinput, value, typioparam, -1); prt = OidOutputFunctionCall(typoutput, values[i]); elog(DEBUG4, "inserted -> %s", prt); pfree(prt); }
char* MapArrayTypeName | ( | char * | s | ) |
Definition at line 1059 of file bootstrap.c.
References i, NAMEDATALEN, and NULL.
{ int i, j; static char newStr[NAMEDATALEN]; /* array type names < NAMEDATALEN long */ if (s == NULL || s[0] == '\0') return s; j = 1; newStr[0] = '_'; for (i = 0; i < NAMEDATALEN - 1 && s[i] != '['; i++, j++) newStr[j] = s[i]; newStr[j] = '\0'; return newStr; }
Form_pg_attribute attrtypes[MAXATTR] |
Definition at line 74 of file bootstrap.c.
Referenced by boot_openrel(), BootstrapModeMain(), DefineAttr(), and InsertOneTuple().
Definition at line 72 of file bootstrap.c.
int numattr |
Definition at line 75 of file bootstrap.c.
Referenced by boot_openrel(), InsertOneTuple(), and tsvector_update_trigger().