Commit f64b8403 authored by Bryan Henderson's avatar Bryan Henderson

Remove most compile-time options, add a few runtime options to make up for it.

In particular, no more compiled-in default for PGDATA or LIBDIR.  Commands
that need them need either invocation options or environment variables.
PGPORT default is hardcoded as 5432, but overrideable with options or
environment variables.
parent 7ac541da
......@@ -7,7 +7,7 @@
* Copyright (c) 1994, Regents of the University of California
*
* IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/bootstrap/bootstrap.c,v 1.10 1996/11/10 01:37:48 bryanh Exp $
* $Header: /cvsroot/pgsql/src/backend/bootstrap/bootstrap.c,v 1.11 1996/11/14 10:23:34 bryanh Exp $
*
*-------------------------------------------------------------------------
*/
......@@ -17,7 +17,7 @@
#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"
......@@ -99,13 +99,13 @@
#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);
/* ----------------
* global variables
* global variables
* ----------------
*/
/*
......@@ -118,34 +118,34 @@
* 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 NUMCUBE 12167
#define NUM 23
#define NUMSQR 529
#define NUMCUBE 12167
char *strtable [STRTABLESIZE];
hashnode *hashtable [HASHTABLESIZE];
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;
char name[NAMEDATALEN];
Oid oid;
Oid elem;
int16 len;
Oid inproc;
Oid outproc;
};
static struct typinfo Procid[] = {
......@@ -154,7 +154,7 @@ static struct typinfo Procid[] = {
{ "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}, */
/* { "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 },
......@@ -172,23 +172,23 @@ static struct typinfo Procid[] = {
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 struct typmap **Typ = (struct typmap **)NULL;
static struct typmap *Ap = (struct typmap *)NULL;
static int Warnings = 0;
static char Blanks[MAXATTR];
static int Warnings = 0;
static char Blanks[MAXATTR];
Relation reldesc; /* current relation descriptor */
Relation reldesc; /* current relation descriptor */
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 */
static char *values[MAXATTR]; /* cooresponding attribute values */
int numattr; /* number of attributes for cur. rel */
extern int fsyncOff; /* do not fsync the database */
#ifdef NEED_SIG_JMP
......@@ -199,11 +199,11 @@ static jmp_buf Warn_restart;
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
......@@ -212,15 +212,15 @@ extern char *optarg;
*/
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;
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;
......@@ -230,12 +230,12 @@ typedef void (*sig_func)();
/* ----------------------------------------------------------------
* misc functions
* misc functions
* ----------------------------------------------------------------
*/
/* ----------------
* error handling / abort routines
* error handling / abort routines
* ----------------
*/
void
......@@ -262,33 +262,33 @@ usage(void)
exitpg(1);
}
int
BootstrapMain(int argc, char *argv[])
/* ----------------------------------------------------------------
* BootstrapMain
* the main loop for handling the backend in bootstrap mode
* 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.
* they are 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
BootstrapMain(int argc, char *argv[])
{
int i;
int portFd = -1;
int i;
int portFd = -1;
char *dbName;
int flag;
int override = 1; /* use BootstrapProcessing or InitProcessing mode */
extern int optind;
extern char *optarg;
extern int optind;
extern char *optarg;
/* ----------------
* initialize signal handlers
* initialize signal handlers
* ----------------
*/
signal(SIGINT, (sig_func) die);
......@@ -298,69 +298,83 @@ BootstrapMain(int argc, char *argv[])
#endif /* win32 */
/* --------------------
* initialize globals
* initialize globals
* -------------------
*/
InitGlobals();
MasterPid = getpid();
/* ----------------
* process command arguments
* 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, "dCOQP:F")) != EOF) {
switch (flag) {
case 'd':
DebugMode = 1; /* print out debuggin info while parsing */
break;
case 'C':
Noversion = 1;
break;
while ((flag = getopt(argc, argv, "D:dCOQP:F")) != EOF) {
switch (flag) {
case 'D':
DataDir = optarg;
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;
}
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();
usage();
} else
if (argc - optind == 1) {
dbName = argv[optind];
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);
}
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
* initialize input fd
* ----------------
*/
if (IsUnderPostmaster == true && portFd < 0) {
fputs("backend: failed, no -P option with -postmaster opt.\n", stderr);
exitpg(1);
fputs("backend: failed, no -P option with -postmaster opt.\n", stderr);
exitpg(1);
}
#ifdef win32
......@@ -370,7 +384,7 @@ BootstrapMain(int argc, char *argv[])
/* ----------------
* backend initialization
* backend initialization
* ----------------
*/
SetProcessingMode((override) ? BootstrapProcessing : InitProcessing);
......@@ -378,16 +392,16 @@ BootstrapMain(int argc, char *argv[])
LockDisable(true);
for (i = 0 ; i < MAXATTR; i++) {
attrtypes[i]=(AttributeTupleForm )NULL;
Blanks[i] = ' ';
attrtypes[i]=(AttributeTupleForm )NULL;
Blanks[i] = ' ';
}
for(i = 0; i < STRTABLESIZE; ++i)
strtable[i] = NULL;
strtable[i] = NULL;
for(i = 0; i < HASHTABLESIZE; ++i)
hashtable[i] = NULL;
hashtable[i] = NULL;
/* ----------------
* abort processing resumes here - What to do in WIN32?
* abort processing resumes here - What to do in WIN32?
* ----------------
*/
#ifndef win32
......@@ -397,12 +411,12 @@ BootstrapMain(int argc, char *argv[])
#else
if (setjmp(Warn_restart) != 0) {
#endif /* win32 */
Warnings++;
AbortCurrentTransaction();
Warnings++;
AbortCurrentTransaction();
}
/* ----------------
* process input.
* process input.
* ----------------
*/
......@@ -421,113 +435,113 @@ BootstrapMain(int argc, char *argv[])
}
/* ----------------------------------------------------------------
* 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;
int i;
struct typmap **app;
Relation rdesc;
HeapScanDesc sdesc;
HeapTuple tup;
if (strlen(relname) > 15)
relname[15] ='\000';
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();
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);
closerel(NULL);
}
if (!Quiet)
printf("Amopen: relation %s. attrsize %d\n", relname,
ATTRIBUTE_TUPLE_SIZE);
printf("Amopen: relation %s. attrsize %d\n", relname,
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, NAMEDATALEN, at->attname.data, at->attlen, at->attnum,
at->atttypid
);
fflush(stdout);
}
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, NAMEDATALEN, 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);
} else
elog(WARN,"closerel: close of '%s' before any relation was opened",
name);
if (reldesc) {
if (namestrcmp(RelationGetRelationName(reldesc), name) != 0)
elog(WARN,"closerel: close of '%s' when '%s' was expected",
name, relname);
} 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");
elog(WARN,"Warning: no opened relation to close.\n");
} else {
if (!Quiet) printf("Amclose: relation %s.\n", relname);
heap_close(reldesc);
reldesc = (Relation)NULL;
if (!Quiet) printf("Amclose: relation %s.\n", relname);
heap_close(reldesc);
reldesc = (Relation)NULL;
}
}
......@@ -547,36 +561,36 @@ DefineAttr(char *name, char *type, int attnum)
int t;
if (reldesc != NULL) {
fputs("Warning: no open relations allowed with 't' command.\n",stderr);
closerel(relname);
fputs("Warning: no open relations allowed with 't' command.\n",stderr);
closerel(relname);
}
t = gettype(type);
if (attrtypes[attnum] == (AttributeTupleForm )NULL)
attrtypes[attnum] = AllocateAttribute();
attrtypes[attnum] = AllocateAttribute();
if (Typ != (struct typmap **)NULL) {
attrtypes[attnum]->atttypid = Ap->am_oid;
namestrcpy(&attrtypes[attnum]->attname, name);
if (!Quiet) printf("<%.*s %s> ", NAMEDATALEN,
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]->atttypid = Ap->am_oid;
namestrcpy(&attrtypes[attnum]->attname, name);
if (!Quiet) printf("<%.*s %s> ", NAMEDATALEN,
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> ", NAMEDATALEN,
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);
attrtypes[attnum]->atttypid = Procid[t].oid;
namestrcpy(&attrtypes[attnum]->attname,name);
if (!Quiet) printf("<%.*s %s> ", NAMEDATALEN,
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
......@@ -588,8 +602,8 @@ InsertOneTuple(Oid objectid)
int i;
if (DebugMode) {
printf("InsertOneTuple oid %d, %d attrs\n", objectid, numattr);
fflush(stdout);
printf("InsertOneTuple oid %d, %d attrs\n", objectid, numattr);
fflush(stdout);
}
tupDesc = CreateTupleDesc(numattr,attrtypes);
......@@ -597,90 +611,90 @@ InsertOneTuple(Oid objectid)
pfree(tupDesc); /* just free's tupDesc, not the attrtypes */
if(objectid !=(Oid)0) {
tuple->t_oid=objectid;
tuple->t_oid=objectid;
}
heap_insert(reldesc, tuple);
pfree(tuple);
if (DebugMode) {
printf("End InsertOneTuple, objectid=%d\n", objectid);
fflush(stdout);
printf("End InsertOneTuple, objectid=%d\n", objectid);
fflush(stdout);
}
/*
* Reset blanks for next tuple
*/
for (i = 0; i<numattr; i++)
Blanks[i] = ' ';
Blanks[i] = ' ';
}
/* ----------------
* InsertOneValue
* InsertOneValue
* ----------------
*/
void
InsertOneValue(Oid objectid, char *value, int i)
{
int typeindex;
char *prt;
int typeindex;
char *prt;
struct typmap **app;
if (DebugMode)
printf("Inserting value: '%s'\n", value);
printf("Inserting value: '%s'\n", value);
if (i < 0 || i >= MAXATTR) {
printf("i out of range: %d\n", i);
Assert(0);
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);
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);
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);
puts("End InsertValue");
fflush(stdout);
}
}
/* ----------------
* InsertOneNull
* InsertOneNull
* ----------------
*/
void
InsertOneNull(int i)
{
if (DebugMode)
printf("Inserting null\n");
printf("Inserting null\n");
if (i < 0 || i >= MAXATTR) {
elog(FATAL, "i out of range (too many attrs): %d\n", i);
elog(FATAL, "i out of range (too many attrs): %d\n", i);
}
values[i] = (char *)NULL;
Blanks[i] = 'n';
......@@ -699,85 +713,85 @@ BootstrapAlreadySeen(Oid id)
seenthis = false;
for (i=0; i < nseen; i++) {
if (seenArray[i] == id) {
seenthis = true;
break;
}
if (seenArray[i] == id) {
seenthis = true;
break;
}
}
if (!seenthis) {
seenArray[nseen] = id;
nseen++;
seenArray[nseen] = id;
nseen++;
}
return (seenthis);
}
/* ----------------
* cleanup
* cleanup
* ----------------
*/
void
cleanup()
{
static int beenhere = 0;
static int beenhere = 0;
if (!beenhere)
beenhere = 1;
beenhere = 1;
else {
elog(FATAL,"Memory manager fault: cleanup called twice.\n", stderr);
exitpg(1);
elog(FATAL,"Memory manager fault: cleanup called twice.\n", stderr);
exitpg(1);
}
if (reldesc != (Relation)NULL) {
heap_close(reldesc);
heap_close(reldesc);
}
CommitTransactionCommand();
exitpg(Warnings);
}
/* ----------------
* gettype
* gettype
* ----------------
*/
int
gettype(char *type)
{
int i;
Relation rdesc;
HeapScanDesc sdesc;
HeapTuple tup;
struct typmap **app;
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);
}
}
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", NAMEDATALEN, type);
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", NAMEDATALEN, 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));
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);
......@@ -790,17 +804,17 @@ gettype(char *type)
}
/* ----------------
* AllocateAttribute
* AllocateAttribute
* ----------------
*/
AttributeTupleForm /* XXX */
AllocateAttribute()
{
AttributeTupleForm attribute =
(AttributeTupleForm)malloc(ATTRIBUTE_TUPLE_SIZE);
(AttributeTupleForm)malloc(ATTRIBUTE_TUPLE_SIZE);
if (!PointerIsValid(attribute)) {
elog(FATAL, "AllocateAttribute: malloc failed");
elog(FATAL, "AllocateAttribute: malloc failed");
}
memset(attribute, 0, ATTRIBUTE_TUPLE_SIZE);
......@@ -808,7 +822,7 @@ AllocateAttribute()
}
/* ----------------
* MapArrayTypeName
* MapArrayTypeName
* XXX arrays of "basetype" are always "_basetype".
* this is an evil hack inherited from rel. 3.1.
* XXX array dimension is thrown away because we
......@@ -828,12 +842,12 @@ MapArrayTypeName(char *s)
static char newStr[NAMEDATALEN]; /* array type names < NAMEDATALEN long */
if (s == NULL || s[0] == '\0')
return s;
return s;
j = 1;
newStr[0] = '_';
for (i=0; i<NAMEDATALEN-1 && s[i] != '['; i++, j++)
newStr[j] = s[i];
newStr[j] = s[i];
newStr[j] = '\0';
......@@ -841,32 +855,32 @@ MapArrayTypeName(char *s)
}
/* ----------------
* 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)
{
hashnode *node;
hashnode *node;
int len;
len= strlen(str);
node = FindStr(str, len, 0);
if (node) {
return (node->strnum);
return (node->strnum);
} else {
node = AddStr(str, len, 0);
return (node->strnum);
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 *
......@@ -877,12 +891,12 @@ LexIDStr(int 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.
* ----------------
*/
int
......@@ -897,54 +911,54 @@ CompHash(char *str, int len)
}
/* ----------------
* 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.
* ----------------
*/
hashnode *
FindStr(char *str, int length, hashnode *mderef)
{
hashnode *node;
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;
}
/*
* 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.
* ----------------
*/
hashnode *
AddStr(char *str, int strlength, int mderef)
{
hashnode *temp, *trail, *newnode;
int hashresult;
int len;
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.");
/* Error, string table overflow, so we Punt */
elog(FATAL,
"There are too many string constants and identifiers for the compiler to handle.");
}
......@@ -958,7 +972,7 @@ AddStr(char *str, int strlength, int mderef)
*/
if ((len = strlength + 1) < NAMEDATALEN)
len = NAMEDATALEN;
len = NAMEDATALEN;
strtable [strtable_end] = malloc((unsigned) len);
strcpy (strtable[strtable_end], str);
......@@ -973,15 +987,15 @@ AddStr(char *str, int strlength, int mderef)
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;
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);
}
......@@ -990,23 +1004,23 @@ AddStr(char *str, int strlength, int mderef)
/*
* index_register() -- record an index that has been set up for building
* later.
* 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;
......@@ -1020,7 +1034,7 @@ index_register(char *heap,
*/
if (nogc == (GlobalMemory) NULL)
nogc = CreateGlobalMemory("BootstrapNoGC");
nogc = CreateGlobalMemory("BootstrapNoGC");
oldcxt = MemoryContextSwitchTo((MemoryContext) nogc);
......@@ -1030,37 +1044,37 @@ index_register(char *heap,
newind->il_natts = natts;
if (PointerIsValid(finfo))
len = FIgetnArgs(finfo) * sizeof(AttrNumber);
len = FIgetnArgs(finfo) * sizeof(AttrNumber);
else
len = natts * sizeof(AttrNumber);
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++);
}
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;
newind->il_params = (Datum *) NULL;
}
if (finfo != (FuncIndexInfo *) NULL) {
newind->il_finfo = (FuncIndexInfo *) palloc(sizeof(FuncIndexInfo));
memmove(newind->il_finfo, finfo, sizeof(FuncIndexInfo));
newind->il_finfo = (FuncIndexInfo *) palloc(sizeof(FuncIndexInfo));
memmove(newind->il_finfo, finfo, sizeof(FuncIndexInfo));
} else {
newind->il_finfo = (FuncIndexInfo *) NULL;
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;
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_predInfo = NULL;
}
newind->il_next = ILHead;
......@@ -1077,31 +1091,31 @@ build_indices()
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);
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);
}
}
......@@ -4,7 +4,7 @@
# Makefile for libpq subsystem (backend half of libpq interface)
#
# IDENTIFICATION
# $Header: /cvsroot/pgsql/src/backend/libpq/Makefile,v 1.3 1996/11/06 08:48:21 scrappy Exp $
# $Header: /cvsroot/pgsql/src/backend/libpq/Makefile,v 1.4 1996/11/14 10:23:51 bryanh Exp $
#
#-------------------------------------------------------------------------
......@@ -16,7 +16,6 @@ INCLUDE_OPT = -I.. \
-I../../include
CFLAGS+=$(INCLUDE_OPT)
CFLAGS+= -DPOSTPORT='"$(POSTPORT)"'
# kerberos flags
ifdef KRBVERS
......
......@@ -7,7 +7,7 @@
*
*
* IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/libpq/pqcomm.c,v 1.6 1996/11/08 05:56:21 momjian Exp $
* $Header: /cvsroot/pgsql/src/backend/libpq/pqcomm.c,v 1.7 1996/11/14 10:23:53 bryanh Exp $
*
*-------------------------------------------------------------------------
*/
......@@ -140,7 +140,7 @@ pq_getport()
if (envport)
return(atoi(envport));
return(atoi(POSTPORT));
return(atoi(DEF_PGPORT));
}
/* --------------------------------
......
......@@ -30,7 +30,6 @@ struct sembuf
#define MAXHOSTNAMELEN 12 /* where is the official definition of this? */
#define MAXPATHLEN _MAX_PATH /* in winsock.h */
#define POSTPORT "5432"
/* NT has stricmp not strcasecmp. Which is ANSI? */
#define strcasecmp(a,b) _stricmp(a,b)
......@@ -46,5 +45,3 @@ struct sembuf
#define GETNCNT 5
#define GETVAL 6
#define POSTGRESDIR "d:\\pglite"
#define PGDATADIR "d:\\pglite\\data"
......@@ -10,38 +10,38 @@
*
*
* IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/postmaster/postmaster.c,v 1.24 1996/11/12 06:46:36 bryanh Exp $
* $Header: /cvsroot/pgsql/src/backend/postmaster/postmaster.c,v 1.25 1996/11/14 10:24:01 bryanh Exp $
*
* NOTES
*
* Initialization:
* The Postmaster sets up a few shared memory data structures
* for the backends. It should at the very least initialize the
* lock manager.
* The Postmaster sets up a few shared memory data structures
* for the backends. It should at the very least initialize the
* lock manager.
*
* Synchronization:
* The Postmaster shares memory with the backends and will have to lock
* the shared memory it accesses. The Postmaster should never block
* on messages from clients.
*
* The Postmaster shares memory with the backends and will have to lock
* the shared memory it accesses. The Postmaster should never block
* on messages from clients.
*
* Garbage Collection:
* The Postmaster cleans up after backends if they have an emergency
* exit and/or core dump.
* The Postmaster cleans up after backends if they have an emergency
* exit and/or core dump.
*
* Communication:
*
*-------------------------------------------------------------------------
*/
/* moved here to prevent double define */
#include <sys/param.h> /* for MAXHOSTNAMELEN on most */
/* moved here to prevent double define */
#include <sys/param.h> /* for MAXHOSTNAMELEN on most */
#ifndef MAXHOSTNAMELEN
#include <netdb.h> /* for MAXHOSTNAMELEN on some */
#include <netdb.h> /* for MAXHOSTNAMELEN on some */
#endif
#include "postgres.h"
#include <signal.h> /* for other stuff */
#include "libpq/pqsignal.h" /* substitute for <signal.h> */
#include <signal.h> /* for other stuff */
#include "libpq/pqsignal.h" /* substitute for <signal.h> */
#include <string.h>
#include <stdlib.h>
......@@ -50,13 +50,13 @@
#endif /* !NO_UNISTD_H */
#include <ctype.h>
#include <sys/types.h> /* for fd_set stuff */
#include <sys/stat.h> /* for umask */
#include <sys/types.h> /* for fd_set stuff */
#include <sys/stat.h> /* for umask */
#include <sys/time.h>
#include <sys/socket.h>
#if defined(USE_LIMITS_H)
# include <machine/limits.h>
# define MAXINT INT_MAX
# define MAXINT INT_MAX
#else
# include <values.h>
#endif /* !USE_LIMITS_H */
......@@ -103,7 +103,7 @@
* but I left this structure around in case that changed.
*/
typedef struct bkend {
int pid; /* process id of backend */
int pid; /* process id of backend */
} Backend;
/* list of active backends. For garbage collection only now. */
......@@ -113,24 +113,27 @@ static Dllist* BackendList;
/* list of ports associated with still open, but incomplete connections */
static Dllist* PortList;
static short PostPortName = -1;
static short ActiveBackends = FALSE;
static int NextBackendId = MAXINT; /* XXX why? */
static char *progname = (char *) NULL;
static short PostPortName = -1;
static short ActiveBackends = FALSE;
static int NextBackendId = MAXINT; /* XXX why? */
static char *progname = (char *) NULL;
char *DataDir = (char *) NULL;
char *DataDir;
/* The PGDATA directory user says to use, or defaults to via environment
variable. NULL if no option given and no environment variable set
*/
/*
* Default Values
*/
static char Execfile[MAXPATHLEN] = "";
static char Execfile[MAXPATHLEN] = "";
static int ServerSock = INVALID_SOCK; /* stream socket server */
static int ServerSock = INVALID_SOCK; /* stream socket server */
/*
* Set by the -o option
*/
static char ExtraOptions[ARGV_SIZE] = "";
static char ExtraOptions[ARGV_SIZE] = "";
/*
* These globals control the behavior of the postmaster in case some
......@@ -139,8 +142,8 @@ static char ExtraOptions[ARGV_SIZE] = "";
* the postmaster stop (rather than kill) peers and not reinitialize
* shared data structures.
*/
static int Reinit = 1;
static int SendStop = 0;
static int Reinit = 1;
static int SendStop = 0;
static int MultiplexedBackends = 0;
static int MultiplexedBackendPort;
......@@ -160,7 +163,6 @@ static void CleanupProc(int pid, int exitstatus);
static int DoExec(StartupInfo *packet, int portFd);
static void ExitPostmaster(int status);
static void usage(const char *);
static void checkDataDir(void);
int ServerLoop(void);
int BackendStartup(StartupInfo *packet, Port *port, int *pidPtr);
static void send_error_reply(Port *port, const char *errormsg);
......@@ -168,142 +170,194 @@ static void send_error_reply(Port *port, const char *errormsg);
extern char *optarg;
extern int optind, opterr;
static void
checkDataDir(const char *DataDir, bool *DataDirOK)
{
if (DataDir == NULL) {
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",
progname);
*DataDirOK = false;
} else {
char path[MAXPATHLEN];
FILE *fp;
sprintf(path, "%s%cbase%ctemplate1%cpg_class",
DataDir, SEP_CHAR, SEP_CHAR, SEP_CHAR);
fp = fopen(path, "r");
if (fp == NULL) {
fprintf(stderr, "%s does not find the database system. "
"Expected to find it "
"in the PGDATA directory \"%s\", but unable to open file "
"with pathname \"%s\".\n\n",
progname, DataDir, path);
*DataDirOK = false;
} else {
char *reason;
/* reason ValidatePgVersion failed. NULL if didn't */
fclose(fp);
#ifndef WIN32
ValidatePgVersion(DataDir, &reason);
#else
reason = NULL;
#endif /* WIN32 */
if (reason) {
fprintf(stderr,
"Database system in directory %s "
"is not compatible with this version of "
"Postgres, or we are unable to read the "
"PG_VERSION file. "
"Explanation from ValidatePgVersion: %s\n\n",
DataDir, reason);
free(reason);
*DataDirOK = false;
} else *DataDirOK = true;
}
}
}
int
PostmasterMain(int argc, char *argv[])
{
extern int NBuffers; /* from buffer/bufmgr.c */
extern bool IsPostmaster; /* from smgr/mm.c */
int opt;
char *hostName;
int status;
int silentflag = 0;
char hostbuf[MAXHOSTNAMELEN];
extern int NBuffers; /* from buffer/bufmgr.c */
extern bool IsPostmaster; /* from smgr/mm.c */
int opt;
char *hostName;
int status;
int silentflag = 0;
char hostbuf[MAXHOSTNAMELEN];
bool DataDirOK; /* We have a usable PGDATA value */
#if defined(WIN32)
WSADATA WSAData;
#endif /* WIN32 */
progname = argv[0];
IsPostmaster = true;
/* for security, no dir or file created can be group or other accessible */
(void) umask((mode_t) 0077);
if (!(hostName = getenv("PGHOST"))) {
if (gethostname(hostbuf, MAXHOSTNAMELEN) < 0)
(void) strcpy(hostbuf, "localhost");
hostName = hostbuf;
if (gethostname(hostbuf, MAXHOSTNAMELEN) < 0)
(void) strcpy(hostbuf, "localhost");
hostName = hostbuf;
}
DataDir = getenv("PGDATA"); /* default value */
opterr = 0;
while ((opt = getopt(argc, argv, "a:B:b:D:dmM:no:p:Ss")) != EOF) {
switch (opt) {
case 'a':
/* Set the authentication system. */
be_setauthsvc(optarg);
break;
case 'B':
/*
* The number of buffers to create. Setting this
* option means we have to start each backend with
* a -B # to make sure they know how many buffers
* were allocated.
*/
NBuffers = atol(optarg);
(void) strcat(ExtraOptions, " -B ");
(void) strcat(ExtraOptions, optarg);
break;
case 'b':
/* Set the backend executable file to use. */
if (!ValidateBackend(optarg))
strcpy(Execfile, optarg);
else {
fprintf(stderr, "%s: invalid backend \"%s\"\n",
progname, optarg);
exit(2);
}
break;
case 'D':
/* Set PGDATA from the command line. */
DataDir = optarg;
break;
case 'd':
/*
* Turn on debugging for the postmaster and the backend
* servers descended from it.
*/
if ((optind < argc) && *argv[optind] != '-') {
DebugLvl = atoi(argv[optind]);
optind++;
}
else
DebugLvl = 1;
break;
case 'm':
MultiplexedBackends = 1;
MultiplexedBackendPort = atoi(optarg);
break;
case 'M':
/* ignore this flag. This may be passed in because the
program was run as 'postgres -M' instead of 'postmaster' */
break;
case 'n':
/* Don't reinit shared mem after abnormal exit */
Reinit = 0;
break;
case 'o':
/*
* Other options to pass to the backend on the
* command line -- useful only for debugging.
*/
(void) strcat(ExtraOptions, " ");
(void) strcat(ExtraOptions, optarg);
break;
case 'p':
/* Set PGPORT by hand. */
PostPortName = (short) atoi(optarg);
break;
case 'S':
/*
* Start in 'S'ilent mode (disassociate from controlling tty).
* You may also think of this as 'S'ysV mode since it's most
* badly needed on SysV-derived systems like SVR4 and HP-UX.
*/
silentflag = 1;
break;
case 's':
/*
* In the event that some backend dumps core,
* send SIGSTOP, rather than SIGUSR1, to all
* its peers. This lets the wily post_hacker
* collect core dumps from everyone.
*/
SendStop = 1;
break;
default:
/* usage() never returns */
usage(progname);
break;
}
switch (opt) {
case 'a':
/* Set the authentication system. */
be_setauthsvc(optarg);
break;
case 'B':
/*
* The number of buffers to create. Setting this
* option means we have to start each backend with
* a -B # to make sure they know how many buffers
* were allocated.
*/
NBuffers = atol(optarg);
(void) strcat(ExtraOptions, " -B ");
(void) strcat(ExtraOptions, optarg);
break;
case 'b':
/* Set the backend executable file to use. */
if (!ValidateBackend(optarg))
strcpy(Execfile, optarg);
else {
fprintf(stderr, "%s: invalid backend \"%s\"\n",
progname, optarg);
exit(2);
}
break;
case 'D':
/* Set PGDATA from the command line. */
DataDir = optarg;
break;
case 'd':
/*
* Turn on debugging for the postmaster and the backend
* servers descended from it.
*/
if ((optind < argc) && *argv[optind] != '-') {
DebugLvl = atoi(argv[optind]);
optind++;
}
else
DebugLvl = 1;
break;
case 'm':
MultiplexedBackends = 1;
MultiplexedBackendPort = atoi(optarg);
break;
case 'M':
/* ignore this flag. This may be passed in because the
program was run as 'postgres -M' instead of 'postmaster' */
break;
case 'n':
/* Don't reinit shared mem after abnormal exit */
Reinit = 0;
break;
case 'o':
/*
* Other options to pass to the backend on the
* command line -- useful only for debugging.
*/
(void) strcat(ExtraOptions, " ");
(void) strcat(ExtraOptions, optarg);
break;
case 'p':
/* Set PGPORT by hand. */
PostPortName = (short) atoi(optarg);
break;
case 'S':
/*
* Start in 'S'ilent mode (disassociate from controlling tty).
* You may also think of this as 'S'ysV mode since it's most
* badly needed on SysV-derived systems like SVR4 and HP-UX.
*/
silentflag = 1;
break;
case 's':
/*
* In the event that some backend dumps core,
* send SIGSTOP, rather than SIGUSR1, to all
* its peers. This lets the wily post_hacker
* collect core dumps from everyone.
*/
SendStop = 1;
break;
default:
/* usage() never returns */
usage(progname);
break;
}
}
if (PostPortName == -1)
PostPortName = pq_getport();
PostPortName = pq_getport();
IsPostmaster = true;
if (!DataDir)
DataDir = GetPGData();
checkDataDir(DataDir, &DataDirOK); /* issues error messages */
if (!DataDirOK) {
fprintf(stderr, "No data directory -- can't proceed.\n");
exit(2);
}
/*
* check whether the data directory exists. Passing this test doesn't
* gaurantee we are accessing the right data base but is a first barrier
* to site administrators who starts up the postmaster without realizing
* it cannot access the data base.
*/
checkDataDir();
if (!Execfile[0] && FindBackend(Execfile, argv[0]) < 0) {
fprintf(stderr, "%s: could not find backend to execute...\n",
argv[0]);
exit(1);
fprintf(stderr, "%s: could not find backend to execute...\n",
argv[0]);
exit(1);
}
......@@ -321,9 +375,9 @@ PostmasterMain(int argc, char *argv[])
status = StreamServerPort(hostName, PostPortName, &ServerSock);
if (status != STATUS_OK) {
fprintf(stderr, "%s: cannot create stream port\n",
progname);
exit(1);
fprintf(stderr, "%s: cannot create stream port\n",
progname);
exit(1);
}
/* set up shared memory and semaphores */
......@@ -338,7 +392,7 @@ PostmasterMain(int argc, char *argv[])
PortList = DLNewList();
if (silentflag)
pmdaemonize();
pmdaemonize();
signal(SIGINT, pmdie);
#ifndef WIN32
......@@ -363,12 +417,12 @@ pmdaemonize(void)
int i;
if (fork())
exit(0);
exit(0);
if (setsid() < 0) {
fprintf(stderr, "%s: ", progname);
perror("cannot disassociate from controlling TTY");
exit(1);
fprintf(stderr, "%s: ", progname);
perror("cannot disassociate from controlling TTY");
exit(1);
}
i = open(NULL_DEV, O_RDWR);
(void) dup2(i, 0);
......@@ -398,9 +452,9 @@ usage(const char *progname)
int
ServerLoop(void)
{
int serverFd = ServerSock;
fd_set rmask, basemask;
int nSockets, nSelected, status, newFd;
int serverFd = ServerSock;
fd_set rmask, basemask;
int nSockets, nSelected, status, newFd;
Dlelem *next, *curr;
/* int orgsigmask = sigblock(0); */
sigset_t oldsigmask, newsigmask;
......@@ -413,104 +467,104 @@ ServerLoop(void)
sigemptyset(&newsigmask);
sigaddset(&newsigmask,SIGCHLD);
for (;;) {
/* sigsetmask(orgsigmask); */
sigprocmask(SIG_SETMASK,&oldsigmask,0);
newFd = -1;
memmove((char *) &rmask, (char *) &basemask, sizeof(fd_set));
if ((nSelected = select(nSockets, &rmask,
(fd_set *) NULL,
(fd_set *) NULL,
(struct timeval *) NULL)) < 0) {
if (errno == EINTR)
continue;
fprintf(stderr, "%s: ServerLoop: select failed\n",
progname);
return(STATUS_ERROR);
/* sigsetmask(orgsigmask); */
sigprocmask(SIG_SETMASK,&oldsigmask,0);
newFd = -1;
memmove((char *) &rmask, (char *) &basemask, sizeof(fd_set));
if ((nSelected = select(nSockets, &rmask,
(fd_set *) NULL,
(fd_set *) NULL,
(struct timeval *) NULL)) < 0) {
if (errno == EINTR)
continue;
fprintf(stderr, "%s: ServerLoop: select failed\n",
progname);
return(STATUS_ERROR);
}
/* [TRH]
* To avoid race conditions, block SIGCHLD signals while we are
* handling the request. (both reaper() and ConnCreate()
* manipulate the BackEnd list, and reaper() calls free() which is
* usually non-reentrant.)
*/
sigprocmask(SIG_BLOCK, &newsigmask, &oldsigmask);
/* sigblock(sigmask(SIGCHLD)); */ /* XXX[TRH] portability */
if (DebugLvl > 1) {
fprintf(stderr, "%s: ServerLoop: %d sockets pending\n",
progname, nSelected);
}
/* new connection pending on our well-known port's socket */
if (FD_ISSET(ServerSock, &rmask)) {
/*
* connect and make an addition to PortList. If
* the connection dies and we notice it, just forget
* about the whole thing.
*/
if (ConnCreate(serverFd, &newFd) == STATUS_OK) {
if (newFd >= nSockets)
nSockets = newFd + 1;
FD_SET(newFd, &rmask);
FD_SET(newFd, &basemask);
if (DebugLvl)
fprintf(stderr, "%s: ServerLoop: connect on %d\n",
progname, newFd);
}
--nSelected;
FD_CLR(ServerSock, &rmask);
}
/* [TRH]
* To avoid race conditions, block SIGCHLD signals while we are
* handling the request. (both reaper() and ConnCreate()
* manipulate the BackEnd list, and reaper() calls free() which is
* usually non-reentrant.)
*/
sigprocmask(SIG_BLOCK, &newsigmask, &oldsigmask);
/* sigblock(sigmask(SIGCHLD)); */ /* XXX[TRH] portability */
if (DebugLvl > 1) {
fprintf(stderr, "%s: ServerLoop: %d sockets pending\n",
progname, nSelected);
}
/* new connection pending on our well-known port's socket */
if (FD_ISSET(ServerSock, &rmask)) {
/*
* connect and make an addition to PortList. If
* the connection dies and we notice it, just forget
* about the whole thing.
*/
if (ConnCreate(serverFd, &newFd) == STATUS_OK) {
if (newFd >= nSockets)
nSockets = newFd + 1;
FD_SET(newFd, &rmask);
FD_SET(newFd, &basemask);
if (DebugLvl)
fprintf(stderr, "%s: ServerLoop: connect on %d\n",
progname, newFd);
}
--nSelected;
FD_CLR(ServerSock, &rmask);
}
if (DebugLvl > 1) {
fprintf(stderr, "%s: ServerLoop:\tnSelected=%d\n",
progname, nSelected);
curr = DLGetHead(PortList);
while (curr) {
Port *port = DLE_VAL(curr);
fprintf(stderr, "%s: ServerLoop:\t\tport %d%s pending\n",
progname, port->sock,
FD_ISSET(port->sock, &rmask)
? "" :
" not");
curr = DLGetSucc(curr);
}
}
curr = DLGetHead(PortList);
while (curr) {
Port *port = (Port*)DLE_VAL(curr);
int lastbytes = port->nBytes;
if (FD_ISSET(port->sock, &rmask) && port->sock != newFd) {
if (DebugLvl > 1)
fprintf(stderr, "%s: ServerLoop:\t\thandling %d\n",
progname, port->sock);
--nSelected;
/*
* Read the incoming packet into its packet buffer.
* Read the connection id out of the packet so we
* know who the packet is from.
*/
status = PacketReceive(port, &port->buf, NON_BLOCKING);
switch (status) {
case STATUS_OK: {
if (DebugLvl > 1) {
fprintf(stderr, "%s: ServerLoop:\tnSelected=%d\n",
progname, nSelected);
curr = DLGetHead(PortList);
while (curr) {
Port *port = DLE_VAL(curr);
fprintf(stderr, "%s: ServerLoop:\t\tport %d%s pending\n",
progname, port->sock,
FD_ISSET(port->sock, &rmask)
? "" :
" not");
curr = DLGetSucc(curr);
}
}
curr = DLGetHead(PortList);
while (curr) {
Port *port = (Port*)DLE_VAL(curr);
int lastbytes = port->nBytes;
if (FD_ISSET(port->sock, &rmask) && port->sock != newFd) {
if (DebugLvl > 1)
fprintf(stderr, "%s: ServerLoop:\t\thandling %d\n",
progname, port->sock);
--nSelected;
/*
* Read the incoming packet into its packet buffer.
* Read the connection id out of the packet so we
* know who the packet is from.
*/
status = PacketReceive(port, &port->buf, NON_BLOCKING);
switch (status) {
case STATUS_OK: {
int CSstatus; /* Completion status of ConnStartup */
char errormsg[200]; /* error msg from ConnStartup */
ConnStartup(port, &CSstatus, errormsg, sizeof(errormsg));
ConnStartup(port, &CSstatus, errormsg, sizeof(errormsg));
if (CSstatus == STATUS_ERROR)
send_error_reply(port, errormsg);
ActiveBackends = TRUE;
ActiveBackends = TRUE;
}
/*FALLTHROUGH*/
case STATUS_INVALID:
if (DebugLvl)
fprintf(stderr, "%s: ServerLoop:\t\tdone with %d\n",
progname, port->sock);
break;
/*FALLTHROUGH*/
case STATUS_INVALID:
if (DebugLvl)
fprintf(stderr, "%s: ServerLoop:\t\tdone with %d\n",
progname, port->sock);
break;
case STATUS_BAD_PACKET:
/*
* This is a bogus client, kill the connection
......@@ -519,41 +573,41 @@ ServerLoop(void)
if (DebugLvl)
fprintf(stderr, "%s: ServerLoop:\t\tbad packet format (reported packet size of %d read on port %d\n", progname, port->nBytes, port->sock);
break;
case STATUS_NOT_DONE:
if (DebugLvl)
fprintf(stderr, "%s: ServerLoop:\t\tpartial packet (%d bytes actually read) on %d\n",
progname, port->nBytes, port->sock);
/*
* If we've received at least a PacketHdr's worth of data
* and we're still receiving data each time we read, we're
* ok. If the client gives us less than a PacketHdr at
* the beginning, just kill the connection and forget
* about the whole thing.
*/
if (lastbytes < port->nBytes) {
if (DebugLvl)
fprintf(stderr, "%s: ServerLoop:\t\tpartial packet on %d ok\n",
progname, port->sock);
curr = DLGetSucc(curr);
continue;
}
break;
case STATUS_ERROR: /* system call error - die */
fprintf(stderr, "%s: ServerLoop:\t\terror receiving packet\n",
progname);
return(STATUS_ERROR);
}
FD_CLR(port->sock, &basemask);
StreamClose(port->sock);
next = DLGetSucc(curr);
DLRemove(curr);
DLFreeElem(curr);
curr = next;
case STATUS_NOT_DONE:
if (DebugLvl)
fprintf(stderr, "%s: ServerLoop:\t\tpartial packet (%d bytes actually read) on %d\n",
progname, port->nBytes, port->sock);
/*
* If we've received at least a PacketHdr's worth of data
* and we're still receiving data each time we read, we're
* ok. If the client gives us less than a PacketHdr at
* the beginning, just kill the connection and forget
* about the whole thing.
*/
if (lastbytes < port->nBytes) {
if (DebugLvl)
fprintf(stderr, "%s: ServerLoop:\t\tpartial packet on %d ok\n",
progname, port->sock);
curr = DLGetSucc(curr);
continue;
}
break;
case STATUS_ERROR: /* system call error - die */
fprintf(stderr, "%s: ServerLoop:\t\terror receiving packet\n",
progname);
return(STATUS_ERROR);
}
FD_CLR(port->sock, &basemask);
StreamClose(port->sock);
next = DLGetSucc(curr);
DLRemove(curr);
DLFreeElem(curr);
curr = next;
continue;
}
curr = DLGetSucc(curr);
}
Assert(nSelected == 0);
}
curr = DLGetSucc(curr);
}
Assert(nSelected == 0);
}
}
......@@ -574,7 +628,7 @@ ConnStartup(Port *port, int *status,
{
MsgType msgType;
char namebuf[NAMEDATALEN + 1];
int pid;
int pid;
PacketBuf *p;
StartupInfo sp;
char *tmp;
......@@ -708,23 +762,23 @@ send_error_reply(Port *port, const char *errormsg)
static int
ConnCreate(int serverFd, int *newFdP)
{
int status;
Port *port;
int status;
Port *port;
if (!(port = (Port *) calloc(1, sizeof(Port)))) {
fprintf(stderr, "%s: ConnCreate: malloc failed\n",
progname);
ExitPostmaster(1);
fprintf(stderr, "%s: ConnCreate: malloc failed\n",
progname);
ExitPostmaster(1);
}
if ((status = StreamConnection(serverFd, port)) != STATUS_OK) {
StreamClose(port->sock);
free(port);
StreamClose(port->sock);
free(port);
}
else {
DLAddHead(PortList, DLNewElem(port));
*newFdP = port->sock;
DLAddHead(PortList, DLNewElem(port));
*newFdP = port->sock;
}
return (status);
......@@ -736,7 +790,7 @@ ConnCreate(int serverFd, int *newFdP)
static void
reset_shared(short port)
{
IPCKey key;
IPCKey key;
key = SystemPortAddressCreateIPCKey((SystemPortAddress) port);
CreateSharedMemoryAndSemaphores(key);
......@@ -758,15 +812,15 @@ pmdie(SIGNAL_ARGS)
static void
reaper(SIGNAL_ARGS)
{
int status; /* backend exit status */
int pid; /* process id of dead backend */
int status; /* backend exit status */
int pid; /* process id of dead backend */
if (DebugLvl)
fprintf(stderr, "%s: reaping dead processes...\n",
progname);
fprintf(stderr, "%s: reaping dead processes...\n",
progname);
#ifndef WIN32
while((pid = waitpid(-1, &status, WNOHANG)) > 0)
CleanupProc(pid, status);
CleanupProc(pid, status);
#endif /* WIN32 */
}
......@@ -779,15 +833,15 @@ reaper(SIGNAL_ARGS)
*/
static void
CleanupProc(int pid,
int exitstatus) /* child's exit status. */
int exitstatus) /* child's exit status. */
{
Dlelem *prev, *curr;
Backend *bp;
int sig;
Backend *bp;
int sig;
if (DebugLvl) {
fprintf(stderr, "%s: CleanupProc: pid %d exited with status %d\n",
progname, pid, exitstatus);
fprintf(stderr, "%s: CleanupProc: pid %d exited with status %d\n",
progname, pid, exitstatus);
}
/*
* -------------------------
......@@ -798,57 +852,57 @@ CleanupProc(int pid,
* -------------------------
*/
if (!exitstatus) {
curr = DLGetHead(BackendList);
while (curr) {
bp = (Backend*)DLE_VAL(curr);
if (bp->pid == pid) {
DLRemove(curr);
DLFreeElem(curr);
break;
}
curr = DLGetSucc(curr);
}
ProcRemove(pid);
return;
curr = DLGetHead(BackendList);
while (curr) {
bp = (Backend*)DLE_VAL(curr);
if (bp->pid == pid) {
DLRemove(curr);
DLFreeElem(curr);
break;
}
curr = DLGetSucc(curr);
}
ProcRemove(pid);
return;
}
curr = DLGetHead(BackendList);
while (curr) {
bp = (Backend*)DLE_VAL(curr);
/*
* -----------------
* SIGUSR1 is the special signal that sez exit without exitpg
* and let the user know what's going on. ProcSemaphoreKill()
* cleans up the backends semaphore. If SendStop is set (-s on
* the command line), then we send a SIGSTOP so that we can
* collect core dumps from all backends by hand.
* -----------------
*/
bp = (Backend*)DLE_VAL(curr);
/*
* -----------------
* SIGUSR1 is the special signal that sez exit without exitpg
* and let the user know what's going on. ProcSemaphoreKill()
* cleans up the backends semaphore. If SendStop is set (-s on
* the command line), then we send a SIGSTOP so that we can
* collect core dumps from all backends by hand.
* -----------------
*/
#ifndef WIN32
sig = (SendStop) ? SIGSTOP : SIGUSR1;
if (bp->pid != pid) {
if (DebugLvl)
fprintf(stderr, "%s: CleanupProc: sending %s to process %d\n",
progname,
(sig == SIGUSR1)
? "SIGUSR1" : "SIGSTOP",
bp->pid);
(void) kill(bp->pid, sig);
}
sig = (SendStop) ? SIGSTOP : SIGUSR1;
if (bp->pid != pid) {
if (DebugLvl)
fprintf(stderr, "%s: CleanupProc: sending %s to process %d\n",
progname,
(sig == SIGUSR1)
? "SIGUSR1" : "SIGSTOP",
bp->pid);
(void) kill(bp->pid, sig);
}
#endif /* WIN32 */
ProcRemove(bp->pid);
prev = DLGetPred(curr);
DLRemove(curr);
DLFreeElem(curr);
if (!prev) { /* removed head */
curr = DLGetHead(BackendList);
continue;
}
curr = DLGetSucc(curr);
ProcRemove(bp->pid);
prev = DLGetPred(curr);
DLRemove(curr);
DLFreeElem(curr);
if (!prev) { /* removed head */
curr = DLGetHead(BackendList);
continue;
}
curr = DLGetSucc(curr);
}
/*
* -------------
......@@ -865,11 +919,11 @@ CleanupProc(int pid,
* ----------------
*/
if (ActiveBackends == TRUE && Reinit) {
if (DebugLvl)
fprintf(stderr, "%s: CleanupProc: reinitializing shared memory and semaphores\n",
progname);
quasi_exitpg();
reset_shared(PostPortName);
if (DebugLvl)
fprintf(stderr, "%s: CleanupProc: reinitializing shared memory and semaphores\n",
progname);
quasi_exitpg();
reset_shared(PostPortName);
}
}
......@@ -877,20 +931,20 @@ CleanupProc(int pid,
* BackendStartup -- start backend process
*
* returns: STATUS_ERROR if the fork/exec failed, STATUS_OK
* otherwise.
* otherwise.
*
*/
int
BackendStartup(StartupInfo *packet, /* client's startup packet */
Port *port,
int *pidPtr)
Port *port,
int *pidPtr)
{
Backend* bn; /* for backend cleanup */
int pid, i;
static char envEntry[4][2 * ARGV_SIZE];
int pid, i;
static char envEntry[4][2 * ARGV_SIZE];
for (i = 0; i < 4; ++i) {
memset(envEntry[i], 0, 2*ARGV_SIZE);
memset(envEntry[i], 0, 2*ARGV_SIZE);
}
/*
* Set up the necessary environment variables for the backend
......@@ -903,50 +957,50 @@ BackendStartup(StartupInfo *packet, /* client's startup packet */
sprintf(envEntry[2], "PG_USER=%s", packet->user);
putenv(envEntry[2]);
if (!getenv("PGDATA")) {
sprintf(envEntry[3], "PGDATA=%s", DataDir);
putenv(envEntry[3]);
sprintf(envEntry[3], "PGDATA=%s", DataDir);
putenv(envEntry[3]);
}
if (DebugLvl > 2) {
char **p;
extern char **environ;
fprintf(stderr, "%s: BackendStartup: environ dump:\n",
progname);
fprintf(stderr, "-----------------------------------------\n");
for (p = environ; *p; ++p)
fprintf(stderr, "\t%s\n", *p);
fprintf(stderr, "-----------------------------------------\n");
char **p;
extern char **environ;
fprintf(stderr, "%s: BackendStartup: environ dump:\n",
progname);
fprintf(stderr, "-----------------------------------------\n");
for (p = environ; *p; ++p)
fprintf(stderr, "\t%s\n", *p);
fprintf(stderr, "-----------------------------------------\n");
}
#ifndef WIN32
if ((pid = FORK()) == 0) { /* child */
if (DoExec(packet, port->sock))
fprintf(stderr, "%s child[%d]: BackendStartup: execv failed\n",
progname, pid);
/* use _exit to keep from double-flushing stdio */
_exit(1);
if ((pid = FORK()) == 0) { /* child */
if (DoExec(packet, port->sock))
fprintf(stderr, "%s child[%d]: BackendStartup: execv failed\n",
progname, pid);
/* use _exit to keep from double-flushing stdio */
_exit(1);
}
/* in parent */
if (pid < 0) {
fprintf(stderr, "%s: BackendStartup: fork failed\n",
progname);
return(STATUS_ERROR);
fprintf(stderr, "%s: BackendStartup: fork failed\n",
progname);
return(STATUS_ERROR);
}
#else
pid = DoExec(packet, port->sock);
if (pid == FALSE) {
fprintf(stderr, "%s: BackendStartup: CreateProcess failed\n",
progname);
return(STATUS_ERROR);
fprintf(stderr, "%s: BackendStartup: CreateProcess failed\n",
progname);
return(STATUS_ERROR);
}
#endif /* WIN32 */
if (DebugLvl)
fprintf(stderr, "%s: BackendStartup: pid %d user %s db %s socket %d\n",
progname, pid, packet->user,
(packet->database[0] == '\0' ? packet->user : packet->database),
port->sock);
fprintf(stderr, "%s: BackendStartup: pid %d user %s db %s socket %d\n",
progname, pid, packet->user,
(packet->database[0] == '\0' ? packet->user : packet->database),
port->sock);
/* adjust backend counter */
/* XXX Don't know why this is done, but for now backend needs it */
......@@ -957,16 +1011,16 @@ BackendStartup(StartupInfo *packet, /* client's startup packet */
* list of backends.
*/
if (!(bn = (Backend *) calloc(1, sizeof (Backend)))) {
fprintf(stderr, "%s: BackendStartup: malloc failed\n",
progname);
ExitPostmaster(1);
fprintf(stderr, "%s: BackendStartup: malloc failed\n",
progname);
ExitPostmaster(1);
}
bn->pid = pid;
DLAddHead(BackendList,DLNewElem(bn));
if (MultiplexedBackends)
MultiplexedBackendPort++;
MultiplexedBackendPort++;
*pidPtr = pid;
......@@ -986,17 +1040,17 @@ BackendStartup(StartupInfo *packet, /* client's startup packet */
static void
split_opts(char **argv, int *argcp, char *s)
{
int i = *argcp;
int i = *argcp;
while (s && *s) {
while (isspace(*s))
++s;
if (*s)
argv[i++] = s;
while (*s && !isspace(*s))
++s;
if (isspace(*s))
*s++ = '\0';
while (isspace(*s))
++s;
if (*s)
argv[i++] = s;
while (*s && !isspace(*s))
++s;
if (isspace(*s))
*s++ = '\0';
}
*argcp = i;
}
......@@ -1010,26 +1064,26 @@ split_opts(char **argv, int *argcp, char *s)
* fork() because we don't have vfork(), then we don't really care.)
*
* returns:
* Shouldn't return at all.
* If execv() fails, return status.
* Shouldn't return at all.
* If execv() fails, return status.
*/
static int
DoExec(StartupInfo *packet, int portFd)
{
char execbuf[MAXPATHLEN];
char portbuf[ARGV_SIZE];
char execbuf[MAXPATHLEN];
char portbuf[ARGV_SIZE];
char mbbuf[ARGV_SIZE];
char debugbuf[ARGV_SIZE];
char ttybuf[ARGV_SIZE + 1];
char argbuf[(2 * ARGV_SIZE) + 1];
char debugbuf[ARGV_SIZE];
char ttybuf[ARGV_SIZE + 1];
char argbuf[(2 * ARGV_SIZE) + 1];
/*
* each argument takes at least three chars, so we can't
* have more than ARGV_SIZE arguments in (2 * ARGV_SIZE)
* chars (i.e., packet->options plus ExtraOptions)...
*/
char *av[ARGV_SIZE];
char dbbuf[ARGV_SIZE + 1];
int ac = 0;
char *av[ARGV_SIZE];
char dbbuf[ARGV_SIZE + 1];
int ac = 0;
int i;
#if defined(WIN32)
char win32_args[(2 * ARGV_SIZE) + 1];
......@@ -1054,16 +1108,16 @@ DoExec(StartupInfo *packet, int portFd)
*/
if (DebugLvl > 1) {
(void) sprintf(debugbuf, "-d%d", DebugLvl - 1);
av[ac++] = debugbuf;
(void) sprintf(debugbuf, "-d%d", DebugLvl - 1);
av[ac++] = debugbuf;
}
else
av[ac++] = "-Q";
av[ac++] = "-Q";
/* Pass the requested debugging output file */
if (packet->tty[0]) {
(void) strncpy(ttybuf, packet->tty, ARGV_SIZE);
av[ac++] = "-o";
(void) strncpy(ttybuf, packet->tty, ARGV_SIZE);
av[ac++] = "-o";
#if defined(WIN32)
/* BIG HACK - The front end is passing "/dev/null" here which
** causes new backends to fail. So, as a very special case,
......@@ -1092,20 +1146,20 @@ DoExec(StartupInfo *packet, int portFd)
split_opts(av, &ac, argbuf);
if (packet->database[0])
(void) strncpy(dbbuf, packet->database, ARGV_SIZE);
(void) strncpy(dbbuf, packet->database, ARGV_SIZE);
else
(void) strncpy(dbbuf, packet->user, NAMEDATALEN);
(void) strncpy(dbbuf, packet->user, NAMEDATALEN);
dbbuf[ARGV_SIZE] = '\0';
av[ac++] = dbbuf;
av[ac] = (char *) NULL;
if (DebugLvl > 1) {
fprintf(stderr, "%s child[%ld]: execv(",
progname, (long)getpid());
for (i = 0; i < ac; ++i)
fprintf(stderr, "%s, ", av[i]);
fprintf(stderr, ")\n");
fprintf(stderr, "%s child[%ld]: execv(",
progname, (long)getpid());
for (i = 0; i < ac; ++i)
fprintf(stderr, "%s, ", av[i]);
fprintf(stderr, ")\n");
}
#ifndef WIN32
......@@ -1156,7 +1210,7 @@ ExitPostmaster(int status)
* should the backends all be killed? probably not.
*/
if (ServerSock != INVALID_SOCK)
close(ServerSock);
close(ServerSock);
exitpg(status);
}
......@@ -1166,50 +1220,17 @@ dumpstatus(SIGNAL_ARGS)
Dlelem *curr = DLGetHead(PortList);
while (curr) {
Port *port = DLE_VAL(curr);
fprintf(stderr, "%s: dumpstatus:\n", progname);
fprintf(stderr, "\tsock %d: nBytes=%d, laddr=0x%lx, raddr=0x%lx\n",
port->sock, port->nBytes,
(long int) port->laddr.sin_addr.s_addr,
(long int) port->raddr.sin_addr.s_addr);
curr = DLGetSucc(curr);
Port *port = DLE_VAL(curr);
fprintf(stderr, "%s: dumpstatus:\n", progname);
fprintf(stderr, "\tsock %d: nBytes=%d, laddr=0x%lx, raddr=0x%lx\n",
port->sock, port->nBytes,
(long int) port->laddr.sin_addr.s_addr,
(long int) port->raddr.sin_addr.s_addr);
curr = DLGetSucc(curr);
}
}
static void
checkDataDir(void)
{
char path[MAXPATHLEN];
FILE *fp;
sprintf(path, "%s%cbase%ctemplate1%cpg_class", DataDir, SEP_CHAR, SEP_CHAR,
SEP_CHAR);
if ((fp=fopen(path, "r")) == NULL) {
fprintf(stderr, "%s does not find the database. Expected to find it "
"in the PGDATA directory \"%s\", but unable to open file "
"with pathname \"%s\".\n",
progname, DataDir, path);
exit(2);
}
fclose(fp);
#ifndef WIN32
{
char *reason; /* reason ValidatePgVersion failed. NULL if didn't */
ValidatePgVersion(DataDir, &reason);
if (reason) {
fprintf(stderr,
"Database system in directory %s "
"is not compatible with this version of "
"Postgres, or we are unable to read the PG_VERSION file. "
"Explanation from ValidatePgVersion: %s\n",
DataDir, reason);
free(reason);
exit(2);
}
}
#endif /* WIN32 */
}
......@@ -7,7 +7,7 @@
*
*
* IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/tcop/postgres.c,v 1.18 1996/11/11 04:54:51 momjian Exp $
* $Header: /cvsroot/pgsql/src/backend/tcop/postgres.c,v 1.19 1996/11/14 10:24:07 bryanh Exp $
*
* NOTES
* this is the "main" module of the postgres backend and
......@@ -15,7 +15,7 @@
*
*-------------------------------------------------------------------------
*/
#include "libpq/pqsignal.h" /* substitute for <signal.h> */
#include "libpq/pqsignal.h" /* substitute for <signal.h> */
#if defined(linux)
#ifndef __USE_POSIX
......@@ -31,9 +31,9 @@
#include <sys/time.h>
#include <sys/types.h>
#include <fcntl.h>
#include <sys/param.h> /* for MAXHOSTNAMELEN on most */
#include <sys/param.h> /* for MAXHOSTNAMELEN on most */
#ifndef MAXHOSTNAMELEN
#include <netdb.h> /* for MAXHOSTNAMELEN on some */
#include <netdb.h> /* for MAXHOSTNAMELEN on some */
#endif
#include <errno.h>
#ifdef aix
......@@ -49,9 +49,9 @@
#include "lib/dllist.h"
#include "parser/catalog_utils.h"
#include "parser/parse_query.h" /* for MakeTimeRange() */
#include "parser/parse_query.h" /* for MakeTimeRange() */
#include "commands/async.h"
#include "tcop/tcopprot.h" /* where declarations for this file go */
#include "tcop/tcopprot.h" /* where declarations for this file go */
#include "optimizer/planner.h"
#include "tcop/tcopprot.h"
......@@ -86,26 +86,26 @@
#include "rewrite/rewriteHandler.h" /* for QueryRewrite() */
/* ----------------
* global variables
* global variables
* ----------------
*/
static bool DebugPrintPlan = false;
static bool DebugPrintParse = false;
static bool DebugPrintRewrittenParsetree = false;
/*static bool EnableRewrite = true; , never changes why have it*/
static bool DebugPrintPlan = false;
static bool DebugPrintParse = false;
static bool DebugPrintRewrittenParsetree = false;
/*static bool EnableRewrite = true; , never changes why have it*/
CommandDest whereToSendOutput;
extern int lockingOff;
extern int NBuffers;
extern int lockingOff;
extern int NBuffers;
int fsyncOff = 0;
int fsyncOff = 0;
int dontExecute = 0;
static int ShowStats;
static bool IsEmptyQuery = false;
int dontExecute = 0;
static int ShowStats;
static bool IsEmptyQuery = false;
Relation reldesc; /* current relation descritor */
char relname[80]; /* current relation name */
Relation reldesc; /* current relation descritor */
char relname[80]; /* current relation name */
#if defined(WIN32) || defined(next)
jmp_buf Warn_restart;
......@@ -116,15 +116,15 @@ sigjmp_buf Warn_restart;
#endif /*defined(WIN32) || defined(next) */
int InWarn;
extern int NBuffers;
extern int NBuffers;
static int EchoQuery = 0; /* default don't echo */
time_t tim;
char pg_pathname[256];
static int ShowParserStats;
static int ShowPlannerStats;
int ShowExecutorStats;
FILE *StatFp;
static int EchoQuery = 0; /* default don't echo */
time_t tim;
char pg_pathname[256];
static int ShowParserStats;
static int ShowPlannerStats;
int ShowExecutorStats;
FILE *StatFp;
typedef struct frontend {
bool fn_connected;
......@@ -137,8 +137,8 @@ typedef struct frontend {
static Dllist* frontendList;
/* ----------------
* people who want to use EOF should #define DONTUSENEWLINE in
* tcop/tcopdebug.h
* people who want to use EOF should #define DONTUSENEWLINE in
* tcop/tcopdebug.h
* ----------------
*/
#ifndef TCOP_DONTUSENEWLINE
......@@ -148,8 +148,8 @@ int UseNewLine = 0; /* Use EOF as query delimiters */
#endif /* TCOP_DONTUSENEWLINE */
/* ----------------
* bushy tree plan flag: if true planner will generate bushy-tree
* plans
* bushy tree plan flag: if true planner will generate bushy-tree
* plans
* ----------------
*/
int BushyPlanFlag = 0; /* default to false -- consider only left-deep trees */
......@@ -162,27 +162,27 @@ int XfuncMode = 0;
/*
* ----------------
* Note: _exec_repeat_ defaults to 1 but may be changed
* by a DEBUG command. If you set this to a large
* number N, run a single query, and then set it
* back to 1 and run N queries, you can get an idea
* of how much time is being spent in the parser and
* planner b/c in the first case this overhead only
* happens once. -cim 6/9/91
* by a DEBUG command. If you set this to a large
* number N, run a single query, and then set it
* back to 1 and run N queries, you can get an idea
* of how much time is being spent in the parser and
* planner b/c in the first case this overhead only
* happens once. -cim 6/9/91
* ----------------
*/
int _exec_repeat_ = 1;
/* ----------------------------------------------------------------
* decls for routines only used in this file
* decls for routines only used in this file
* ----------------------------------------------------------------
*/
static char InteractiveBackend(char *inBuf);
static char SocketBackend(char *inBuf, int multiplexedBackend);
static char ReadCommand(char *inBuf, int multiplexedBackend);
static char SocketBackend(char *inBuf, bool multiplexedBackend);
static char ReadCommand(char *inBuf, bool multiplexedBackend);
/* ----------------------------------------------------------------
* routines to obtain user input
* routines to obtain user input
* ----------------------------------------------------------------
*/
......@@ -195,82 +195,82 @@ static char ReadCommand(char *inBuf, int multiplexedBackend);
static char
InteractiveBackend(char *inBuf)
{
char *stuff = inBuf; /* current place in input buffer */
int c; /* character read from getc() */
bool end = false; /* end-of-input flag */
bool backslashSeen = false; /* have we seen a \ ? */
char *stuff = inBuf; /* current place in input buffer */
int c; /* character read from getc() */
bool end = false; /* end-of-input flag */
bool backslashSeen = false; /* have we seen a \ ? */
/* ----------------
* display a prompt and obtain input from the user
* display a prompt and obtain input from the user
* ----------------
*/
printf("> ");
for (;;) {
if (UseNewLine) {
/* ----------------
* if we are using \n as a delimiter, then read
* characters until the \n.
* ----------------
*/
while ( (c = getc(stdin)) != EOF) {
if (c == '\n') {
if (backslashSeen) {
stuff--;
continue;
} else {
/* keep the newline character */
*stuff++ = '\n';
*stuff++ = '\0';
break;
}
} else if (c == '\\')
backslashSeen = true;
else
backslashSeen = false;
*stuff++ = (char)c;
}
if (c == EOF)
end = true;
} else {
/* ----------------
* otherwise read characters until EOF.
* ----------------
*/
while ( (c = getc(stdin)) != EOF )
*stuff++ = (char)c;
if ( stuff == inBuf )
end = true;
}
if (end) {
if (!Quiet) puts("EOF");
IsEmptyQuery = true;
exitpg(0);
}
/* ----------------
* otherwise we have a user query so process it.
* ----------------
*/
break;
if (UseNewLine) {
/* ----------------
* if we are using \n as a delimiter, then read
* characters until the \n.
* ----------------
*/
while ( (c = getc(stdin)) != EOF) {
if (c == '\n') {
if (backslashSeen) {
stuff--;
continue;
} else {
/* keep the newline character */
*stuff++ = '\n';
*stuff++ = '\0';
break;
}
} else if (c == '\\')
backslashSeen = true;
else
backslashSeen = false;
*stuff++ = (char)c;
}
if (c == EOF)
end = true;
} else {
/* ----------------
* otherwise read characters until EOF.
* ----------------
*/
while ( (c = getc(stdin)) != EOF )
*stuff++ = (char)c;
if ( stuff == inBuf )
end = true;
}
if (end) {
if (!Quiet) puts("EOF");
IsEmptyQuery = true;
exitpg(0);
}
/* ----------------
* otherwise we have a user query so process it.
* ----------------
*/
break;
}
/* ----------------
* if the query echo flag was given, print the query..
* if the query echo flag was given, print the query..
* ----------------
*/
if (EchoQuery)
printf("query is: %s\n", inBuf);
printf("query is: %s\n", inBuf);
return('Q');
}
/* ----------------
* SocketBackend() Is called for frontend-backend connections
* SocketBackend() Is called for frontend-backend connections
*
* If the input is a query (case 'Q') then the string entered by
* the user is placed in its parameter inBuf.
......@@ -282,91 +282,91 @@ InteractiveBackend(char *inBuf)
*/
static char
SocketBackend(char *inBuf, int multiplexedBackend)
SocketBackend(char *inBuf, bool multiplexedBackend)
{
char qtype[2];
char result = '\0';
/* ----------------
* get input from the frontend
* get input from the frontend
* ----------------
*/
(void) strcpy(qtype, "?");
if (pq_getnchar(qtype,0,1) == EOF) {
/* ------------
* when front-end applications quits/dies
* ------------
*/
if (multiplexedBackend) {
return 'X';
}
else
exitpg(0);
/* ------------
* when front-end applications quits/dies
* ------------
*/
if (multiplexedBackend) {
return 'X';
}
else
exitpg(0);
}
switch(*qtype) {
/* ----------------
* 'Q': user entered a query
* ----------------
*/
/* ----------------
* 'Q': user entered a query
* ----------------
*/
case 'Q':
pq_getstr(inBuf, MAX_PARSE_BUFFER);
result = 'Q';
break;
/* ----------------
* 'F': calling user/system functions
* ----------------
*/
case 'F':
pq_getstr(inBuf, MAX_PARSE_BUFFER);/* ignore the rest of the line */
pq_getstr(inBuf, MAX_PARSE_BUFFER);
result = 'Q';
break;
/* ----------------
* 'F': calling user/system functions
* ----------------
*/
case 'F':
pq_getstr(inBuf, MAX_PARSE_BUFFER);/* ignore the rest of the line */
result = 'F';
break;
/* ----------------
* 'X': frontend is exiting
* ----------------
*/
/* ----------------
* 'X': frontend is exiting
* ----------------
*/
case 'X':
result = 'X';
break;
/* ----------------
* otherwise we got garbage from the frontend.
*
* XXX are we certain that we want to do an elog(FATAL) here?
* -cim 1/24/90
* ----------------
*/
result = 'X';
break;
/* ----------------
* otherwise we got garbage from the frontend.
*
* XXX are we certain that we want to do an elog(FATAL) here?
* -cim 1/24/90
* ----------------
*/
default:
elog(FATAL, "Socket command type %c unknown\n", *qtype);
break;
elog(FATAL, "Socket command type %c unknown\n", *qtype);
break;
}
return result;
}
/* ----------------
* ReadCommand reads a command from either the frontend or
* standard input, places it in inBuf, and returns a char
* representing whether the string is a 'Q'uery or a 'F'astpath
* call.
* ReadCommand reads a command from either the frontend or
* standard input, places it in inBuf, and returns a char
* representing whether the string is a 'Q'uery or a 'F'astpath
* call.
* ----------------
*/
static char
ReadCommand(char *inBuf, int multiplexedBackend)
ReadCommand(char *inBuf, bool multiplexedBackend)
{
if (IsUnderPostmaster || multiplexedBackend)
return SocketBackend(inBuf, multiplexedBackend);
return SocketBackend(inBuf, multiplexedBackend);
else
return InteractiveBackend(inBuf);
return InteractiveBackend(inBuf);
}
List *
pg_plan(char *query_string, /* string to execute */
Oid *typev, /* argument types */
int nargs, /* number of arguments */
QueryTreeList **queryListP, /* pointer to the parse trees */
CommandDest dest) /* where results should go */
pg_plan(char *query_string, /* string to execute */
Oid *typev, /* argument types */
int nargs, /* number of arguments */
QueryTreeList **queryListP, /* pointer to the parse trees */
CommandDest dest) /* where results should go */
{
QueryTreeList *querytree_list;
int i;
......@@ -378,17 +378,17 @@ pg_plan(char *query_string, /* string to execute */
Query* querytree;
/* ----------------
* (1) parse the request string into a list of parse trees
* (1) parse the request string into a list of parse trees
* ----------------
*/
if (ShowParserStats)
ResetUsage();
ResetUsage();
querytree_list = parser(query_string, typev, nargs);
if (ShowParserStats) {
fprintf(stderr, "! Parser Stats:\n");
ShowUsage();
fprintf(stderr, "! Parser Stats:\n");
ShowUsage();
}
/* new_list holds the rewritten queries */
......@@ -397,46 +397,46 @@ pg_plan(char *query_string, /* string to execute */
new_list->qtrees = (Query**)malloc(new_list->len * sizeof(Query*));
/* ----------------
* (2) rewrite the queries, as necessary
* (2) rewrite the queries, as necessary
* ----------------
*/
j = 0; /* counter for the new_list, new_list can be longer than
old list as a result of rewrites */
old list as a result of rewrites */
for (i=0;i<querytree_list->len;i++) {
querytree = querytree_list->qtrees[i];
/* don't rewrite utilites */
if (querytree->commandType == CMD_UTILITY) {
new_list->qtrees[j++] = querytree;
continue;
}
if ( DebugPrintParse == true ) {
printf("\ninput string is \"%s\"\n",query_string);
printf("\n---- \tparser outputs :\n");
nodeDisplay(querytree);
printf("\n");
}
/* rewrite queries (retrieve, append, delete, replace) */
rewritten = QueryRewrite(querytree);
if (rewritten != NULL) {
int len, k;
len = length(rewritten);
if (len == 1)
new_list->qtrees[j++] = (Query*)lfirst(rewritten);
else {
/* rewritten queries are longer than original query */
/* grow the new_list to accommodate */
new_list->len += len - 1; /* - 1 because originally we
allocated one space for the query */
new_list->qtrees = realloc(new_list->qtrees,
new_list->len * sizeof(Query*));
for (k=0;k<len;k++)
new_list->qtrees[j++] = (Query*)nth(k, rewritten);
}
}
/* don't rewrite utilites */
if (querytree->commandType == CMD_UTILITY) {
new_list->qtrees[j++] = querytree;
continue;
}
if ( DebugPrintParse == true ) {
printf("\ninput string is \"%s\"\n",query_string);
printf("\n---- \tparser outputs :\n");
nodeDisplay(querytree);
printf("\n");
}
/* rewrite queries (retrieve, append, delete, replace) */
rewritten = QueryRewrite(querytree);
if (rewritten != NULL) {
int len, k;
len = length(rewritten);
if (len == 1)
new_list->qtrees[j++] = (Query*)lfirst(rewritten);
else {
/* rewritten queries are longer than original query */
/* grow the new_list to accommodate */
new_list->len += len - 1; /* - 1 because originally we
allocated one space for the query */
new_list->qtrees = realloc(new_list->qtrees,
new_list->len * sizeof(Query*));
for (k=0;k<len;k++)
new_list->qtrees[j++] = (Query*)nth(k, rewritten);
}
}
}
/* we're done with the original lists, free it */
......@@ -455,83 +455,83 @@ pg_plan(char *query_string, /* string to execute */
* ----------------
*/
for (i=0;i<querytree_list->len;i++) {
List *l;
List *rt = NULL;
querytree = querytree_list->qtrees[i];
/* ----------------
* utilities don't have time ranges
* ----------------
*/
if (querytree->commandType == CMD_UTILITY)
continue;
rt = querytree->rtable;
foreach (l, rt) {
RangeTblEntry *rte = lfirst(l);
TimeRange *timequal = rte->timeRange;
if (timequal) {
int timecode = (rte->timeRange->endDate == NULL)? 0 : 1;
rte->timeQual = makeTimeRange(rte->timeRange->startDate,
rte->timeRange->endDate,
timecode);
}else {
rte->timeQual = NULL;
}
}
/* check for archived relations */
plan_archive(rt);
List *l;
List *rt = NULL;
querytree = querytree_list->qtrees[i];
/* ----------------
* utilities don't have time ranges
* ----------------
*/
if (querytree->commandType == CMD_UTILITY)
continue;
rt = querytree->rtable;
foreach (l, rt) {
RangeTblEntry *rte = lfirst(l);
TimeRange *timequal = rte->timeRange;
if (timequal) {
int timecode = (rte->timeRange->endDate == NULL)? 0 : 1;
rte->timeQual = makeTimeRange(rte->timeRange->startDate,
rte->timeRange->endDate,
timecode);
}else {
rte->timeQual = NULL;
}
}
/* check for archived relations */
plan_archive(rt);
}
if (DebugPrintRewrittenParsetree == true) {
printf("\n=================\n");
printf(" After Rewriting\n");
printf("=================\n");
for (i=0; i<querytree_list->len; i++) {
print(querytree_list->qtrees[i]);
printf("\n");
}
printf("\n=================\n");
printf(" After Rewriting\n");
printf("=================\n");
for (i=0; i<querytree_list->len; i++) {
print(querytree_list->qtrees[i]);
printf("\n");
}
}
for (i=0; i<querytree_list->len;i++) {
querytree = querytree_list->qtrees[i];
/*
* For each query that isn't a utility invocation,
* generate a plan.
*/
if (querytree->commandType != CMD_UTILITY) {
if (IsAbortedTransactionBlockState()) {
/* ----------------
* the EndCommand() stuff is to tell the frontend
* that the command ended. -cim 6/1/90
* ----------------
*/
char *tag = "*ABORT STATE*";
EndCommand(tag, dest);
elog(NOTICE, "(transaction aborted): %s",
"queries ignored until END");
*queryListP = (QueryTreeList*)NULL;
return (List*)NULL;
}
if (ShowPlannerStats) ResetUsage();
plan = planner(querytree);
if (ShowPlannerStats) {
fprintf(stderr, "! Planner Stats:\n");
ShowUsage();
}
plan_list = lappend(plan_list, plan);
/*
* For each query that isn't a utility invocation,
* generate a plan.
*/
if (querytree->commandType != CMD_UTILITY) {
if (IsAbortedTransactionBlockState()) {
/* ----------------
* the EndCommand() stuff is to tell the frontend
* that the command ended. -cim 6/1/90
* ----------------
*/
char *tag = "*ABORT STATE*";
EndCommand(tag, dest);
elog(NOTICE, "(transaction aborted): %s",
"queries ignored until END");
*queryListP = (QueryTreeList*)NULL;
return (List*)NULL;
}
if (ShowPlannerStats) ResetUsage();
plan = planner(querytree);
if (ShowPlannerStats) {
fprintf(stderr, "! Planner Stats:\n");
ShowUsage();
}
plan_list = lappend(plan_list, plan);
#ifdef INDEXSCAN_PATCH
/* ----------------
* Print plan if debugging.
......@@ -539,44 +539,44 @@ pg_plan(char *query_string, /* string to execute */
* also for queries in functions. DZ - 27-8-1996
* ----------------
*/
if ( DebugPrintPlan == true ) {
printf("\nPlan is :\n");
nodeDisplay(plan);
printf("\n");
}
if ( DebugPrintPlan == true ) {
printf("\nPlan is :\n");
nodeDisplay(plan);
printf("\n");
}
#endif
}
}
#ifdef FUNC_UTIL_PATCH
/*
* If the command is an utility append a null plan. This is
* needed to keep the plan_list aligned with the querytree_list
* or the function executor will crash. DZ - 30-8-1996
*/
else {
plan_list = lappend(plan_list, NULL);
}
/*
* If the command is an utility append a null plan. This is
* needed to keep the plan_list aligned with the querytree_list
* or the function executor will crash. DZ - 30-8-1996
*/
else {
plan_list = lappend(plan_list, NULL);
}
#endif
}
if (queryListP)
*queryListP = querytree_list;
*queryListP = querytree_list;
return (plan_list);
}
/* ----------------------------------------------------------------
* pg_eval()
*
* Takes a querystring, runs the parser/utilities or
* parser/planner/executor over it as necessary
* Begin Transaction Should have been called before this
* and CommitTransaction After this is called
* This is strictly because we do not allow for nested xactions.
* pg_eval()
*
* Takes a querystring, runs the parser/utilities or
* parser/planner/executor over it as necessary
* Begin Transaction Should have been called before this
* and CommitTransaction After this is called
* This is strictly because we do not allow for nested xactions.
*
* NON-OBVIOUS-RESTRICTIONS
* this function _MUST_ allocate a new "parsetree" each time,
* since it may be stored in a named portal and should not
* change its value.
* NON-OBVIOUS-RESTRICTIONS
* this function _MUST_ allocate a new "parsetree" each time,
* since it may be stored in a named portal and should not
* change its value.
*
* ----------------------------------------------------------------
*/
......@@ -589,10 +589,10 @@ pg_eval(char *query_string, char **argv, Oid *typev, int nargs)
void
pg_eval_dest(char *query_string, /* string to execute */
char **argv, /* arguments */
Oid *typev, /* argument types */
int nargs, /* number of arguments */
CommandDest dest) /* where results should go */
char **argv, /* arguments */
Oid *typev, /* argument types */
int nargs, /* number of arguments */
CommandDest dest) /* where results should go */
{
List *plan_list;
Plan *plan;
......@@ -605,87 +605,87 @@ pg_eval_dest(char *query_string, /* string to execute */
/* pg_plan could have failed */
if (querytree_list == NULL)
return;
return;
for (i=0;i<querytree_list->len;i++) {
querytree = querytree_list->qtrees[i];
querytree = querytree_list->qtrees[i];
#ifdef FUNC_UTIL_PATCH
/*
* Advance on the plan_list in every case. Now the plan_list
* has the same length of the querytree_list. DZ - 30-8-1996
*/
plan = (Plan *) lfirst(plan_list);
plan_list = lnext(plan_list);
/*
* Advance on the plan_list in every case. Now the plan_list
* has the same length of the querytree_list. DZ - 30-8-1996
*/
plan = (Plan *) lfirst(plan_list);
plan_list = lnext(plan_list);
#endif
if (querytree->commandType == CMD_UTILITY) {
/* ----------------
* process utility functions (create, destroy, etc..)
*
* Note: we do not check for the transaction aborted state
* because that is done in ProcessUtility.
* ----------------
*/
if (! Quiet) {
time(&tim);
printf("\tProcessUtility() at %s\n", ctime(&tim));
}
ProcessUtility(querytree->utilityStmt, dest);
} else {
if (querytree->commandType == CMD_UTILITY) {
/* ----------------
* process utility functions (create, destroy, etc..)
*
* Note: we do not check for the transaction aborted state
* because that is done in ProcessUtility.
* ----------------
*/
if (! Quiet) {
time(&tim);
printf("\tProcessUtility() at %s\n", ctime(&tim));
}
ProcessUtility(querytree->utilityStmt, dest);
} else {
#ifndef FUNC_UTIL_PATCH
/*
* Moved before the if. DZ - 30-8-1996
*/
plan = (Plan *) lfirst(plan_list);
plan_list = lnext(plan_list);
/*
* Moved before the if. DZ - 30-8-1996
*/
plan = (Plan *) lfirst(plan_list);
plan_list = lnext(plan_list);
#endif
#ifdef INDEXSCAN_PATCH
/*
* Print moved in pg_plan. DZ - 27-8-1996
*/
/*
* Print moved in pg_plan. DZ - 27-8-1996
*/
#else
/* ----------------
* print plan if debugging
* ----------------
*/
if ( DebugPrintPlan == true ) {
printf("\nPlan is :\n");
nodeDisplay(plan);
printf("\n");
}
/* ----------------
* print plan if debugging
* ----------------
*/
if ( DebugPrintPlan == true ) {
printf("\nPlan is :\n");
nodeDisplay(plan);
printf("\n");
}
#endif
/* ----------------
* execute the plan
*
*/
if (ShowExecutorStats)
ResetUsage();
for (j = 0; j < _exec_repeat_; j++) {
if (! Quiet) {
time(&tim);
printf("\tProcessQuery() at %s\n", ctime(&tim));
}
ProcessQuery(querytree, plan, argv, typev, nargs, dest);
}
if (ShowExecutorStats) {
fprintf(stderr, "! Executor Stats:\n");
ShowUsage();
}
}
/*
* In a query block, we want to increment the command counter
* between queries so that the effects of early queries are
* visible to subsequent ones.
*/
if (querytree_list)
CommandCounterIncrement();
/* ----------------
* execute the plan
*
*/
if (ShowExecutorStats)
ResetUsage();
for (j = 0; j < _exec_repeat_; j++) {
if (! Quiet) {
time(&tim);
printf("\tProcessQuery() at %s\n", ctime(&tim));
}
ProcessQuery(querytree, plan, argv, typev, nargs, dest);
}
if (ShowExecutorStats) {
fprintf(stderr, "! Executor Stats:\n");
ShowUsage();
}
}
/*
* In a query block, we want to increment the command counter
* between queries so that the effects of early queries are
* visible to subsequent ones.
*/
if (querytree_list)
CommandCounterIncrement();
}
free(querytree_list->qtrees);
......@@ -693,15 +693,15 @@ pg_eval_dest(char *query_string, /* string to execute */
}
/* --------------------------------
* signal handler routines used in PostgresMain()
* signal handler routines used in PostgresMain()
*
* handle_warn() is used to catch kill(getpid(),1) which
* occurs when elog(WARN) is called.
* handle_warn() is used to catch kill(getpid(),1) which
* occurs when elog(WARN) is called.
*
* quickdie() occurs when signalled by the postmaster, some backend
* has bought the farm we need to stop what we're doing and exit.
*
* die() preforms an orderly cleanup via ExitPostgres()
* die() preforms an orderly cleanup via ExitPostgres()
* --------------------------------
*/
......@@ -747,8 +747,8 @@ her exceeded legal ranges or was a divide by zero");
static void usage(char* progname)
{
fprintf(stderr,
"Usage: %s [-B nbufs] [-d lvl] ] [-f plantype] \t[-m portno] [\t -o filename]\n",
progname);
"Usage: %s [-B nbufs] [-d lvl] ] [-f plantype] \t[-m portno] [\t -o filename]\n",
progname);
fprintf(stderr,"\t[-P portno] [-t tracetype] [-x opttype] [-bCEiLFNopQSs] [dbname]\n");
fprintf(stderr, " b: consider bushy plan trees during optimization\n");
fprintf(stderr, " B: set number of buffers in buffer pool\n");
......@@ -774,8 +774,8 @@ static void usage(char* progname)
}
/* ----------------------------------------------------------------
* PostgresMain
* postgres main loop
* PostgresMain
* postgres main loop
* all backends, interactive or otherwise start here
* ----------------------------------------------------------------
*/
......@@ -783,10 +783,10 @@ int
PostgresMain(int argc, char *argv[])
{
int flagC;
int flagQ;
int flagS;
int flagE;
int flag;
int flagQ;
int flagS;
int flagE;
int flag;
char *DBName = NULL;
int errs = 0;
......@@ -795,7 +795,7 @@ PostgresMain(int argc, char *argv[])
char parser_input[MAX_PARSE_BUFFER];
char *userName;
int multiplexedBackend = 0;
bool multiplexedBackend;
char* hostName; /* the host name of the backend server */
char hostbuf[MAXHOSTNAMELEN];
int serverSock;
......@@ -814,12 +814,12 @@ PostgresMain(int argc, char *argv[])
WSADATA WSAData;
#endif /* WIN32 */
extern int optind;
extern char *optarg;
extern int optind;
extern char *optarg;
extern short DebugLvl;
/* ----------------
* register signal handlers.
* register signal handlers.
* ----------------
*/
signal(SIGINT, die);
......@@ -834,14 +834,15 @@ PostgresMain(int argc, char *argv[])
#endif /* WIN32 */
/* --------------------
* initialize globals
* initialize globals
* -------------------
*/
InitGlobals();
MasterPid = getpid();
DataDir = GetPGData();
/* ----------------
* parse command line arguments
* parse command line arguments
* ----------------
*/
flagC = flagQ = flagS = flagE = ShowStats = 0;
......@@ -850,58 +851,60 @@ PostgresMain(int argc, char *argv[])
/* get hostname is either the environment variable PGHOST
or 'localhost' */
if (!(hostName = getenv("PGHOST"))) {
if (gethostname(hostbuf, MAXHOSTNAMELEN) < 0)
(void) strcpy(hostbuf, "localhost");
hostName = hostbuf;
if (gethostname(hostbuf, MAXHOSTNAMELEN) < 0)
(void) strcpy(hostbuf, "localhost");
hostName = hostbuf;
}
while ((flag = getopt(argc, argv, "B:bCd:Ef:iLm:MNo:P:pQSst:x:F")) != EOF)
switch (flag) {
case 'b':
/* ----------------
* set BushyPlanFlag to true.
* ----------------
*/
BushyPlanFlag = 1;
break;
case 'B':
/* ----------------
* specify the size of buffer pool
* ----------------
*/
NBuffers = atoi(optarg);
break;
case 'C':
/* ----------------
* don't print version string (don't know why this is 'C' --mao)
* ----------------
*/
flagC = 1;
break;
/* ----------------
* -debug mode
* ----------------
*/
case 'd':
/* DebugMode = true; */
flagQ = 0;
DebugPrintPlan = true;
DebugPrintParse = true;
DebugPrintRewrittenParsetree = true;
DebugLvl = (short)atoi(optarg);
break;
case 'E':
/* ----------------
* E - echo the query the user entered
* ----------------
*/
flagE = 1;
break;
DataDir = getenv("PGDATA"); /* default */
multiplexedBackend = false; /* default */
while ((flag = getopt(argc, argv, "B:bCD:d:Ef:iLm:MNo:P:pQSst:x:F"))
!= EOF)
switch (flag) {
case 'b':
/* ----------------
* set BushyPlanFlag to true.
* ----------------
*/
BushyPlanFlag = 1;
break;
case 'B':
/* ----------------
* specify the size of buffer pool
* ----------------
*/
NBuffers = atoi(optarg);
break;
case 'C':
/* ----------------
* don't print version string (don't know why this is 'C' --mao)
* ----------------
*/
flagC = 1;
break;
case 'D': /* PGDATA directory */
DataDir = optarg;
case 'd': /* debug level */
flagQ = 0;
DebugPrintPlan = true;
DebugPrintParse = true;
DebugPrintRewrittenParsetree = true;
DebugLvl = (short)atoi(optarg);
break;
case 'E':
/* ----------------
* E - echo the query the user entered
* ----------------
*/
flagE = 1;
break;
case 'F':
/* --------------------
* turn off fsync
......@@ -910,52 +913,52 @@ PostgresMain(int argc, char *argv[])
fsyncOff = 1;
break;
case 'f':
/* -----------------
* f - forbid generation of certain plans
* -----------------
*/
switch (optarg[0]) {
case 's': /* seqscan */
case 'f':
/* -----------------
* f - forbid generation of certain plans
* -----------------
*/
switch (optarg[0]) {
case 's': /* seqscan */
_enable_seqscan_ = false;
break;
case 'i': /* indexscan */
case 'i': /* indexscan */
_enable_indexscan_ = false;
break;
case 'n': /* nestloop */
case 'n': /* nestloop */
_enable_nestloop_ = false;
break;
case 'm': /* mergejoin */
case 'm': /* mergejoin */
_enable_mergesort_ = false;
break;
case 'h': /* hashjoin */
case 'h': /* hashjoin */
_enable_hashjoin_ = false;
break;
default:
default:
errs++;
}
break;
case 'i':
dontExecute = 1;
break;
case 'L':
/* --------------------
* turn off locking
* --------------------
*/
lockingOff = 1;
break;
case 'm':
/* start up a listening backend that can respond to
multiple front-ends. (Note: all the front-end connections
are still connected to a single-threaded backend. Requests
are FCFS. Everything is in one transaction
*/
multiplexedBackend = 1;
serverPortnum = atoi(optarg);
}
break;
case 'i':
dontExecute = 1;
break;
case 'L':
/* --------------------
* turn off locking
* --------------------
*/
lockingOff = 1;
break;
case 'm':
/* start up a listening backend that can respond to
multiple front-ends. (Note: all the front-end connections
are still connected to a single-threaded backend. Requests
are FCFS. Everything is in one transaction
*/
multiplexedBackend = true;
serverPortnum = atoi(optarg);
#ifdef WIN32
/* There was no postmaster started so the shared memory
** for the shared memory table hasn't been allocated so
......@@ -963,159 +966,168 @@ PostgresMain(int argc, char *argv[])
*/
_nt_init();
#endif /* WIN32 */
break;
case 'M':
exit(PostmasterMain(argc, argv));
break;
case 'N':
/* ----------------
* N - Don't use newline as a query delimiter
* ----------------
*/
UseNewLine = 0;
break;
case 'o':
/* ----------------
* o - send output (stdout and stderr) to the given file
* ----------------
*/
(void) strncpy(OutputFileName, optarg, MAXPGPATH);
break;
case 'p': /* started by postmaster */
/* ----------------
* p - special flag passed if backend was forked
* by a postmaster.
* ----------------
*/
IsUnderPostmaster = true;
break;
case 'P':
/* ----------------
* P - Use the passed file descriptor number as the port
* on which to communicate with the user. This is ONLY
* useful for debugging when fired up by the postmaster.
* ----------------
*/
Portfd = atoi(optarg);
break;
case 'Q':
/* ----------------
* Q - set Quiet mode (reduce debugging output)
* ----------------
*/
flagQ = 1;
break;
case 'S':
/* ----------------
* S - assume stable main memory
* (don't flush all pages at end transaction)
* ----------------
*/
flagS = 1;
SetTransactionFlushEnabled(false);
break;
case 's':
/* ----------------
* s - report usage statistics (timings) after each query
* ----------------
*/
ShowStats = 1;
StatFp = stderr;
break;
case 't':
/* ----------------
* tell postgres to report usage statistics (timings) for
* each query
*
* -tpa[rser] = print stats for parser time of each query
* -tpl[anner] = print stats for planner time of each query
* -te[xecutor] = print stats for executor time of each query
* caution: -s can not be used together with -t.
* ----------------
*/
StatFp = stderr;
switch (optarg[0]) {
case 'p': if (optarg[1] == 'a')
ShowParserStats = 1;
else if (optarg[1] == 'l')
ShowPlannerStats = 1;
else
errs++;
break;
case 'e': ShowExecutorStats = 1; break;
default: errs++; break;
}
break;
case 'x':
break;
case 'M':
exit(PostmasterMain(argc, argv));
break;
case 'N':
/* ----------------
* N - Don't use newline as a query delimiter
* ----------------
*/
UseNewLine = 0;
break;
case 'o':
/* ----------------
* o - send output (stdout and stderr) to the given file
* ----------------
*/
(void) strncpy(OutputFileName, optarg, MAXPGPATH);
break;
case 'p': /* started by postmaster */
/* ----------------
* p - special flag passed if backend was forked
* by a postmaster.
* ----------------
*/
IsUnderPostmaster = true;
break;
case 'P':
/* ----------------
* P - Use the passed file descriptor number as the port
* on which to communicate with the user. This is ONLY
* useful for debugging when fired up by the postmaster.
* ----------------
*/
Portfd = atoi(optarg);
break;
case 'Q':
/* ----------------
* Q - set Quiet mode (reduce debugging output)
* ----------------
*/
flagQ = 1;
break;
case 'S':
/* ----------------
* S - assume stable main memory
* (don't flush all pages at end transaction)
* ----------------
*/
flagS = 1;
SetTransactionFlushEnabled(false);
break;
case 's':
/* ----------------
* s - report usage statistics (timings) after each query
* ----------------
*/
ShowStats = 1;
StatFp = stderr;
break;
case 't':
/* ----------------
* tell postgres to report usage statistics (timings) for
* each query
*
* -tpa[rser] = print stats for parser time of each query
* -tpl[anner] = print stats for planner time of each query
* -te[xecutor] = print stats for executor time of each query
* caution: -s can not be used together with -t.
* ----------------
*/
StatFp = stderr;
switch (optarg[0]) {
case 'p': if (optarg[1] == 'a')
ShowParserStats = 1;
else if (optarg[1] == 'l')
ShowPlannerStats = 1;
else
errs++;
break;
case 'e': ShowExecutorStats = 1; break;
default: errs++; break;
}
break;
case 'x':
#if 0 /* planner/xfunc.h */
/* control joey hellerstein's expensive function optimization */
if (XfuncMode != 0)
{
fprintf(stderr, "only one -x flag is allowed\n");
errs++;
break;
}
if (strcmp(optarg, "off") == 0)
XfuncMode = XFUNC_OFF;
else if (strcmp(optarg, "nor") == 0)
XfuncMode = XFUNC_NOR;
else if (strcmp(optarg, "nopull") == 0)
XfuncMode = XFUNC_NOPULL;
else if (strcmp(optarg, "nopm") == 0)
XfuncMode = XFUNC_NOPM;
else if (strcmp(optarg, "pullall") == 0)
XfuncMode = XFUNC_PULLALL;
else if (strcmp(optarg, "wait") == 0)
XfuncMode = XFUNC_WAIT;
else {
fprintf(stderr, "use -x {off,nor,nopull,nopm,pullall,wait}\n");
errs++;
}
/* control joey hellerstein's expensive function optimization */
if (XfuncMode != 0)
{
fprintf(stderr, "only one -x flag is allowed\n");
errs++;
break;
}
if (strcmp(optarg, "off") == 0)
XfuncMode = XFUNC_OFF;
else if (strcmp(optarg, "nor") == 0)
XfuncMode = XFUNC_NOR;
else if (strcmp(optarg, "nopull") == 0)
XfuncMode = XFUNC_NOPULL;
else if (strcmp(optarg, "nopm") == 0)
XfuncMode = XFUNC_NOPM;
else if (strcmp(optarg, "pullall") == 0)
XfuncMode = XFUNC_PULLALL;
else if (strcmp(optarg, "wait") == 0)
XfuncMode = XFUNC_WAIT;
else {
fprintf(stderr, "use -x {off,nor,nopull,nopm,pullall,wait}\n");
errs++;
}
#endif
break;
default:
/* ----------------
* default: bad command line option
* ----------------
*/
errs++;
}
break;
default:
/* ----------------
* default: bad command line option
* ----------------
*/
errs++;
}
/* ----------------
* get user name and pathname and check command line validity
* get user name and pathname and check command line validity
* ----------------
*/
SetPgUserName();
userName = GetPgUserName();
if (FindBackend(pg_pathname, argv[0]) < 0)
elog(FATAL, "%s: could not locate executable, bailing out...",
argv[0]);
elog(FATAL, "%s: could not locate executable, bailing out...",
argv[0]);
if (errs || argc - optind > 1) {
usage (argv[0]);
exitpg(1);
usage (argv[0]);
exitpg(1);
} else if (argc - optind == 1) {
DBName = argv[optind];
DBName = argv[optind];
} else if ((DBName = userName) == NULL) {
fprintf(stderr, "%s: USER undefined and no database specified\n",
argv[0]);
exitpg(1);
fprintf(stderr, "%s: USER undefined and no database specified\n",
argv[0]);
exitpg(1);
}
if (ShowStats &&
(ShowParserStats || ShowPlannerStats || ShowExecutorStats)) {
fprintf(stderr, "-s can not be used together with -t.\n");
exitpg(1);
(ShowParserStats || ShowPlannerStats || ShowExecutorStats)) {
fprintf(stderr, "-s can not be used together with -t.\n");
exitpg(1);
}
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);
}
Noversion = flagC;
......@@ -1123,52 +1135,52 @@ PostgresMain(int argc, char *argv[])
EchoQuery = flagE;
/* ----------------
* print flags
* print flags
* ----------------
*/
if (! Quiet) {
puts("\t---debug info---");
printf("\tQuiet = %c\n", Quiet ? 't' : 'f');
printf("\tNoversion = %c\n", Noversion ? 't' : 'f');
printf("\tstable = %c\n", flagS ? 't' : 'f');
printf("\ttimings = %c\n", ShowStats ? 't' : 'f');
printf("\tbufsize = %d\n", NBuffers);
printf("\tquery echo = %c\n", EchoQuery ? 't' : 'f');
printf("\tmultiplexed backend? = %c\n", multiplexedBackend ? 't' : 'f');
printf("\tDatabaseName = [%s]\n", DBName);
puts("\t----------------\n");
puts("\t---debug info---");
printf("\tQuiet = %c\n", Quiet ? 't' : 'f');
printf("\tNoversion = %c\n", Noversion ? 't' : 'f');
printf("\tstable = %c\n", flagS ? 't' : 'f');
printf("\ttimings = %c\n", ShowStats ? 't' : 'f');
printf("\tbufsize = %d\n", NBuffers);
printf("\tquery echo = %c\n", EchoQuery ? 't' : 'f');
printf("\tmultiplexed backend? = %c\n", multiplexedBackend ? 't' : 'f');
printf("\tDatabaseName = [%s]\n", DBName);
puts("\t----------------\n");
}
/* ----------------
* initialize portal file descriptors
* initialize portal file descriptors
* ----------------
*/
if (IsUnderPostmaster == true) {
if (Portfd < 0) {
fprintf(stderr,
"Postmaster flag set: no port number specified, use /dev/null\n");
Portfd = open(NULL_DEV, O_RDWR, 0666);
}
pq_init(Portfd);
if (Portfd < 0) {
fprintf(stderr,
"Postmaster flag set: no port number specified, use /dev/null\n");
Portfd = open(NULL_DEV, O_RDWR, 0666);
}
pq_init(Portfd);
}
#ifdef WIN32
if ((status = WSAStartup(MAKEWORD(1,1), &WSAData)) == 0)
(void) printf("%s\nInitializing WinSock: %s\n", WSAData.szDescription, WSAData.szSystemStatus);
(void) printf("%s\nInitializing WinSock: %s\n", WSAData.szDescription, WSAData.szSystemStatus);
else {
fprintf(stderr, "Error initializing WinSock: %d is the err", status);
exit(1);
fprintf(stderr, "Error initializing WinSock: %d is the err", status);
exit(1);
}
#endif /* WIN32 */
if (multiplexedBackend) {
if (serverPortnum == 0 ||
StreamServerPort(hostName, serverPortnum, &serverSock) != STATUS_OK)
{
fprintf(stderr, "Postgres: cannot create stream port %d\n", serverPortnum);
exit(1);
}
StreamServerPort(hostName, serverPortnum, &serverSock) != STATUS_OK)
{
fprintf(stderr, "Postgres: cannot create stream port %d\n", serverPortnum);
exit(1);
}
/*
{
char buf[100];
......@@ -1183,34 +1195,34 @@ PostgresMain(int argc, char *argv[])
frontendList = DLNewList();
/* add the original FrontEnd to the list */
if (IsUnderPostmaster == true) {
FrontEnd *fe = malloc(sizeof(FrontEnd));
FD_SET(Portfd, &basemask);
maxFd = Max(serverSock,Portfd) + 1;
fe->fn_connected = true;
fe->fn_Pfin = Pfin;
fe->fn_Pfout = Pfout;
fe->fn_done = false;
(fe->fn_port).sock = Portfd;
DLAddHead(frontendList, DLNewElem(fe));
numFE++;
FrontEnd *fe = malloc(sizeof(FrontEnd));
FD_SET(Portfd, &basemask);
maxFd = Max(serverSock,Portfd) + 1;
fe->fn_connected = true;
fe->fn_Pfin = Pfin;
fe->fn_Pfout = Pfout;
fe->fn_done = false;
(fe->fn_port).sock = Portfd;
DLAddHead(frontendList, DLNewElem(fe));
numFE++;
} else {
numFE = 1;
maxFd = serverSock + 1;
numFE = 1;
maxFd = serverSock + 1;
}
}
if (IsUnderPostmaster || multiplexedBackend)
whereToSendOutput = Remote;
whereToSendOutput = Remote;
else
whereToSendOutput = Debug;
whereToSendOutput = Debug;
SetProcessingMode(InitProcessing);
/* initialize */
if (! Quiet) {
puts("\tInitPostgres()..");
puts("\tInitPostgres()..");
}
#if WIN32
......@@ -1220,7 +1232,7 @@ PostgresMain(int argc, char *argv[])
InitPostgres(DBName);
/* ----------------
* if an exception is encountered, processing resumes here
* if an exception is encountered, processing resumes here
* so we abort the current transaction and start a new one.
* This must be done after we initialize the slave backends
* so that the slaves signal the master to abort the transaction
......@@ -1238,26 +1250,26 @@ PostgresMain(int argc, char *argv[])
#else
if (setjmp(Warn_restart) != 0) {
#endif /* WIN32 */
InWarn = 1;
InWarn = 1;
time(&tim);
if (! Quiet)
printf("\tAbortCurrentTransaction() at %s\n", ctime(&tim));
time(&tim);
if (! Quiet)
printf("\tAbortCurrentTransaction() at %s\n", ctime(&tim));
memset(parser_input, 0, MAX_PARSE_BUFFER);
AbortCurrentTransaction();
memset(parser_input, 0, MAX_PARSE_BUFFER);
AbortCurrentTransaction();
}
InWarn = 0;
/* ----------------
* POSTGRES main processing loop begins here
* POSTGRES main processing loop begins here
* ----------------
*/
if (IsUnderPostmaster == false) {
puts("\nPOSTGRES backend interactive interface");
puts("$Revision: 1.18 $ $Date: 1996/11/11 04:54:51 $");
puts("\nPOSTGRES backend interactive interface");
puts("$Revision: 1.19 $ $Date: 1996/11/14 10:24:07 $");
}
/* ----------------
......@@ -1272,183 +1284,183 @@ PostgresMain(int argc, char *argv[])
for (;;) {
if (multiplexedBackend) {
if (numFE == 0)
break;
memmove((char *) &rmask, (char *) &basemask, sizeof(fd_set));
nSelected = select(maxFd, &rmask,0,0,0);
if (nSelected < 0) {
if (errno == EINTR) continue;
fprintf(stderr,"postgres: multiplexed backend select failed\n");
exitpg(1);
}
if (FD_ISSET(serverSock, &rmask)) {
/* new connection pending on our well-known port's socket */
newFE = (FrontEnd*) malloc (sizeof(FrontEnd));
memset(newFE, 0, sizeof(FrontEnd));
newFE->fn_connected = false;
newFE->fn_done = false;
newPort = &(newFE->fn_port);
if (StreamConnection(serverSock,newPort) != STATUS_OK) {
StreamClose(newPort->sock);
newFd = -1;
}
else {
DLAddHead(frontendList, DLNewElem(newFE));
numFE++;
newFd = newPort->sock;
if (newFd >= maxFd) maxFd = newFd + 1;
FD_SET(newFd, &rmask);
FD_SET(newFd, &basemask);
--nSelected;
FD_CLR(serverSock, &rmask);
}
continue;
} /* if FD_ISSET(serverSock) */
if (numFE == 0)
break;
memmove((char *) &rmask, (char *) &basemask, sizeof(fd_set));
nSelected = select(maxFd, &rmask,0,0,0);
if (nSelected < 0) {
if (errno == EINTR) continue;
fprintf(stderr,"postgres: multiplexed backend select failed\n");
exitpg(1);
}
if (FD_ISSET(serverSock, &rmask)) {
/* new connection pending on our well-known port's socket */
newFE = (FrontEnd*) malloc (sizeof(FrontEnd));
memset(newFE, 0, sizeof(FrontEnd));
newFE->fn_connected = false;
newFE->fn_done = false;
newPort = &(newFE->fn_port);
if (StreamConnection(serverSock,newPort) != STATUS_OK) {
StreamClose(newPort->sock);
newFd = -1;
}
else {
DLAddHead(frontendList, DLNewElem(newFE));
numFE++;
newFd = newPort->sock;
if (newFd >= maxFd) maxFd = newFd + 1;
FD_SET(newFd, &rmask);
FD_SET(newFd, &basemask);
--nSelected;
FD_CLR(serverSock, &rmask);
}
continue;
} /* if FD_ISSET(serverSock) */
/* if we get here, it means that the serverSocket was not the one
selected. Instead, one of the front ends was selected.
find which one */
curr = DLGetHead(frontendList);
while (curr) {
FrontEnd *fe = (FrontEnd*)DLE_VAL(curr);
Port *port = &(fe->fn_port);
/* this is lifted from postmaster.c */
if (FD_ISSET(port->sock, &rmask)) {
if (fe->fn_connected == false) {
/* we have a message from a new frontEnd */
status = PacketReceive(port, &port->buf, NON_BLOCKING);
if (status == STATUS_OK) {
fe->fn_connected = true;
pq_init(port->sock);
fe->fn_Pfin = Pfin;
fe->fn_Pfout = Pfout;
}
else
fprintf(stderr,"Multiplexed backend: error in reading packets from %d\n", port->sock);
selected. Instead, one of the front ends was selected.
find which one */
curr = DLGetHead(frontendList);
while (curr) {
FrontEnd *fe = (FrontEnd*)DLE_VAL(curr);
Port *port = &(fe->fn_port);
/* this is lifted from postmaster.c */
if (FD_ISSET(port->sock, &rmask)) {
if (fe->fn_connected == false) {
/* we have a message from a new frontEnd */
status = PacketReceive(port, &port->buf, NON_BLOCKING);
if (status == STATUS_OK) {
fe->fn_connected = true;
pq_init(port->sock);
fe->fn_Pfin = Pfin;
fe->fn_Pfout = Pfout;
}
else
fprintf(stderr,"Multiplexed backend: error in reading packets from %d\n", port->sock);
}
else /* we have a query from an existing, active FrontEnd */
{
Pfin = fe->fn_Pfin;
Pfout = fe->fn_Pfout;
currentFE = fe;
else /* we have a query from an existing, active FrontEnd */
{
Pfin = fe->fn_Pfin;
Pfout = fe->fn_Pfout;
currentFE = fe;
}
if (fe->fn_done)
{
Dlelem *c = curr;
curr = DLGetSucc(curr);
DLRemove(c);
}
if (fe->fn_done)
{
Dlelem *c = curr;
curr = DLGetSucc(curr);
DLRemove(c);
}
break;
}
else
curr = DLGetSucc(curr);
}
}
else
curr = DLGetSucc(curr);
}
}
/* ----------------
* (1) read a command.
* ----------------
*/
memset(parser_input, 0, MAX_PARSE_BUFFER);
firstchar = ReadCommand(parser_input, multiplexedBackend);
/* process the command */
switch (firstchar) {
/* ----------------
* 'F' indicates a fastpath call.
* XXX HandleFunctionRequest
* ----------------
*/
case 'F':
IsEmptyQuery = false;
/* start an xact for this function invocation */
if (! Quiet) {
time(&tim);
printf("\tStartTransactionCommand() at %s\n", ctime(&tim));
}
StartTransactionCommand();
HandleFunctionRequest();
break;
/* ----------------
* 'Q' indicates a user query
* ----------------
*/
case 'Q':
fflush(stdout);
if ( parser_input[0] == ' ' && parser_input[1] == '\0' ) {
/* ----------------
* if there is nothing in the input buffer, don't bother
* trying to parse and execute anything..
* ----------------
*/
IsEmptyQuery = true;
} else {
/* ----------------
* otherwise, process the input string.
* ----------------
*/
IsEmptyQuery = false;
if (ShowStats)
ResetUsage();
/* start an xact for this query */
if (! Quiet) {
time(&tim);
printf("\tStartTransactionCommand() at %s\n", ctime(&tim));
}
StartTransactionCommand();
pg_eval(parser_input, (char **) NULL, (Oid *) NULL, 0);
if (ShowStats)
ShowUsage();
}
break;
/* ----------------
* 'X' means that the frontend is closing down the socket
* ----------------
*/
case 'X':
IsEmptyQuery = true;
/* ----------------
* (1) read a command.
* ----------------
*/
memset(parser_input, 0, MAX_PARSE_BUFFER);
firstchar = ReadCommand(parser_input, multiplexedBackend);
/* process the command */
switch (firstchar) {
/* ----------------
* 'F' indicates a fastpath call.
* XXX HandleFunctionRequest
* ----------------
*/
case 'F':
IsEmptyQuery = false;
/* start an xact for this function invocation */
if (! Quiet) {
time(&tim);
printf("\tStartTransactionCommand() at %s\n", ctime(&tim));
}
StartTransactionCommand();
HandleFunctionRequest();
break;
/* ----------------
* 'Q' indicates a user query
* ----------------
*/
case 'Q':
fflush(stdout);
if ( parser_input[0] == ' ' && parser_input[1] == '\0' ) {
/* ----------------
* if there is nothing in the input buffer, don't bother
* trying to parse and execute anything..
* ----------------
*/
IsEmptyQuery = true;
} else {
/* ----------------
* otherwise, process the input string.
* ----------------
*/
IsEmptyQuery = false;
if (ShowStats)
ResetUsage();
/* start an xact for this query */
if (! Quiet) {
time(&tim);
printf("\tStartTransactionCommand() at %s\n", ctime(&tim));
}
StartTransactionCommand();
pg_eval(parser_input, (char **) NULL, (Oid *) NULL, 0);
if (ShowStats)
ShowUsage();
}
break;
/* ----------------
* 'X' means that the frontend is closing down the socket
* ----------------
*/
case 'X':
IsEmptyQuery = true;
if (multiplexedBackend) {
FD_CLR(currentFE->fn_port.sock, &basemask);
currentFE->fn_done = true;
currentFE->fn_done = true;
numFE--;
}
pq_close();
break;
default:
elog(WARN,"unknown frontend message was recieved");
}
/* ----------------
* (3) commit the current transaction
*
* Note: if we had an empty input buffer, then we didn't
* call pg_eval, so we don't bother to commit this transaction.
* ----------------
*/
if (! IsEmptyQuery) {
if (! Quiet) {
time(&tim);
printf("\tCommitTransactionCommand() at %s\n", ctime(&tim));
}
CommitTransactionCommand();
} else {
if (IsUnderPostmaster || multiplexedBackend)
NullCommand(Remote);
}
}
pq_close();
break;
default:
elog(WARN,"unknown frontend message was recieved");
}
/* ----------------
* (3) commit the current transaction
*
* Note: if we had an empty input buffer, then we didn't
* call pg_eval, so we don't bother to commit this transaction.
* ----------------
*/
if (! IsEmptyQuery) {
if (! Quiet) {
time(&tim);
printf("\tCommitTransactionCommand() at %s\n", ctime(&tim));
}
CommitTransactionCommand();
} else {
if (IsUnderPostmaster || multiplexedBackend)
NullCommand(Remote);
}
} /* infinite for-loop */
exitpg(0);
return 1;
......@@ -1487,16 +1499,16 @@ ShowUsage(void)
memmove((char *)&user, (char *)&r.ru_utime, sizeof(user));
memmove((char *)&sys, (char *)&r.ru_stime,sizeof(sys));
if (elapse_t.tv_usec < Save_t.tv_usec) {
elapse_t.tv_sec--;
elapse_t.tv_usec += 1000000;
elapse_t.tv_sec--;
elapse_t.tv_usec += 1000000;
}
if (r.ru_utime.tv_usec < Save_r.ru_utime.tv_usec) {
r.ru_utime.tv_sec--;
r.ru_utime.tv_usec += 1000000;
r.ru_utime.tv_sec--;
r.ru_utime.tv_usec += 1000000;
}
if (r.ru_stime.tv_usec < Save_r.ru_stime.tv_usec) {
r.ru_stime.tv_sec--;
r.ru_stime.tv_usec += 1000000;
r.ru_stime.tv_sec--;
r.ru_stime.tv_usec += 1000000;
}
/*
......
......@@ -7,7 +7,7 @@
*
*
* IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/utils/error/elog.c,v 1.10 1996/11/10 03:03:28 momjian Exp $
* $Header: /cvsroot/pgsql/src/backend/utils/error/elog.c,v 1.11 1996/11/14 10:24:22 bryanh Exp $
*
*-------------------------------------------------------------------------
*/
......@@ -234,7 +234,7 @@ DebugFileOpen(void)
fd = fileno(stderr);
if (fcntl(fd, F_GETFD, 0) < 0) {
sprintf(OutputFileName, "%s/pg.errors.%d",
GetPGData(), (int)getpid());
DataDir, (int)getpid());
fd = open(OutputFileName, O_CREAT|O_APPEND|O_WRONLY, 0666);
}
#endif /* WIN32 */
......
......@@ -4,7 +4,7 @@
# Makefile for utils/init
#
# IDENTIFICATION
# $Header: /cvsroot/pgsql/src/backend/utils/init/Makefile,v 1.3 1996/11/12 06:46:40 bryanh Exp $
# $Header: /cvsroot/pgsql/src/backend/utils/init/Makefile,v 1.4 1996/11/14 10:24:32 bryanh Exp $
#
#-------------------------------------------------------------------------
......@@ -16,9 +16,6 @@ INCLUDE_OPT = -I../.. \
-I../../../include
CFLAGS += $(INCLUDE_OPT)
# The following defines really ought to go in config.h
CFLAGS += -DPOSTGRESDIR='"$(POSTGRESDIR)"' -DPGDATADIR='"$(DATADIR)"' \
-DPOSTPORT='"$(POSTPORT)"'
OBJS = enbl.o findbe.o globals.o miscinit.o postinit.o
......
......@@ -7,7 +7,7 @@
*
*
* IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/utils/init/globals.c,v 1.2 1996/11/06 10:31:54 scrappy Exp $
* $Header: /cvsroot/pgsql/src/backend/utils/init/globals.c,v 1.3 1996/11/14 10:24:38 bryanh Exp $
*
* NOTES
* Globals used all over the place should be declared here and not
......@@ -99,12 +99,3 @@ char *SharedSystemRelationNames[] = {
VariableRelationName,
0
};
/* set up global variables, pointers, etc. */
void InitGlobals()
{
MasterPid = getpid();
DataDir = GetPGData();
}
......@@ -7,7 +7,7 @@
*
*
* IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/utils/init/miscinit.c,v 1.2 1996/11/06 10:31:57 scrappy Exp $
* $Header: /cvsroot/pgsql/src/backend/utils/init/miscinit.c,v 1.3 1996/11/14 10:24:41 bryanh Exp $
*
*-------------------------------------------------------------------------
*/
......@@ -345,35 +345,3 @@ SetUserId()
UserRelationName);
UserId = (Oid) ((Form_pg_user) GETSTRUCT(userTup))->usesysid;
}
/* ----------------
* GetPGHome
*
* Get POSTGRESHOME from environment, or return default.
* ----------------
*/
char *
GetPGHome()
{
#ifdef USE_ENVIRONMENT
char *h;
if ((h = getenv("POSTGRESHOME")) != (char *) NULL)
return (h);
#endif /* USE_ENVIRONMENT */
return (POSTGRESDIR);
}
char *
GetPGData()
{
#ifdef USE_ENVIRONMENT
char *p;
if ((p = getenv("PGDATA")) != (char *) NULL) {
return (p);
}
#endif /* USE_ENVIRONMENT */
return (PGDATADIR);
}
......@@ -7,21 +7,17 @@
#
#
# IDENTIFICATION
# $Header: /cvsroot/pgsql/src/bin/createdb/Attic/Makefile,v 1.2 1996/11/11 13:39:34 bryanh Exp $
# $Header: /cvsroot/pgsql/src/bin/createdb/Attic/Makefile,v 1.3 1996/11/14 10:24:45 bryanh Exp $
#
#-------------------------------------------------------------------------
SRCDIR= ../..
include ../../Makefile.global
SEDSCRIPT= \
-e "s^_fUnKy_BINDIR_sTuFf_^$(BINDIR)^g" \
-e "s^_fUnKy_POSTPORT_sTuFf_^$(POSTPORT)^g"
all: createdb
createdb:
sed $(SEDSCRIPT) <createdb.sh >createdb
createdb: createdb.sh
cp createdb.sh createdb
install: createdb
$(INSTALL) $(INSTL_EXE_OPTS) $< $(DESTDIR)$(BINDIR)/$<
......
......@@ -11,23 +11,10 @@
#
#
# IDENTIFICATION
# $Header: /cvsroot/pgsql/src/bin/createdb/Attic/createdb.sh,v 1.4 1996/09/21 06:24:07 scrappy Exp $
# $Header: /cvsroot/pgsql/src/bin/createdb/Attic/createdb.sh,v 1.5 1996/11/14 10:24:46 bryanh Exp $
#
#-------------------------------------------------------------------------
# ----------------
# Set paths from environment or default values.
# The _fUnKy_..._sTuFf_ gets set when the script is installed
# from the default value for this build.
# Currently the only thing we look for from the environment is
# PGDATA, PGHOST, and PGPORT
#
# ----------------
[ -z "$PGPORT" ] && PGPORT=_fUnKy_POSTPORT_sTuFf_
[ -z "$PGHOST" ] && PGHOST=localhost
BINDIR=_fUnKy_BINDIR_sTuFf_
PATH=$BINDIR:$PATH
CMDNAME=`basename $0`
if [ -z "$USER" ]; then
......@@ -55,12 +42,29 @@ do
shift;
done
AUTHOPT="-a $AUTHSYS"
[ -z "$AUTHSYS" ] && AUTHOPT=""
if [-z "$AUTHSYS" ]; then
AUTHOPT = ""
else
AUTHOPT = "-a $AUTHSYS"
fi
if [-z "$PGHOST" ]; then
PGHOSTOPT = ""
else
PGHOSTOPT = "-h $PGHOST"
fi
psql -tq $AUTHOPT -h $PGHOST -p $PGPORT -c "create database $dbname" template1 || {
if [-z "$PGPORT" ]; then
PGPORTOPT = ""
else
PGPORTOPT = "-p $PGPORT"
fi
psql -tq $AUTHOPT $PGHOSTOPT $PGPORTOPT -c "create database $dbname" template1
if [ $? -ne 0 ]
echo "$CMDNAME: database creation failed on $dbname."
exit 1
}
fi
exit 0
......@@ -7,7 +7,7 @@
#
#
# IDENTIFICATION
# $Header: /cvsroot/pgsql/src/bin/createuser/Attic/Makefile,v 1.2 1996/11/11 13:39:40 bryanh Exp $
# $Header: /cvsroot/pgsql/src/bin/createuser/Attic/Makefile,v 1.3 1996/11/14 10:24:48 bryanh Exp $
#
#-------------------------------------------------------------------------
......@@ -15,14 +15,12 @@ SRCDIR= ../..
include ../../Makefile.global
SEDSCRIPT= \
-e "s^_fUnKy_BINDIR_sTuFf_^$(BINDIR)^g" \
-e "s^_fUnKy_POSTPORT_sTuFf_^$(POSTPORT)^g" \
-e "s^_fUnKy_DASH_N_sTuFf_^$(DASH_N)^g" \
-e "s^_fUnKy_BACKSLASH_C_sTuFf_^$(BACKSLASH_C)^g"
all: createuser
createuser:
createuser: createuser.sh
sed $(SEDSCRIPT) <createuser.sh >createuser
install: createuser
......
......@@ -8,25 +8,12 @@
#
#
# IDENTIFICATION
# $Header: /cvsroot/pgsql/src/bin/createuser/Attic/createuser.sh,v 1.5 1996/10/04 20:29:35 scrappy Exp $
# $Header: /cvsroot/pgsql/src/bin/createuser/Attic/createuser.sh,v 1.6 1996/11/14 10:24:54 bryanh Exp $
#
# Note - this should NOT be setuid.
#
#-------------------------------------------------------------------------
# ----------------
# Set paths from environment or default values.
# The _fUnKy_..._sTuFf_ gets set when the script is installed
# from the default value for this build.
# Currently the only thing we look for from the environment is
# PGDATA, PGHOST, and PGPORT
#
# ----------------
[ -z "$PGPORT" ] && PGPORT=_fUnKy_POSTPORT_sTuFf_
[ -z "$PGHOST" ] && PGHOST=localhost
BINDIR=_fUnKy_BINDIR_sTuFf_
PATH=$BINDIR:$PATH
CMDNAME=`basename $0`
if [ -z "$USER" ]; then
......@@ -52,10 +39,25 @@ do
shift;
done
AUTHOPT="-a $AUTHSYS"
[ -z "$AUTHSYS" ] && AUTHOPT=""
if [-z "$AUTHSYS" ]; then
AUTHOPT = ""
else
AUTHOPT = "-a $AUTHSYS"
fi
if [-z "$PGHOST" ]; then
PGHOSTOPT = ""
else
PGHOSTOPT = "-h $PGHOST"
fi
if [-z "$PGPORT" ]; then
PGPORTOPT = ""
else
PGPORTOPT = "-p $PGPORT"
fi
PARGS="-tq $AUTHOPT -h $PGHOST -p $PGPORT"
PARGS="-tq $AUTHOPT $PGHOSTOPT $PGPORTOPT
#
# generate the first part of the actual monitor command
......
......@@ -7,21 +7,17 @@
#
#
# IDENTIFICATION
# $Header: /cvsroot/pgsql/src/bin/destroydb/Attic/Makefile,v 1.2 1996/11/11 13:39:47 bryanh Exp $
# $Header: /cvsroot/pgsql/src/bin/destroydb/Attic/Makefile,v 1.3 1996/11/14 10:25:10 bryanh Exp $
#
#-------------------------------------------------------------------------
SRCDIR= ../..
include ../../Makefile.global
SEDSCRIPT= \
-e "s^_fUnKy_BINDIR_sTuFf_^$(BINDIR)^g" \
-e "s^_fUnKy_POSTPORT_sTuFf_^$(POSTPORT)^g"
all: destroydb
destroydb:
sed $(SEDSCRIPT) <destroydb.sh >destroydb
destroydb: destroydb.sh
cp destroydb.sh destroydb
install: destroydb
$(INSTALL) $(INSTL_EXE_OPTS) $< $(DESTDIR)$(BINDIR)/$<
......
......@@ -11,23 +11,10 @@
#
#
# IDENTIFICATION
# $Header: /cvsroot/pgsql/src/bin/destroydb/Attic/destroydb.sh,v 1.4 1996/09/21 06:24:24 scrappy Exp $
# $Header: /cvsroot/pgsql/src/bin/destroydb/Attic/destroydb.sh,v 1.5 1996/11/14 10:25:14 bryanh Exp $
#
#-------------------------------------------------------------------------
# ----------------
# Set paths from environment or default values.
# The _fUnKy_..._sTuFf_ gets set when the script is installed
# from the default value for this build.
# Currently the only thing we look for from the environment is
# PGDATA, PGHOST, and PGPORT
#
# ----------------
[ -z "$PGPORT" ] && PGPORT=_fUnKy_POSTPORT_sTuFf_
[ -z "$PGHOST" ] && PGHOST=localhost
BINDIR=_fUnKy_BINDIR_sTuFf_
PATH=$BINDIR:$PATH
CMDNAME=`basename $0`
if [ -z "$USER" ]; then
......@@ -55,10 +42,25 @@ do
shift;
done
AUTHOPT="-a $AUTHSYS"
[ -z "$AUTHSYS" ] && AUTHOPT=""
if [-z "$AUTHSYS" ]; then
AUTHOPT = ""
else
AUTHOPT = "-a $AUTHSYS"
fi
if [-z "$PGHOST" ]; then
PGHOSTOPT = ""
else
PGHOSTOPT = "-h $PGHOST"
fi
if [-z "$PGPORT" ]; then
PGPORTOPT = ""
else
PGPORTOPT = "-p $PGPORT"
fi
psql -tq -h $PGHOST -p $PGPORT -c "drop database $dbname" template1
psql -tq $AUTHOPT $PGHOSTOPT $PGPORTOPT -c "drop database $dbname" template1
if [ $? -ne 0 ]
then
......
......@@ -7,7 +7,7 @@
#
#
# IDENTIFICATION
# $Header: /cvsroot/pgsql/src/bin/destroyuser/Attic/Makefile,v 1.2 1996/11/11 13:40:04 bryanh Exp $
# $Header: /cvsroot/pgsql/src/bin/destroyuser/Attic/Makefile,v 1.3 1996/11/14 10:25:16 bryanh Exp $
#
#-------------------------------------------------------------------------
......@@ -15,14 +15,12 @@ SRCDIR= ../..
include ../../Makefile.global
SEDSCRIPT= \
-e "s^_fUnKy_BINDIR_sTuFf_^$(BINDIR)^g" \
-e "s^_fUnKy_POSTPORT_sTuFf_^$(POSTPORT)^g" \
-e "s^_fUnKy_DASH_N_sTuFf_^$(DASH_N)^g" \
-e "s^_fUnKy_BACKSLASH_C_sTuFf_^$(BACKSLASH_C)^g"
all: destroyuser
destroyuser:
destroyuser: destroyuser.sh
sed $(SEDSCRIPT) <destroyuser.sh >destroyuser
install: destroyuser
......
......@@ -8,25 +8,12 @@
#
#
# IDENTIFICATION
# $Header: /cvsroot/pgsql/src/bin/destroyuser/Attic/destroyuser.sh,v 1.4 1996/09/21 06:24:31 scrappy Exp $
# $Header: /cvsroot/pgsql/src/bin/destroyuser/Attic/destroyuser.sh,v 1.5 1996/11/14 10:25:19 bryanh Exp $
#
# Note - this should NOT be setuid.
#
#-------------------------------------------------------------------------
# ----------------
# Set paths from environment or default values.
# The _fUnKy_..._sTuFf_ gets set when the script is installed
# from the default value for this build.
# Currently the only thing we look for from the environment is
# PGDATA, PGHOST, and PGPORT
#
# ----------------
[ -z "$PGPORT" ] && PGPORT=_fUnKy_POSTPORT_sTuFf_
[ -z "$PGHOST" ] && PGHOST=localhost
BINDIR=_fUnKy_BINDIR_sTuFf_
PATH=$BINDIR:$PATH
CMDNAME=`basename $0`
if [ -z "$USER" ]; then
......@@ -52,10 +39,25 @@ do
shift;
done
AUTHOPT="-a $AUTHSYS"
[ -z "$AUTHSYS" ] && AUTHOPT=""
if [-z "$AUTHSYS" ]; then
AUTHOPT = ""
else
AUTHOPT = "-a $AUTHSYS"
fi
if [-z "$PGHOST" ]; then
PGHOSTOPT = ""
else
PGHOSTOPT = "-h $PGHOST"
fi
if [-z "$PGPORT" ]; then
PGPORTOPT = ""
else
PGPORTOPT = "-p $PGPORT"
fi
PARGS="-tq $AUTHOPT -p $PGPORT -h $PGHOST"
PARGS="-tq $AUTHOPT $PGHOSTOPT $PGPORTOPT
#
# generate the first part of the actual monitor command
......
......@@ -7,7 +7,7 @@
#
#
# IDENTIFICATION
# $Header: /cvsroot/pgsql/src/bin/initdb/Makefile,v 1.2 1996/11/11 13:40:25 bryanh Exp $
# $Header: /cvsroot/pgsql/src/bin/initdb/Makefile,v 1.3 1996/11/14 10:25:22 bryanh Exp $
#
#-------------------------------------------------------------------------
......@@ -15,16 +15,12 @@ SRCDIR= ../..
include ../../Makefile.global
SEDSCRIPT= \
-e "s^_fUnKy_BINDIR_sTuFf_^$(BINDIR)^g" \
-e "s^_fUnKy_LIBDIR_sTuFf_^$(LIBDIR)^g" \
-e "s^_fUnKy_DATADIR_sTuFf_^$(DATADIR)^g" \
-e "s^_fUnKy_NAMEDATALEN_sTuFf_^$(NAMEDATALEN)^g" \
-e "s^_fUnKy_OIDNAMELEN_sTuFf_^$(OIDNAMELEN)^g" \
-e "s^_fUnKy_POSTPORT_sTuFf_^$(POSTPORT)^g"
-e "s^_fUnKy_OIDNAMELEN_sTuFf_^$(OIDNAMELEN)^g"
all: initdb
initdb:
initdb: initdb.sh
sed $(SEDSCRIPT) <initdb.sh >initdb
install: initdb
......
......@@ -26,31 +26,32 @@
#
#
# IDENTIFICATION
# $Header: /cvsroot/pgsql/src/bin/initdb/Attic/initdb.sh,v 1.12 1996/10/12 07:49:56 bryanh Exp $
# $Header: /cvsroot/pgsql/src/bin/initdb/Attic/initdb.sh,v 1.13 1996/11/14 10:25:33 bryanh Exp $
#
#-------------------------------------------------------------------------
# ----------------
# Set paths from environment or default values.
# The _fUnKy_..._sTuFf_ gets set when the script is built (with make)
# from parameters set in the make file.
# Currently the only thing we look for from the environment is
# PGDATA, PGHOST, and PGPORT. However, we should have environment
# variables for all the paths.
#
# ----------------
[ -z "$PGDATA" ] && { PGDATA=_fUnKy_DATADIR_sTuFf_; export PGDATA; }
[ -z "$PGPORT" ] && { PGPORT=_fUnKy_POSTPORT_sTuFf_; export PGPORT; }
[ -z "$PGHOST" ] && { PGHOST=localhost; export PGHOST; }
BINDIR=_fUnKy_BINDIR_sTuFf_
LIBDIR=_fUnKy_LIBDIR_sTuFf_
NAMEDATALEN=_fUnKy_NAMEDATALEN_sTuFf_
OIDNAMELEN=_fUnKy_OIDNAMELEN_sTuFf_
PATH=$BINDIR:$PATH
export PATH
CMDNAME=`basename $0`
# Find the default PGLIB directory (the directory that contains miscellaneous
# files that are part of Postgres). The user-written program postconfig
# outputs variable settings like "PGLIB=/usr/lib/whatever". If it doesn't
# output a PGLIB value, then there is no default and the user must
# specify the pglib option. Postconfig may not exist, in which case
# our invocation of it silently fails.
# The x=x below is to satisfy export if postconfig returns nothing.
export x=x $(postconfig 2>/dev/null)
# Set defaults:
debug=0
noclean=0
......@@ -62,45 +63,60 @@ do
# ${ARG#--username=} is not reliable or available on all platforms
case "$1" in
--debug|-d)
debug=1
echo "Running with debug mode on."
;;
--noclean|-n)
noclean=1
echo "Running with noclean mode on. Mistakes will not be cleaned up."
;;
--template|-t)
template_only=1
echo "updating template1 database only."
;;
--username=*)
POSTGRES_SUPERUSERNAME="`echo $1 | sed s/^--username=//`"
;;
-u)
shift
POSTGRES_SUPERUSERNAME="$1"
;;
-u*)
POSTGRES_SUPERUSERNAME="`echo $1 | sed s/^-u//`"
;;
--pgdata=*)
PGDATA="`echo $1 | sed s/^--pgdata=//`"
;;
-r)
shift
PGDATA="$1"
;;
-r*)
PGDATA="`echo $1 | sed s/^-r//`"
;;
*)
echo "Unrecognized option '$1'. Syntax is:"
echo "initdb [-t | --template] [-d | --debug] [-n | --noclean]" \
"[-u SUPERUSER | --username=SUPERUSER] [-r DATADIR | --pgdata=DATADIR]"
exit 100
esac
shift
--debug|-d)
debug=1
echo "Running with debug mode on."
;;
--noclean|-n)
noclean=1
echo "Running with noclean mode on. "
"Mistakes will not be cleaned up."
;;
--template|-t)
template_only=1
echo "updating template1 database only."
;;
--username=*)
POSTGRES_SUPERUSERNAME="`echo $1 | sed s/^--username=//`"
;;
-u)
shift
POSTGRES_SUPERUSERNAME="$1"
;;
-u*)
POSTGRES_SUPERUSERNAME="`echo $1 | sed s/^-u//`"
;;
--pgdata=*)
PGDATA="`echo $1 | sed s/^--pgdata=//`"
;;
-r)
shift
PGDATA="$1"
;;
-r*)
PGDATA="`echo $1 | sed s/^-r//`"
;;
--pglib=*)
PGLIB="`echo $1 | sed s/^--pglib=//`"
;;
-l)
shift
PGLIB="$1"
;;
-l*)
PGLIB="`echo $1 | sed s/^-l//`"
;;
*)
echo "Unrecognized option '$1'. Syntax is:"
echo "initdb [-t | --template] [-d | --debug]" \
"[-n | --noclean]" \
"[-u SUPERUSER | --username=SUPERUSER]" \
"[-r DATADIR | --pgdata=DATADIR]" \
"[-l LIBDIR | --pglib=LIBDIR]"
exit 100
esac
shift
done
if [ "$debug" -eq 1 ]; then
......@@ -109,9 +125,34 @@ else
BACKENDARGS="-boot -C -F -Q"
fi
TEMPLATE=$LIBDIR/local1_template1.bki.source
GLOBAL=$LIBDIR/global1.bki.source
PG_HBA_SAMPLE=$LIBDIR/pg_hba.conf.sample
TEMPLATE=$PGLIB/local1_template1.bki.source
GLOBAL=$PGLIB/global1.bki.source
PG_HBA_SAMPLE=$PGLIB/pg_hba.conf.sample
#-------------------------------------------------------------------------
# Make sure he told us where to find the Postgres files.
#-------------------------------------------------------------------------
if [ -z $PGLIB ]; then
echo "$CMDNAME does not know where to find the files that make up "
echo "Postgres (the PGLIB directory). You must identify the PGLIB "
echo "directory either with a --pglib invocation option, or by "
echo "setting the PGLIB environment variable, or by having a program "
echo "called 'postconfig' in your search path that sets the PGLIB "
echo "environment variable."
exit 20
fi
#-------------------------------------------------------------------------
# Make sure he told us where to build the database system
#-------------------------------------------------------------------------
if [ -z $PGDATA ]; then
echo "$CMDNAME: You must identify the PGDATA directory, where the data"
echo "for this database system will reside. Do this with either a"
echo "--pgdata invocation option or a PGDATA environment variable."
echo
exit 20
fi
#-------------------------------------------------------------------------
# Find the input files
......@@ -120,7 +161,9 @@ PG_HBA_SAMPLE=$LIBDIR/pg_hba.conf.sample
for PREREQ_FILE in $TEMPLATE $GLOBAL $PG_HBA_SAMPLE; do
if [ ! -f $PREREQ_FILE ]; then
echo "$CMDNAME does not find the file '$PREREQ_FILE'."
echo "This means Postgres95 is incorrectly installed."
echo "This means you have identified an invalid PGLIB directory."
echo "You specify a PGLIB directory with a --pglib invocation "
echo "option, a PGLIB environment variable, or a postconfig program."
exit 1
fi
done
......@@ -157,15 +200,13 @@ fi
if [ $POSTGRES_SUPERUID -ne `pg_id` -a `pg_id` -ne 0 ]; then
echo "Only the unix superuser may initialize a database with a different"
echo "Postgres superuser. (You must be able to create files that belong"
echo "to the specified Postgres userid)."
echo "to the specified unix user)."
exit 2
fi
echo "We are initializing the database system with username" \
"$POSTGRES_SUPERUSERNAME (uid=$POSTGRES_SUPERUID)."
echo "Please be aware that Postgres is not secure. Anyone who can connect"
echo "to the database can act as user $POSTGRES_SUPERUSERNAME" \
"with very little effort."
echo "This user will own all the files and must also own the server process."
echo
# -----------------------------------------------------------------------
......@@ -182,8 +223,8 @@ if [ -d "$PGDATA" ]; then
echo "database system already exists."
echo
echo "If you want to create a new database system, either remove "
echo "the $PGDATA directory or run initdb with environment variable"
echo "PGDATA set to something other than $PGDATA."
echo "the $PGDATA directory or run initdb with a --pgdata option "
echo "other than $PGDATA."
exit 1
fi
else
......
......@@ -159,6 +159,14 @@
/* OIDNAMELEN should be set to NAMEDATALEN + sizeof(Oid) */
#define OIDNAMELEN 36
/*
* DEF_PGPORT is the TCP port number on which the Postmaster listens by
* default. This can be overriden by command options, environment variables,
* and the postconfig hook.
*/
#define DEF_PGPORT "5432"
/* turn this on if you prefer European style dates instead of American
* style dates
*/
......
......@@ -4,7 +4,6 @@
* this file contains general postgres administration and initialization
* stuff that used to be spread out between the following files:
* globals.h global variables
* magic.h PG_RELEASE, PG_VERSION, etc defines
* pdir.h directory path crud
* pinit.h postgres initialization
* pmod.h processing modes
......@@ -12,7 +11,7 @@
*
* Copyright (c) 1994, Regents of the University of California
*
* $Id: miscadmin.h,v 1.3 1996/11/12 06:47:10 bryanh Exp $
* $Id: miscadmin.h,v 1.4 1996/11/14 10:25:42 bryanh Exp $
*
* NOTES
* some of the information in this file will be moved to
......@@ -36,13 +35,12 @@ extern int PostmasterMain(int argc, char* argv[]);
* from utils/init/globals.c
*/
extern int Portfd;
extern int Noversion; /* moved from magic.c */
extern int MasterPid; /* declared and defined in utils/initglobals.c */
extern int Noversion;
extern int MasterPid;
extern int Quiet;
extern char *DataDir;
extern char OutputFileName[];
extern void InitGlobals(void);
/*
* done in storage/backendid.h for now.
......@@ -83,8 +81,6 @@ extern char *GetPgUserName(void);
extern void SetPgUserName(void);
extern Oid GetUserId(void);
extern void SetUserId(void);
extern char *GetPGHome(void);
extern char *GetPGData(void);
extern int ValidateBackend(char *path);
extern int FindBackend(char *backend, char *argv0);
extern int CheckPathAccess(char *path, char *name, int open_mode);
......
......@@ -7,7 +7,7 @@
#
#
# IDENTIFICATION
# $Header: /cvsroot/pgsql/src/interfaces/libpq++/Attic/Makefile,v 1.3 1996/11/13 10:35:39 bryanh Exp $
# $Header: /cvsroot/pgsql/src/interfaces/libpq++/Attic/Makefile,v 1.4 1996/11/14 10:25:54 bryanh Exp $
#
#-------------------------------------------------------------------------
......@@ -21,7 +21,7 @@ INCLUDE_OPT= \
-I../include \
-I$(LIBPQDIR)
CXXFLAGS+= $(INCLUDE_OPT) -DPOSTPORT='"$(POSTPORT)"'
CXXFLAGS+= $(INCLUDE_OPT)
ifdef KRBVERS
CXXFLAGS+= $(KRBFLAGS)
......
......@@ -7,7 +7,7 @@
#
#
# IDENTIFICATION
# $Header: /cvsroot/pgsql/src/interfaces/libpq/Makefile,v 1.16 1996/11/12 11:42:21 bryanh Exp $
# $Header: /cvsroot/pgsql/src/interfaces/libpq/Makefile,v 1.17 1996/11/14 10:25:48 bryanh Exp $
#
#-------------------------------------------------------------------------
......@@ -17,7 +17,7 @@ include ../Makefile.global
# We need the backend directory here for its fmgr.h
INCLUDE_OPT= -I../include -I../backend
CFLAGS+= $(INCLUDE_OPT) -DPOSTPORT='"$(POSTPORT)"'
CFLAGS+= $(INCLUDE_OPT)
ifdef KRBVERS
CFLAGS+= $(KRBFLAGS)
......
......@@ -7,7 +7,7 @@
*
*
* IDENTIFICATION
* $Header: /cvsroot/pgsql/src/interfaces/libpq/fe-connect.c,v 1.18 1996/11/11 12:16:54 scrappy Exp $
* $Header: /cvsroot/pgsql/src/interfaces/libpq/fe-connect.c,v 1.19 1996/11/14 10:25:50 bryanh Exp $
*
*-------------------------------------------------------------------------
*/
......@@ -63,7 +63,7 @@ static void conninfo_free(void);
/* ----------
* Definition of the conninfo parametes and their fallback resources.
* Definition of the conninfo parameters and their fallback resources.
* If Environment-Var and Compiled-in are specified as NULL, no
* fallback is available. If after all no value can be determined
* for an option, an error is returned.
......@@ -93,7 +93,7 @@ static PQconninfoOption PQconninfoOptions[] = {
{ "host", "PGHOST", DefaultHost, NULL,
"Database-Host", "", 40 },
{ "port", "PGPORT", POSTPORT, NULL,
{ "port", "PGPORT", DEF_PGPORT, NULL,
"Database-Port", "", 6 },
{ "tty", "PGTTY", DefaultTty, NULL,
......@@ -192,7 +192,6 @@ PQconnectdb(const char *conninfo)
conn->Pfdebug = NULL;
conn->port = NULL;
conn->notifyList = DLNewList();
conn->lobjfuncs = NULL;
conn->pghost = strdup(conninfo_getval("host"));
conn->pgport = strdup(conninfo_getval("port"));
......@@ -300,7 +299,6 @@ PQsetdb(const char *pghost, const char* pgport, const char* pgoptions, const cha
conn->Pfdebug = NULL;
conn->port = NULL;
conn->notifyList = DLNewList();
conn->lobjfuncs = NULL;
if (!pghost || pghost[0] == '\0') {
if (!(tmp = getenv("PGHOST"))) {
......@@ -312,7 +310,7 @@ PQsetdb(const char *pghost, const char* pgport, const char* pgoptions, const cha
if (!pgport || pgport[0] == '\0') {
if (!(tmp = getenv("PGPORT"))) {
tmp = POSTPORT;
tmp = DEF_PGPORT;
}
conn->pgport = strdup(tmp);
} else
......@@ -521,7 +519,6 @@ freePGconn(PGconn *conn)
if (conn->dbName) free(conn->dbName);
if (conn->pguser) free(conn->pguser);
if (conn->notifyList) DLFreeList(conn->notifyList);
if (conn->lobjfuncs) free(conn->lobjfuncs);
free(conn);
}
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment