From 02b1a7fd5160d4117973527dc6d4214cd225a97c Mon Sep 17 00:00:00 2001
From: Tom Lane <tgl@sss.pgh.pa.us>
Date: Sat, 8 Sep 2001 01:10:21 +0000
Subject: [PATCH] Clean up some confusion about where and how to set
 whereToSendOutput. We will no longer try to send elog messages to the client
 before we have initialized backend libpq (oops); however, reporting bogus
 commandline switches via elog does work now (not irrelevant, because of
 PGOPTIONS). Fix problem with inappropriate sending of checkpoint-process
 messages to stderr.

---
 src/backend/catalog/pg_proc.c       |  5 ++-
 src/backend/commands/async.c        |  5 ++-
 src/backend/commands/define.c       |  9 ++---
 src/backend/libpq/pqsignal.c        |  7 ++--
 src/backend/postmaster/postmaster.c | 17 +++++++--
 src/backend/tcop/postgres.c         | 55 ++++++++++++++++++-----------
 src/backend/tcop/utility.c          |  4 +--
 src/backend/utils/adt/sets.c        |  7 ++--
 src/include/catalog/pg_proc.h       |  8 ++---
 src/include/commands/defrem.h       |  5 ++-
 10 files changed, 69 insertions(+), 53 deletions(-)

diff --git a/src/backend/catalog/pg_proc.c b/src/backend/catalog/pg_proc.c
index e285e435a3..68309a9af1 100644
--- a/src/backend/catalog/pg_proc.c
+++ b/src/backend/catalog/pg_proc.c
@@ -8,7 +8,7 @@
  *
  *
  * IDENTIFICATION
- *	  $Header: /cvsroot/pgsql/src/backend/catalog/pg_proc.c,v 1.58 2001/08/23 00:49:46 tgl Exp $
+ *	  $Header: /cvsroot/pgsql/src/backend/catalog/pg_proc.c,v 1.59 2001/09/08 01:10:19 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -53,8 +53,7 @@ ProcedureCreate(char *procedureName,
 				int32 perbyte_cpu,
 				int32 percall_cpu,
 				int32 outin_ratio,
-				List *argList,
-				CommandDest dest)
+				List *argList)
 {
 	int			i;
 	Relation	rel;
diff --git a/src/backend/commands/async.c b/src/backend/commands/async.c
index dde2412a6e..6333efafc6 100644
--- a/src/backend/commands/async.c
+++ b/src/backend/commands/async.c
@@ -7,7 +7,7 @@
  * Portions Copyright (c) 1994, Regents of the University of California
  *
  * IDENTIFICATION
- *	  $Header: /cvsroot/pgsql/src/backend/commands/async.c,v 1.79 2001/06/17 22:27:15 tgl Exp $
+ *	  $Header: /cvsroot/pgsql/src/backend/commands/async.c,v 1.80 2001/09/08 01:10:20 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -85,7 +85,6 @@
 #include "libpq/libpq.h"
 #include "libpq/pqformat.h"
 #include "miscadmin.h"
-#include "tcop/dest.h"
 #include "tcop/tcopprot.h"
 #include "utils/fmgroids.h"
 #include "utils/ps_status.h"
@@ -94,7 +93,7 @@
 
 /* stuff that we really ought not be touching directly :-( */
 extern TransactionState CurrentTransactionState;
-extern CommandDest whereToSendOutput;
+
 
 /*
  * State for outbound notifies consists of a list of all relnames NOTIFYed
diff --git a/src/backend/commands/define.c b/src/backend/commands/define.c
index 947257b5e1..764cceff70 100644
--- a/src/backend/commands/define.c
+++ b/src/backend/commands/define.c
@@ -10,7 +10,7 @@
  *
  *
  * IDENTIFICATION
- *	  $Header: /cvsroot/pgsql/src/backend/commands/define.c,v 1.59 2001/09/06 02:07:42 tgl Exp $
+ *	  $Header: /cvsroot/pgsql/src/backend/commands/define.c,v 1.60 2001/09/08 01:10:20 tgl Exp $
  *
  * DESCRIPTION
  *	  The "DefineFoo" routines take the parse tree and pick out the
@@ -50,7 +50,6 @@
 #include "miscadmin.h"
 #include "optimizer/cost.h"
 #include "parser/parse_expr.h"
-#include "tcop/dest.h"
 #include "utils/builtins.h"
 #include "utils/syscache.h"
 
@@ -212,10 +211,9 @@ interpret_AS_clause(const char *languageName, const List *as,
 /*
  * CreateFunction
  *	 Execute a CREATE FUNCTION utility statement.
- *
  */
 void
-CreateFunction(ProcedureStmt *stmt, CommandDest dest)
+CreateFunction(ProcedureStmt *stmt)
 {
 	char	   *probin_str;
 
@@ -338,8 +336,7 @@ CreateFunction(ProcedureStmt *stmt, CommandDest dest)
 					perbyte_cpu,
 					percall_cpu,
 					outin_ratio,
-					stmt->argTypes,
-					dest);
+					stmt->argTypes);
 }
 
 
diff --git a/src/backend/libpq/pqsignal.c b/src/backend/libpq/pqsignal.c
index 028db10408..effe2e09cf 100644
--- a/src/backend/libpq/pqsignal.c
+++ b/src/backend/libpq/pqsignal.c
@@ -9,7 +9,7 @@
  *
  *
  * IDENTIFICATION
- *	  $Header: /cvsroot/pgsql/src/backend/libpq/pqsignal.c,v 1.22 2001/09/07 16:12:48 wieck Exp $
+ *	  $Header: /cvsroot/pgsql/src/backend/libpq/pqsignal.c,v 1.23 2001/09/08 01:10:20 tgl Exp $
  *
  * NOTES
  *		This shouldn't be in libpq, but the monitor and some other
@@ -46,12 +46,15 @@
 
 
 /*
- * Initialize BlockSig and UnBlockSig.
+ * Initialize BlockSig, UnBlockSig, and AuthBlockSig.
  *
  * BlockSig is the set of signals to block when we are trying to block
  * signals.  This includes all signals we normally expect to get, but NOT
  * signals that should never be turned off.
  *
+ * AuthBlockSig is the set of signals to block during authentication;
+ * it's essentially BlockSig minus SIGTERM and SIGQUIT.
+ *
  * UnBlockSig is the set of signals to block when we don't want to block
  * signals (is this ever nonzero??)
  */
diff --git a/src/backend/postmaster/postmaster.c b/src/backend/postmaster/postmaster.c
index 0de3ad6b12..b1e6bc23b2 100644
--- a/src/backend/postmaster/postmaster.c
+++ b/src/backend/postmaster/postmaster.c
@@ -37,7 +37,7 @@
  *
  *
  * IDENTIFICATION
- *	  $Header: /cvsroot/pgsql/src/backend/postmaster/postmaster.c,v 1.240 2001/09/07 16:12:48 wieck Exp $
+ *	  $Header: /cvsroot/pgsql/src/backend/postmaster/postmaster.c,v 1.241 2001/09/08 01:10:20 tgl Exp $
  *
  * NOTES
  *
@@ -687,6 +687,15 @@ PostmasterMain(int argc, char *argv[])
 	pqsignal(SIGTTIN, SIG_IGN); /* ignored */
 	pqsignal(SIGTTOU, SIG_IGN); /* ignored */
 
+	/*
+	 * Reset whereToSendOutput from Debug (its starting state) to None.
+	 * This prevents elog from sending messages to stderr unless the
+	 * syslog/stderr switch permits.  We don't do this until the postmaster
+	 * is fully launched, since startup failures may as well be reported
+	 * to stderr.
+	 */
+	whereToSendOutput = None;
+
 	/*
 	 * Initialize and startup the statistics collector process
 	 */
@@ -1932,8 +1941,6 @@ DoBackend(Port *port)
 	/* Reset MyProcPid to new backend's pid */
 	MyProcPid = getpid();
 
-	whereToSendOutput = Remote;	/* XXX probably doesn't belong here */
-
 	/*
 	 * We arrange for a simple exit(0) if we receive SIGTERM or SIGQUIT
 	 * during any client authentication related communication. Otherwise
@@ -1955,6 +1962,10 @@ DoBackend(Port *port)
 
 	ClientAuthentication(MyProcPort); /* might not return, if failure */
 
+	/*
+	 * Done with authentication.  Prevent SIGTERM/SIGQUIT again until
+	 * backend startup is complete.
+	 */
 	PG_SETMASK(&BlockSig);
 
 	/*
diff --git a/src/backend/tcop/postgres.c b/src/backend/tcop/postgres.c
index b8c57bb4d7..3aa28e1dbe 100644
--- a/src/backend/tcop/postgres.c
+++ b/src/backend/tcop/postgres.c
@@ -8,7 +8,7 @@
  *
  *
  * IDENTIFICATION
- *	  $Header: /cvsroot/pgsql/src/backend/tcop/postgres.c,v 1.231 2001/09/07 16:12:48 wieck Exp $
+ *	  $Header: /cvsroot/pgsql/src/backend/tcop/postgres.c,v 1.232 2001/09/08 01:10:20 tgl Exp $
  *
  * NOTES
  *	  this is the "main" module of the postgres backend and
@@ -85,6 +85,7 @@ bool		ShowPortNumber;
 
 bool		Log_connections = false;
 
+/* Note: whereToSendOutput is initialized for the bootstrap/standalone case */
 CommandDest whereToSendOutput = Debug;
 
 static bool dontExecute = false;
@@ -536,7 +537,7 @@ pg_plan_query(Query *querytree)
 
 	if (Show_planner_stats)
 	{
-		fprintf(stderr, "PLANNER STATISTICS\n");
+		fprintf(StatFp, "PLANNER STATISTICS\n");
 		ShowUsage();
 	}
 
@@ -813,7 +814,7 @@ pg_exec_query_string(char *query_string,		/* string to execute */
 
 				if (Show_executor_stats)
 				{
-					fprintf(stderr, "EXECUTOR STATISTICS\n");
+					fprintf(StatFp, "EXECUTOR STATISTICS\n");
 					ShowUsage();
 				}
 			}
@@ -910,9 +911,9 @@ quickdie(SIGNAL_ARGS)
 	PG_SETMASK(&BlockSig);
 	elog(NOTICE, "Message from PostgreSQL backend:"
 		 "\n\tThe Postmaster has informed me that some other backend"
-		 "\tdied abnormally and possibly corrupted shared memory."
+		 "\n\tdied abnormally and possibly corrupted shared memory."
 		 "\n\tI have rolled back the current transaction and am"
-		 "\tgoing to terminate your database system connection and exit."
+		 "\n\tgoing to terminate your database system connection and exit."
 	"\n\tPlease reconnect to the database system and repeat your query.");
 
 	/*
@@ -968,6 +969,10 @@ die(SIGNAL_ARGS)
 /*
  * Shutdown signal from postmaster during client authentication.
  * Simply exit(0).
+ *
+ * XXX: possible future improvement: try to send a message indicating
+ * why we are disconnecting.  Problem is to be sure we don't block while
+ * doing so nor mess up the authentication message exchange.
  */
 void
 authdie(SIGNAL_ARGS)
@@ -1163,6 +1168,16 @@ PostgresMain(int argc, char *argv[],
 
 	SetProcessingMode(InitProcessing);
 
+	/*
+	 * If under postmaster, initialize libpq and enable reporting of
+	 * elog errors to the client.
+	 */
+	if (IsUnderPostmaster)
+	{
+		pq_init();				/* initialize libpq at backend startup */
+		whereToSendOutput = Remote;	/* now safe to elog to client */
+	}
+
 	/*
 	 * Set default values for command-line options.
 	 */
@@ -1209,7 +1224,7 @@ PostgresMain(int argc, char *argv[],
 #ifdef USE_ASSERT_CHECKING
 				SetConfigOption("debug_assertions", optarg, ctx, true);
 #else
-				fprintf(stderr, "Assert checking is not compiled in\n");
+				elog(NOTICE, "Assert checking is not compiled in");
 #endif
 				break;
 
@@ -1439,7 +1454,7 @@ PostgresMain(int argc, char *argv[],
 				 */
 				if (XfuncMode != 0)
 				{
-					fprintf(stderr, "only one -x flag is allowed\n");
+					elog(NOTICE, "only one -x flag is allowed");
 					errs++;
 					break;
 				}
@@ -1457,7 +1472,7 @@ PostgresMain(int argc, char *argv[],
 					XfuncMode = XFUNC_WAIT;
 				else
 				{
-					fprintf(stderr, "use -x {off,nor,nopull,nopm,pullall,wait}\n");
+					elog(NOTICE, "use -x {off,nor,nopull,nopm,pullall,wait}");
 					errs++;
 				}
 #endif
@@ -1492,14 +1507,11 @@ PostgresMain(int argc, char *argv[],
 
 	/*
 	 * Post-processing for command line options.
-	 *
-	 * XXX It'd be nice if libpq were already running here, so we could do
-	 * elog(NOTICE) instead of just writing on stderr...
 	 */
 	if (Show_query_stats &&
 		(Show_parser_stats || Show_planner_stats || Show_executor_stats))
 	{
-		fprintf(stderr, "Query statistics are disabled because parser, planner, or executor statistics are on.\n");
+		elog(NOTICE, "Query statistics are disabled because parser, planner, or executor statistics are on.");
 		SetConfigOption("show_query_stats", "false", ctx, true);
 	}
 
@@ -1508,9 +1520,9 @@ PostgresMain(int argc, char *argv[],
 		if (!potential_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",
+					"data.  You must specify the directory that contains the "
+					"database system either by specifying the -D invocation "
+					"option or by setting the PGDATA environment variable.\n\n",
 					argv[0]);
 			proc_exit(1);
 		}
@@ -1578,11 +1590,11 @@ PostgresMain(int argc, char *argv[],
 		/* noninteractive case: nothing should be left after switches */
 		if (errs || argc != optind || DBName == NULL)
 		{
-			fprintf(stderr, "%s: invalid command line arguments\nTry -? for help.\n", argv[0]);
+			elog(NOTICE, "%s: invalid command line arguments\nTry -? for help.",
+				 argv[0]);
 			proc_exit(0);		/* not 1, that causes system-wide
 								 * restart... */
 		}
-		pq_init();				/* initialize libpq at backend startup */
 		BaseInit();
 	}
 	else
@@ -1590,15 +1602,16 @@ PostgresMain(int argc, char *argv[],
 		/* interactive case: database name can be last arg on command line */
 		if (errs || argc - optind > 1)
 		{
-			fprintf(stderr, "%s: invalid command line arguments\nTry -? for help.\n", argv[0]);
+			elog(NOTICE, "%s: invalid command line arguments\nTry -? for help.",
+				 argv[0]);
 			proc_exit(1);
 		}
 		else if (argc - optind == 1)
 			DBName = argv[optind];
 		else if ((DBName = username) == NULL)
 		{
-			fprintf(stderr, "%s: user name undefined and no database specified\n",
-					argv[0]);
+			elog(NOTICE, "%s: user name undefined and no database specified\n",
+				 argv[0]);
 			proc_exit(1);
 		}
 
@@ -1723,7 +1736,7 @@ PostgresMain(int argc, char *argv[],
 	if (!IsUnderPostmaster)
 	{
 		puts("\nPOSTGRES backend interactive interface ");
-		puts("$Revision: 1.231 $ $Date: 2001/09/07 16:12:48 $\n");
+		puts("$Revision: 1.232 $ $Date: 2001/09/08 01:10:20 $\n");
 	}
 
 	/*
diff --git a/src/backend/tcop/utility.c b/src/backend/tcop/utility.c
index c05546fb8e..18cf913470 100644
--- a/src/backend/tcop/utility.c
+++ b/src/backend/tcop/utility.c
@@ -10,7 +10,7 @@
  *
  *
  * IDENTIFICATION
- *	  $Header: /cvsroot/pgsql/src/backend/tcop/utility.c,v 1.116 2001/08/21 16:36:04 tgl Exp $
+ *	  $Header: /cvsroot/pgsql/src/backend/tcop/utility.c,v 1.117 2001/09/08 01:10:20 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -525,7 +525,7 @@ ProcessUtility(Node *parsetree,
 		case T_ProcedureStmt:	/* CREATE FUNCTION */
 			set_ps_display(commandTag = "CREATE");
 
-			CreateFunction((ProcedureStmt *) parsetree, dest);	/* everything */
+			CreateFunction((ProcedureStmt *) parsetree);
 			break;
 
 		case T_IndexStmt:		/* CREATE INDEX */
diff --git a/src/backend/utils/adt/sets.c b/src/backend/utils/adt/sets.c
index c48526a7ba..922dc5a2b1 100644
--- a/src/backend/utils/adt/sets.c
+++ b/src/backend/utils/adt/sets.c
@@ -10,7 +10,7 @@
  *
  *
  * IDENTIFICATION
- *	  $Header: /cvsroot/pgsql/src/backend/utils/adt/Attic/sets.c,v 1.37 2001/03/22 03:59:54 momjian Exp $
+ *	  $Header: /cvsroot/pgsql/src/backend/utils/adt/Attic/sets.c,v 1.38 2001/09/08 01:10:20 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -26,8 +26,6 @@
 #include "utils/sets.h"
 #include "utils/syscache.h"
 
-extern CommandDest whereToSendOutput;	/* defined in tcop/postgres.c */
-
 
 /*
  *	  SetDefine		   - converts query string defining set to an oid
@@ -65,8 +63,7 @@ SetDefine(char *querystr, char *typename)
 							 0, /* perbyte_cpu */
 							 0, /* percall_cpu */
 							 100,		/* outin_ratio */
-							 NIL,		/* argList */
-							 whereToSendOutput);
+							 NIL);		/* argList */
 
 	/*
 	 * Since we're still inside this command of the transaction, we can't
diff --git a/src/include/catalog/pg_proc.h b/src/include/catalog/pg_proc.h
index fc1a5a73b6..c6fb359993 100644
--- a/src/include/catalog/pg_proc.h
+++ b/src/include/catalog/pg_proc.h
@@ -7,7 +7,7 @@
  * Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group
  * Portions Copyright (c) 1994, Regents of the University of California
  *
- * $Id: pg_proc.h,v 1.209 2001/09/06 04:57:29 ishii Exp $
+ * $Id: pg_proc.h,v 1.210 2001/09/08 01:10:20 tgl Exp $
  *
  * NOTES
  *	  The script catalog/genbki.sh reads this file and generates .bki
@@ -23,7 +23,7 @@
 #ifndef PG_PROC_H
 #define PG_PROC_H
 
-#include "tcop/dest.h"
+#include "nodes/pg_list.h"
 
 /* ----------------
  *		postgres.h contains the system type definintions and the
@@ -2757,8 +2757,6 @@ extern Oid ProcedureCreate(char *procedureName,
 				int32 perbyte_cpu,
 				int32 percall_cpu,
 				int32 outin_ratio,
-				List *argList,
-				CommandDest dest);
-
+				List *argList);
 
 #endif	 /* PG_PROC_H */
diff --git a/src/include/commands/defrem.h b/src/include/commands/defrem.h
index 88c8a93135..d2c01862d9 100644
--- a/src/include/commands/defrem.h
+++ b/src/include/commands/defrem.h
@@ -7,7 +7,7 @@
  * Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group
  * Portions Copyright (c) 1994, Regents of the University of California
  *
- * $Id: defrem.h,v 1.24 2001/08/21 16:36:06 tgl Exp $
+ * $Id: defrem.h,v 1.25 2001/09/08 01:10:21 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -15,7 +15,6 @@
 #define DEFREM_H
 
 #include "nodes/parsenodes.h"
-#include "tcop/dest.h"
 
 /*
  * prototypes in indexcmds.c
@@ -36,7 +35,7 @@ extern void ReindexDatabase(const char *databaseName, bool force, bool all);
 /*
  * prototypes in define.c
  */
-extern void CreateFunction(ProcedureStmt *stmt, CommandDest dest);
+extern void CreateFunction(ProcedureStmt *stmt);
 extern void DefineOperator(char *name, List *parameters);
 extern void DefineAggregate(char *name, List *parameters);
 extern void DefineType(char *name, List *parameters);