postgres.c 92.7 KB
Newer Older
1 2
/*-------------------------------------------------------------------------
 *
3
 * postgres.c
4
 *	  POSTGRES C Backend Interface
5
 *
P
 
PostgreSQL Daemon 已提交
6
 * Portions Copyright (c) 1996-2005, PostgreSQL Global Development Group
B
Add:  
Bruce Momjian 已提交
7
 * Portions Copyright (c) 1994, Regents of the University of California
8 9 10
 *
 *
 * IDENTIFICATION
11
 *	  $PostgreSQL: pgsql/src/backend/tcop/postgres.c,v 1.463 2005/09/26 15:51:12 momjian Exp $
12 13
 *
 * NOTES
14 15
 *	  this is the "main" module of the postgres backend and
 *	  hence the main module of the "traffic cop".
16 17 18
 *
 *-------------------------------------------------------------------------
 */
B
Bruce Momjian 已提交
19

20 21
#include "postgres.h"

B
Bruce Momjian 已提交
22
#include <unistd.h>
23
#include <signal.h>
B
Bruce Momjian 已提交
24
#include <fcntl.h>
25
#include <sys/socket.h>
26
#if HAVE_SYS_SELECT_H
27
#include <sys/select.h>
28
#endif
29
#ifdef HAVE_GETOPT_H
B
Bruce Momjian 已提交
30
#include <getopt.h>
31
#endif
32

33
#include "access/printtup.h"
34
#include "access/xlog.h"
35
#include "catalog/pg_type.h"
36
#include "commands/async.h"
37
#include "commands/prepare.h"
38
#include "commands/trigger.h"
39
#include "libpq/libpq.h"
40
#include "libpq/pqformat.h"
41
#include "libpq/pqsignal.h"
B
Bruce Momjian 已提交
42
#include "miscadmin.h"
43 44
#include "nodes/print.h"
#include "optimizer/cost.h"
45
#include "optimizer/planner.h"
46
#include "parser/analyze.h"
47
#include "parser/parser.h"
B
Bruce Momjian 已提交
48
#include "rewrite/rewriteHandler.h"
49
#include "storage/freespace.h"
50
#include "storage/ipc.h"
51
#include "storage/pg_shmem.h"
52
#include "storage/proc.h"
53
#include "storage/sinval.h"
54 55
#include "tcop/fastpath.h"
#include "tcop/pquery.h"
B
Bruce Momjian 已提交
56
#include "tcop/tcopprot.h"
57
#include "tcop/utility.h"
58
#include "utils/flatfiles.h"
59
#include "utils/guc.h"
60
#include "utils/lsyscache.h"
61
#include "utils/memutils.h"
M
 
Marc G. Fournier 已提交
62
#include "utils/ps_status.h"
B
Bruce Momjian 已提交
63
#include "mb/pg_wchar.h"
64

65
#include "pgstat.h"
M
 
Marc G. Fournier 已提交
66

67 68 69
extern int	optind;
extern char *optarg;

70
/* ----------------
71
 *		global variables
72 73
 * ----------------
 */
74
const char *debug_query_string; /* for pgmonitor and
B
Bruce Momjian 已提交
75
								 * log_min_error_statement */
76

77
/* Note: whereToSendOutput is initialized for the bootstrap/standalone case */
78
CommandDest whereToSendOutput = Debug;
79

80
/* flag for logging end of session */
B
Bruce Momjian 已提交
81
bool		Log_disconnections = false;
82

83 84
LogStmtLevel log_statement = LOGSTMT_NONE;

85 86 87 88
/* GUC variable for maximum stack depth (measured in kilobytes) */
int			max_stack_depth = 2048;


89 90 91 92
/* ----------------
 *		private variables
 * ----------------
 */
93

94
/* max_stack_depth converted to bytes for speed of checking */
B
Bruce Momjian 已提交
95
static int	max_stack_depth_bytes = 2048 * 1024;
96 97 98 99 100

/* stack base pointer (initialized by PostgresMain) */
static char *stack_base_ptr = NULL;


101 102 103 104 105
/*
 * Flag to mark SIGHUP. Whenever the main loop comes around it
 * will reread the configuration file. (Better than doing the
 * reading in the signal handler, ey?)
 */
106
static volatile sig_atomic_t got_SIGHUP = false;
107

108 109 110 111 112 113
/*
 * Flag to keep track of whether we have started a transaction.
 * For extended query protocol this has to be remembered across messages.
 */
static bool xact_started = false;

114 115 116 117 118 119 120
/*
 * Flag to indicate that we are doing the outer loop's read-from-client,
 * as opposed to any random read from client that might happen within
 * commands like COPY FROM STDIN.
 */
static bool DoingCommandRead = false;

121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141
/*
 * Flags to implement skip-till-Sync-after-error behavior for messages of
 * the extended query protocol.
 */
static bool doing_extended_query_message = false;
static bool ignore_till_sync = false;

/*
 * If an unnamed prepared statement exists, it's stored here.
 * We keep it separate from the hashtable kept by commands/prepare.c
 * in order to reduce overhead for short-lived queries.
 */
static MemoryContext unnamed_stmt_context = NULL;
static PreparedStatement *unnamed_stmt_pstmt = NULL;


static bool EchoQuery = false;	/* default don't echo */

/*
 * people who want to use EOF should #define DONTUSENEWLINE in
 * tcop/tcopdebug.h
142 143
 */
#ifndef TCOP_DONTUSENEWLINE
144
static int	UseNewLine = 1;		/* Use newlines query delimiters (the
145
								 * default) */
B
Bruce Momjian 已提交
146

147
#else
148
static int	UseNewLine = 0;		/* Use EOF as query delimiters */
149
#endif   /* TCOP_DONTUSENEWLINE */
150 151 152


/* ----------------------------------------------------------------
153
 *		decls for routines only used in this file
154 155
 * ----------------------------------------------------------------
 */
156 157 158
static int	InteractiveBackend(StringInfo inBuf);
static int	SocketBackend(StringInfo inBuf);
static int	ReadCommand(StringInfo inBuf);
159 160
static bool log_after_parse(List *raw_parsetree_list,
				const char *query_string, char **prepare_string);
161
static List *pg_rewrite_queries(List *querytree_list);
162
static void start_xact_command(void);
163
static void finish_xact_command(void);
164
static void SigHupHandler(SIGNAL_ARGS);
165
static void log_disconnections(int code, Datum arg);
166 167 168


/* ----------------------------------------------------------------
169
 *		routines to obtain user input
170 171 172 173
 * ----------------------------------------------------------------
 */

/* ----------------
174
 *	InteractiveBackend() is called for user interactive connections
175 176 177
 *
 *	the string entered by the user is placed in its parameter inBuf,
 *	and we act like a Q message was received.
178
 *
179
 *	EOF is returned if end-of-file input is seen; time to shut down.
180 181 182
 * ----------------
 */

183
static int
184
InteractiveBackend(StringInfo inBuf)
185
{
186 187 188
	int			c;				/* character read from getc() */
	bool		end = false;	/* end-of-input flag */
	bool		backslashSeen = false;	/* have we seen a \ ? */
189

190 191
	/*
	 * display a prompt and obtain input from the user
192
	 */
193
	printf("backend> ");
194
	fflush(stdout);
195

196 197 198
	/* Reset inBuf to empty */
	inBuf->len = 0;
	inBuf->data[0] = '\0';
199
	inBuf->cursor = 0;
200

201 202 203 204
	for (;;)
	{
		if (UseNewLine)
		{
205 206 207
			/*
			 * if we are using \n as a delimiter, then read characters
			 * until the \n.
208 209 210 211 212 213 214
			 */
			while ((c = getc(stdin)) != EOF)
			{
				if (c == '\n')
				{
					if (backslashSeen)
					{
215 216 217
						/* discard backslash from inBuf */
						inBuf->data[--inBuf->len] = '\0';
						backslashSeen = false;
218 219 220 221 222
						continue;
					}
					else
					{
						/* keep the newline character */
223
						appendStringInfoChar(inBuf, '\n');
224 225 226 227 228 229 230 231
						break;
					}
				}
				else if (c == '\\')
					backslashSeen = true;
				else
					backslashSeen = false;

232
				appendStringInfoChar(inBuf, (char) c);
233 234 235 236 237 238 239
			}

			if (c == EOF)
				end = true;
		}
		else
		{
240 241
			/*
			 * otherwise read characters until EOF.
242 243
			 */
			while ((c = getc(stdin)) != EOF)
244
				appendStringInfoChar(inBuf, (char) c);
245

246
			if (inBuf->len == 0)
247 248 249 250
				end = true;
		}

		if (end)
251
			return EOF;
252

253 254
		/*
		 * otherwise we have a user query so process it.
255 256 257 258
		 */
		break;
	}

259 260 261
	/* Add '\0' to make it look the same as message case. */
	appendStringInfoChar(inBuf, (char) '\0');

262 263
	/*
	 * if the query echo flag was given, print the query..
264 265
	 */
	if (EchoQuery)
266
		printf("statement: %s\n", inBuf->data);
267
	fflush(stdout);
268

269
	return 'Q';
270 271 272
}

/* ----------------
273
 *	SocketBackend()		Is called for frontend-backend connections
274
 *
275
 *	Returns the message type code, and loads message body data into inBuf.
276
 *
277
 *	EOF is returned if the connection is lost.
278 279
 * ----------------
 */
280
static int
281
SocketBackend(StringInfo inBuf)
282
{
283
	int			qtype;
284

285
	/*
286
	 * Get message type code from the frontend.
287
	 */
288
	qtype = pq_getbyte();
289

290 291
	if (qtype == EOF)			/* frontend disconnected */
	{
292 293 294
		ereport(COMMERROR,
				(errcode(ERRCODE_PROTOCOL_VIOLATION),
				 errmsg("unexpected EOF on client connection")));
295 296 297 298 299
		return qtype;
	}

	/*
	 * Validate message type code before trying to read body; if we have
B
Bruce Momjian 已提交
300 301
	 * lost sync, better to say "command unknown" than to run out of
	 * memory because we used garbage as a length word.
302 303 304
	 *
	 * This also gives us a place to set the doing_extended_query_message
	 * flag as soon as possible.
305
	 */
306
	switch (qtype)
307
	{
308
		case 'Q':				/* simple query */
309
			doing_extended_query_message = false;
310 311 312 313 314
			if (PG_PROTOCOL_MAJOR(FrontendProtocol) < 3)
			{
				/* old style without length word; convert */
				if (pq_getstring(inBuf))
				{
315 316
					ereport(COMMERROR,
							(errcode(ERRCODE_PROTOCOL_VIOLATION),
B
Bruce Momjian 已提交
317
						 errmsg("unexpected EOF on client connection")));
318 319 320
					return EOF;
				}
			}
321 322
			break;

323
		case 'F':				/* fastpath function call */
324 325
			/* we let fastpath.c cope with old-style input of this */
			doing_extended_query_message = false;
326
			break;
327

328
		case 'X':				/* terminate */
329
			doing_extended_query_message = false;
330
			ignore_till_sync = false;
331 332 333 334 335 336 337 338 339 340 341
			break;

		case 'B':				/* bind */
		case 'C':				/* close */
		case 'D':				/* describe */
		case 'E':				/* execute */
		case 'H':				/* flush */
		case 'P':				/* parse */
			doing_extended_query_message = true;
			/* these are only legal in protocol 3 */
			if (PG_PROTOCOL_MAJOR(FrontendProtocol) < 3)
342 343
				ereport(FATAL,
						(errcode(ERRCODE_PROTOCOL_VIOLATION),
B
Bruce Momjian 已提交
344
					 errmsg("invalid frontend message type %d", qtype)));
345 346 347 348 349 350 351 352 353
			break;

		case 'S':				/* sync */
			/* stop any active skip-till-Sync */
			ignore_till_sync = false;
			/* mark not-extended, so that a new error doesn't begin skip */
			doing_extended_query_message = false;
			/* only legal in protocol 3 */
			if (PG_PROTOCOL_MAJOR(FrontendProtocol) < 3)
354 355
				ereport(FATAL,
						(errcode(ERRCODE_PROTOCOL_VIOLATION),
B
Bruce Momjian 已提交
356
					 errmsg("invalid frontend message type %d", qtype)));
357
			break;
358

359 360 361
		case 'd':				/* copy data */
		case 'c':				/* copy done */
		case 'f':				/* copy fail */
362 363 364
			doing_extended_query_message = false;
			/* these are only legal in protocol 3 */
			if (PG_PROTOCOL_MAJOR(FrontendProtocol) < 3)
365 366
				ereport(FATAL,
						(errcode(ERRCODE_PROTOCOL_VIOLATION),
B
Bruce Momjian 已提交
367
					 errmsg("invalid frontend message type %d", qtype)));
368
			break;
369

370
		default:
B
Bruce Momjian 已提交
371

372
			/*
B
Bruce Momjian 已提交
373 374 375
			 * Otherwise we got garbage from the frontend.	We treat this
			 * as fatal because we have probably lost message boundary
			 * sync, and there's no good way to recover.
376
			 */
377 378 379
			ereport(FATAL,
					(errcode(ERRCODE_PROTOCOL_VIOLATION),
					 errmsg("invalid frontend message type %d", qtype)));
380
			break;
381
	}
382

383 384 385 386 387 388 389 390 391 392 393
	/*
	 * In protocol version 3, all frontend messages have a length word
	 * next after the type code; we can read the message contents
	 * independently of the type.
	 */
	if (PG_PROTOCOL_MAJOR(FrontendProtocol) >= 3)
	{
		if (pq_getmessage(inBuf, 0))
			return EOF;			/* suitable message already logged */
	}

394
	return qtype;
395 396 397
}

/* ----------------
398
 *		ReadCommand reads a command from either the frontend or
399 400 401
 *		standard input, places it in inBuf, and returns the
 *		message type code (first byte of the message).
 *		EOF is returned if end of file.
402 403
 * ----------------
 */
404
static int
405
ReadCommand(StringInfo inBuf)
406
{
407
	int			result;
408

409
	if (whereToSendOutput == Remote)
410
		result = SocketBackend(inBuf);
411
	else
412 413
		result = InteractiveBackend(inBuf);
	return result;
414 415
}

416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461
/*
 * prepare_for_client_read -- set up to possibly block on client input
 *
 * This must be called immediately before any low-level read from the
 * client connection.  It is necessary to do it at a sufficiently low level
 * that there won't be any other operations except the read kernel call
 * itself between this call and the subsequent client_read_ended() call.
 * In particular there mustn't be use of malloc() or other potentially
 * non-reentrant libc functions.  This restriction makes it safe for us
 * to allow interrupt service routines to execute nontrivial code while
 * we are waiting for input.
 */
void
prepare_for_client_read(void)
{
	if (DoingCommandRead)
	{
		/* Enable immediate processing of asynchronous signals */
		EnableNotifyInterrupt();
		EnableCatchupInterrupt();

		/* Allow "die" interrupt to be processed while waiting */
		ImmediateInterruptOK = true;

		/* And don't forget to detect one that already arrived */
		QueryCancelPending = false;
		CHECK_FOR_INTERRUPTS();
	}
}

/*
 * client_read_ended -- get out of the client-input state
 */
void
client_read_ended(void)
{
	if (DoingCommandRead)
	{
		ImmediateInterruptOK = false;
		QueryCancelPending = false;		/* forget any CANCEL signal */

		DisableNotifyInterrupt();
		DisableCatchupInterrupt();
	}
}

462 463 464 465 466 467

/*
 * Parse a query string and pass it through the rewriter.
 *
 * A list of Query nodes is returned, since the string might contain
 * multiple queries and/or the rewriter might expand one query to several.
468 469 470
 *
 * NOTE: this routine is no longer used for processing interactive queries,
 * but it is still needed for parsing of SQL function bodies.
471
 */
472
List *
B
Bruce Momjian 已提交
473
pg_parse_and_rewrite(const char *query_string,	/* string to execute */
474
					 Oid *paramTypes,	/* parameter types */
B
Bruce Momjian 已提交
475
					 int numParams)		/* number of parameters */
476
{
477
	List	   *raw_parsetree_list;
478
	List	   *querytree_list;
479
	ListCell   *list_item;
480

481 482
	/*
	 * (1) parse the request string into a list of raw parse trees.
483
	 */
484
	raw_parsetree_list = pg_parse_query(query_string);
485

486 487
	/*
	 * (2) Do parse analysis and rule rewrite.
488 489 490 491
	 */
	querytree_list = NIL;
	foreach(list_item, raw_parsetree_list)
	{
B
Bruce Momjian 已提交
492
		Node	   *parsetree = (Node *) lfirst(list_item);
493

494
		querytree_list = list_concat(querytree_list,
B
Bruce Momjian 已提交
495 496 497
									 pg_analyze_and_rewrite(parsetree,
															paramTypes,
															numParams));
498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515
	}

	return querytree_list;
}

/*
 * Do raw parsing (only).
 *
 * A list of parsetrees is returned, since there might be multiple
 * commands in the given string.
 *
 * NOTE: for interactive queries, it is important to keep this routine
 * separate from the analysis & rewrite stages.  Analysis and rewriting
 * cannot be done in an aborted transaction, since they require access to
 * database tables.  So, we rely on the raw parser to determine whether
 * we've seen a COMMIT or ABORT command; when we are in abort state, other
 * commands are not processed any further than the raw parse stage.
 */
516
List *
517
pg_parse_query(const char *query_string)
518
{
519
	List	   *raw_parsetree_list;
520

B
Rename:  
Bruce Momjian 已提交
521
	if (log_parser_stats)
522 523
		ResetUsage();

524
	raw_parsetree_list = raw_parser(query_string);
525

526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542
	if (log_parser_stats)
		ShowUsage("PARSER STATISTICS");

	return raw_parsetree_list;
}

static bool
log_after_parse(List *raw_parsetree_list, const char *query_string,
				   char **prepare_string)
{
	ListCell   *parsetree_item;
	bool		log_this_statement = (log_statement == LOGSTMT_ALL);

	*prepare_string = NULL;

	/*	Check if we need to log the statement, and get prepare_string. */
	foreach(parsetree_item, raw_parsetree_list)
543
	{
544 545 546 547 548 549 550 551 552 553
		Node	   *parsetree = (Node *) lfirst(parsetree_item);
		const char *commandTag;

		if (IsA(parsetree, ExplainStmt) &&
			((ExplainStmt *) parsetree)->analyze)
			parsetree = (Node *) (((ExplainStmt *) parsetree)->query);

		if (IsA(parsetree, PrepareStmt))
			parsetree = (Node *) (((PrepareStmt *) parsetree)->query);

554 555
		if (IsA(parsetree, SelectStmt) &&
			((SelectStmt *) parsetree)->into == NULL)
556 557 558 559 560 561 562 563 564 565 566 567 568 569 570
			continue;		/* optimization for frequent command */

		if (log_statement == LOGSTMT_MOD &&
			(IsA(parsetree, InsertStmt) ||
			 IsA(parsetree, UpdateStmt) ||
			 IsA(parsetree, DeleteStmt) ||
			 IsA(parsetree, TruncateStmt) ||
			 (IsA(parsetree, CopyStmt) &&
			  ((CopyStmt *) parsetree)->is_from)))	/* COPY FROM */
			log_this_statement = true;

		commandTag = CreateCommandTag(parsetree);
		if ((log_statement == LOGSTMT_MOD ||
			 log_statement == LOGSTMT_DDL) &&
			(strncmp(commandTag, "CREATE ", strlen("CREATE ")) == 0 ||
571
			 IsA(parsetree, SelectStmt) || /* SELECT INTO, CREATE AS */
572 573 574 575 576 577 578 579 580 581 582
			 strncmp(commandTag, "ALTER ", strlen("ALTER ")) == 0 ||
			 strncmp(commandTag, "DROP ", strlen("DROP ")) == 0 ||
			 IsA(parsetree, GrantStmt) ||	/* GRANT or REVOKE */
			 IsA(parsetree, CommentStmt)))
			log_this_statement = true;

		/*
		 *	For the first EXECUTE we find, record the client statement
		 *	used by the PREPARE.
		 */
		if (IsA(parsetree, ExecuteStmt))
583
		{
584 585 586 587 588
			ExecuteStmt *stmt = (ExecuteStmt *) parsetree;
			PreparedStatement *entry;

			if ((entry = FetchPreparedStatement(stmt->name, false)) != NULL &&
				entry->query_string)
589
			{
590 591 592 593
				*prepare_string = palloc(strlen(entry->query_string) +
							  strlen("  [client PREPARE:  %s]") - 1);
				sprintf(*prepare_string, "  [client PREPARE:  %s]",
							  entry->query_string);
594 595 596
			}
		}
	}
597 598 599 600 601 602 603 604 605 606
	
	if (log_this_statement)
	{
		ereport(LOG,
				(errmsg("statement: %s%s", query_string,
						*prepare_string ? *prepare_string : "")));
		return true;
	}
	else
		return false;
607 608
}

609

610
/*
611 612
 * Given a raw parsetree (gram.y output), and optionally information about
 * types of parameter symbols ($n), perform parse analysis and rule rewriting.
613 614 615 616 617 618
 *
 * A list of Query nodes is returned, since either the analyzer or the
 * rewriter might expand one query to several.
 *
 * NOTE: for reasons mentioned above, this must be separate from raw parsing.
 */
619
List *
620
pg_analyze_and_rewrite(Node *parsetree, Oid *paramTypes, int numParams)
621 622 623
{
	List	   *querytree_list;

624 625
	/*
	 * (1) Perform parse analysis.
626
	 */
B
Rename:  
Bruce Momjian 已提交
627
	if (log_parser_stats)
628 629
		ResetUsage();

630
	querytree_list = parse_analyze(parsetree, paramTypes, numParams);
631

B
Rename:  
Bruce Momjian 已提交
632
	if (log_parser_stats)
633
		ShowUsage("PARSE ANALYSIS STATISTICS");
634

635 636
	/*
	 * (2) Rewrite the queries, as necessary
637 638 639 640 641 642 643 644
	 */
	querytree_list = pg_rewrite_queries(querytree_list);

	return querytree_list;
}

/*
 * Perform rewriting of a list of queries produced by parse analysis.
645 646 647
 *
 * Note: queries must just have come from the parser, because we do not do
 * AcquireRewriteLocks() on them.
648
 */
649
static List *
650 651 652
pg_rewrite_queries(List *querytree_list)
{
	List	   *new_list = NIL;
653
	ListCell   *list_item;
654 655 656 657 658

	if (log_parser_stats)
		ResetUsage();

	/*
B
Bruce Momjian 已提交
659 660
	 * rewritten queries are collected in new_list.  Note there may be
	 * more or fewer than in the original list.
661
	 */
662
	foreach(list_item, querytree_list)
663
	{
664
		Query	   *querytree = (Query *) lfirst(list_item);
665

666
		if (Debug_print_parse)
667
			elog_node_display(DEBUG1, "parse tree", querytree,
668
							  Debug_pretty_print);
669 670 671

		if (querytree->commandType == CMD_UTILITY)
		{
672 673
			/* don't rewrite utilities, just dump 'em into new_list */
			new_list = lappend(new_list, querytree);
674
		}
675
		else
676
		{
677
			/* rewrite regular queries */
678 679
			List	   *rewritten = QueryRewrite(querytree);

680
			new_list = list_concat(new_list, rewritten);
681 682 683 684 685
		}
	}

	querytree_list = new_list;

B
Rename:  
Bruce Momjian 已提交
686
	if (log_parser_stats)
687
		ShowUsage("REWRITER STATISTICS");
688

689
#ifdef COPY_PARSE_PLAN_TREES
B
Bruce Momjian 已提交
690 691 692 693 694

	/*
	 * Optional debugging check: pass querytree output through
	 * copyObject()
	 */
695 696
	new_list = (List *) copyObject(querytree_list);
	/* This checks both copyObject() and the equal() routines... */
B
Bruce Momjian 已提交
697
	if (!equal(new_list, querytree_list))
698
		elog(WARNING, "copyObject() failed to produce an equal parse tree");
699 700
	else
		querytree_list = new_list;
701 702
#endif

703
	if (Debug_print_rewritten)
704
		elog_node_display(DEBUG1, "rewritten parse tree", querytree_list,
705
						  Debug_pretty_print);
706

707 708
	return querytree_list;
}
709 710


711
/* Generate a plan for a single already-rewritten query. */
712
Plan *
713
pg_plan_query(Query *querytree, ParamListInfo boundParams)
714 715
{
	Plan	   *plan;
716

717 718 719
	/* Utility commands have no plans. */
	if (querytree->commandType == CMD_UTILITY)
		return NULL;
720

B
Rename:  
Bruce Momjian 已提交
721
	if (log_planner_stats)
722
		ResetUsage();
723

724
	/* call the optimizer */
725
	plan = planner(querytree, false, 0, boundParams);
726

B
Rename:  
Bruce Momjian 已提交
727
	if (log_planner_stats)
728
		ShowUsage("PLANNER STATISTICS");
729

730 731 732
#ifdef COPY_PARSE_PLAN_TREES
	/* Optional debugging check: pass plan output through copyObject() */
	{
B
Bruce Momjian 已提交
733
		Plan	   *new_plan = (Plan *) copyObject(plan);
734

B
Bruce Momjian 已提交
735 736
		/*
		 * equal() currently does not have routines to compare Plan nodes,
737 738 739 740
		 * so don't try to test equality here.  Perhaps fix someday?
		 */
#ifdef NOT_USED
		/* This checks both copyObject() and the equal() routines... */
B
Bruce Momjian 已提交
741
		if (!equal(new_plan, plan))
742
			elog(WARNING, "copyObject() failed to produce an equal plan tree");
743 744 745 746 747 748
		else
#endif
			plan = new_plan;
	}
#endif

749 750
	/*
	 * Print plan if debugging.
751
	 */
752
	if (Debug_print_plan)
753
		elog_node_display(DEBUG1, "plan", plan, Debug_pretty_print);
754

755
	return plan;
756 757
}

758 759
/*
 * Generate plans for a list of already-rewritten queries.
760
 *
761 762 763 764 765 766 767 768 769
 * If needSnapshot is TRUE, we haven't yet set a snapshot for the current
 * query.  A snapshot must be set before invoking the planner, since it
 * might try to evaluate user-defined functions.  But we must not set a
 * snapshot if the list contains only utility statements, because some
 * utility statements depend on not having frozen the snapshot yet.
 * (We assume that such statements cannot appear together with plannable
 * statements in the rewriter's output.)
 */
List *
770 771
pg_plan_queries(List *querytrees, ParamListInfo boundParams,
				bool needSnapshot)
772 773
{
	List	   *plan_list = NIL;
774
	ListCell   *query_list;
775 776 777 778 779 780 781 782 783 784 785 786 787 788 789

	foreach(query_list, querytrees)
	{
		Query	   *query = (Query *) lfirst(query_list);
		Plan	   *plan;

		if (query->commandType == CMD_UTILITY)
		{
			/* Utility commands have no plans. */
			plan = NULL;
		}
		else
		{
			if (needSnapshot)
			{
790
				ActiveSnapshot = CopySnapshot(GetTransactionSnapshot());
791 792
				needSnapshot = false;
			}
793
			plan = pg_plan_query(query, boundParams);
794 795 796 797 798 799 800 801 802 803
		}

		plan_list = lappend(plan_list, plan);
	}

	return plan_list;
}


/*
804
 * exec_simple_query
805
 *
806
 * Execute a "simple Query" protocol message.
807
 */
808
static void
809
exec_simple_query(const char *query_string)
810
{
B
Bruce Momjian 已提交
811
	CommandDest dest = whereToSendOutput;
812
	MemoryContext oldcontext;
813 814
	List	   *parsetree_list;
	ListCell   *parsetree_item;
815
	struct timeval start_t, stop_t;
B
Rename:  
Bruce Momjian 已提交
816
	bool		save_log_duration = log_duration;
B
Bruce Momjian 已提交
817
	int			save_log_min_duration_statement = log_min_duration_statement;
818
	bool		save_log_statement_stats = log_statement_stats;
819 820 821
	char		*prepare_string = NULL;
	bool		was_logged = false;
	
822 823 824
	/*
	 * Report query to various monitoring facilities.
	 */
825
	debug_query_string = query_string;
826

827 828
	pgstat_report_activity(query_string);

829
	/*
B
Bruce Momjian 已提交
830 831 832 833
	 * We use save_log_* so "SET log_duration = true"  and "SET
	 * log_min_duration_statement = true" don't report incorrect time
	 * because gettimeofday() wasn't called. Similarly,
	 * log_statement_stats has to be captured once.
834
	 */
835
	if (save_log_duration || save_log_min_duration_statement != -1)
836
		gettimeofday(&start_t, NULL);
837

838 839 840
	if (save_log_statement_stats)
		ResetUsage();

841
	/*
B
Bruce Momjian 已提交
842 843 844 845
	 * Start up a transaction command.	All queries generated by the
	 * query_string will be in this same command block, *unless* we find a
	 * BEGIN/COMMIT/ABORT statement; we have to force a new xact command
	 * after one of those, else bad things will happen in xact.c. (Note
846
	 * that this will normally change current memory context.)
847 848
	 */
	start_xact_command();
849 850

	/*
B
Bruce Momjian 已提交
851 852 853 854
	 * Zap any pre-existing unnamed statement.	(While not strictly
	 * necessary, it seems best to define simple-Query mode as if it used
	 * the unnamed statement and portal; this ensures we recover any
	 * storage used by prior unnamed operations.)
855 856 857 858 859 860 861 862
	 */
	unnamed_stmt_pstmt = NULL;
	if (unnamed_stmt_context)
	{
		DropDependentPortals(unnamed_stmt_context);
		MemoryContextDelete(unnamed_stmt_context);
	}
	unnamed_stmt_context = NULL;
863

864 865 866
	/*
	 * Switch to appropriate context for constructing parsetrees.
	 */
867
	oldcontext = MemoryContextSwitchTo(MessageContext);
868

869 870
	QueryContext = CurrentMemoryContext;

B
Bruce Momjian 已提交
871
	/*
B
Bruce Momjian 已提交
872 873
	 * Do basic parsing of the query or queries (this should be safe even
	 * if we are in aborted transaction state!)
874
	 */
875
	parsetree_list = pg_parse_query(query_string);
876

877 878 879 880
	if (log_statement != LOGSTMT_NONE || save_log_min_duration_statement != -1)
		was_logged = log_after_parse(parsetree_list, query_string,
										&prepare_string);

881
	/*
882
	 * Switch back to transaction context to enter the loop.
883 884 885 886
	 */
	MemoryContextSwitchTo(oldcontext);

	/*
887
	 * Run through the raw parsetree(s) and process each one.
888
	 */
889
	foreach(parsetree_item, parsetree_list)
890
	{
B
Bruce Momjian 已提交
891
		Node	   *parsetree = (Node *) lfirst(parsetree_item);
892 893
		const char *commandTag;
		char		completionTag[COMPLETION_TAG_BUFSIZE];
B
Bruce Momjian 已提交
894
		List	   *querytree_list,
895 896
				   *plantree_list;
		Portal		portal;
897 898
		DestReceiver *receiver;
		int16		format;
899

900
		/*
B
Bruce Momjian 已提交
901 902 903 904
		 * Get the command name for use in status display (it also becomes
		 * the default completion tag, down inside PortalRun).	Set
		 * ps_status and do any special start-of-SQL-command processing
		 * needed by the destination.
905 906 907 908 909
		 */
		commandTag = CreateCommandTag(parsetree);

		set_ps_display(commandTag);

910
		BeginCommand(commandTag, dest);
911

912
		/*
913
		 * If we are in an aborted transaction, reject all commands except
914 915
		 * COMMIT/ABORT.  It is important that this test occur before we
		 * try to do parse analysis, rewrite, or planning, since all those
B
Bruce Momjian 已提交
916 917 918
		 * phases try to do database accesses, which may fail in abort
		 * state. (It might be safe to allow some additional utility
		 * commands in this state, but not many...)
919 920
		 */
		if (IsAbortedTransactionBlockState())
921
		{
B
Bruce Momjian 已提交
922
			bool		allowit = false;
923

924
			if (IsA(parsetree, TransactionStmt))
925 926 927
			{
				TransactionStmt *stmt = (TransactionStmt *) parsetree;

928
				if (stmt->kind == TRANS_STMT_COMMIT ||
929
					stmt->kind == TRANS_STMT_PREPARE ||
930 931
					stmt->kind == TRANS_STMT_ROLLBACK ||
					stmt->kind == TRANS_STMT_ROLLBACK_TO)
932
					allowit = true;
933
			}
934

B
Bruce Momjian 已提交
935
			if (!allowit)
936 937 938
				ereport(ERROR,
						(errcode(ERRCODE_IN_FAILED_SQL_TRANSACTION),
						 errmsg("current transaction is aborted, "
B
Bruce Momjian 已提交
939
					"commands ignored until end of transaction block")));
940
		}
941

942
		/* Make sure we are in a transaction command */
943
		start_xact_command();
944

945
		/* If we got a cancel signal in parsing or prior command, quit */
946
		CHECK_FOR_INTERRUPTS();
947 948

		/*
949
		 * OK to analyze, rewrite, and plan this query.
950
		 *
B
Bruce Momjian 已提交
951 952
		 * Switch to appropriate context for constructing querytrees (again,
		 * these must outlive the execution context).
953
		 */
954
		oldcontext = MemoryContextSwitchTo(MessageContext);
955

956
		querytree_list = pg_analyze_and_rewrite(parsetree, NULL, 0);
V
Vadim B. Mikheev 已提交
957

958
		plantree_list = pg_plan_queries(querytree_list, NULL, true);
959 960 961 962

		/* If we got a cancel signal in analysis or planning, quit */
		CHECK_FOR_INTERRUPTS();

963
		/*
B
Bruce Momjian 已提交
964 965
		 * Create unnamed portal to run the query or queries in. If there
		 * already is one, silently drop it.
966
		 */
967
		portal = CreatePortal("", true, true);
968

969 970 971 972 973 974
		PortalDefineQuery(portal,
						  query_string,
						  commandTag,
						  querytree_list,
						  plantree_list,
						  MessageContext);
975

976
		/*
977
		 * Start the portal.  No parameters here.
978
		 */
979
		PortalStart(portal, NULL, InvalidSnapshot);
980

981 982
		/*
		 * Select the appropriate output format: text unless we are doing
B
Bruce Momjian 已提交
983 984 985
		 * a FETCH from a binary cursor.  (Pretty grotty to have to do
		 * this here --- but it avoids grottiness in other places.	Ah,
		 * the joys of backward compatibility...)
986 987 988 989 990 991 992 993 994 995 996 997
		 */
		format = 0;				/* TEXT is default */
		if (IsA(parsetree, FetchStmt))
		{
			FetchStmt  *stmt = (FetchStmt *) parsetree;

			if (!stmt->ismove)
			{
				Portal		fportal = GetPortalByName(stmt->portalname);

				if (PortalIsValid(fportal) &&
					(fportal->cursorOptions & CURSOR_OPT_BINARY))
B
Bruce Momjian 已提交
998
					format = 1; /* BINARY */
999 1000 1001 1002 1003 1004 1005 1006 1007 1008 1009 1010 1011 1012 1013
			}
		}
		PortalSetResultFormat(portal, 1, &format);

		/*
		 * Now we can create the destination receiver object.
		 */
		receiver = CreateDestReceiver(dest, portal);

		/*
		 * Switch back to transaction context for execution.
		 */
		MemoryContextSwitchTo(oldcontext);

		/*
B
Bruce Momjian 已提交
1014 1015
		 * Run the portal to completion, and then drop it (and the
		 * receiver).
1016
		 */
1017 1018
		(void) PortalRun(portal,
						 FETCH_ALL,
1019 1020
						 receiver,
						 receiver,
1021
						 completionTag);
1022

1023
		(*receiver->rDestroy) (receiver);
1024

1025
		PortalDrop(portal, false);
1026

1027
		if (IsA(parsetree, TransactionStmt))
1028
		{
1029
			/*
B
Bruce Momjian 已提交
1030 1031 1032
			 * If this was a transaction control statement, commit it. We
			 * will start a new xact command for the next command (if
			 * any).
1033
			 */
1034
			finish_xact_command();
1035
		}
1036
		else if (lnext(parsetree_item) == NULL)
1037
		{
1038
			/*
B
Bruce Momjian 已提交
1039 1040 1041 1042 1043 1044 1045 1046 1047
			 * If this is the last parsetree of the query string, close
			 * down transaction statement before reporting
			 * command-complete.  This is so that any end-of-transaction
			 * errors are reported before the command-complete message is
			 * issued, to avoid confusing clients who will expect either a
			 * command-complete message or an error, not one and then the
			 * other.  But for compatibility with historical Postgres
			 * behavior, we do not force a transaction boundary between
			 * queries appearing in a single query string.
1048
			 */
1049
			finish_xact_command();
1050
		}
1051
		else
1052
		{
1053
			/*
B
Bruce Momjian 已提交
1054 1055
			 * We need a CommandCounterIncrement after every query, except
			 * those that start or end a transaction block.
1056 1057
			 */
			CommandCounterIncrement();
1058
		}
1059 1060 1061

		/*
		 * Tell client that we're done with this query.  Note we emit
B
Bruce Momjian 已提交
1062 1063 1064 1065
		 * exactly one EndCommand report for each raw parsetree, thus one
		 * for each SQL command the client sent, regardless of rewriting.
		 * (But a command aborted by error will not send an EndCommand
		 * report at all.)
1066
		 */
1067
		EndCommand(completionTag, dest);
B
Bruce Momjian 已提交
1068
	}							/* end loop over parsetrees */
1069

1070 1071 1072 1073 1074
	/*
	 * Close down transaction statement, if one is open.
	 */
	finish_xact_command();

1075 1076 1077
	/*
	 * If there were no parsetrees, return EmptyQueryResponse message.
	 */
1078
	if (!parsetree_list)
1079 1080
		NullCommand(dest);

1081
	QueryContext = NULL;
1082

1083
	/*
B
Bruce Momjian 已提交
1084 1085
	 * Combine processing here as we need to calculate the query duration
	 * in both instances.
1086
	 */
1087
	if (save_log_duration || save_log_min_duration_statement != -1)
1088
	{
B
Bruce Momjian 已提交
1089 1090
		long		usecs;

1091
		gettimeofday(&stop_t, NULL);
1092 1093 1094 1095 1096
		if (stop_t.tv_usec < start_t.tv_usec)
		{
			stop_t.tv_sec--;
			stop_t.tv_usec += 1000000;
		}
1097 1098
		usecs = (long) (stop_t.tv_sec - start_t.tv_sec) * 1000000 +
				(long) (stop_t.tv_usec - start_t.tv_usec);
B
Bruce Momjian 已提交
1099

1100
		/* Only print duration if we previously printed the statement. */
1101
		if (was_logged && save_log_duration)
B
Bruce Momjian 已提交
1102 1103
			ereport(LOG,
					(errmsg("duration: %ld.%03ld ms",
B
Bruce Momjian 已提交
1104 1105 1106
						(long) ((stop_t.tv_sec - start_t.tv_sec) * 1000 +
							  (stop_t.tv_usec - start_t.tv_usec) / 1000),
					 (long) (stop_t.tv_usec - start_t.tv_usec) % 1000)));
B
Bruce Momjian 已提交
1107

B
Bruce Momjian 已提交
1108
		/*
B
Bruce Momjian 已提交
1109 1110
		 * Output a duration_statement to the log if the query has
		 * exceeded the min duration, or if we are to print all durations.
B
Bruce Momjian 已提交
1111
		 */
B
Bruce Momjian 已提交
1112 1113 1114
		if (save_log_min_duration_statement == 0 ||
			(save_log_min_duration_statement > 0 &&
			 usecs >= save_log_min_duration_statement * 1000))
1115
			ereport(LOG,
1116
					(errmsg("duration: %ld.%03ld ms  statement: %s%s",
B
Bruce Momjian 已提交
1117 1118 1119
						(long) ((stop_t.tv_sec - start_t.tv_sec) * 1000 +
							  (stop_t.tv_usec - start_t.tv_usec) / 1000),
						(long) (stop_t.tv_usec - start_t.tv_usec) % 1000,
1120 1121
							query_string,
							prepare_string ? prepare_string : "")));
1122
	}
1123

1124 1125 1126
	if (save_log_statement_stats)
		ShowUsage("QUERY STATISTICS");

1127 1128 1129
	if (prepare_string != NULL)
		pfree(prepare_string);

1130
	debug_query_string = NULL;
1131 1132
}

1133 1134 1135 1136 1137 1138 1139 1140
/*
 * exec_parse_message
 *
 * Execute a "Parse" protocol message.
 */
static void
exec_parse_message(const char *query_string,	/* string to execute */
				   const char *stmt_name,		/* name for prepared stmt */
B
Bruce Momjian 已提交
1141 1142
				   Oid *paramTypes,		/* parameter types */
				   int numParams)		/* number of parameters */
1143 1144 1145 1146 1147 1148 1149 1150 1151 1152 1153 1154 1155 1156 1157 1158 1159 1160 1161 1162 1163 1164
{
	MemoryContext oldcontext;
	List	   *parsetree_list;
	const char *commandTag;
	List	   *querytree_list,
			   *plantree_list,
			   *param_list;
	bool		is_named;
	bool		save_log_statement_stats = log_statement_stats;

	/*
	 * Report query to various monitoring facilities.
	 */
	debug_query_string = query_string;

	pgstat_report_activity(query_string);

	set_ps_display("PARSE");

	if (save_log_statement_stats)
		ResetUsage();

1165 1166
	if (log_statement == LOGSTMT_ALL)
		ereport(LOG,
1167 1168 1169
				(errmsg("statement: PREPARE %s AS %s",
						(*stmt_name != '\0') ? stmt_name : "<unnamed>",
						query_string)));
1170

1171 1172 1173 1174 1175 1176 1177 1178 1179 1180
	/*
	 * Start up a transaction command so we can run parse analysis etc.
	 * (Note that this will normally change current memory context.)
	 * Nothing happens if we are already in one.
	 */
	start_xact_command();

	/*
	 * Switch to appropriate context for constructing parsetrees.
	 *
B
Bruce Momjian 已提交
1181 1182 1183 1184 1185 1186 1187 1188 1189 1190
	 * We have two strategies depending on whether the prepared statement is
	 * named or not.  For a named prepared statement, we do parsing in
	 * MessageContext and copy the finished trees into the prepared
	 * statement's private context; then the reset of MessageContext
	 * releases temporary space used by parsing and planning.  For an
	 * unnamed prepared statement, we assume the statement isn't going to
	 * hang around long, so getting rid of temp space quickly is probably
	 * not worth the costs of copying parse/plan trees.  So in this case,
	 * we set up a special context for the unnamed statement, and do all
	 * the parsing/planning therein.
1191 1192 1193 1194 1195 1196 1197 1198 1199 1200 1201 1202 1203 1204 1205 1206 1207 1208 1209 1210 1211 1212 1213 1214 1215 1216 1217 1218 1219 1220 1221 1222 1223 1224 1225 1226
	 */
	is_named = (stmt_name[0] != '\0');
	if (is_named)
	{
		/* Named prepared statement --- parse in MessageContext */
		oldcontext = MemoryContextSwitchTo(MessageContext);
	}
	else
	{
		/* Unnamed prepared statement --- release any prior unnamed stmt */
		unnamed_stmt_pstmt = NULL;
		if (unnamed_stmt_context)
		{
			DropDependentPortals(unnamed_stmt_context);
			MemoryContextDelete(unnamed_stmt_context);
		}
		unnamed_stmt_context = NULL;
		/* create context for parsing/planning */
		unnamed_stmt_context =
			AllocSetContextCreate(TopMemoryContext,
								  "unnamed prepared statement",
								  ALLOCSET_DEFAULT_MINSIZE,
								  ALLOCSET_DEFAULT_INITSIZE,
								  ALLOCSET_DEFAULT_MAXSIZE);
		oldcontext = MemoryContextSwitchTo(unnamed_stmt_context);
	}

	QueryContext = CurrentMemoryContext;

	/*
	 * Do basic parsing of the query or queries (this should be safe even
	 * if we are in aborted transaction state!)
	 */
	parsetree_list = pg_parse_query(query_string);

	/*
B
Bruce Momjian 已提交
1227 1228 1229
	 * We only allow a single user statement in a prepared statement. This
	 * is mainly to keep the protocol simple --- otherwise we'd need to
	 * worry about multiple result tupdescs and things like that.
1230
	 */
1231
	if (list_length(parsetree_list) > 1)
1232 1233 1234
		ereport(ERROR,
				(errcode(ERRCODE_SYNTAX_ERROR),
				 errmsg("cannot insert multiple commands into a prepared statement")));
1235 1236 1237

	if (parsetree_list != NIL)
	{
1238
		Node	   *parsetree = (Node *) linitial(parsetree_list);
B
Bruce Momjian 已提交
1239
		int			i;
1240 1241 1242 1243 1244 1245 1246 1247

		/*
		 * Get the command name for possible use in status display.
		 */
		commandTag = CreateCommandTag(parsetree);

		/*
		 * If we are in an aborted transaction, reject all commands except
B
Bruce Momjian 已提交
1248 1249 1250 1251
		 * COMMIT/ROLLBACK.  It is important that this test occur before
		 * we try to do parse analysis, rewrite, or planning, since all
		 * those phases try to do database accesses, which may fail in
		 * abort state. (It might be safe to allow some additional utility
1252 1253 1254 1255 1256 1257 1258 1259 1260 1261 1262
		 * commands in this state, but not many...)
		 */
		if (IsAbortedTransactionBlockState())
		{
			bool		allowit = false;

			if (IsA(parsetree, TransactionStmt))
			{
				TransactionStmt *stmt = (TransactionStmt *) parsetree;

				if (stmt->kind == TRANS_STMT_COMMIT ||
1263
					stmt->kind == TRANS_STMT_PREPARE ||
1264 1265
					stmt->kind == TRANS_STMT_ROLLBACK ||
					stmt->kind == TRANS_STMT_ROLLBACK_TO)
1266 1267 1268 1269
					allowit = true;
			}

			if (!allowit)
1270 1271 1272
				ereport(ERROR,
						(errcode(ERRCODE_IN_FAILED_SQL_TRANSACTION),
						 errmsg("current transaction is aborted, "
B
Bruce Momjian 已提交
1273
					"commands ignored until end of transaction block")));
1274 1275 1276 1277 1278 1279 1280 1281 1282 1283 1284 1285 1286 1287 1288 1289 1290 1291 1292 1293 1294
		}

		/*
		 * OK to analyze, rewrite, and plan this query.  Note that the
		 * originally specified parameter set is not required to be
		 * complete, so we have to use parse_analyze_varparams().
		 */
		if (log_parser_stats)
			ResetUsage();

		querytree_list = parse_analyze_varparams(parsetree,
												 &paramTypes,
												 &numParams);

		/*
		 * Check all parameter types got determined, and convert array
		 * representation to a list for storage.
		 */
		param_list = NIL;
		for (i = 0; i < numParams; i++)
		{
B
Bruce Momjian 已提交
1295
			Oid			ptype = paramTypes[i];
1296 1297

			if (ptype == InvalidOid || ptype == UNKNOWNOID)
1298 1299
				ereport(ERROR,
						(errcode(ERRCODE_INDETERMINATE_DATATYPE),
B
Bruce Momjian 已提交
1300 1301
				 errmsg("could not determine data type of parameter $%d",
						i + 1)));
1302
			param_list = lappend_oid(param_list, ptype);
1303 1304 1305 1306 1307 1308 1309
		}

		if (log_parser_stats)
			ShowUsage("PARSE ANALYSIS STATISTICS");

		querytree_list = pg_rewrite_queries(querytree_list);

1310 1311 1312 1313 1314 1315 1316 1317
		/*
		 * If this is the unnamed statement and it has parameters, defer
		 * query planning until Bind.  Otherwise do it now.
		 */
		if (!is_named && numParams > 0)
			plantree_list = NIL;
		else
			plantree_list = pg_plan_queries(querytree_list, NULL, true);
1318 1319 1320
	}
	else
	{
B
Bruce Momjian 已提交
1321
		/* Empty input string.	This is legal. */
1322 1323 1324 1325 1326 1327 1328 1329 1330 1331 1332 1333 1334 1335 1336 1337 1338 1339 1340 1341 1342 1343 1344 1345 1346 1347 1348 1349 1350 1351 1352 1353 1354 1355 1356 1357 1358 1359 1360 1361 1362 1363 1364
		commandTag = NULL;
		querytree_list = NIL;
		plantree_list = NIL;
		param_list = NIL;
	}

	/* If we got a cancel signal in analysis or planning, quit */
	CHECK_FOR_INTERRUPTS();

	/*
	 * Store the query as a prepared statement.  See above comments.
	 */
	if (is_named)
	{
		StorePreparedStatement(stmt_name,
							   query_string,
							   commandTag,
							   querytree_list,
							   plantree_list,
							   param_list);
	}
	else
	{
		PreparedStatement *pstmt;

		pstmt = (PreparedStatement *) palloc0(sizeof(PreparedStatement));
		/* query_string needs to be copied into unnamed_stmt_context */
		pstmt->query_string = pstrdup(query_string);
		/* the rest is there already */
		pstmt->commandTag = commandTag;
		pstmt->query_list = querytree_list;
		pstmt->plan_list = plantree_list;
		pstmt->argtype_list = param_list;
		pstmt->context = unnamed_stmt_context;
		/* Now the unnamed statement is complete and valid */
		unnamed_stmt_pstmt = pstmt;
	}

	MemoryContextSwitchTo(oldcontext);

	QueryContext = NULL;

	/*
B
Bruce Momjian 已提交
1365 1366 1367 1368
	 * We do NOT close the open transaction command here; that only
	 * happens when the client sends Sync.	Instead, do
	 * CommandCounterIncrement just in case something happened during
	 * parse/plan.
1369 1370 1371 1372 1373 1374 1375 1376 1377 1378 1379 1380 1381 1382 1383 1384 1385 1386 1387 1388 1389 1390 1391 1392 1393
	 */
	CommandCounterIncrement();

	/*
	 * Send ParseComplete.
	 */
	if (whereToSendOutput == Remote)
		pq_putemptymessage('1');

	if (save_log_statement_stats)
		ShowUsage("PARSE MESSAGE STATISTICS");

	debug_query_string = NULL;
}

/*
 * exec_bind_message
 *
 * Process a "Bind" message to create a portal from a prepared statement
 */
static void
exec_bind_message(StringInfo input_message)
{
	const char *portal_name;
	const char *stmt_name;
1394 1395
	int			numPFormats;
	int16	   *pformats = NULL;
1396
	int			numParams;
1397 1398 1399
	int			numRFormats;
	int16	   *rformats = NULL;
	int			i;
1400 1401 1402
	PreparedStatement *pstmt;
	Portal		portal;
	ParamListInfo params;
1403
	bool		isaborted = IsAbortedTransactionBlockState();
1404 1405 1406 1407 1408 1409

	pgstat_report_activity("<BIND>");

	set_ps_display("BIND");

	/*
B
Bruce Momjian 已提交
1410 1411 1412
	 * Start up a transaction command so we can call functions etc. (Note
	 * that this will normally change current memory context.) Nothing
	 * happens if we are already in one.
1413 1414 1415
	 */
	start_xact_command();

1416 1417 1418
	/* Switch back to message context */
	MemoryContextSwitchTo(MessageContext);

1419 1420 1421 1422
	/* Get the fixed part of the message */
	portal_name = pq_getmsgstring(input_message);
	stmt_name = pq_getmsgstring(input_message);

1423 1424 1425 1426 1427 1428 1429 1430 1431 1432 1433 1434 1435
	/* Get the parameter format codes */
	numPFormats = pq_getmsgint(input_message, 2);
	if (numPFormats > 0)
	{
		pformats = (int16 *) palloc(numPFormats * sizeof(int16));
		for (i = 0; i < numPFormats; i++)
			pformats[i] = pq_getmsgint(input_message, 2);
	}

	/* Get the parameter value count */
	numParams = pq_getmsgint(input_message, 2);

	if (numPFormats > 1 && numPFormats != numParams)
1436 1437
		ereport(ERROR,
				(errcode(ERRCODE_PROTOCOL_VIOLATION),
B
Bruce Momjian 已提交
1438 1439
		errmsg("bind message has %d parameter formats but %d parameters",
			   numPFormats, numParams)));
1440 1441 1442 1443 1444 1445 1446 1447 1448

	/* Find prepared statement */
	if (stmt_name[0] != '\0')
		pstmt = FetchPreparedStatement(stmt_name, true);
	else
	{
		/* special-case the unnamed statement */
		pstmt = unnamed_stmt_pstmt;
		if (!pstmt)
1449 1450
			ereport(ERROR,
					(errcode(ERRCODE_UNDEFINED_PSTATEMENT),
B
Bruce Momjian 已提交
1451
				   errmsg("unnamed prepared statement does not exist")));
1452 1453
	}

1454
	if (numParams != list_length(pstmt->argtype_list))
1455 1456 1457
		ereport(ERROR,
				(errcode(ERRCODE_PROTOCOL_VIOLATION),
				 errmsg("bind message supplies %d parameters, but prepared statement \"%s\" requires %d",
B
Bruce Momjian 已提交
1458
			   numParams, stmt_name, list_length(pstmt->argtype_list))));
1459 1460 1461 1462 1463 1464 1465 1466 1467 1468

	/*
	 * Create the portal.  Allow silent replacement of an existing portal
	 * only if the unnamed portal is specified.
	 */
	if (portal_name[0] == '\0')
		portal = CreatePortal(portal_name, true, true);
	else
		portal = CreatePortal(portal_name, false, false);

1469
	/* We need to output the parameter values someday */
1470 1471 1472 1473
	if (log_statement == LOGSTMT_ALL)
		ereport(LOG,
				(errmsg("statement: <BIND> %s", portal_name)));

1474 1475 1476
	/*
	 * Fetch parameters, if any, and store in the portal's memory context.
	 *
B
Bruce Momjian 已提交
1477 1478 1479
	 * In an aborted transaction, we can't risk calling user-defined
	 * functions, but we can't fail to Bind either, so bind all parameters
	 * to null values.
1480 1481 1482
	 */
	if (numParams > 0)
	{
1483
		ListCell   *l;
1484 1485 1486 1487 1488 1489 1490
		MemoryContext oldContext;

		oldContext = MemoryContextSwitchTo(PortalGetHeapMemory(portal));

		params = (ParamListInfo)
			palloc0((numParams + 1) * sizeof(ParamListInfoData));

1491
		i = 0;
1492 1493
		foreach(l, pstmt->argtype_list)
		{
1494
			Oid			ptype = lfirst_oid(l);
1495
			int32		plength;
1496 1497
			bool		isNull;

1498 1499 1500
			plength = pq_getmsgint(input_message, 4);
			isNull = (plength == -1);

1501 1502
			if (!isNull)
			{
1503
				const char *pvalue = pq_getmsgbytes(input_message, plength);
1504 1505

				if (isaborted)
1506 1507
				{
					/* We don't bother to check the format in this case */
1508
					isNull = true;
1509
				}
1510 1511
				else
				{
B
Bruce Momjian 已提交
1512
					int16		pformat;
1513
					StringInfoData pbuf;
B
Bruce Momjian 已提交
1514
					char		csave;
1515 1516 1517 1518 1519 1520

					if (numPFormats > 1)
						pformat = pformats[i];
					else if (numPFormats > 0)
						pformat = pformats[0];
					else
B
Bruce Momjian 已提交
1521
						pformat = 0;	/* default = text */
1522

1523
					/*
B
Bruce Momjian 已提交
1524 1525 1526 1527 1528 1529 1530
					 * Rather than copying data around, we just set up a
					 * phony StringInfo pointing to the correct portion of
					 * the message buffer.	We assume we can scribble on
					 * the message buffer so as to maintain the convention
					 * that StringInfos have a trailing null.  This is
					 * grotty but is a big win when dealing with very
					 * large parameter strings.
1531 1532 1533 1534 1535 1536 1537 1538 1539
					 */
					pbuf.data = (char *) pvalue;
					pbuf.maxlen = plength + 1;
					pbuf.len = plength;
					pbuf.cursor = 0;

					csave = pbuf.data[plength];
					pbuf.data[plength] = '\0';

1540 1541
					if (pformat == 0)
					{
1542 1543
						Oid			typinput;
						Oid			typioparam;
1544 1545
						char	   *pstring;

1546
						getTypeInputInfo(ptype, &typinput, &typioparam);
B
Bruce Momjian 已提交
1547

1548
						/*
B
Bruce Momjian 已提交
1549 1550
						 * We have to do encoding conversion before
						 * calling the typinput routine.
1551
						 */
1552
						pstring = pg_client_to_server(pbuf.data, plength);
1553
						params[i].value =
1554
							OidFunctionCall3(typinput,
1555
											 CStringGetDatum(pstring),
1556
											 ObjectIdGetDatum(typioparam),
1557 1558 1559 1560 1561 1562 1563
											 Int32GetDatum(-1));
						/* Free result of encoding conversion, if any */
						if (pstring != pbuf.data)
							pfree(pstring);
					}
					else if (pformat == 1)
					{
1564 1565
						Oid			typreceive;
						Oid			typioparam;
1566

B
Bruce Momjian 已提交
1567 1568 1569 1570
						/*
						 * Call the parameter type's binary input
						 * converter
						 */
1571
						getTypeBinaryInputInfo(ptype, &typreceive, &typioparam);
1572 1573

						params[i].value =
1574
							OidFunctionCall3(typreceive,
1575
											 PointerGetDatum(&pbuf),
1576 1577
											 ObjectIdGetDatum(typioparam),
											 Int32GetDatum(-1));
1578 1579 1580

						/* Trouble if it didn't eat the whole buffer */
						if (pbuf.cursor != pbuf.len)
1581 1582 1583
							ereport(ERROR,
									(errcode(ERRCODE_INVALID_BINARY_REPRESENTATION),
									 errmsg("incorrect binary data format in bind parameter %d",
B
Bruce Momjian 已提交
1584
											i + 1)));
1585 1586 1587
					}
					else
					{
1588 1589 1590 1591
						ereport(ERROR,
								(errcode(ERRCODE_INVALID_PARAMETER_VALUE),
								 errmsg("unsupported format code: %d",
										pformat)));
1592
					}
1593 1594 1595

					/* Restore message buffer contents */
					pbuf.data[plength] = csave;
1596 1597
				}
			}
1598

1599 1600
			params[i].kind = PARAM_NUM;
			params[i].id = i + 1;
1601
			params[i].ptype = ptype;
1602 1603 1604 1605 1606 1607 1608 1609 1610 1611 1612 1613
			params[i].isnull = isNull;

			i++;
		}

		params[i].kind = PARAM_INVALID;

		MemoryContextSwitchTo(oldContext);
	}
	else
		params = NULL;

1614 1615 1616 1617 1618 1619 1620 1621 1622
	/* Get the result format codes */
	numRFormats = pq_getmsgint(input_message, 2);
	if (numRFormats > 0)
	{
		rformats = (int16 *) palloc(numRFormats * sizeof(int16));
		for (i = 0; i < numRFormats; i++)
			rformats[i] = pq_getmsgint(input_message, 2);
	}

1623 1624 1625
	pq_getmsgend(input_message);

	/*
1626 1627 1628
	 * If we didn't plan the query before, do it now.  This allows the
	 * planner to make use of the concrete parameter values we now have.
	 *
B
Bruce Momjian 已提交
1629 1630
	 * This happens only for unnamed statements, and so switching into the
	 * statement context for planning is correct (see notes in
1631
	 * exec_parse_message).
1632
	 */
1633 1634 1635 1636 1637 1638 1639 1640 1641 1642 1643 1644 1645 1646 1647 1648 1649 1650 1651
	if (pstmt->plan_list == NIL && pstmt->query_list != NIL &&
		!isaborted)
	{
		MemoryContext oldContext = MemoryContextSwitchTo(pstmt->context);

		pstmt->plan_list = pg_plan_queries(pstmt->query_list, params, true);
		MemoryContextSwitchTo(oldContext);
	}

	/*
	 * Define portal and start execution.
	 */
	PortalDefineQuery(portal,
					  pstmt->query_string,
					  pstmt->commandTag,
					  pstmt->query_list,
					  pstmt->plan_list,
					  pstmt->context);

1652
	PortalStart(portal, params, InvalidSnapshot);
1653

1654 1655 1656 1657 1658
	/*
	 * Apply the result format requests to the portal.
	 */
	PortalSetResultFormat(portal, numRFormats, rformats);

1659 1660 1661 1662 1663 1664 1665 1666 1667 1668 1669 1670 1671
	/*
	 * Send BindComplete.
	 */
	if (whereToSendOutput == Remote)
		pq_putemptymessage('2');
}

/*
 * exec_execute_message
 *
 * Process an "Execute" message for a portal
 */
static void
1672
exec_execute_message(const char *portal_name, long max_rows)
1673
{
B
Bruce Momjian 已提交
1674
	CommandDest dest;
1675
	DestReceiver *receiver;
1676 1677 1678 1679 1680
	Portal		portal;
	bool		is_trans_stmt = false;
	bool		is_trans_exit = false;
	bool		completed;
	char		completionTag[COMPLETION_TAG_BUFSIZE];
1681 1682 1683 1684
	struct timeval start_t,	stop_t;
	bool		save_log_duration = log_duration;
	int			save_log_min_duration_statement = log_min_duration_statement;
	bool		save_log_statement_stats = log_statement_stats;
1685
	bool		execute_is_fetch = false;
1686 1687 1688 1689

	/* Adjust destination to tell printtup.c what to do */
	dest = whereToSendOutput;
	if (dest == Remote)
1690
		dest = RemoteExecute;
1691 1692 1693

	portal = GetPortalByName(portal_name);
	if (!PortalIsValid(portal))
1694 1695 1696
		ereport(ERROR,
				(errcode(ERRCODE_UNDEFINED_CURSOR),
				 errmsg("portal \"%s\" does not exist", portal_name)));
1697

1698 1699 1700 1701 1702 1703 1704 1705 1706
	/*
	 * If we re-issue an Execute protocol request against an existing
	 * portal, then we are only fetching more rows rather than 
	 * completely re-executing the query from the start. atStart is never
	 * reset for a v3 portal, so we are safe to use this check.
	 */
	if (!portal->atStart)
		execute_is_fetch = true;

1707
	/*
B
Bruce Momjian 已提交
1708 1709
	 * If the original query was a null string, just return
	 * EmptyQueryResponse.
1710 1711 1712 1713 1714 1715 1716 1717
	 */
	if (portal->commandTag == NULL)
	{
		Assert(portal->parseTrees == NIL);
		NullCommand(dest);
		return;
	}

1718 1719 1720 1721 1722 1723 1724
	/* Should we display the portal names here? */
	if (execute_is_fetch)
	{
		debug_query_string = "fetch message";
		pgstat_report_activity("<FETCH>");
	}
	else if (portal->sourceText)
1725 1726 1727 1728 1729 1730 1731 1732 1733 1734 1735 1736
	{
		debug_query_string = portal->sourceText;
		pgstat_report_activity(portal->sourceText);
	}
	else
	{
		debug_query_string = "execute message";
		pgstat_report_activity("<EXECUTE>");
	}

	set_ps_display(portal->commandTag);

1737 1738 1739 1740 1741 1742 1743 1744 1745 1746 1747 1748 1749 1750 1751
	/*
	 * We use save_log_* so "SET log_duration = true"  and "SET
	 * log_min_duration_statement = true" don't report incorrect time
	 * because gettimeofday() wasn't called. Similarly,
	 * log_statement_stats has to be captured once.
	 */
	if (save_log_duration || save_log_min_duration_statement != -1)
		gettimeofday(&start_t, NULL);

	if (save_log_statement_stats)
		ResetUsage();

	if (log_statement == LOGSTMT_ALL)
		/* We have the portal, so output the source query. */
		ereport(LOG,
1752 1753
				(errmsg("statement: %sEXECUTE %s  [PREPARE:  %s]",
						(execute_is_fetch) ? "FETCH from " : "",
1754
						(*portal_name != '\0') ? portal_name : "<unnamed>",
1755 1756
						portal->sourceText ? portal->sourceText : "")));

1757 1758 1759
	BeginCommand(portal->commandTag, dest);

	/* Check for transaction-control commands */
1760
	if (list_length(portal->parseTrees) == 1)
1761
	{
1762
		Query	   *query = (Query *) linitial(portal->parseTrees);
1763 1764 1765 1766 1767 1768 1769 1770 1771

		if (query->commandType == CMD_UTILITY &&
			query->utilityStmt != NULL &&
			IsA(query->utilityStmt, TransactionStmt))
		{
			TransactionStmt *stmt = (TransactionStmt *) query->utilityStmt;

			is_trans_stmt = true;
			if (stmt->kind == TRANS_STMT_COMMIT ||
1772
				stmt->kind == TRANS_STMT_PREPARE ||
1773 1774
				stmt->kind == TRANS_STMT_ROLLBACK ||
				stmt->kind == TRANS_STMT_ROLLBACK_TO)
1775 1776 1777 1778
				is_trans_exit = true;
		}
	}

1779
	/*
B
Bruce Momjian 已提交
1780 1781 1782
	 * Create dest receiver in MessageContext (we don't want it in
	 * transaction context, because that may get deleted if portal
	 * contains VACUUM).
1783 1784 1785
	 */
	receiver = CreateDestReceiver(dest, portal);

1786
	/*
B
Bruce Momjian 已提交
1787 1788
	 * Ensure we are in a transaction command (this should normally be the
	 * case already due to prior BIND).
1789 1790 1791 1792 1793 1794 1795 1796 1797 1798
	 */
	start_xact_command();

	/*
	 * If we are in aborted transaction state, the only portals we can
	 * actually run are those containing COMMIT or ROLLBACK commands.
	 */
	if (IsAbortedTransactionBlockState())
	{
		if (!is_trans_exit)
1799 1800 1801
			ereport(ERROR,
					(errcode(ERRCODE_IN_FAILED_SQL_TRANSACTION),
					 errmsg("current transaction is aborted, "
B
Bruce Momjian 已提交
1802
					"commands ignored until end of transaction block")));
1803 1804 1805 1806 1807 1808 1809 1810 1811 1812 1813 1814 1815
	}

	/* Check for cancel signal before we start execution */
	CHECK_FOR_INTERRUPTS();

	/*
	 * Okay to run the portal.
	 */
	if (max_rows <= 0)
		max_rows = FETCH_ALL;

	completed = PortalRun(portal,
						  max_rows,
1816 1817
						  receiver,
						  receiver,
1818 1819
						  completionTag);

1820
	(*receiver->rDestroy) (receiver);
1821

1822 1823 1824 1825 1826
	if (completed)
	{
		if (is_trans_stmt)
		{
			/*
B
Bruce Momjian 已提交
1827 1828 1829
			 * If this was a transaction control statement, commit it.	We
			 * will start a new xact command for the next command (if
			 * any).
1830
			 */
1831
			finish_xact_command();
1832 1833 1834 1835
		}
		else
		{
			/*
B
Bruce Momjian 已提交
1836 1837
			 * We need a CommandCounterIncrement after every query, except
			 * those that start or end a transaction block.
1838 1839 1840 1841 1842 1843 1844 1845 1846 1847 1848 1849 1850 1851
			 */
			CommandCounterIncrement();
		}

		/* Send appropriate CommandComplete to client */
		EndCommand(completionTag, dest);
	}
	else
	{
		/* Portal run not complete, so send PortalSuspended */
		if (whereToSendOutput == Remote)
			pq_putemptymessage('s');
	}

1852 1853 1854 1855 1856 1857 1858 1859 1860 1861 1862 1863 1864 1865 1866 1867 1868 1869 1870 1871 1872 1873 1874 1875 1876 1877 1878 1879 1880 1881 1882 1883 1884
	/*
	 * Combine processing here as we need to calculate the query duration
	 * in both instances.
	 */
	if (save_log_duration || save_log_min_duration_statement != -1)
	{
		long		usecs;

		gettimeofday(&stop_t, NULL);
		if (stop_t.tv_usec < start_t.tv_usec)
		{
			stop_t.tv_sec--;
			stop_t.tv_usec += 1000000;
		}
		usecs = (long) (stop_t.tv_sec - start_t.tv_sec) * 1000000 +
				(long) (stop_t.tv_usec - start_t.tv_usec);

		/* Only print duration if we previously printed the statement. */
		if (log_statement == LOGSTMT_ALL && save_log_duration)
			ereport(LOG,
					(errmsg("duration: %ld.%03ld ms",
						(long) ((stop_t.tv_sec - start_t.tv_sec) * 1000 +
							  (stop_t.tv_usec - start_t.tv_usec) / 1000),
					 (long) (stop_t.tv_usec - start_t.tv_usec) % 1000)));

		/*
		 * Output a duration_statement to the log if the query has
		 * exceeded the min duration, or if we are to print all durations.
		 */
		if (save_log_min_duration_statement == 0 ||
			(save_log_min_duration_statement > 0 &&
			 usecs >= save_log_min_duration_statement * 1000))
			ereport(LOG,
1885
					(errmsg("duration: %ld.%03ld ms  statement: %sEXECUTE %s  [PREPARE:  %s]",
1886 1887 1888
						(long) ((stop_t.tv_sec - start_t.tv_sec) * 1000 +
							  (stop_t.tv_usec - start_t.tv_usec) / 1000),
						(long) (stop_t.tv_usec - start_t.tv_usec) % 1000,
1889
							(execute_is_fetch) ? "FETCH from " : "",
1890
							(*portal_name != '\0') ? portal_name : "<unnamed>",
1891 1892 1893 1894 1895 1896
							portal->sourceText ? portal->sourceText : "")));
	}

	if (save_log_statement_stats)
		ShowUsage("QUERY STATISTICS");

1897 1898 1899 1900 1901 1902 1903 1904 1905 1906 1907 1908
	debug_query_string = NULL;
}

/*
 * exec_describe_statement_message
 *
 * Process a "Describe" message for a prepared statement
 */
static void
exec_describe_statement_message(const char *stmt_name)
{
	PreparedStatement *pstmt;
1909
	TupleDesc	tupdesc;
1910
	ListCell   *l;
1911 1912 1913 1914 1915 1916 1917 1918 1919 1920
	StringInfoData buf;

	/* Find prepared statement */
	if (stmt_name[0] != '\0')
		pstmt = FetchPreparedStatement(stmt_name, true);
	else
	{
		/* special-case the unnamed statement */
		pstmt = unnamed_stmt_pstmt;
		if (!pstmt)
1921 1922
			ereport(ERROR,
					(errcode(ERRCODE_UNDEFINED_PSTATEMENT),
B
Bruce Momjian 已提交
1923
				   errmsg("unnamed prepared statement does not exist")));
1924 1925 1926 1927 1928
	}

	if (whereToSendOutput != Remote)
		return;					/* can't actually do anything... */

1929 1930 1931
	/*
	 * First describe the parameters...
	 */
B
Bruce Momjian 已提交
1932
	pq_beginmessage(&buf, 't'); /* parameter description message type */
1933
	pq_sendint(&buf, list_length(pstmt->argtype_list), 2);
1934 1935 1936

	foreach(l, pstmt->argtype_list)
	{
1937
		Oid			ptype = lfirst_oid(l);
1938 1939 1940 1941

		pq_sendint(&buf, (int) ptype, 4);
	}
	pq_endmessage(&buf);
1942 1943 1944 1945 1946 1947

	/*
	 * Next send RowDescription or NoData to describe the result...
	 */
	tupdesc = FetchPreparedStatementResultDesc(pstmt);
	if (tupdesc)
1948 1949 1950
		SendRowDescriptionMessage(tupdesc,
								  FetchPreparedStatementTargetList(pstmt),
								  NULL);
1951 1952 1953
	else
		pq_putemptymessage('n');	/* NoData */

1954 1955 1956 1957 1958 1959 1960 1961 1962 1963 1964 1965 1966 1967
}

/*
 * exec_describe_portal_message
 *
 * Process a "Describe" message for a portal
 */
static void
exec_describe_portal_message(const char *portal_name)
{
	Portal		portal;

	portal = GetPortalByName(portal_name);
	if (!PortalIsValid(portal))
1968 1969 1970
		ereport(ERROR,
				(errcode(ERRCODE_UNDEFINED_CURSOR),
				 errmsg("portal \"%s\" does not exist", portal_name)));
1971 1972 1973 1974 1975

	if (whereToSendOutput != Remote)
		return;					/* can't actually do anything... */

	if (portal->tupDesc)
1976 1977
		SendRowDescriptionMessage(portal->tupDesc,
								  FetchPortalTargetList(portal),
1978
								  portal->formats);
1979 1980 1981 1982 1983
	else
		pq_putemptymessage('n');	/* NoData */
}


1984 1985 1986 1987 1988 1989
/*
 * Convenience routines for starting/committing a single command.
 */
static void
start_xact_command(void)
{
1990 1991
	if (!xact_started)
	{
1992 1993
		ereport(DEBUG3,
				(errmsg_internal("StartTransactionCommand")));
1994
		StartTransactionCommand();
1995 1996 1997 1998

		/* Set statement timeout running, if any */
		if (StatementTimeout > 0)
			enable_sig_alarm(StatementTimeout, true);
1999 2000 2001
		else
			cancel_from_timeout = false;
		
2002 2003
		xact_started = true;
	}
2004 2005 2006
}

static void
2007
finish_xact_command(void)
2008
{
2009 2010 2011 2012
	if (xact_started)
	{
		/* Cancel any active statement timeout before committing */
		disable_sig_alarm(true);
2013

2014
		/* Now commit the command */
2015 2016
		ereport(DEBUG3,
				(errmsg_internal("CommitTransactionCommand")));
2017

2018
		CommitTransactionCommand();
2019

2020 2021 2022 2023 2024 2025
#ifdef MEMORY_CONTEXT_CHECKING
		/* Check all memory contexts that weren't freed during commit */
		/* (those that were, were checked before being deleted) */
		MemoryContextCheck(TopMemoryContext);
#endif

2026
#ifdef SHOW_MEMORY_STATS
2027
		/* Print mem stats after each commit for leak tracking */
2028 2029
		if (ShowStats)
			MemoryContextStats(TopMemoryContext);
2030
#endif
2031 2032 2033

		xact_started = false;
	}
2034 2035 2036
}


2037
/* --------------------------------
2038
 *		signal handler routines used in PostgresMain()
2039 2040 2041
 * --------------------------------
 */

2042
/*
T
Tom Lane 已提交
2043
 * quickdie() occurs when signalled SIGQUIT by the postmaster.
2044 2045 2046 2047
 *
 * Some backend has bought the farm,
 * so we need to stop what we're doing and exit.
 */
T
Tom Lane 已提交
2048
void
2049
quickdie(SIGNAL_ARGS)
2050
{
2051
	PG_SETMASK(&BlockSig);
B
Bruce Momjian 已提交
2052

2053
	/*
B
Bruce Momjian 已提交
2054
	 * Ideally this should be ereport(FATAL), but then we'd not get
2055
	 * control back...
2056 2057 2058
	 */
	ereport(WARNING,
			(errcode(ERRCODE_CRASH_SHUTDOWN),
B
Bruce Momjian 已提交
2059 2060 2061 2062 2063
			 errmsg("terminating connection because of crash of another server process"),
			 errdetail("The postmaster has commanded this server process to roll back"
					 " the current transaction and exit, because another"
			   " server process exited abnormally and possibly corrupted"
					   " shared memory."),
2064
			 errhint("In a moment you should be able to reconnect to the"
2065
					 " database and repeat your command.")));
B
Bruce Momjian 已提交
2066

2067
	/*
2068 2069 2070 2071
	 * DO NOT proc_exit() -- we're here because shared memory may be
	 * corrupted, so we don't want to try to clean up our transaction.
	 * Just nail the windows shut and get out of town.
	 *
B
Bruce Momjian 已提交
2072 2073 2074 2075
	 * Note we do exit(1) not exit(0).	This is to force the postmaster into
	 * a system reset cycle if some idiot DBA sends a manual SIGQUIT to a
	 * random backend.	This is necessary precisely because we don't clean
	 * up our shared memory state.
2076
	 */
2077
	exit(1);
2078 2079
}

2080
/*
2081 2082
 * Shutdown signal from postmaster: abort transaction and exit
 * at soonest convenient time
2083
 */
2084
void
2085
die(SIGNAL_ARGS)
2086
{
2087 2088 2089
	int			save_errno = errno;

	/* Don't joggle the elbow of proc_exit */
B
Bruce Momjian 已提交
2090
	if (!proc_exit_inprogress)
2091
	{
2092
		InterruptPending = true;
2093
		ProcDiePending = true;
B
Bruce Momjian 已提交
2094

2095
		/*
B
Bruce Momjian 已提交
2096 2097
		 * If it's safe to interrupt, and we're waiting for input or a
		 * lock, service the interrupt immediately
2098
		 */
2099 2100
		if (ImmediateInterruptOK && InterruptHoldoffCount == 0 &&
			CritSectionCount == 0)
2101
		{
2102 2103 2104
			/* bump holdoff count to make ProcessInterrupts() a no-op */
			/* until we are done getting ready for it */
			InterruptHoldoffCount++;
2105
			DisableNotifyInterrupt();
2106
			DisableCatchupInterrupt();
2107
			/* Make sure CheckDeadLock won't run while shutting down... */
2108
			LockWaitCancel();
2109
			InterruptHoldoffCount--;
2110 2111
			ProcessInterrupts();
		}
2112
	}
2113 2114

	errno = save_errno;
2115 2116
}

2117
/*
2118
 * Timeout or shutdown signal from postmaster during client authentication.
2119
 * Simply exit(0).
2120 2121 2122
 *
 * XXX: possible future improvement: try to send a message indicating
 * why we are disconnecting.  Problem is to be sure we don't block while
2123
 * doing so, nor mess up the authentication message exchange.
2124 2125 2126 2127 2128 2129 2130
 */
void
authdie(SIGNAL_ARGS)
{
	exit(0);
}

2131
/*
2132 2133
 * Query-cancel signal from postmaster: abort current transaction
 * at soonest convenient time
2134
 */
2135
void
2136
StatementCancelHandler(SIGNAL_ARGS)
2137
{
2138 2139
	int			save_errno = errno;

B
Bruce Momjian 已提交
2140
	/*
2141
	 * Don't joggle the elbow of proc_exit
B
Bruce Momjian 已提交
2142
	 */
2143
	if (!proc_exit_inprogress)
2144
	{
2145 2146
		InterruptPending = true;
		QueryCancelPending = true;
B
Bruce Momjian 已提交
2147

2148
		/*
2149
		 * If it's safe to interrupt, and we're waiting for a lock,
B
Bruce Momjian 已提交
2150 2151
		 * service the interrupt immediately.  No point in interrupting if
		 * we're waiting for input, however.
2152
		 */
2153
		if (ImmediateInterruptOK && InterruptHoldoffCount == 0 &&
2154
			CritSectionCount == 0)
2155
		{
2156 2157 2158 2159 2160 2161
			/* bump holdoff count to make ProcessInterrupts() a no-op */
			/* until we are done getting ready for it */
			InterruptHoldoffCount++;
			if (LockWaitCancel())
			{
				DisableNotifyInterrupt();
2162
				DisableCatchupInterrupt();
T
Tom Lane 已提交
2163
				InterruptHoldoffCount--;
2164 2165 2166 2167
				ProcessInterrupts();
			}
			else
				InterruptHoldoffCount--;
2168
		}
2169 2170
	}

2171
	errno = save_errno;
2172 2173
}

2174
/* signal handler for floating point exception */
2175
void
2176 2177
FloatExceptionHandler(SIGNAL_ARGS)
{
2178 2179 2180
	ereport(ERROR,
			(errcode(ERRCODE_FLOATING_POINT_EXCEPTION),
			 errmsg("floating-point exception"),
B
Bruce Momjian 已提交
2181 2182 2183
		   errdetail("An invalid floating-point operation was signaled. "
					 "This probably means an out-of-range result or an "
					 "invalid operation, such as division by zero.")));
2184 2185
}

2186
/* SIGHUP: set flag to re-read config file at next convenient time */
2187
static void
2188
SigHupHandler(SIGNAL_ARGS)
2189
{
2190
	got_SIGHUP = true;
2191 2192
}

2193

2194 2195 2196 2197 2198 2199 2200 2201 2202 2203
/*
 * ProcessInterrupts: out-of-line portion of CHECK_FOR_INTERRUPTS() macro
 *
 * If an interrupt condition is pending, and it's safe to service it,
 * then clear the flag and accept the interrupt.  Called only when
 * InterruptPending is true.
 */
void
ProcessInterrupts(void)
{
2204 2205
	/* OK to accept interrupt now? */
	if (InterruptHoldoffCount != 0 || CritSectionCount != 0)
2206 2207 2208 2209 2210
		return;
	InterruptPending = false;
	if (ProcDiePending)
	{
		ProcDiePending = false;
B
Bruce Momjian 已提交
2211 2212
		QueryCancelPending = false;		/* ProcDie trumps QueryCancel */
		ImmediateInterruptOK = false;	/* not idle anymore */
2213
		DisableNotifyInterrupt();
2214
		DisableCatchupInterrupt();
2215 2216
		ereport(FATAL,
				(errcode(ERRCODE_ADMIN_SHUTDOWN),
B
Bruce Momjian 已提交
2217
		 errmsg("terminating connection due to administrator command")));
2218 2219 2220 2221
	}
	if (QueryCancelPending)
	{
		QueryCancelPending = false;
B
Bruce Momjian 已提交
2222
		ImmediateInterruptOK = false;	/* not idle anymore */
2223
		DisableNotifyInterrupt();
2224
		DisableCatchupInterrupt();
2225 2226 2227 2228 2229 2230 2231 2232
		if (cancel_from_timeout)
			ereport(ERROR,
					(errcode(ERRCODE_QUERY_CANCELED),
					 errmsg("canceling statement due to statement timeout")));
		else
			ereport(ERROR,
					(errcode(ERRCODE_QUERY_CANCELED),
					 errmsg("canceling statement due to user request")));
2233 2234 2235 2236
	}
	/* If we get here, do nothing (probably, QueryCancelPending was reset) */
}

2237

2238 2239 2240 2241 2242 2243 2244 2245 2246 2247 2248 2249 2250
/*
 * check_stack_depth: check for excessively deep recursion
 *
 * This should be called someplace in any recursive routine that might possibly
 * recurse deep enough to overflow the stack.  Most Unixen treat stack
 * overflow as an unrecoverable SIGSEGV, so we want to error out ourselves
 * before hitting the hardware limit.  Unfortunately we have no direct way
 * to detect the hardware limit, so we have to rely on the admin to set a
 * GUC variable for it ...
 */
void
check_stack_depth(void)
{
B
Bruce Momjian 已提交
2251 2252
	char		stack_top_loc;
	int			stack_depth;
2253 2254 2255 2256 2257

	/*
	 * Compute distance from PostgresMain's local variables to my own
	 *
	 * Note: in theory stack_depth should be ptrdiff_t or some such, but
B
Bruce Momjian 已提交
2258 2259
	 * since the whole point of this code is to bound the value to
	 * something much less than integer-sized, int should work fine.
2260 2261
	 */
	stack_depth = (int) (stack_base_ptr - &stack_top_loc);
B
Bruce Momjian 已提交
2262

2263
	/*
B
Bruce Momjian 已提交
2264 2265
	 * Take abs value, since stacks grow up on some machines, down on
	 * others
2266 2267 2268
	 */
	if (stack_depth < 0)
		stack_depth = -stack_depth;
B
Bruce Momjian 已提交
2269

2270 2271 2272 2273
	/*
	 * Trouble?
	 *
	 * The test on stack_base_ptr prevents us from erroring out if called
B
Bruce Momjian 已提交
2274 2275 2276
	 * during process setup or in a non-backend process.  Logically it
	 * should be done first, but putting it here avoids wasting cycles
	 * during normal cases.
2277 2278 2279 2280 2281 2282 2283 2284 2285 2286 2287 2288 2289 2290 2291 2292 2293 2294 2295 2296 2297 2298
	 */
	if (stack_depth > max_stack_depth_bytes &&
		stack_base_ptr != NULL)
	{
		ereport(ERROR,
				(errcode(ERRCODE_STATEMENT_TOO_COMPLEX),
				 errmsg("stack depth limit exceeded"),
				 errhint("Increase the configuration parameter \"max_stack_depth\".")));
	}
}

/* GUC assign hook to update max_stack_depth_bytes from max_stack_depth */
bool
assign_max_stack_depth(int newval, bool doit, GucSource source)
{
	/* Range check was already handled by guc.c */
	if (doit)
		max_stack_depth_bytes = newval * 1024;
	return true;
}


2299
static void
2300
usage(const char *progname)
2301
{
2302
	printf(_("%s is the PostgreSQL stand-alone backend.  It is not\nintended to be used by normal users.\n\n"), progname);
2303

2304 2305
	printf(_("Usage:\n  %s [OPTION]... [DBNAME]\n\n"), progname);
	printf(_("Options:\n"));
M
 
Marc G. Fournier 已提交
2306
#ifdef USE_ASSERT_CHECKING
2307
	printf(_("  -A 1|0          enable/disable run-time assert checking\n"));
M
 
Marc G. Fournier 已提交
2308
#endif
2309 2310 2311 2312 2313 2314 2315 2316 2317 2318 2319 2320 2321 2322 2323 2324 2325 2326 2327 2328 2329 2330
	printf(_("  -B NBUFFERS     number of shared buffers\n"));
	printf(_("  -c NAME=VALUE   set run-time parameter\n"));
	printf(_("  -d 0-5          debugging level (0 is off)\n"));
	printf(_("  -D DATADIR      database directory\n"));
	printf(_("  -e              use European date input format (DMY)\n"));
	printf(_("  -E              echo query before execution\n"));
	printf(_("  -F              turn fsync off\n"));
	printf(_("  -N              do not use newline as interactive query delimiter\n"));
	printf(_("  -o FILENAME     send stdout and stderr to given file\n"));
	printf(_("  -P              disable system indexes\n"));
	printf(_("  -s              show statistics after each query\n"));
	printf(_("  -S WORK-MEM     set amount of memory for sorts (in kB)\n"));
	printf(_("  --describe-config  describe configuration parameters, then exit\n"));
	printf(_("  --help          show this help, then exit\n"));
	printf(_("  --version       output version information, then exit\n"));
	printf(_("\nDeveloper options:\n"));
	printf(_("  -f s|i|n|m|h    forbid use of some plan types\n"));
	printf(_("  -i              do not execute queries\n"));
	printf(_("  -O              allow system table structure changes\n"));
	printf(_("  -t pa|pl|ex     show timings after each query\n"));
	printf(_("  -W NUM          wait NUM seconds to allow attach from a debugger\n"));
	printf(_("\nReport bugs to <pgsql-bugs@postgresql.org>.\n"));
2331 2332
}

2333

2334 2335 2336 2337 2338 2339 2340 2341 2342 2343 2344 2345 2346 2347 2348 2349 2350 2351 2352 2353 2354 2355 2356 2357 2358 2359 2360 2361 2362 2363 2364 2365 2366 2367 2368
/*
 * set_debug_options --- apply "-d N" command line option
 *
 * -d is not quite the same as setting log_min_messages because it enables
 * other output options.
 */
void
set_debug_options(int debug_flag, GucContext context, GucSource source)
{
	if (debug_flag > 0)
	{
		char		debugstr[64];

		sprintf(debugstr, "debug%d", debug_flag);
		SetConfigOption("log_min_messages", debugstr, context, source);
	}
	else
		SetConfigOption("log_min_messages", "notice", context, source);

	if (debug_flag >= 1 && context == PGC_POSTMASTER)
	{
		SetConfigOption("log_connections", "true", context, source);
		SetConfigOption("log_disconnections", "true", context, source);
	}
	if (debug_flag >= 2)
		SetConfigOption("log_statement", "all", context, source);
	if (debug_flag >= 3)
		SetConfigOption("debug_print_parse", "true", context, source);
	if (debug_flag >= 4)
		SetConfigOption("debug_print_plan", "true", context, source);
	if (debug_flag >= 5)
		SetConfigOption("debug_print_rewritten", "true", context, source);
}


2369
/* ----------------------------------------------------------------
2370
 * PostgresMain
B
Bruce Momjian 已提交
2371
 *	   postgres main loop -- all backends, interactive or otherwise start here
2372
 *
2373 2374 2375 2376
 * argc/argv are the command line arguments to be used.  (When being forked
 * by the postmaster, these are not the original argv array of the process.)
 * username is the (possibly authenticated) PostgreSQL user name to be used
 * for the session.
2377 2378 2379
 * ----------------------------------------------------------------
 */
int
2380
PostgresMain(int argc, char *argv[], const char *username)
2381
{
2382
	int			flag;
2383
	const char *dbname = NULL;
2384
	char	   *userDoption = NULL;
2385
	bool		secure;
2386
	int			errs = 0;
2387
	int			debug_flag = -1;		/* -1 means not given */
2388
	List	   *guc_names = NIL;		/* for SUSET options */
2389 2390
	List	   *guc_values = NIL;
	GucContext	ctx;
2391
	GucSource	gucsource;
2392
	bool		am_superuser;
2393
	char	   *tmp;
2394
	int			firstchar;
2395
	char		stack_base;
B
Bruce Momjian 已提交
2396
	StringInfoData input_message;
2397
	sigjmp_buf	local_sigjmp_buf;
2398
	volatile bool send_rfq = true;
B
Bruce Momjian 已提交
2399

2400 2401 2402 2403
#define PendingConfigOption(name,val) \
	(guc_names = lappend(guc_names, pstrdup(name)), \
	 guc_values = lappend(guc_values, pstrdup(val)))

2404
	/*
B
Bruce Momjian 已提交
2405 2406
	 * Catch standard options before doing much else.  This even works on
	 * systems without getopt_long.
2407 2408 2409
	 */
	if (!IsUnderPostmaster && argc > 1)
	{
B
Bruce Momjian 已提交
2410
		if (strcmp(argv[1], "--help") == 0 || strcmp(argv[1], "-?") == 0)
2411 2412 2413 2414
		{
			usage(argv[0]);
			exit(0);
		}
B
Bruce Momjian 已提交
2415
		if (strcmp(argv[1], "--version") == 0 || strcmp(argv[1], "-V") == 0)
2416
		{
2417
			puts(PG_VERSIONSTR);
2418 2419
			exit(0);
		}
B
Bruce Momjian 已提交
2420
	}
2421

2422 2423 2424 2425 2426 2427
	/*
	 * initialize globals (already done if under postmaster, but not if
	 * standalone; cheap enough to do over)
	 */
	MyProcPid = getpid();

2428 2429 2430 2431 2432
	/*
	 * Fire up essential subsystems: error and memory management
	 *
	 * If we are running under the postmaster, this is done already.
	 */
2433
	if (!IsUnderPostmaster)
2434 2435
		MemoryContextInit();

2436 2437
	set_ps_display("startup");

2438 2439
	SetProcessingMode(InitProcessing);

2440 2441 2442
	/* Set up reference point for stack depth checking */
	stack_base_ptr = &stack_base;

2443 2444 2445 2446 2447 2448 2449
	/* Compute paths, if we didn't inherit them from postmaster */
	if (my_exec_path[0] == '\0')
	{
		if (find_my_exec(argv[0], my_exec_path) < 0)
			elog(FATAL, "%s: could not locate my own executable path",
				 argv[0]);
	}
B
Bruce Momjian 已提交
2450

B
Bruce Momjian 已提交
2451 2452
	if (pkglib_path[0] == '\0')
		get_pkglib_path(my_exec_path, pkglib_path);
2453

2454
	/*
2455
	 * Set default values for command-line options.
2456
	 */
2457
	EchoQuery = false;
2458

2459
	if (!IsUnderPostmaster)
2460
		InitializeGUCOptions();
2461

2462 2463 2464 2465 2466 2467 2468 2469 2470 2471 2472 2473 2474 2475 2476 2477 2478
	/* ----------------
	 *	parse command line arguments
	 *
	 *	There are now two styles of command line layout for the backend:
	 *
	 *	For interactive use (not started from postmaster) the format is
	 *		postgres [switches] [databasename]
	 *	If the databasename is omitted it is taken to be the user name.
	 *
	 *	When started from the postmaster, the format is
	 *		postgres [secure switches] -p databasename [insecure switches]
	 *	Switches appearing after -p came from the client (via "options"
	 *	field of connection request).  For security reasons we restrict
	 *	what these switches can do.
	 * ----------------
	 */

2479 2480
	/* all options are allowed until '-p' */
	secure = true;
2481
	ctx = PGC_POSTMASTER;
2482
	gucsource = PGC_S_ARGV;		/* initial switches came from command line */
2483

2484
	while ((flag = getopt(argc, argv, "A:B:c:D:d:Eef:FiNOPo:p:S:st:v:W:-:")) != -1)
2485
	{
2486 2487
		switch (flag)
		{
M
 
Marc G. Fournier 已提交
2488 2489
			case 'A':
#ifdef USE_ASSERT_CHECKING
2490
				SetConfigOption("debug_assertions", optarg, ctx, gucsource);
M
 
Marc G. Fournier 已提交
2491
#else
2492 2493 2494
				ereport(WARNING,
						(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
						 errmsg("assert checking is not compiled in")));
M
 
Marc G. Fournier 已提交
2495 2496
#endif
				break;
2497

2498
			case 'B':
2499 2500 2501

				/*
				 * specify the size of buffer pool
2502
				 */
2503
				SetConfigOption("shared_buffers", optarg, ctx, gucsource);
2504
				break;
2505

2506
			case 'D':			/* PGDATA or config directory */
2507
				if (secure)
2508
					userDoption = optarg;
M
 
Marc G. Fournier 已提交
2509
				break;
2510

2511
			case 'd':			/* debug level */
2512
				debug_flag = atoi(optarg);
2513
				break;
2514 2515

			case 'E':
2516 2517 2518

				/*
				 * E - echo the query the user entered
2519
				 */
2520
				EchoQuery = true;
2521
				break;
2522 2523

			case 'e':
2524 2525

				/*
2526
				 * Use European date input format (DMY)
2527
				 */
2528
				SetConfigOption("datestyle", "euro", ctx, gucsource);
2529
				break;
2530 2531

			case 'F':
2532 2533 2534

				/*
				 * turn off fsync
2535
				 */
2536
				SetConfigOption("fsync", "false", ctx, gucsource);
2537
				break;
2538 2539

			case 'f':
2540 2541 2542

				/*
				 * f - forbid generation of certain plans
2543
				 */
2544
				tmp = NULL;
2545 2546 2547
				switch (optarg[0])
				{
					case 's':	/* seqscan */
2548
						tmp = "enable_seqscan";
2549 2550
						break;
					case 'i':	/* indexscan */
2551
						tmp = "enable_indexscan";
2552
						break;
2553 2554 2555
					case 'b':	/* bitmapscan */
						tmp = "enable_bitmapscan";
						break;
2556
					case 't':	/* tidscan */
2557
						tmp = "enable_tidscan";
2558 2559
						break;
					case 'n':	/* nestloop */
2560
						tmp = "enable_nestloop";
2561 2562
						break;
					case 'm':	/* mergejoin */
2563
						tmp = "enable_mergejoin";
2564 2565
						break;
					case 'h':	/* hashjoin */
2566
						tmp = "enable_hashjoin";
2567 2568 2569 2570
						break;
					default:
						errs++;
				}
2571
				if (tmp)
2572
					SetConfigOption(tmp, "false", ctx, gucsource);
2573 2574
				break;

2575
			case 'N':
2576 2577 2578

				/*
				 * N - Don't use newline as a query delimiter
2579 2580 2581
				 */
				UseNewLine = 0;
				break;
2582

2583
			case 'O':
2584 2585 2586

				/*
				 * allow system table structure modifications
2587
				 */
2588 2589
				if (secure)		/* XXX safe to allow from client??? */
					allowSystemTableMods = true;
2590 2591
				break;

H
Hiroshi Inoue 已提交
2592
			case 'P':
2593 2594 2595

				/*
				 * ignore system indexes
2596
				 *
B
Bruce Momjian 已提交
2597 2598 2599
				 * As of PG 7.4 this is safe to allow from the client, since
				 * it only disables reading the system indexes, not
				 * writing them.  Worst case consequence is slowness.
H
Hiroshi Inoue 已提交
2600
				 */
2601
				IgnoreSystemIndexes(true);
H
Hiroshi Inoue 已提交
2602 2603
				break;

T
Tom Lane 已提交
2604
			case 'o':
2605 2606 2607

				/*
				 * o - send output (stdout and stderr) to the given file
T
Tom Lane 已提交
2608
				 */
2609 2610
				if (secure)
					StrNCpy(OutputFileName, optarg, MAXPGPATH);
T
Tom Lane 已提交
2611 2612
				break;

2613
			case 'p':
B
Bruce Momjian 已提交
2614

2615 2616 2617
				/*
				 * p - special flag passed if backend was forked by a
				 * postmaster.
2618
				 */
2619 2620
				if (secure)
				{
2621
					dbname = strdup(optarg);
2622

B
Bruce Momjian 已提交
2623 2624
					secure = false;		/* subsequent switches are NOT
										 * secure */
2625
					ctx = PGC_BACKEND;
2626
					gucsource = PGC_S_CLIENT;
2627
				}
2628
				break;
2629

2630
			case 'S':
2631 2632 2633

				/*
				 * S - amount of sort memory to use in 1k bytes
2634
				 */
2635
				SetConfigOption("work_mem", optarg, ctx, gucsource);
2636
				break;
2637 2638

			case 's':
2639 2640 2641

				/*
				 * s - report usage statistics (timings) after each query
2642 2643 2644
				 *
				 * Since log options are SUSET, we need to postpone unless
				 * still in secure context
2645
				 */
2646 2647 2648 2649 2650
				if (ctx == PGC_BACKEND)
					PendingConfigOption("log_statement_stats", "true");
				else
					SetConfigOption("log_statement_stats", "true",
									ctx, gucsource);
M
 
Marc G. Fournier 已提交
2651 2652
				break;

2653
			case 't':
2654
				/* ---------------
2655 2656 2657 2658 2659 2660 2661 2662 2663
				 *	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.
				 * ----------------
				 */
2664
				tmp = NULL;
2665 2666 2667 2668
				switch (optarg[0])
				{
					case 'p':
						if (optarg[1] == 'a')
B
Rename:  
Bruce Momjian 已提交
2669
							tmp = "log_parser_stats";
2670
						else if (optarg[1] == 'l')
B
Rename:  
Bruce Momjian 已提交
2671
							tmp = "log_planner_stats";
2672 2673 2674 2675
						else
							errs++;
						break;
					case 'e':
2676
						tmp = "log_executor_stats";
2677 2678 2679 2680 2681
						break;
					default:
						errs++;
						break;
				}
2682
				if (tmp)
2683 2684 2685 2686 2687 2688
				{
					if (ctx == PGC_BACKEND)
						PendingConfigOption(tmp, "true");
					else
						SetConfigOption(tmp, "true", ctx, gucsource);
				}
2689 2690
				break;

2691
			case 'v':
2692 2693
				if (secure)
					FrontendProtocol = (ProtocolVersion) atoi(optarg);
2694 2695
				break;

M
 
Marc G. Fournier 已提交
2696
			case 'W':
2697 2698 2699

				/*
				 * wait N seconds to allow attach from a debugger
M
 
Marc G. Fournier 已提交
2700
				 */
B
Bruce Momjian 已提交
2701
				pg_usleep(atoi(optarg) * 1000000L);
M
 
Marc G. Fournier 已提交
2702 2703
				break;

2704
			case 'c':
2705
			case '-':
2706
				{
B
Bruce Momjian 已提交
2707 2708
					char	   *name,
							   *value;
2709

B
Bruce Momjian 已提交
2710 2711 2712 2713
					ParseLongOption(optarg, &name, &value);
					if (!value)
					{
						if (flag == '-')
2714 2715 2716 2717
							ereport(ERROR,
									(errcode(ERRCODE_SYNTAX_ERROR),
									 errmsg("--%s requires a value",
											optarg)));
B
Bruce Momjian 已提交
2718
						else
2719 2720 2721 2722
							ereport(ERROR,
									(errcode(ERRCODE_SYNTAX_ERROR),
									 errmsg("-c %s requires a value",
											optarg)));
B
Bruce Momjian 已提交
2723 2724
					}

2725 2726 2727 2728 2729 2730 2731 2732
					/*
					 * If a SUSET option, must postpone evaluation, unless
					 * we are still reading secure switches.
					 */
					if (ctx == PGC_BACKEND && IsSuperuserConfigOption(name))
						PendingConfigOption(name, value);
					else
						SetConfigOption(name, value, ctx, gucsource);
B
Bruce Momjian 已提交
2733 2734 2735 2736 2737
					free(name);
					if (value)
						free(value);
					break;
				}
2738

2739 2740
			default:
				errs++;
T
Tom Lane 已提交
2741
				break;
2742
		}
2743 2744
	}

2745 2746 2747 2748 2749 2750 2751 2752 2753 2754 2755 2756 2757 2758 2759 2760 2761 2762 2763 2764 2765 2766 2767 2768 2769 2770
	/*
	 * Process any additional GUC variable settings passed in startup
	 * packet.  These are handled exactly like command-line variables.
	 */
	if (MyProcPort != NULL)
	{
		ListCell   *gucopts = list_head(MyProcPort->guc_options);

		while (gucopts)
		{
			char	   *name;
			char	   *value;

			name = lfirst(gucopts);
			gucopts = lnext(gucopts);

			value = lfirst(gucopts);
			gucopts = lnext(gucopts);

			if (IsSuperuserConfigOption(name))
				PendingConfigOption(name, value);
			else
				SetConfigOption(name, value, PGC_BACKEND, PGC_S_CLIENT);
		}
	}

2771 2772
	/* Acquire configuration parameters, unless inherited from postmaster */
	if (!IsUnderPostmaster)
2773
	{
2774 2775
		if (!SelectConfigFiles(userDoption, argv[0]))
			proc_exit(1);
2776
	}
2777

2778
	/*
2779
	 * Set up signal handlers and masks.
2780
	 *
2781
	 * Note that postmaster blocked all signals before forking child process,
B
Bruce Momjian 已提交
2782 2783
	 * so there is no race condition whereby we might receive a signal
	 * before we have set up the handler.
T
Tom Lane 已提交
2784 2785
	 *
	 * Also note: it's best not to use any signals that are SIG_IGNored in
B
Bruce Momjian 已提交
2786
	 * the postmaster.	If such a signal arrives before we are able to
2787
	 * change the handler to non-SIG_IGN, it'll get dropped.  Instead,
B
Bruce Momjian 已提交
2788 2789
	 * make a dummy handler in the postmaster to reserve the signal. (Of
	 * course, this isn't an issue for signals that are locally generated,
2790
	 * such as SIGALRM and SIGPIPE.)
2791
	 */
2792
	pqsignal(SIGHUP, SigHupHandler);	/* set flag to read config file */
B
Bruce Momjian 已提交
2793
	pqsignal(SIGINT, StatementCancelHandler);	/* cancel current query */
2794
	pqsignal(SIGTERM, die);		/* cancel current query and exit */
2795
	pqsignal(SIGQUIT, quickdie);	/* hard crash time */
B
Bruce Momjian 已提交
2796
	pqsignal(SIGALRM, handle_sig_alarm);		/* timeout conditions */
2797 2798 2799 2800 2801

	/*
	 * Ignore failure to write to frontend. Note: if frontend closes
	 * connection, we will notice it and exit cleanly when control next
	 * returns to outer loop.  This seems safer than forcing exit in the
2802 2803 2804
	 * midst of output during who-knows-what operation...
	 */
	pqsignal(SIGPIPE, SIG_IGN);
2805 2806
	pqsignal(SIGUSR1, CatchupInterruptHandler);
	pqsignal(SIGUSR2, NotifyInterruptHandler);
2807
	pqsignal(SIGFPE, FloatExceptionHandler);
2808 2809

	/*
B
Bruce Momjian 已提交
2810 2811
	 * Reset some signals that are accepted by postmaster but not by
	 * backend
2812
	 */
2813 2814
	pqsignal(SIGCHLD, SIG_DFL); /* system() requires this on some
								 * platforms */
2815

2816 2817
	pqinitmask();

T
Tom Lane 已提交
2818
	/* We allow SIGQUIT (quickdie) at all times */
2819
#ifdef HAVE_SIGPROCMASK
T
Tom Lane 已提交
2820
	sigdelset(&BlockSig, SIGQUIT);
2821
#else
T
Tom Lane 已提交
2822
	BlockSig &= ~(sigmask(SIGQUIT));
2823 2824
#endif

T
Tom Lane 已提交
2825
	PG_SETMASK(&BlockSig);		/* block everything except SIGQUIT */
2826

2827

2828
	if (IsUnderPostmaster)
2829
	{
2830
		/* noninteractive case: nothing should be left after switches */
2831
		if (errs || argc != optind || dbname == NULL)
2832
		{
2833 2834
			ereport(FATAL,
					(errcode(ERRCODE_SYNTAX_ERROR),
B
Bruce Momjian 已提交
2835 2836
			 errmsg("invalid command-line arguments for server process"),
			errhint("Try \"%s --help\" for more information.", argv[0])));
2837
		}
2838

2839
		BaseInit();
2840
	}
2841
	else
2842
	{
2843 2844 2845
		/* interactive case: database name can be last arg on command line */
		if (errs || argc - optind > 1)
		{
2846 2847 2848 2849
			ereport(FATAL,
					(errcode(ERRCODE_SYNTAX_ERROR),
					 errmsg("%s: invalid command-line arguments",
							argv[0]),
B
Bruce Momjian 已提交
2850
			errhint("Try \"%s --help\" for more information.", argv[0])));
2851 2852
		}
		else if (argc - optind == 1)
2853 2854
			dbname = argv[optind];
		else if ((dbname = username) == NULL)
2855
		{
2856 2857 2858 2859
			ereport(FATAL,
					(errcode(ERRCODE_INVALID_PARAMETER_VALUE),
					 errmsg("%s: no database nor user name specified",
							argv[0])));
2860
		}
2861

2862
		/*
2863 2864
		 * Validate we have been given a reasonable-looking DataDir (if
		 * under postmaster, assume postmaster did this already).
2865
		 */
2866
		Assert(DataDir);
2867 2868
		ValidatePgVersion(DataDir);

2869 2870 2871
		/* Change into DataDir (if under postmaster, was done already) */
		ChangeToDataDir();

2872
		/*
2873
		 * Create lockfile for data directory.
2874
		 */
2875
		CreateDataDirLockFile(false);
2876

2877
		BaseInit();
2878 2879 2880 2881 2882

		/*
		 * Start up xlog for standalone backend, and register to have it
		 * closed down at exit.
		 */
2883
		StartupXLOG();
2884
		on_shmem_exit(ShutdownXLOG, 0);
2885 2886 2887 2888 2889 2890 2891

		/*
		 * Read any existing FSM cache file, and register to write one out
		 * at exit.
		 */
		LoadFreeSpaceMap();
		on_shmem_exit(DumpFreeSpaceMap, 0);
2892 2893 2894 2895 2896 2897

		/*
		 * We have to build the flat file for pg_database, but not for
		 * the user and group tables, since we won't try to do authentication.
		 */
		BuildFlatFiles(true);
2898 2899
	}

2900
	/*
2901 2902 2903 2904 2905
	 * General initialization.
	 *
	 * NOTE: if you are tempted to add code in this vicinity, consider
	 * putting it inside InitPostgres() instead.  In particular, anything
	 * that involves database access should be there, not here.
2906
	 */
2907 2908
	ereport(DEBUG3,
			(errmsg_internal("InitPostgres")));
2909
	am_superuser = InitPostgres(dbname, username);
2910

2911
	SetProcessingMode(NormalProcessing);
2912

2913
	/*
2914 2915
	 * Now that we know if client is a superuser, we can try to apply SUSET
	 * GUC options that came from the client.
2916 2917 2918 2919 2920 2921 2922 2923 2924 2925 2926 2927 2928 2929 2930 2931 2932 2933 2934 2935 2936 2937 2938 2939 2940 2941 2942 2943
	 */
	ctx = am_superuser ? PGC_SUSET : PGC_USERSET;

	if (debug_flag >= 0)
		set_debug_options(debug_flag, ctx, PGC_S_CLIENT);

	if (guc_names != NIL)
	{
		ListCell   *namcell,
				   *valcell;

		forboth(namcell, guc_names, valcell, guc_values)
		{
			char	   *name = (char *) lfirst(namcell);
			char	   *value = (char *) lfirst(valcell);

			SetConfigOption(name, value, ctx, PGC_S_CLIENT);
			pfree(name);
			pfree(value);
		}
	}

	/*
	 * Now all GUC states are fully set up.  Report them to client if
	 * appropriate.
	 */
	BeginReportingGUCOptions();

2944 2945 2946 2947 2948 2949 2950
	/*
	 * Also set up handler to log session end; we have to wait till now
	 * to be sure Log_disconnections has its final value.
	 */
	if (IsUnderPostmaster && Log_disconnections)
		on_proc_exit(log_disconnections, 0);

2951 2952
	/*
	 * Send this backend's cancellation info to the frontend.
2953
	 */
M
 
Marc G. Fournier 已提交
2954 2955 2956
	if (whereToSendOutput == Remote &&
		PG_PROTOCOL_MAJOR(FrontendProtocol) >= 2)
	{
2957
		StringInfoData buf;
B
Bruce Momjian 已提交
2958

2959
		pq_beginmessage(&buf, 'K');
2960 2961 2962
		pq_sendint(&buf, (int32) MyProcPid, sizeof(int32));
		pq_sendint(&buf, (int32) MyCancelKey, sizeof(int32));
		pq_endmessage(&buf);
M
 
Marc G. Fournier 已提交
2963 2964 2965
		/* Need not flush since ReadyForQuery will do it. */
	}

2966 2967
	/* Welcome banner for standalone case */
	if (whereToSendOutput == Debug)
2968
		printf("\nPostgreSQL stand-alone backend %s\n", PG_VERSION);
2969

2970 2971 2972
	/*
	 * Create the memory context we will use in the main loop.
	 *
2973 2974
	 * MessageContext is reset once per iteration of the main loop, ie, upon
	 * completion of processing of each command message from the client.
2975
	 */
2976 2977 2978 2979 2980
	MessageContext = AllocSetContextCreate(TopMemoryContext,
										   "MessageContext",
										   ALLOCSET_DEFAULT_MINSIZE,
										   ALLOCSET_DEFAULT_INITSIZE,
										   ALLOCSET_DEFAULT_MAXSIZE);
2981

2982
	/*
2983
	 * Remember stand-alone backend startup time
2984 2985
	 */
	if (!IsUnderPostmaster)
2986
		PgStartTime = GetCurrentTimestamp();
2987

2988 2989
	/*
	 * POSTGRES main processing loop begins here
2990
	 *
2991 2992
	 * If an exception is encountered, processing resumes here so we abort
	 * the current transaction and start a new one.
2993
	 *
B
Bruce Momjian 已提交
2994 2995
	 * You might wonder why this isn't coded as an infinite loop around a
	 * PG_TRY construct.  The reason is that this is the bottom of the
2996 2997 2998
	 * exception stack, and so with PG_TRY there would be no exception
	 * handler in force at all during the CATCH part.  By leaving the
	 * outermost setjmp always active, we have at least some chance of
B
Bruce Momjian 已提交
2999 3000
	 * recovering from an error during error recovery.	(If we get into an
	 * infinite loop thereby, it will soon be stopped by overflow of
3001
	 * elog.c's internal state stack.)
3002 3003
	 */

3004
	if (sigsetjmp(local_sigjmp_buf, 1) != 0)
3005
	{
3006
		/*
3007
		 * NOTE: if you are tempted to add more code in this if-block,
3008
		 * consider the high probability that it should be in
B
Bruce Momjian 已提交
3009 3010 3011 3012
		 * AbortTransaction() instead.	The only stuff done directly here
		 * should be stuff that is guaranteed to apply *only* for
		 * outer-level error recovery, such as adjusting the FE/BE
		 * protocol status.
3013 3014 3015 3016 3017 3018 3019 3020 3021 3022
		 */

		/* Since not using PG_TRY, must reset error stack by hand */
		error_context_stack = NULL;

		/* Prevent interrupts while cleaning up */
		HOLD_INTERRUPTS();

		/*
		 * Forget any pending QueryCancel request, since we're returning
B
Bruce Momjian 已提交
3023 3024
		 * to the idle loop anyway, and cancel the statement timer if
		 * running.
3025 3026
		 */
		QueryCancelPending = false;
3027
		disable_sig_alarm(true);
B
Bruce Momjian 已提交
3028
		QueryCancelPending = false;		/* again in case timeout occurred */
3029 3030

		/*
B
Bruce Momjian 已提交
3031 3032 3033
		 * Turn off these interrupts too.  This is only needed here and
		 * not in other exception-catching places since these interrupts
		 * are only enabled while we wait for client input.
3034
		 */
3035
		DoingCommandRead = false;
3036
		DisableNotifyInterrupt();
3037
		DisableCatchupInterrupt();
3038

3039 3040 3041
		/* Make sure libpq is in a good state */
		pq_comm_reset();

3042 3043
		/* Report the error to the client and/or server log */
		EmitErrorReport();
3044

3045
		/*
B
Bruce Momjian 已提交
3046 3047
		 * Make sure debug_query_string gets reset before we possibly
		 * clobber the storage it points at.
3048
		 */
3049
		debug_query_string = NULL;
3050

3051
		/*
3052
		 * Abort the current transaction in order to recover.
3053
		 */
3054
		AbortCurrentTransaction();
3055 3056

		/*
3057 3058
		 * Now return to normal top-level context and clear ErrorContext
		 * for next time.
3059 3060
		 */
		MemoryContextSwitchTo(TopMemoryContext);
3061
		FlushErrorState();
3062
		QueryContext = NULL;
3063

3064 3065
		/*
		 * If we were handling an extended-query-protocol message,
B
Bruce Momjian 已提交
3066 3067
		 * initiate skip till next Sync.  This also causes us not to issue
		 * ReadyForQuery (until we get Sync).
3068 3069 3070
		 */
		if (doing_extended_query_message)
			ignore_till_sync = true;
3071

3072 3073 3074 3075
		/* We don't have a transaction command open anymore */
		xact_started = false;

		/* Now we can allow interrupts again */
3076
		RESUME_INTERRUPTS();
3077
	}
3078

3079 3080
	/* We can now handle ereport(ERROR) */
	PG_exception_stack = &local_sigjmp_buf;
3081

3082
	PG_SETMASK(&UnBlockSig);
3083

3084 3085
	if (!ignore_till_sync)
		send_rfq = true;		/* initially, or after error */
3086

3087 3088
	/*
	 * Non-error queries loop here.
3089 3090 3091 3092
	 */

	for (;;)
	{
3093
		/*
B
Bruce Momjian 已提交
3094 3095
		 * At top of loop, reset extended-query-message flag, so that any
		 * errors encountered in "idle" state don't provoke skip.
3096 3097 3098
		 */
		doing_extended_query_message = false;

3099
		/*
B
Bruce Momjian 已提交
3100
		 * Release storage left over from prior query cycle, and create a
3101
		 * new query input buffer in the cleared MessageContext.
3102
		 */
3103 3104
		MemoryContextSwitchTo(MessageContext);
		MemoryContextResetAndDeleteChildren(MessageContext);
3105

3106
		initStringInfo(&input_message);
3107

3108
		/*
3109 3110
		 * (1) If we've reached idle state, tell the frontend we're ready
		 * for a new query.
3111
		 *
3112
		 * Note: this includes fflush()'ing the last of the prior output.
3113 3114 3115
		 *
		 * This is also a good time to send collected statistics to the
		 * collector, and to update the PS stats display.  We avoid doing
B
Bruce Momjian 已提交
3116
		 * those every time through the message loop because it'd slow
3117 3118
		 * down processing of batched messages, and because we don't want
		 * to report uncommitted updates (that confuses autovacuum).
B
Bruce Momjian 已提交
3119
		 */
3120 3121
		if (send_rfq)
		{
3122
			if (IsTransactionOrTransactionBlock())
3123 3124 3125 3126 3127 3128
			{
				set_ps_display("idle in transaction");
				pgstat_report_activity("<IDLE> in transaction");
			}
			else
			{
3129 3130
				pgstat_report_tabstat();

3131 3132 3133
				set_ps_display("idle");
				pgstat_report_activity("<IDLE>");
			}
3134

3135 3136
			ReadyForQuery(whereToSendOutput);
			send_rfq = false;
3137
		}
3138

3139
		/*
3140 3141 3142 3143
		 * (2) Allow asynchronous signals to be executed immediately
		 * if they come in while we are waiting for client input.
		 * (This must be conditional since we don't want, say, reads on
		 * behalf of COPY FROM STDIN doing the same thing.)
3144
		 */
3145 3146
		QueryCancelPending = false;		/* forget any earlier CANCEL signal */
		DoingCommandRead = true;
3147

3148 3149
		/*
		 * (3) read a command (loop blocks here)
3150
		 */
3151
		firstchar = ReadCommand(&input_message);
3152

3153 3154
		/*
		 * (4) disable async signal conditions again.
3155
		 */
3156
		DoingCommandRead = false;
3157

3158 3159 3160
		/*
		 * (5) check for any other interesting events that happened while
		 * we slept.
3161 3162 3163 3164 3165 3166 3167
		 */
		if (got_SIGHUP)
		{
			got_SIGHUP = false;
			ProcessConfigFile(PGC_SIGHUP);
		}

3168
		/*
B
Bruce Momjian 已提交
3169 3170
		 * (6) process the command.  But ignore it if we're skipping till
		 * Sync.
3171
		 */
3172
		if (ignore_till_sync && firstchar != EOF)
3173 3174
			continue;

3175 3176
		switch (firstchar)
		{
3177
			case 'Q':			/* simple query */
3178
				{
3179 3180
					const char *query_string;

3181 3182
					query_string = pq_getmsgstring(&input_message);
					pq_getmsgend(&input_message);
3183

3184
					exec_simple_query(query_string);
3185

3186 3187
					send_rfq = true;
				}
3188 3189
				break;

3190 3191 3192 3193 3194 3195 3196
			case 'P':			/* parse */
				{
					const char *stmt_name;
					const char *query_string;
					int			numParams;
					Oid		   *paramTypes = NULL;

3197 3198 3199
					stmt_name = pq_getmsgstring(&input_message);
					query_string = pq_getmsgstring(&input_message);
					numParams = pq_getmsgint(&input_message, 2);
3200 3201
					if (numParams > 0)
					{
B
Bruce Momjian 已提交
3202
						int			i;
3203 3204 3205

						paramTypes = (Oid *) palloc(numParams * sizeof(Oid));
						for (i = 0; i < numParams; i++)
3206
							paramTypes[i] = pq_getmsgint(&input_message, 4);
3207
					}
3208
					pq_getmsgend(&input_message);
3209 3210 3211 3212 3213 3214 3215

					exec_parse_message(query_string, stmt_name,
									   paramTypes, numParams);
				}
				break;

			case 'B':			/* bind */
B
Bruce Momjian 已提交
3216

3217
				/*
B
Bruce Momjian 已提交
3218 3219
				 * this message is complex enough that it seems best to
				 * put the field extraction out-of-line
3220
				 */
3221
				exec_bind_message(&input_message);
3222 3223 3224 3225 3226
				break;

			case 'E':			/* execute */
				{
					const char *portal_name;
B
Bruce Momjian 已提交
3227
					int			max_rows;
3228

3229 3230 3231
					portal_name = pq_getmsgstring(&input_message);
					max_rows = pq_getmsgint(&input_message, 4);
					pq_getmsgend(&input_message);
3232

3233
					exec_execute_message(portal_name, max_rows);
3234 3235 3236
				}
				break;

3237 3238
			case 'F':			/* fastpath function call */
				/* Tell the collector what we're doing */
3239 3240
				pgstat_report_activity("<FASTPATH> function call");

3241
				/* start an xact for this function invocation */
3242
				start_xact_command();
3243

3244 3245 3246
				/* switch back to message context */
				MemoryContextSwitchTo(MessageContext);

3247 3248 3249
				/* set snapshot in case function needs one */
				ActiveSnapshot = CopySnapshot(GetTransactionSnapshot());

3250
				if (HandleFunctionRequest(&input_message) == EOF)
3251 3252
				{
					/* lost frontend connection during F message input */
B
Bruce Momjian 已提交
3253

3254
					/*
3255
					 * Reset whereToSendOutput to prevent ereport from
B
Bruce Momjian 已提交
3256
					 * attempting to send any more messages to client.
3257 3258 3259 3260
					 */
					if (whereToSendOutput == Remote)
						whereToSendOutput = None;

3261
					proc_exit(0);
3262
				}
3263 3264

				/* commit the function-invocation transaction */
3265
				finish_xact_command();
3266

3267
				send_rfq = true;
3268 3269
				break;

B
Bruce Momjian 已提交
3270
			case 'C':			/* close */
3271
				{
B
Bruce Momjian 已提交
3272
					int			close_type;
3273 3274
					const char *close_target;

3275 3276 3277
					close_type = pq_getmsgbyte(&input_message);
					close_target = pq_getmsgstring(&input_message);
					pq_getmsgend(&input_message);
3278 3279 3280 3281 3282 3283 3284 3285 3286 3287 3288 3289 3290 3291 3292 3293 3294 3295 3296 3297 3298 3299 3300 3301 3302 3303 3304 3305

					switch (close_type)
					{
						case 'S':
							if (close_target[0] != '\0')
								DropPreparedStatement(close_target, false);
							else
							{
								/* special-case the unnamed statement */
								unnamed_stmt_pstmt = NULL;
								if (unnamed_stmt_context)
								{
									DropDependentPortals(unnamed_stmt_context);
									MemoryContextDelete(unnamed_stmt_context);
								}
								unnamed_stmt_context = NULL;
							}
							break;
						case 'P':
							{
								Portal		portal;

								portal = GetPortalByName(close_target);
								if (PortalIsValid(portal))
									PortalDrop(portal, false);
							}
							break;
						default:
3306 3307
							ereport(ERROR,
									(errcode(ERRCODE_PROTOCOL_VIOLATION),
B
Bruce Momjian 已提交
3308 3309
							   errmsg("invalid CLOSE message subtype %d",
									  close_type)));
3310 3311 3312 3313
							break;
					}

					if (whereToSendOutput == Remote)
B
Bruce Momjian 已提交
3314
						pq_putemptymessage('3');		/* CloseComplete */
3315 3316 3317 3318 3319
				}
				break;

			case 'D':			/* describe */
				{
B
Bruce Momjian 已提交
3320
					int			describe_type;
3321 3322
					const char *describe_target;

3323 3324 3325
					describe_type = pq_getmsgbyte(&input_message);
					describe_target = pq_getmsgstring(&input_message);
					pq_getmsgend(&input_message);
3326 3327 3328 3329 3330 3331 3332 3333 3334 3335

					switch (describe_type)
					{
						case 'S':
							exec_describe_statement_message(describe_target);
							break;
						case 'P':
							exec_describe_portal_message(describe_target);
							break;
						default:
3336 3337
							ereport(ERROR,
									(errcode(ERRCODE_PROTOCOL_VIOLATION),
B
Bruce Momjian 已提交
3338 3339
							errmsg("invalid DESCRIBE message subtype %d",
								   describe_type)));
3340 3341 3342 3343 3344
							break;
					}
				}
				break;

B
Bruce Momjian 已提交
3345
			case 'H':			/* flush */
3346
				pq_getmsgend(&input_message);
3347 3348 3349 3350
				if (whereToSendOutput == Remote)
					pq_flush();
				break;

B
Bruce Momjian 已提交
3351
			case 'S':			/* sync */
3352
				pq_getmsgend(&input_message);
3353
				finish_xact_command();
3354 3355 3356
				send_rfq = true;
				break;

3357
				/*
B
Bruce Momjian 已提交
3358 3359 3360
				 * 'X' means that the frontend is closing down the socket.
				 * EOF means unexpected loss of frontend connection.
				 * Either way, perform normal shutdown.
3361 3362
				 */
			case 'X':
3363
			case EOF:
B
Bruce Momjian 已提交
3364

3365
				/*
B
Bruce Momjian 已提交
3366 3367
				 * Reset whereToSendOutput to prevent ereport from
				 * attempting to send any more messages to client.
3368 3369 3370
				 */
				if (whereToSendOutput == Remote)
					whereToSendOutput = None;
B
Bruce Momjian 已提交
3371

3372 3373
				/*
				 * NOTE: if you are tempted to add more code here, DON'T!
B
Bruce Momjian 已提交
3374 3375
				 * Whatever you had in mind to do should be set up as an
				 * on_proc_exit or on_shmem_exit callback, instead.
3376 3377 3378
				 * Otherwise it will fail to be called during other
				 * backend-shutdown scenarios.
				 */
3379
				proc_exit(0);
3380

B
Bruce Momjian 已提交
3381 3382 3383 3384
			case 'd':			/* copy data */
			case 'c':			/* copy done */
			case 'f':			/* copy fail */

3385
				/*
B
Bruce Momjian 已提交
3386 3387
				 * Accept but ignore these messages, per protocol spec; we
				 * probably got here because a COPY failed, and the
3388 3389 3390 3391
				 * frontend is still sending data.
				 */
				break;

3392
			default:
3393 3394 3395 3396
				ereport(FATAL,
						(errcode(ERRCODE_PROTOCOL_VIOLATION),
						 errmsg("invalid frontend message type %d",
								firstchar)));
3397
		}
3398
	}							/* end of input-reading loop */
3399

3400 3401
	/* can't get here because the above loop never exits */
	Assert(false);
3402

3403
	return 1;					/* keep compiler quiet */
3404 3405
}

3406
#ifndef HAVE_GETRUSAGE
B
Bruce Momjian 已提交
3407 3408
#include "rusagestub.h"
#else
3409
#include <sys/resource.h>
3410
#endif   /* HAVE_GETRUSAGE */
3411

3412 3413
static struct rusage Save_r;
static struct timeval Save_t;
3414 3415

void
3416
ResetUsage(void)
3417
{
3418
	getrusage(RUSAGE_SELF, &Save_r);
3419
	gettimeofday(&Save_t, NULL);
3420
	ResetBufferUsage();
3421
	/* ResetTupleCount(); */
3422 3423 3424
}

void
3425
ShowUsage(const char *title)
3426
{
3427
	StringInfoData str;
3428 3429 3430 3431
	struct timeval user,
				sys;
	struct timeval elapse_t;
	struct rusage r;
B
Bruce Momjian 已提交
3432
	char	   *bufusage;
3433 3434

	getrusage(RUSAGE_SELF, &r);
3435
	gettimeofday(&elapse_t, NULL);
3436 3437
	memcpy((char *) &user, (char *) &r.ru_utime, sizeof(user));
	memcpy((char *) &sys, (char *) &r.ru_stime, sizeof(sys));
3438 3439 3440 3441 3442 3443 3444 3445 3446 3447 3448 3449 3450 3451 3452 3453 3454 3455 3456 3457 3458 3459 3460 3461
	if (elapse_t.tv_usec < Save_t.tv_usec)
	{
		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;
	}
	if (r.ru_stime.tv_usec < Save_r.ru_stime.tv_usec)
	{
		r.ru_stime.tv_sec--;
		r.ru_stime.tv_usec += 1000000;
	}

	/*
	 * the only stats we don't show here are for memory usage -- i can't
	 * figure out how to interpret the relevant fields in the rusage
	 * struct, and they change names across o/s platforms, anyway. if you
	 * can figure out what the entries mean, you can somehow extract
	 * resident set size, shared text size, and unshared data and stack
	 * sizes.
	 */
3462
	initStringInfo(&str);
3463

3464 3465
	appendStringInfo(&str, "! system usage stats:\n");
	appendStringInfo(&str,
3466
			"!\t%ld.%06ld elapsed %ld.%06ld user %ld.%06ld system sec\n",
3467 3468 3469
					 (long) (elapse_t.tv_sec - Save_t.tv_sec),
					 (long) (elapse_t.tv_usec - Save_t.tv_usec),
					 (long) (r.ru_utime.tv_sec - Save_r.ru_utime.tv_sec),
B
Bruce Momjian 已提交
3470
				   (long) (r.ru_utime.tv_usec - Save_r.ru_utime.tv_usec),
3471
					 (long) (r.ru_stime.tv_sec - Save_r.ru_stime.tv_sec),
B
Bruce Momjian 已提交
3472
				  (long) (r.ru_stime.tv_usec - Save_r.ru_stime.tv_usec));
3473
	appendStringInfo(&str,
B
Bruce Momjian 已提交
3474
					 "!\t[%ld.%06ld user %ld.%06ld sys total]\n",
3475 3476 3477 3478
					 (long) user.tv_sec,
					 (long) user.tv_usec,
					 (long) sys.tv_sec,
					 (long) sys.tv_usec);
3479
/* BeOS has rusage but only has some fields, and not these... */
3480
#if defined(HAVE_GETRUSAGE)
3481
	appendStringInfo(&str,
B
Bruce Momjian 已提交
3482 3483
					 "!\t%ld/%ld [%ld/%ld] filesystem blocks in/out\n",
					 r.ru_inblock - Save_r.ru_inblock,
3484
	/* they only drink coffee at dec */
B
Bruce Momjian 已提交
3485 3486
					 r.ru_oublock - Save_r.ru_oublock,
					 r.ru_inblock, r.ru_oublock);
3487
	appendStringInfo(&str,
3488
		  "!\t%ld/%ld [%ld/%ld] page faults/reclaims, %ld [%ld] swaps\n",
B
Bruce Momjian 已提交
3489 3490 3491 3492 3493
					 r.ru_majflt - Save_r.ru_majflt,
					 r.ru_minflt - Save_r.ru_minflt,
					 r.ru_majflt, r.ru_minflt,
					 r.ru_nswap - Save_r.ru_nswap,
					 r.ru_nswap);
3494
	appendStringInfo(&str,
3495
	 "!\t%ld [%ld] signals rcvd, %ld/%ld [%ld/%ld] messages rcvd/sent\n",
B
Bruce Momjian 已提交
3496 3497 3498 3499 3500
					 r.ru_nsignals - Save_r.ru_nsignals,
					 r.ru_nsignals,
					 r.ru_msgrcv - Save_r.ru_msgrcv,
					 r.ru_msgsnd - Save_r.ru_msgsnd,
					 r.ru_msgrcv, r.ru_msgsnd);
3501
	appendStringInfo(&str,
3502
		 "!\t%ld/%ld [%ld/%ld] voluntary/involuntary context switches\n",
B
Bruce Momjian 已提交
3503 3504 3505
					 r.ru_nvcsw - Save_r.ru_nvcsw,
					 r.ru_nivcsw - Save_r.ru_nivcsw,
					 r.ru_nvcsw, r.ru_nivcsw);
3506
#endif   /* HAVE_GETRUSAGE */
3507 3508

	bufusage = ShowBufferUsage();
3509
	appendStringInfo(&str, "! buffer usage stats:\n%s", bufusage);
3510 3511 3512
	pfree(bufusage);

	/* remove trailing newline */
B
Bruce Momjian 已提交
3513
	if (str.data[str.len - 1] == '\n')
3514 3515
		str.data[--str.len] = '\0';

3516 3517 3518
	ereport(LOG,
			(errmsg_internal("%s", title),
			 errdetail("%s", str.data)));
3519 3520

	pfree(str.data);
3521
}
3522 3523 3524 3525

/*
 * on_proc_exit handler to log end of session
 */
B
Bruce Momjian 已提交
3526
static void
3527
log_disconnections(int code, Datum arg)
3528
{
B
Bruce Momjian 已提交
3529
	Port	   *port = MyProcPort;
3530
	struct timeval end;
B
Bruce Momjian 已提交
3531 3532 3533 3534 3535 3536 3537 3538 3539 3540 3541 3542 3543
	int			hours,
				minutes,
				seconds;

	char		session_time[20];
	char		uname[6 + NAMEDATALEN];
	char		dbname[10 + NAMEDATALEN];
	char		remote_host[7 + NI_MAXHOST];
	char		remote_port[7 + NI_MAXSERV];

	snprintf(uname, sizeof(uname), " user=%s", port->user_name);
	snprintf(dbname, sizeof(dbname), " database=%s", port->database_name);
	snprintf(remote_host, sizeof(remote_host), " host=%s",
3544
			 port->remote_host);
3545 3546 3547 3548 3549
	if (port->remote_port[0])
		snprintf(remote_port, sizeof(remote_port), " port=%s", port->remote_port);
	else
		remote_port[0] = '\0';
		
B
Bruce Momjian 已提交
3550
	gettimeofday(&end, NULL);
3551 3552 3553 3554 3555 3556 3557 3558 3559

	if (end.tv_usec < port->session_start.tv_usec)
	{
		end.tv_sec--;
		end.tv_usec += 1000000;
	}
	end.tv_sec -= port->session_start.tv_sec;
	end.tv_usec -= port->session_start.tv_usec;

3560 3561 3562 3563
	hours = end.tv_sec / SECS_PER_HOUR;
	end.tv_sec %= SECS_PER_HOUR;
	minutes = end.tv_sec / SECS_PER_MINUTE;
	seconds = end.tv_sec % SECS_PER_MINUTE;
3564 3565 3566 3567

	/* if time has gone backwards for some reason say so, or print time */

	if (end.tv_sec < 0)
B
Bruce Momjian 已提交
3568
		snprintf(session_time, sizeof(session_time), "negative!");
3569
	else
B
Bruce Momjian 已提交
3570 3571 3572 3573 3574

		/*
		 * for stricter accuracy here we could round - this is close
		 * enough
		 */
3575
		snprintf(session_time, sizeof(session_time),
B
Bruce Momjian 已提交
3576 3577 3578
				 "%d:%02d:%02d.%02d",
				 hours, minutes, seconds, (int) (end.tv_usec / 10000));

3579
	ereport(
B
Bruce Momjian 已提交
3580 3581 3582
			LOG,
			(errmsg("disconnection: session time: %s%s%s%s%s",
				session_time, uname, dbname, remote_host, remote_port)));
3583 3584

}