diff options
author | Bruce Momjian <bruce@momjian.us> | 1997-09-07 05:04:48 +0000 |
---|---|---|
committer | Bruce Momjian <bruce@momjian.us> | 1997-09-07 05:04:48 +0000 |
commit | 1ccd423235a48739d6f7a4d7889705b5f9ecc69b (patch) | |
tree | 8001c4e839dfad8f29ceda7f8c5f5dbb8759b564 /src/backend/bootstrap/bootstrap.c | |
parent | 8fecd4febf8357f3cc20383ed29ced484877d5ac (diff) | |
download | postgresql-1ccd423235a48739d6f7a4d7889705b5f9ecc69b.tar.gz postgresql-1ccd423235a48739d6f7a4d7889705b5f9ecc69b.zip |
Massive commit to run PGINDENT on all *.c and *.h files.
Diffstat (limited to 'src/backend/bootstrap/bootstrap.c')
-rw-r--r-- | src/backend/bootstrap/bootstrap.c | 1683 |
1 files changed, 892 insertions, 791 deletions
diff --git a/src/backend/bootstrap/bootstrap.c b/src/backend/bootstrap/bootstrap.c index 6b27010d3a9..9fd4bf719b3 100644 --- a/src/backend/bootstrap/bootstrap.c +++ b/src/backend/bootstrap/bootstrap.c @@ -1,23 +1,23 @@ /*------------------------------------------------------------------------- * * bootstrap.c-- - * routines to support running postgres in 'bootstrap' mode - * bootstrap mode is used to create the initial template database + * 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: /cvsroot/pgsql/src/backend/bootstrap/bootstrap.c,v 1.21 1997/08/19 21:30:24 momjian Exp $ + * $Header: /cvsroot/pgsql/src/backend/bootstrap/bootstrap.c,v 1.22 1997/09/07 04:39:49 momjian Exp $ * *------------------------------------------------------------------------- */ -#include <unistd.h> /* For getopt() */ +#include <unistd.h> /* For getopt() */ #include <time.h> #include <stdio.h> #include <signal.h> #include <setjmp.h> -#define BOOTSTRAP_INCLUDE /* mask out stuff in tcop/tcopprot.h */ +#define BOOTSTRAP_INCLUDE /* mask out stuff in tcop/tcopprot.h */ #include "postgres.h" @@ -41,7 +41,7 @@ #include "utils/nabstime.h" #include "access/htup.h" #include "utils/tqual.h" -#include "storage/buf.h" +#include "storage/buf.h" #include "access/relscan.h" #include "access/heapam.h" @@ -55,7 +55,7 @@ #include "catalog/pg_type.h" -#include "access/itup.h" +#include "access/itup.h" #include "bootstrap/bootstrap.h" #include "tcop/tcopprot.h" @@ -69,7 +69,7 @@ #include "access/xact.h" #ifndef HAVE_MEMMOVE -# include "regex/utils.h" +#include "regex/utils.h" #endif #include <string.h> @@ -100,20 +100,20 @@ #include "utils/palloc.h" -#define ALLOC(t, c) (t *)calloc((unsigned)(c), sizeof(t)) -#define FIRST_TYPE_OID 16 /* OID of the first type */ +#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); +extern int Int_yyparse(void); static hashnode *AddStr(char *str, int strlength, int mderef); static AttributeTupleForm AllocateAttribute(void); -static bool BootstrapAlreadySeen(Oid id); -static int CompHash (char *str, int len); -static hashnode *FindStr (char *str, int length, hashnode *mderef); -static int gettype(char *type); -static void cleanup(void); +static bool BootstrapAlreadySeen(Oid id); +static int CompHash(char *str, int len); +static hashnode *FindStr(char *str, int length, hashnode * mderef); +static int gettype(char *type); +static void cleanup(void); /* ---------------- - * global variables + * global variables * ---------------- */ /* @@ -126,130 +126,138 @@ static void cleanup(void); * position of its string pointer in the array of string pointers. */ -#define STRTABLESIZE 10000 -#define HASHTABLESIZE 503 +#define STRTABLESIZE 10000 +#define HASHTABLESIZE 503 /* Hash function numbers */ -#define NUM 23 -#define NUMSQR 529 +#define NUM 23 +#define NUMSQR 529 #define NUMCUBE 12167 -char *strtable [STRTABLESIZE]; -hashnode *hashtable [HASHTABLESIZE]; +char *strtable[STRTABLESIZE]; +hashnode *hashtable[HASHTABLESIZE]; -static int strtable_end = -1; /* Tells us last occupied string space */ +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. + * 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; +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 }, - { "char16", 20, 0, 16, F_CHAR16IN, F_CHAR16OUT}, -/* { "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 } + {"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}, + {"char16", 20, 0, 16, F_CHAR16IN, F_CHAR16OUT}, +/* { "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); +static int n_types = sizeof(Procid) / sizeof(struct typinfo); -struct typmap { /* a hack */ - Oid am_oid; - TypeTupleFormData am_typ; +struct typmap +{ /* a hack */ + Oid am_oid; + TypeTupleFormData 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 */ +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 */ -AttributeTupleForm attrtypes[MAXATTR]; /* points to attribute info */ -static char *values[MAXATTR]; /* cooresponding attribute values */ -int numattr; /* number of attributes for cur. rel */ -extern int fsyncOff; /* do not fsync the database */ +AttributeTupleForm attrtypes[MAXATTR]; /* points to attribute info */ +static char *values[MAXATTR];/* cooresponding attribute values */ +int numattr; /* number of attributes for cur. rel */ +extern int fsyncOff; /* do not fsync the database */ #ifndef HAVE_SIGSETJMP -static jmp_buf Warn_restart; -#define sigsetjmp(x,y) setjmp(x) +static jmp_buf Warn_restart; + +#define sigsetjmp(x,y) setjmp(x) #define siglongjmp longjmp #else static sigjmp_buf Warn_restart; + #endif -int DebugMode; -static GlobalMemory nogc = (GlobalMemory) NULL; /* special no-gc mem context */ +int DebugMode; +static GlobalMemory nogc = (GlobalMemory) NULL; /* special no-gc mem + * context */ + +extern int optind; +extern char *optarg; -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. + * 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; +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)(); + +typedef void (*sig_func) (); + + - /* ---------------------------------------------------------------- - * misc functions + * misc functions * ---------------------------------------------------------------- */ /* ---------------- - * error handling / abort routines + * error handling / abort routines * ---------------- */ void err_out(void) { - Warnings++; - cleanup(); + Warnings++; + cleanup(); } /* usage: @@ -258,15 +266,15 @@ err_out(void) static void usage(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"); - - exitpg(1); + 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"); + + exitpg(1); } @@ -274,286 +282,316 @@ usage(void) int BootstrapMain(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 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 + * 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); + 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); #ifndef win32 - pqsignal(SIGHUP, (sig_func) die); - pqsignal(SIGTERM, (sig_func) die); -#endif /* win32 */ - - /* -------------------- - * initialize globals - * ------------------- - */ - - MasterPid = getpid(); - - /* ---------------- - * process command arguments - * ---------------- - */ - - /* Set defaults, to be overriden by explicit options below */ - Quiet = 0; - Noversion = 0; - 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 = 1; /* print out debugging info while parsing */ - break; - case 'C': - Noversion = 1; - break; - case 'F': - fsyncOff = 1; - break; - case 'O': - override = true; - break; - case 'Q': - Quiet = 1; - 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]); - exitpg(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); - exitpg(1); - } - } - - /* ---------------- - * initialize input fd - * ---------------- - */ - if (IsUnderPostmaster == true && portFd < 0) { - fputs("backend: failed, no -P option with -postmaster opt.\n", stderr); - exitpg(1); - } - + pqsignal(SIGHUP, (sig_func) die); + pqsignal(SIGTERM, (sig_func) die); +#endif /* win32 */ + + /* -------------------- + * initialize globals + * ------------------- + */ + + MasterPid = getpid(); + + /* ---------------- + * process command arguments + * ---------------- + */ + + /* Set defaults, to be overriden by explicit options below */ + Quiet = 0; + Noversion = 0; + 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 = 1; /* print out debugging info while parsing */ + break; + case 'C': + Noversion = 1; + break; + case 'F': + fsyncOff = 1; + break; + case 'O': + override = true; + break; + case 'Q': + Quiet = 1; + 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]); + exitpg(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); + exitpg(1); + } + } + + /* ---------------- + * initialize input fd + * ---------------- + */ + if (IsUnderPostmaster == true && portFd < 0) + { + fputs("backend: failed, no -P option with -postmaster opt.\n", stderr); + exitpg(1); + } + #ifdef win32 - _nt_init(); - _nt_attach(); -#endif /* win32 */ - - - /* ---------------- - * backend initialization - * ---------------- - */ - SetProcessingMode((override) ? BootstrapProcessing : InitProcessing); - InitPostgres(dbName); - LockDisable(true); - - for (i = 0 ; i < MAXATTR; i++) { - attrtypes[i]=(AttributeTupleForm )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 - What to do in WIN32? - * ---------------- - */ -#ifndef win32 - pqsignal(SIGHUP, handle_warn); - - if (sigsetjmp(Warn_restart, 1) != 0) { + _nt_init(); + _nt_attach(); +#endif /* win32 */ + + + /* ---------------- + * backend initialization + * ---------------- + */ + SetProcessingMode((override) ? BootstrapProcessing : InitProcessing); + InitPostgres(dbName); + LockDisable(true); + + for (i = 0; i < MAXATTR; i++) + { + attrtypes[i] = (AttributeTupleForm) 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 - What to do in WIN32? + * ---------------- + */ +#ifndef win32 + pqsignal(SIGHUP, handle_warn); + + if (sigsetjmp(Warn_restart, 1) != 0) + { #else - if (setjmp(Warn_restart) != 0) { -#endif /* win32 */ - 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; + if (setjmp(Warn_restart) != 0) + { +#endif /* win32 */ + 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 + * MANUAL BACKEND INTERACTIVE INTERFACE COMMANDS * ---------------------------------------------------------------- */ /* ---------------- - * boot_openrel + * boot_openrel * ---------------- */ void boot_openrel(char *relname) { - int i; - struct typmap **app; - Relation rdesc; - HeapScanDesc sdesc; - HeapTuple tup; - - if (strlen(relname) > 15) - relname[15] ='\000'; - - if (Typ == (struct typmap **)NULL) { - StartPortalAllocMode(DefaultAllocMode, 0); - rdesc = heap_openr(TypeRelationName); - sdesc = heap_beginscan(rdesc, 0, NowTimeQual, 0, (ScanKey)NULL); - for (i=0; PointerIsValid(tup=heap_getnext(sdesc,0,(Buffer *)NULL)); ++i); - heap_endscan(sdesc); - app = Typ = ALLOC(struct typmap *, i + 1); - while (i-- > 0) - *app++ = ALLOC(struct typmap, 1); - *app = (struct typmap *)NULL; - sdesc = heap_beginscan(rdesc, 0, NowTimeQual, 0, (ScanKey)NULL); - app = Typ; - while (PointerIsValid(tup = heap_getnext(sdesc, 0, (Buffer *)NULL))) { - (*app)->am_oid = tup->t_oid; - memmove((char *)&(*app++)->am_typ, - (char *)GETSTRUCT(tup), - sizeof ((*app)->am_typ)); - } - heap_endscan(sdesc); - heap_close(rdesc); - 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(reldesc->rd_id, - attrtypes[i]->attname.data); - else - attrtypes[i]->attisset = false; - - if (DebugMode) { - AttributeTupleForm 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); - } - } + int i; + struct typmap **app; + Relation rdesc; + HeapScanDesc sdesc; + HeapTuple tup; + + if (strlen(relname) > 15) + relname[15] = '\000'; + + if (Typ == (struct typmap **) NULL) + { + StartPortalAllocMode(DefaultAllocMode, 0); + rdesc = heap_openr(TypeRelationName); + sdesc = heap_beginscan(rdesc, 0, NowTimeQual, 0, (ScanKey) NULL); + for (i = 0; PointerIsValid(tup = heap_getnext(sdesc, 0, (Buffer *) NULL)); ++i); + heap_endscan(sdesc); + app = Typ = ALLOC(struct typmap *, i + 1); + while (i-- > 0) + *app++ = ALLOC(struct typmap, 1); + *app = (struct typmap *) NULL; + sdesc = heap_beginscan(rdesc, 0, NowTimeQual, 0, (ScanKey) NULL); + app = Typ; + while (PointerIsValid(tup = heap_getnext(sdesc, 0, (Buffer *) NULL))) + { + (*app)->am_oid = tup->t_oid; + memmove((char *) &(*app++)->am_typ, + (char *) GETSTRUCT(tup), + sizeof((*app)->am_typ)); + } + heap_endscan(sdesc); + heap_close(rdesc); + 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(reldesc->rd_id, + attrtypes[i]->attname.data); + else + attrtypes[i]->attisset = false; + + if (DebugMode) + { + AttributeTupleForm 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 + * closerel * ---------------- */ void closerel(char *name) { - if (name) { - if (reldesc) { - if (namestrcmp(RelationGetRelationName(reldesc), name) != 0) - elog(WARN,"closerel: close of '%s' when '%s' was expected", - name, relname ? relname : "(null)"); - } else - elog(WARN,"closerel: close of '%s' before any relation was opened", - name); - - } - - if (reldesc == NULL) { - elog(WARN,"Warning: no opened relation to close.\n"); - } else { - if (!Quiet) printf("Amclose: relation %s.\n", relname ? relname : "(null)"); - heap_close(reldesc); - reldesc = (Relation)NULL; - } + if (name) + { + if (reldesc) + { + if (namestrcmp(RelationGetRelationName(reldesc), name) != 0) + elog(WARN, "closerel: close of '%s' when '%s' was expected", + name, relname ? relname : "(null)"); + } + else + elog(WARN, "closerel: close of '%s' before any relation was opened", + name); + + } + + if (reldesc == NULL) + { + elog(WARN, "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() * @@ -565,563 +603,626 @@ closerel(char *name) void DefineAttr(char *name, char *type, int attnum) { - int attlen; - int t; - - if (reldesc != NULL) { - fputs("Warning: no open relations allowed with 't' command.\n",stderr); - closerel(relname); - } - - t = gettype(type); - if (attrtypes[attnum] == (AttributeTupleForm )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; - } else { - attrtypes[attnum]->atttypid = Procid[t].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[t].len; - attrtypes[attnum]->attbyval = (attlen==1) || (attlen==2)||(attlen==4); - } + int attlen; + int t; + + if (reldesc != NULL) + { + fputs("Warning: no open relations allowed with 't' command.\n", stderr); + closerel(relname); + } + + t = gettype(type); + if (attrtypes[attnum] == (AttributeTupleForm) 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; + } + else + { + attrtypes[attnum]->atttypid = Procid[t].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[t].len; + attrtypes[attnum]->attbyval = (attlen == 1) || (attlen == 2) || (attlen == 4); + } } /* ---------------- - * InsertOneTuple - * assumes that 'oid' will not be zero. + * InsertOneTuple + * assumes that 'oid' will not be zero. * ---------------- */ void InsertOneTuple(Oid objectid) { - HeapTuple tuple; - TupleDesc tupDesc; - - int i; - - if (DebugMode) { - printf("InsertOneTuple oid %d, %d attrs\n", objectid, numattr); - fflush(stdout); - } - - tupDesc = CreateTupleDesc(numattr,attrtypes); - tuple = heap_formtuple(tupDesc,(Datum*)values,Blanks); - pfree(tupDesc); /* just free's tupDesc, not the attrtypes */ - - if(objectid !=(Oid)0) { - tuple->t_oid=objectid; - } - heap_insert(reldesc, tuple); - pfree(tuple); - if (DebugMode) { - printf("End InsertOneTuple, objectid=%d\n", objectid); - fflush(stdout); - } - /* - * Reset blanks for next tuple - */ - for (i = 0; i<numattr; i++) - Blanks[i] = ' '; + HeapTuple tuple; + TupleDesc tupDesc; + + int i; + + if (DebugMode) + { + printf("InsertOneTuple oid %d, %d attrs\n", objectid, numattr); + fflush(stdout); + } + + tupDesc = CreateTupleDesc(numattr, attrtypes); + tuple = heap_formtuple(tupDesc, (Datum *) values, Blanks); + pfree(tupDesc); /* just free's tupDesc, not the attrtypes */ + + if (objectid != (Oid) 0) + { + tuple->t_oid = objectid; + } + heap_insert(reldesc, tuple); + pfree(tuple); + if (DebugMode) + { + printf("End InsertOneTuple, objectid=%d\n", objectid); + fflush(stdout); + } + + /* + * Reset blanks for next tuple + */ + for (i = 0; i < numattr; i++) + Blanks[i] = ' '; } /* ---------------- - * InsertOneValue + * InsertOneValue * ---------------- */ void InsertOneValue(Oid objectid, char *value, int i) { - int typeindex; - char *prt; - struct typmap **app; - - if (DebugMode) - printf("Inserting value: '%s'\n", value); - if (i < 0 || i >= MAXATTR) { - printf("i out of range: %d\n", i); - Assert(0); - } - - if (Typ != (struct typmap **)NULL) { - struct typmap *ap; - if (DebugMode) - puts("Typ != NULL"); - app = Typ; - while (*app && (*app)->am_oid != reldesc->rd_att->attrs[i]->atttypid) - ++app; - ap = *app; - if (ap == NULL) { - printf("Unable to find atttypid in Typ list! %d\n", - reldesc->rd_att->attrs[i]->atttypid - ); - Assert(0); - } - values[i] = fmgr(ap->am_typ.typinput, - value, - ap->am_typ.typelem, - -1); /* shouldn't have char() or varchar() types - during boostrapping but just to be safe */ - prt = fmgr(ap->am_typ.typoutput, values[i], - ap->am_typ.typelem); - if (!Quiet) printf("%s ", prt); - pfree(prt); - } else { - typeindex = attrtypes[i]->atttypid - FIRST_TYPE_OID; - if (DebugMode) - printf("Typ == NULL, typeindex = %d idx = %d\n", typeindex, i); - values[i] = fmgr(Procid[typeindex].inproc, value, - Procid[typeindex].elem, -1); - prt = fmgr(Procid[typeindex].outproc, values[i], - Procid[typeindex].elem); - if (!Quiet) printf("%s ", prt); - pfree(prt); - } - if (DebugMode) { - puts("End InsertValue"); - fflush(stdout); - } + int typeindex; + char *prt; + struct typmap **app; + + if (DebugMode) + printf("Inserting value: '%s'\n", value); + if (i < 0 || i >= MAXATTR) + { + printf("i out of range: %d\n", i); + Assert(0); + } + + if (Typ != (struct typmap **) NULL) + { + struct typmap *ap; + + if (DebugMode) + puts("Typ != NULL"); + app = Typ; + while (*app && (*app)->am_oid != reldesc->rd_att->attrs[i]->atttypid) + ++app; + ap = *app; + if (ap == NULL) + { + printf("Unable to find atttypid in Typ list! %d\n", + reldesc->rd_att->attrs[i]->atttypid + ); + Assert(0); + } + values[i] = fmgr(ap->am_typ.typinput, + value, + ap->am_typ.typelem, + -1); /* shouldn't have char() or varchar() + * types during boostrapping but just to + * be safe */ + prt = fmgr(ap->am_typ.typoutput, values[i], + ap->am_typ.typelem); + if (!Quiet) + printf("%s ", prt); + pfree(prt); + } + else + { + typeindex = attrtypes[i]->atttypid - FIRST_TYPE_OID; + if (DebugMode) + printf("Typ == NULL, typeindex = %d idx = %d\n", typeindex, i); + values[i] = fmgr(Procid[typeindex].inproc, value, + Procid[typeindex].elem, -1); + prt = fmgr(Procid[typeindex].outproc, values[i], + Procid[typeindex].elem); + if (!Quiet) + printf("%s ", prt); + pfree(prt); + } + if (DebugMode) + { + puts("End InsertValue"); + fflush(stdout); + } } /* ---------------- - * InsertOneNull + * InsertOneNull * ---------------- */ void InsertOneNull(int i) { - if (DebugMode) - printf("Inserting null\n"); - if (i < 0 || i >= MAXATTR) { - elog(FATAL, "i out of range (too many attrs): %d\n", i); - } - values[i] = (char *)NULL; - Blanks[i] = 'n'; + if (DebugMode) + printf("Inserting null\n"); + if (i < 0 || i >= MAXATTR) + { + elog(FATAL, "i out of range (too many attrs): %d\n", i); + } + values[i] = (char *) NULL; + Blanks[i] = 'n'; } #define MORE_THAN_THE_NUMBER_OF_CATALOGS 256 -static bool +static bool BootstrapAlreadySeen(Oid id) { - static Oid seenArray[MORE_THAN_THE_NUMBER_OF_CATALOGS]; - static int nseen = 0; - bool seenthis; - int i; - - seenthis = false; - - for (i=0; i < nseen; i++) { - if (seenArray[i] == id) { - seenthis = true; - break; - } - } - if (!seenthis) { - seenArray[nseen] = id; - nseen++; - } - return (seenthis); + static Oid seenArray[MORE_THAN_THE_NUMBER_OF_CATALOGS]; + static int nseen = 0; + bool seenthis; + int i; + + seenthis = false; + + for (i = 0; i < nseen; i++) + { + if (seenArray[i] == id) + { + seenthis = true; + break; + } + } + if (!seenthis) + { + seenArray[nseen] = id; + nseen++; + } + return (seenthis); } /* ---------------- - * cleanup + * cleanup * ---------------- */ static void cleanup() { - static int beenhere = 0; - - if (!beenhere) - beenhere = 1; - else { - elog(FATAL,"Memory manager fault: cleanup called twice.\n", stderr); - exitpg(1); - } - if (reldesc != (Relation)NULL) { - heap_close(reldesc); - } - CommitTransactionCommand(); - exitpg(Warnings); + static int beenhere = 0; + + if (!beenhere) + beenhere = 1; + else + { + elog(FATAL, "Memory manager fault: cleanup called twice.\n", stderr); + exitpg(1); + } + if (reldesc != (Relation) NULL) + { + heap_close(reldesc); + } + CommitTransactionCommand(); + exitpg(Warnings); } /* ---------------- - * gettype + * gettype * ---------------- */ static int gettype(char *type) { - int i; - Relation rdesc; - HeapScanDesc sdesc; - HeapTuple tup; - struct typmap **app; - - if (Typ != (struct typmap **)NULL) { - for (app = Typ; *app != (struct typmap *)NULL; app++) { - if (strncmp((*app)->am_typ.typname.data, type, NAMEDATALEN) == 0) { - Ap = *app; - return((*app)->am_oid); - } - } - } else { - for (i = 0; i <= n_types; i++) { - if (strncmp(type, Procid[i].name, NAMEDATALEN) == 0) { - return(i); - } - } - if (DebugMode) - printf("bootstrap.c: External Type: %s\n", type); - rdesc = heap_openr(TypeRelationName); - sdesc = heap_beginscan(rdesc, 0, NowTimeQual, 0, (ScanKey)NULL); - i = 0; - while (PointerIsValid(tup = heap_getnext(sdesc, 0, (Buffer *)NULL))) - ++i; - heap_endscan(sdesc); - app = Typ = ALLOC(struct typmap *, i + 1); - while (i-- > 0) - *app++ = ALLOC(struct typmap, 1); - *app = (struct typmap *)NULL; - sdesc = heap_beginscan(rdesc, 0, NowTimeQual, 0, (ScanKey)NULL); - app = Typ; - while (PointerIsValid(tup = heap_getnext(sdesc, 0, (Buffer *)NULL))) { - (*app)->am_oid = tup->t_oid; - memmove((char *)&(*app++)->am_typ, - (char *)GETSTRUCT(tup), - sizeof ((*app)->am_typ)); - } - heap_endscan(sdesc); - heap_close(rdesc); - return(gettype(type)); - } - elog(WARN, "Error: unknown type '%s'.\n", type); - err_out(); - /* not reached, here to make compiler happy */ - return 0; + int i; + Relation rdesc; + HeapScanDesc sdesc; + HeapTuple tup; + struct typmap **app; + + if (Typ != (struct typmap **) NULL) + { + for (app = Typ; *app != (struct typmap *) NULL; app++) + { + if (strncmp((*app)->am_typ.typname.data, type, NAMEDATALEN) == 0) + { + Ap = *app; + return ((*app)->am_oid); + } + } + } + else + { + for (i = 0; i <= n_types; i++) + { + if (strncmp(type, Procid[i].name, NAMEDATALEN) == 0) + { + return (i); + } + } + if (DebugMode) + printf("bootstrap.c: External Type: %s\n", type); + rdesc = heap_openr(TypeRelationName); + sdesc = heap_beginscan(rdesc, 0, NowTimeQual, 0, (ScanKey) NULL); + i = 0; + while (PointerIsValid(tup = heap_getnext(sdesc, 0, (Buffer *) NULL))) + ++i; + heap_endscan(sdesc); + app = Typ = ALLOC(struct typmap *, i + 1); + while (i-- > 0) + *app++ = ALLOC(struct typmap, 1); + *app = (struct typmap *) NULL; + sdesc = heap_beginscan(rdesc, 0, NowTimeQual, 0, (ScanKey) NULL); + app = Typ; + while (PointerIsValid(tup = heap_getnext(sdesc, 0, (Buffer *) NULL))) + { + (*app)->am_oid = tup->t_oid; + memmove((char *) &(*app++)->am_typ, + (char *) GETSTRUCT(tup), + sizeof((*app)->am_typ)); + } + heap_endscan(sdesc); + heap_close(rdesc); + return (gettype(type)); + } + elog(WARN, "Error: unknown type '%s'.\n", type); + err_out(); + /* not reached, here to make compiler happy */ + return 0; } /* ---------------- - * AllocateAttribute + * AllocateAttribute * ---------------- */ -static AttributeTupleForm /* XXX */ +static AttributeTupleForm /* XXX */ AllocateAttribute() { - AttributeTupleForm attribute = - (AttributeTupleForm)malloc(ATTRIBUTE_TUPLE_SIZE); - - if (!PointerIsValid(attribute)) { - elog(FATAL, "AllocateAttribute: malloc failed"); - } - memset(attribute, 0, ATTRIBUTE_TUPLE_SIZE); - - return (attribute); + AttributeTupleForm attribute = + (AttributeTupleForm) malloc(ATTRIBUTE_TUPLE_SIZE); + + if (!PointerIsValid(attribute)) + { + elog(FATAL, "AllocateAttribute: malloc failed"); + } + memset(attribute, 0, ATTRIBUTE_TUPLE_SIZE); + + return (attribute); } /* ---------------- - * MapArrayTypeName + * MapArrayTypeName * XXX arrays of "basetype" are always "_basetype". - * this is an evil hack inherited from rel. 3.1. + * this is an evil hack inherited from rel. 3.1. * XXX array dimension is thrown away because we - * don't support fixed-dimension arrays. again, - * sickness from 3.1. - * - * the string passed in must have a '[' character in it + * don't support fixed-dimension arrays. again, + * sickness from 3.1. + * + * the string passed in must have a '[' character in it * * the string returned is a pointer to static storage and should NOT * be freed by the CALLER. * ---------------- */ -char* +char * MapArrayTypeName(char *s) { - int i, j; - static char newStr[NAMEDATALEN]; /* array type names < NAMEDATALEN long */ + int i, + j; + static char newStr[NAMEDATALEN]; /* array type names < + * NAMEDATALEN long */ - if (s == NULL || s[0] == '\0') - return s; + 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'; + j = 1; + newStr[0] = '_'; + for (i = 0; i < NAMEDATALEN - 1 && s[i] != '['; i++, j++) + newStr[j] = s[i]; - return newStr; + newStr[j] = '\0'; + + return newStr; } /* ---------------- - * EnterString - * returns the string table position of the identifier - * passed to it. We add it to the table if we can't find it. + * EnterString + * returns the string table position of the identifier + * passed to it. We add it to the table if we can't find it. * ---------------- */ int -EnterString (char *str) +EnterString(char *str) { - hashnode *node; - int len; - - len= strlen(str); - - node = FindStr(str, len, 0); - if (node) { - return (node->strnum); - } else { - node = AddStr(str, len, 0); - return (node->strnum); - } + hashnode *node; + int len; + + len = strlen(str); + + node = FindStr(str, len, 0); + if (node) + { + return (node->strnum); + } + else + { + node = AddStr(str, len, 0); + return (node->strnum); + } } /* ---------------- - * LexIDStr - * when given an idnum into the 'string-table' return the string - * associated with the idnum + * LexIDStr + * when given an idnum into the 'string-table' return the string + * associated with the idnum * ---------------- */ -char * -LexIDStr(int ident_num) +char * +LexIDStr(int ident_num) { - return(strtable[ident_num]); -} + return (strtable[ident_num]); +} /* ---------------- - * CompHash + * CompHash * - * Compute a hash function for a given string. We look at the first, - * the last, and the middle character of a string to try to get spread - * the strings out. The function is rather arbitrary, except that we - * are mod'ing by a prime number. + * Compute a hash function for a given string. We look at the first, + * the last, and the middle character of a string to try to get spread + * the strings out. The function is rather arbitrary, except that we + * are mod'ing by a prime number. * ---------------- */ static int CompHash(char *str, int len) { - register int result; - - result =(NUM * str[0] + NUMSQR * str[len-1] + NUMCUBE * str[(len-1)/2]); - - return (result % HASHTABLESIZE); - + register int result; + + result = (NUM * str[0] + NUMSQR * str[len - 1] + NUMCUBE * str[(len - 1) / 2]); + + return (result % HASHTABLESIZE); + } /* ---------------- - * FindStr + * FindStr * - * This routine looks for the specified string in the hash - * table. It returns a pointer to the hash node found, - * or NULL if the string is not in the table. + * This routine looks for the specified string in the hash + * table. It returns a pointer to the hash node found, + * or NULL if the string is not in the table. * ---------------- */ static hashnode * -FindStr(char *str, int length, hashnode *mderef) +FindStr(char *str, int length, hashnode * mderef) { - hashnode *node; - node = hashtable [CompHash (str, length)]; - while (node != NULL) { - /* - * We must differentiate between string constants that - * might have the same value as a identifier - * and the identifier itself. - */ - if (!strcmp(str, strtable[node->strnum])) { - return(node); /* no need to check */ - } else { - node = node->next; - } - } - /* Couldn't find it in the list */ - return (NULL); + hashnode *node; + + node = hashtable[CompHash(str, length)]; + while (node != NULL) + { + + /* + * We must differentiate between string constants that might have + * the same value as a identifier and the identifier itself. + */ + if (!strcmp(str, strtable[node->strnum])) + { + return (node); /* no need to check */ + } + else + { + node = node->next; + } + } + /* Couldn't find it in the list */ + return (NULL); } /* ---------------- - * AddStr + * AddStr * - * This function adds the specified string, along with its associated - * data, to the hash table and the string table. We return the node - * so that the calling routine can find out the unique id that AddStr - * has assigned to this string. + * This function adds the specified string, along with its associated + * data, to the hash table and the string table. We return the node + * so that the calling routine can find out the unique id that AddStr + * has assigned to this string. * ---------------- */ static hashnode * AddStr(char *str, int strlength, int mderef) { - hashnode *temp, *trail, *newnode; - int hashresult; - int len; - - if (++strtable_end == STRTABLESIZE) { - /* Error, string table overflow, so we Punt */ - elog(FATAL, - "There are too many string constants and identifiers for the compiler to handle."); - - - } - - /* - * Some of the utilites (eg, define type, create relation) assume - * that the string they're passed is a NAMEDATALEN. We get array bound - * read violations from purify if we don't allocate at least NAMEDATALEN - * bytes for strings of this sort. Because we're lazy, we allocate - * at least NAMEDATALEN bytes all the time. - */ - - if ((len = strlength + 1) < NAMEDATALEN) - len = NAMEDATALEN; - - strtable [strtable_end] = malloc((unsigned) len); - strcpy (strtable[strtable_end], str); - - /* Now put a node in the hash table */ - - newnode = (hashnode*)malloc(sizeof(hashnode)*1); - newnode->strnum = strtable_end; - newnode->next = NULL; - - /* Find out where it goes */ - - hashresult = CompHash (str, strlength); - if (hashtable [hashresult] == NULL) { - hashtable [hashresult] = newnode; - } else { /* There is something in the list */ - trail = hashtable [hashresult]; - temp = trail->next; - while (temp != NULL) { - trail = temp; - temp = temp->next; - } - trail->next = newnode; - } - return (newnode); + hashnode *temp, + *trail, + *newnode; + int hashresult; + int len; + + if (++strtable_end == STRTABLESIZE) + { + /* Error, string table overflow, so we Punt */ + elog(FATAL, + "There are too many string constants and identifiers for the compiler to handle."); + + + } + + /* + * Some of the utilites (eg, define type, create relation) assume that + * the string they're passed is a NAMEDATALEN. We get array bound + * read violations from purify if we don't allocate at least + * NAMEDATALEN bytes for strings of this sort. Because we're lazy, we + * allocate at least NAMEDATALEN bytes all the time. + */ + + if ((len = strlength + 1) < NAMEDATALEN) + len = NAMEDATALEN; + + strtable[strtable_end] = malloc((unsigned) len); + strcpy(strtable[strtable_end], str); + + /* Now put a node in the hash table */ + + newnode = (hashnode *) malloc(sizeof(hashnode) * 1); + newnode->strnum = strtable_end; + newnode->next = NULL; + + /* Find out where it goes */ + + hashresult = CompHash(str, strlength); + if (hashtable[hashresult] == NULL) + { + hashtable[hashresult] = newnode; + } + else + { /* There is something in the list */ + trail = hashtable[hashresult]; + temp = trail->next; + while (temp != NULL) + { + trail = temp; + temp = temp->next; + } + trail->next = newnode; + } + return (newnode); } /* - * index_register() -- record an index that has been set up for building - * later. + * index_register() -- record an index that has been set up for building + * later. * - * At bootstrap time, we define a bunch of indices on system catalogs. - * We postpone actually building the indices until just before we're - * finished with initialization, however. This is because more classes - * and indices may be defined, and we want to be sure that all of them - * are present in the index. + * At bootstrap time, we define a bunch of indices on system catalogs. + * We postpone actually building the indices until just before we're + * finished with initialization, however. This is because more classes + * and indices may be defined, and we want to be sure that all of them + * are present in the index. */ void index_register(char *heap, - char *ind, - int natts, - AttrNumber *attnos, - uint16 nparams, - Datum *params, - FuncIndexInfo *finfo, - PredInfo *predInfo) + char *ind, + int natts, + AttrNumber * attnos, + uint16 nparams, + Datum * params, + FuncIndexInfo * finfo, + PredInfo * predInfo) { - Datum *v; - IndexList *newind; - int len; - MemoryContext oldcxt; - - /* - * XXX mao 10/31/92 -- don't gc index reldescs, associated info - * at bootstrap time. we'll declare the indices now, but want to - * create them later. - */ - - if (nogc == (GlobalMemory) NULL) - nogc = CreateGlobalMemory("BootstrapNoGC"); - - oldcxt = MemoryContextSwitchTo((MemoryContext) nogc); - - newind = (IndexList *) palloc(sizeof(IndexList)); - newind->il_heap = pstrdup(heap); - newind->il_ind = pstrdup(ind); - newind->il_natts = natts; - - if (PointerIsValid(finfo)) - len = FIgetnArgs(finfo) * sizeof(AttrNumber); - else - len = natts * sizeof(AttrNumber); - - newind->il_attnos = (AttrNumber *) palloc(len); - memmove(newind->il_attnos, attnos, len); - - if ((newind->il_nparams = nparams) > 0) { - v = newind->il_params = (Datum *) palloc(2 * nparams * sizeof(Datum)); - nparams *= 2; - while (nparams-- > 0) { - *v = (Datum) palloc(strlen((char *)(*params)) + 1); - strcpy((char *) *v++, (char *) *params++); - } - } else { - newind->il_params = (Datum *) NULL; - } - - if (finfo != (FuncIndexInfo *) NULL) { - newind->il_finfo = (FuncIndexInfo *) palloc(sizeof(FuncIndexInfo)); - memmove(newind->il_finfo, finfo, sizeof(FuncIndexInfo)); - } else { - newind->il_finfo = (FuncIndexInfo *) NULL; - } - - if (predInfo != NULL) { - newind->il_predInfo = (PredInfo*)palloc(sizeof(PredInfo)); - newind->il_predInfo->pred = predInfo->pred; - newind->il_predInfo->oldPred = predInfo->oldPred; - } else { - newind->il_predInfo = NULL; - } - - newind->il_next = ILHead; - - ILHead = newind; - - MemoryContextSwitchTo(oldcxt); + Datum *v; + IndexList *newind; + int len; + MemoryContext oldcxt; + + /* + * XXX mao 10/31/92 -- don't gc index reldescs, associated info at + * bootstrap time. we'll declare the indices now, but want to create + * them later. + */ + + if (nogc == (GlobalMemory) NULL) + nogc = CreateGlobalMemory("BootstrapNoGC"); + + oldcxt = MemoryContextSwitchTo((MemoryContext) nogc); + + newind = (IndexList *) palloc(sizeof(IndexList)); + newind->il_heap = pstrdup(heap); + newind->il_ind = pstrdup(ind); + newind->il_natts = natts; + + if (PointerIsValid(finfo)) + len = FIgetnArgs(finfo) * sizeof(AttrNumber); + else + len = natts * sizeof(AttrNumber); + + newind->il_attnos = (AttrNumber *) palloc(len); + memmove(newind->il_attnos, attnos, len); + + if ((newind->il_nparams = nparams) > 0) + { + v = newind->il_params = (Datum *) palloc(2 * nparams * sizeof(Datum)); + nparams *= 2; + while (nparams-- > 0) + { + *v = (Datum) palloc(strlen((char *) (*params)) + 1); + strcpy((char *) *v++, (char *) *params++); + } + } + else + { + newind->il_params = (Datum *) NULL; + } + + if (finfo != (FuncIndexInfo *) NULL) + { + newind->il_finfo = (FuncIndexInfo *) palloc(sizeof(FuncIndexInfo)); + memmove(newind->il_finfo, finfo, sizeof(FuncIndexInfo)); + } + else + { + newind->il_finfo = (FuncIndexInfo *) NULL; + } + + if (predInfo != NULL) + { + newind->il_predInfo = (PredInfo *) palloc(sizeof(PredInfo)); + newind->il_predInfo->pred = predInfo->pred; + newind->il_predInfo->oldPred = predInfo->oldPred; + } + else + { + newind->il_predInfo = NULL; + } + + newind->il_next = ILHead; + + ILHead = newind; + + MemoryContextSwitchTo(oldcxt); } void build_indices() { - Relation heap; - Relation ind; - - for ( ; ILHead != (IndexList *) NULL; ILHead = ILHead->il_next) { - heap = heap_openr(ILHead->il_heap); - ind = index_openr(ILHead->il_ind); - index_build(heap, ind, ILHead->il_natts, ILHead->il_attnos, - ILHead->il_nparams, ILHead->il_params, ILHead->il_finfo, - ILHead->il_predInfo); - - /* - * All of the rest of this routine is needed only because in bootstrap - * processing we don't increment xact id's. The normal DefineIndex - * code replaces a pg_class tuple with updated info including the - * relhasindex flag (which we need to have updated). Unfortunately, - * there are always two indices defined on each catalog causing us to - * update the same pg_class tuple twice for each catalog getting an - * index during bootstrap resulting in the ghost tuple problem (see - * heap_replace). To get around this we change the relhasindex - * field ourselves in this routine keeping track of what catalogs we - * already changed so that we don't modify those tuples twice. The - * normal mechanism for updating pg_class is disabled during bootstrap. - * - * -mer - */ - heap = heap_openr(ILHead->il_heap); - - if (!BootstrapAlreadySeen(heap->rd_id)) - UpdateStats(heap->rd_id, 0, true); - } + Relation heap; + Relation ind; + + for (; ILHead != (IndexList *) NULL; ILHead = ILHead->il_next) + { + heap = heap_openr(ILHead->il_heap); + ind = index_openr(ILHead->il_ind); + index_build(heap, ind, ILHead->il_natts, ILHead->il_attnos, + ILHead->il_nparams, ILHead->il_params, ILHead->il_finfo, + ILHead->il_predInfo); + + /* + * All of the rest of this routine is needed only because in + * bootstrap processing we don't increment xact id's. The normal + * DefineIndex code replaces a pg_class tuple with updated info + * including the relhasindex flag (which we need to have updated). + * Unfortunately, there are always two indices defined on each + * catalog causing us to update the same pg_class tuple twice for + * each catalog getting an index during bootstrap resulting in the + * ghost tuple problem (see heap_replace). To get around this we + * change the relhasindex field ourselves in this routine keeping + * track of what catalogs we already changed so that we don't + * modify those tuples twice. The normal mechanism for updating + * pg_class is disabled during bootstrap. + * + * -mer + */ + heap = heap_openr(ILHead->il_heap); + + if (!BootstrapAlreadySeen(heap->rd_id)) + UpdateStats(heap->rd_id, 0, true); + } } - |