⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 bootstrap.c

📁 关系型数据库 Postgresql 6.5.2
💻 C
📖 第 1 页 / 共 2 页
字号:
/*------------------------------------------------------------------------- * * bootstrap.c *	  routines to support running postgres in 'bootstrap' mode *	bootstrap mode is used to create the initial template database * * Copyright (c) 1994, Regents of the University of California * * IDENTIFICATION *	  $Header: /usr/local/cvsroot/pgsql/src/backend/bootstrap/bootstrap.c,v 1.60.2.1 1999/08/02 05:56:52 scrappy Exp $ * *------------------------------------------------------------------------- */#include <unistd.h>#include <time.h>#include <signal.h>#include <setjmp.h>#define BOOTSTRAP_INCLUDE		/* mask out stuff in tcop/tcopprot.h */#include "postgres.h"#ifdef HAVE_GETOPT_H#include <getopt.h>#endif#include "access/genam.h"#include "access/heapam.h"#include "bootstrap/bootstrap.h"#include "catalog/catname.h"#include "catalog/index.h"#include "catalog/pg_type.h"#include "libpq/pqsignal.h"#include "miscadmin.h"#include "tcop/tcopprot.h"#include "utils/builtins.h"#include "utils/lsyscache.h"#include "utils/portal.h"#define ALLOC(t, c)		(t *)calloc((unsigned)(c), sizeof(t))#define FIRST_TYPE_OID 16		/* OID of the first type */extern int	Int_yyparse(void);static hashnode *AddStr(char *str, int strlength, int mderef);static Form_pg_attribute AllocateAttribute(void);static bool BootstrapAlreadySeen(Oid id);static int	CompHash(char *str, int len);static hashnode *FindStr(char *str, int length, hashnode *mderef);static Oid	gettype(char *type);static void cleanup(void);/* ---------------- *		global variables * ---------------- *//* * In the lexical analyzer, we need to get the reference number quickly from * the string, and the string from the reference number.  Thus we have * as our data structure a hash table, where the hashing key taken from * the particular string.  The hash table is chained.  One of the fields * of the hash table node is an index into the array of character pointers. * The unique index number that every string is assigned is simply the * position of its string pointer in the array of string pointers. */#define STRTABLESIZE	10000#define HASHTABLESIZE	503/* Hash function numbers */#define NUM		23#define NUMSQR	529#define NUMCUBE 12167char	   *strtable[STRTABLESIZE];hashnode   *hashtable[HASHTABLESIZE];static int	strtable_end = -1;	/* Tells us last occupied string space *//*- * Basic information associated with each type.  This is used before * pg_type is created. * *		XXX several of these input/output functions do catalog scans *			(e.g., F_REGPROCIN scans pg_proc).	this obviously creates some *			order dependencies in the catalog creation process. */struct typinfo{	char		name[NAMEDATALEN];	Oid			oid;	Oid			elem;	int16		len;	Oid			inproc;	Oid			outproc;};static struct typinfo Procid[] = {	{"bool", 16, 0, 1, F_BOOLIN, F_BOOLOUT},	{"bytea", 17, 0, -1, F_BYTEAIN, F_BYTEAOUT},	{"char", 18, 0, 1, F_CHARIN, F_CHAROUT},	{"name", 19, 0, NAMEDATALEN, F_NAMEIN, F_NAMEOUT},	{"dummy", 20, 0, 16, 0, 0},/*	  { "dt",		  20,	 0,  4, F_DTIN,			F_DTOUT}, */	{"int2", 21, 0, 2, F_INT2IN, F_INT2OUT},	{"int28", 22, 0, 16, F_INT28IN, F_INT28OUT},	{"int4", 23, 0, 4, F_INT4IN, F_INT4OUT},	{"regproc", 24, 0, 4, F_REGPROCIN, F_REGPROCOUT},	{"text", 25, 0, -1, F_TEXTIN, F_TEXTOUT},	{"oid", 26, 0, 4, F_INT4IN, F_INT4OUT},	{"tid", 27, 0, 6, F_TIDIN, F_TIDOUT},	{"xid", 28, 0, 5, F_XIDIN, F_XIDOUT},	{"iid", 29, 0, 1, F_CIDIN, F_CIDOUT},	{"oid8", 30, 0, 32, F_OID8IN, F_OID8OUT},	{"smgr", 210, 0, 2, F_SMGRIN, F_SMGROUT},	{"_int4", 1007, 23, -1, F_ARRAY_IN, F_ARRAY_OUT},	{"_aclitem", 1034, 1033, -1, F_ARRAY_IN, F_ARRAY_OUT}};static int	n_types = sizeof(Procid) / sizeof(struct typinfo);struct typmap{								/* a hack */	Oid			am_oid;	FormData_pg_type am_typ;};static struct typmap **Typ = (struct typmap **) NULL;static struct typmap *Ap = (struct typmap *) NULL;static int	Warnings = 0;static char Blanks[MAXATTR];static char *relname;			/* current relation name */Form_pg_attribute attrtypes[MAXATTR];	/* points to attribute info */static char *values[MAXATTR];	/* cooresponding attribute values */int			numattr;			/* number of attributes for cur. rel */extern bool disableFsync;		/* do not fsync the database */int			DebugMode;static GlobalMemory nogc = (GlobalMemory) NULL; /* special no-gc mem												 * context */extern int	optind;extern char *optarg;/* *	At bootstrap time, we first declare all the indices to be built, and *	then build them.  The IndexList structure stores enough information *	to allow us to build the indices after they've been declared. */typedef struct _IndexList{	char	   *il_heap;	char	   *il_ind;	int			il_natts;	AttrNumber *il_attnos;	uint16		il_nparams;	Datum	   *il_params;	FuncIndexInfo *il_finfo;	PredInfo   *il_predInfo;	struct _IndexList *il_next;} IndexList;static IndexList *ILHead = (IndexList *) NULL;typedef void (*sig_func) ();/* ---------------------------------------------------------------- *						misc functions * ---------------------------------------------------------------- *//* ---------------- *		error handling / abort routines * ---------------- */voiderr_out(void){	Warnings++;	cleanup();}/* usage:   usage help for the bootstrap backen*/static voidusage(void){	fprintf(stderr, "Usage: postgres -boot [-d] [-C] [-F] [-O] [-Q] ");	fprintf(stderr, "[-P portno] [dbName]\n");	fprintf(stderr, "     d: debug mode\n");	fprintf(stderr, "     C: disable version checking\n");	fprintf(stderr, "     F: turn off fsync\n");	fprintf(stderr, "     O: set BootstrapProcessing mode\n");	fprintf(stderr, "     P portno: specify port number\n");	proc_exit(1);}intBootstrapMain(int argc, char *argv[])/* ---------------------------------------------------------------- *	 The main loop for handling the backend in bootstrap mode *	 the bootstrap mode is used to initialize the template database *	 the bootstrap backend doesn't speak SQL, but instead expects *	 commands in a special bootstrap language. * *	 The arguments passed in to BootstrapMain are the run-time arguments *	 without the argument '-boot', the caller is required to have *	 removed -boot from the run-time args * ---------------------------------------------------------------- */{	int			i;	int			portFd = -1;	char	   *dbName;	int			flag;	int			override = 1;	/* use BootstrapProcessing or								 * InitProcessing mode */	extern int	optind;	extern char *optarg;	/* ----------------	 *	initialize signal handlers	 * ----------------	 */	pqsignal(SIGINT, (sig_func) die);	pqsignal(SIGHUP, (sig_func) die);	pqsignal(SIGTERM, (sig_func) die);	/* --------------------	 *	initialize globals	 * -------------------	 */	MyProcPid = getpid();	/* ----------------	 *	process command arguments	 * ----------------	 */	/* Set defaults, to be overriden by explicit options below */	Quiet = false;	Noversion = false;	dbName = NULL;	DataDir = getenv("PGDATA"); /* Null if no PGDATA variable */	while ((flag = getopt(argc, argv, "D:dCOQP:F")) != EOF)	{		switch (flag)		{			case 'D':				DataDir = optarg;				break;			case 'd':				DebugMode = true;		/* print out debugging info while										 * parsing */				break;			case 'C':				Noversion = true;				break;			case 'F':				disableFsync = true;				break;			case 'O':				override = true;				break;			case 'Q':				Quiet = true;				break;			case 'P':			/* specify port */				portFd = atoi(optarg);				break;			default:				usage();				break;		}	}							/* while */	if (argc - optind > 1)		usage();	else if (argc - optind == 1)		dbName = argv[optind];	if (!DataDir)	{		fprintf(stderr, "%s does not know where to find the database system "				"data.  You must specify the directory that contains the "				"database system either by specifying the -D invocation "			 "option or by setting the PGDATA environment variable.\n\n",				argv[0]);		proc_exit(1);	}	if (dbName == NULL)	{		dbName = getenv("USER");		if (dbName == NULL)		{			fputs("bootstrap backend: failed, no db name specified\n", stderr);			fputs("          and no USER enviroment variable\n", stderr);			proc_exit(1);		}	}	/* ----------------	 *	initialize input fd	 * ----------------	 */	if (IsUnderPostmaster && portFd < 0)	{		fputs("backend: failed, no -P option with -postmaster opt.\n", stderr);		proc_exit(1);	}	/* ----------------	 *	backend initialization	 * ----------------	 */	SetProcessingMode((override) ? BootstrapProcessing : InitProcessing);	InitPostgres(dbName);	LockDisable(true);	for (i = 0; i < MAXATTR; i++)	{		attrtypes[i] = (Form_pg_attribute) NULL;		Blanks[i] = ' ';	}	for (i = 0; i < STRTABLESIZE; ++i)		strtable[i] = NULL;	for (i = 0; i < HASHTABLESIZE; ++i)		hashtable[i] = NULL;	/* ----------------	 *	abort processing resumes here	 * ----------------	 */	pqsignal(SIGHUP, handle_warn);	if (sigsetjmp(Warn_restart, 1) != 0)	{		Warnings++;		AbortCurrentTransaction();	}	/* ----------------	 *	process input.	 * ----------------	 */	/*	 * the sed script boot.sed renamed yyparse to Int_yyparse for the	 * bootstrap parser to avoid conflicts with the normal SQL parser	 */	Int_yyparse();	/* clean up processing */	StartTransactionCommand();	cleanup();	/* not reached, here to make compiler happy */	return 0;}/* ---------------------------------------------------------------- *				MANUAL BACKEND INTERACTIVE INTERFACE COMMANDS * ---------------------------------------------------------------- *//* ---------------- *		boot_openrel * ---------------- */voidboot_openrel(char *relname){	int			i;	struct typmap **app;	Relation	rel;	HeapScanDesc scan;	HeapTuple	tup;	if (strlen(relname) >= NAMEDATALEN - 1)		relname[NAMEDATALEN - 1] = '\0';	if (Typ == (struct typmap **) NULL)	{		StartPortalAllocMode(DefaultAllocMode, 0);		rel = heap_openr(TypeRelationName);		scan = heap_beginscan(rel, 0, SnapshotNow, 0, (ScanKey) NULL);		i = 0;		while (HeapTupleIsValid(tup = heap_getnext(scan, 0)))			++i;		heap_endscan(scan);		app = Typ = ALLOC(struct typmap *, i + 1);		while (i-- > 0)			*app++ = ALLOC(struct typmap, 1);		*app = (struct typmap *) NULL;		scan = heap_beginscan(rel, 0, SnapshotNow, 0, (ScanKey) NULL);		app = Typ;		while (HeapTupleIsValid(tup = heap_getnext(scan, 0)))		{			(*app)->am_oid = tup->t_data->t_oid;			memmove((char *) &(*app++)->am_typ,					(char *) GETSTRUCT(tup),					sizeof((*app)->am_typ));		}		heap_endscan(scan);		heap_close(rel);		EndPortalAllocMode();	}	if (reldesc != NULL)		closerel(NULL);	if (!Quiet)		printf("Amopen: relation %s. attrsize %d\n", relname ? relname : "(null)",			   (int) ATTRIBUTE_TUPLE_SIZE);	reldesc = heap_openr(relname);	Assert(reldesc);	numattr = reldesc->rd_rel->relnatts;	for (i = 0; i < numattr; i++)	{		if (attrtypes[i] == NULL)			attrtypes[i] = AllocateAttribute();		memmove((char *) attrtypes[i],				(char *) reldesc->rd_att->attrs[i],				ATTRIBUTE_TUPLE_SIZE);		/* Some old pg_attribute tuples might not have attisset. */		/*		 * If the attname is attisset, don't look for it - it may not be		 * defined yet.		 */		if (namestrcmp(&attrtypes[i]->attname, "attisset") == 0)			attrtypes[i]->attisset = get_attisset(RelationGetRelid(reldesc),											 attrtypes[i]->attname.data);		else			attrtypes[i]->attisset = false;		if (DebugMode)		{			Form_pg_attribute at = attrtypes[i];			printf("create attribute %d name %s len %d num %d type %d\n",				   i, at->attname.data, at->attlen, at->attnum,				   at->atttypid				);			fflush(stdout);		}	}}/* ---------------- *		closerel * ---------------- */voidcloserel(char *name){	if (name)	{		if (reldesc)		{			if (namestrcmp(RelationGetRelationName(reldesc), name) != 0)				elog(ERROR, "closerel: close of '%s' when '%s' was expected",					 name, relname ? relname : "(null)");		}		else			elog(ERROR, "closerel: close of '%s' before any relation was opened",				 name);	}	if (reldesc == NULL)		elog(ERROR, "Warning: no opened relation to close.\n");	else	{		if (!Quiet)			printf("Amclose: relation %s.\n", relname ? relname : "(null)");		heap_close(reldesc);		reldesc = (Relation) NULL;	}}/* ---------------- * DEFINEATTR() * * define a <field,type> pair * if there are n fields in a relation to be created, this routine * will be called n times * ---------------- */voidDefineAttr(char *name, char *type, int attnum){	int			attlen;	Oid			typeoid;	if (reldesc != NULL)	{		fputs("Warning: no open relations allowed with 't' command.\n", stderr);		closerel(relname);	}	typeoid = gettype(type);	if (attrtypes[attnum] == (Form_pg_attribute) NULL)		attrtypes[attnum] = AllocateAttribute();	if (Typ != (struct typmap **) NULL)	{		attrtypes[attnum]->atttypid = Ap->am_oid;		namestrcpy(&attrtypes[attnum]->attname, name);		if (!Quiet)			printf("<%s %s> ", attrtypes[attnum]->attname.data, type);		attrtypes[attnum]->attnum = 1 + attnum; /* fillatt */		attlen = attrtypes[attnum]->attlen = Ap->am_typ.typlen;		attrtypes[attnum]->attbyval = Ap->am_typ.typbyval;		attrtypes[attnum]->attalign = Ap->am_typ.typalign;	}	else	{		attrtypes[attnum]->atttypid = Procid[typeoid].oid;		namestrcpy(&attrtypes[attnum]->attname, name);		if (!Quiet)			printf("<%s %s> ", attrtypes[attnum]->attname.data, type);		attrtypes[attnum]->attnum = 1 + attnum; /* fillatt */		attlen = attrtypes[attnum]->attlen = Procid[typeoid].len;		/*		 * Cheat like mad to fill in these items from the length only.		 * This only has to work for types used in the system catalogs...		 */		switch (attlen)		{			case 1:				attrtypes[attnum]->attbyval = true;				attrtypes[attnum]->attalign = 'c';				break;			case 2:				attrtypes[attnum]->attbyval = true;				attrtypes[attnum]->attalign = 's';				break;			case 4:				attrtypes[attnum]->attbyval = true;				attrtypes[attnum]->attalign = 'i';				break;			default:				attrtypes[attnum]->attbyval = false;				attrtypes[attnum]->attalign = 'i';				break;		}	}	attrtypes[attnum]->attcacheoff = -1;	attrtypes[attnum]->atttypmod = -1;}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -