postgres.c 105.0 KB
Newer Older
1 2
/*-------------------------------------------------------------------------
 *
3
 * postgres.c
4
 *	  POSTGRES C Backend Interface
5
 *
6
 * Portions Copyright (c) 1996-2010, 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.580 2010/01/02 16:57:52 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"

22
#include <time.h>
B
Bruce Momjian 已提交
23
#include <unistd.h>
24
#include <signal.h>
B
Bruce Momjian 已提交
25
#include <fcntl.h>
26
#include <sys/socket.h>
27
#ifdef HAVE_SYS_SELECT_H
28
#include <sys/select.h>
29
#endif
30
#ifdef HAVE_SYS_RESOURCE_H
31
#include <sys/time.h>
32 33
#include <sys/resource.h>
#endif
34
#ifdef HAVE_GETOPT_H
B
Bruce Momjian 已提交
35
#include <getopt.h>
36
#endif
37

38 39 40 41
#ifndef HAVE_GETRUSAGE
#include "rusagestub.h"
#endif

42
#include "access/printtup.h"
43
#include "access/xact.h"
44
#include "catalog/pg_type.h"
45
#include "commands/async.h"
46
#include "commands/prepare.h"
47
#include "libpq/libpq.h"
48
#include "libpq/pqformat.h"
49
#include "libpq/pqsignal.h"
B
Bruce Momjian 已提交
50
#include "miscadmin.h"
51
#include "nodes/print.h"
52
#include "optimizer/planner.h"
53 54
#include "pgstat.h"
#include "pg_trace.h"
55
#include "parser/analyze.h"
56
#include "parser/parser.h"
57
#include "postmaster/autovacuum.h"
58
#include "postmaster/postmaster.h"
B
Bruce Momjian 已提交
59
#include "rewrite/rewriteHandler.h"
60
#include "storage/bufmgr.h"
61 62
#include "storage/ipc.h"
#include "storage/proc.h"
63
#include "storage/procsignal.h"
64
#include "storage/sinval.h"
65
#include "storage/standby.h"
66 67
#include "tcop/fastpath.h"
#include "tcop/pquery.h"
B
Bruce Momjian 已提交
68
#include "tcop/tcopprot.h"
69
#include "tcop/utility.h"
70
#include "utils/lsyscache.h"
71
#include "utils/memutils.h"
M
 
Marc G. Fournier 已提交
72
#include "utils/ps_status.h"
73
#include "utils/snapmgr.h"
B
Bruce Momjian 已提交
74
#include "mb/pg_wchar.h"
75

M
 
Marc G. Fournier 已提交
76

77
extern char *optarg;
78 79 80 81 82 83
extern int	optind;

#ifdef HAVE_INT_OPTRESET
extern int	optreset;			/* might not be declared by system headers */
#endif

84

85
/* ----------------
86
 *		global variables
87 88
 * ----------------
 */
89
const char *debug_query_string; /* client-supplied query string */
90

91
/* Note: whereToSendOutput is initialized for the bootstrap/standalone case */
92
CommandDest whereToSendOutput = DestDebug;
93

94
/* flag for logging end of session */
B
Bruce Momjian 已提交
95
bool		Log_disconnections = false;
96

97
int			log_statement = LOGSTMT_NONE;
98

99
/* GUC variable for maximum stack depth (measured in kilobytes) */
100
int			max_stack_depth = 100;
101

102 103 104 105
/* wait N seconds to allow attach from a debugger */
int			PostAuthDelay = 0;


106

107 108 109 110
/* ----------------
 *		private variables
 * ----------------
 */
111

112
/* max_stack_depth converted to bytes for speed of checking */
113
static long max_stack_depth_bytes = 100 * 1024L;
114

N
Neil Conway 已提交
115 116 117 118
/*
 * Stack base pointer -- initialized by PostgresMain. This is not static
 * so that PL/Java can modify it.
 */
B
Bruce Momjian 已提交
119
char	   *stack_base_ptr = NULL;
120 121


122 123 124 125 126
/*
 * 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?)
 */
127
static volatile sig_atomic_t got_SIGHUP = false;
128

129 130 131 132 133 134
/*
 * 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;

135 136 137 138 139 140 141
/*
 * 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;

142 143 144 145 146 147 148 149 150 151 152 153
/*
 * 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.
 */
154
static CachedPlanSource *unnamed_stmt_psrc = NULL;
B
Bruce Momjian 已提交
155

156
/* workspace for building a new unnamed statement in */
157 158 159
static MemoryContext unnamed_stmt_context = NULL;


160 161 162 163
/* assorted command-line switches */
static const char *userDoption = NULL;		/* -D switch */

static bool EchoQuery = false;				/* -E switch */
164 165 166 167

/*
 * people who want to use EOF should #define DONTUSENEWLINE in
 * tcop/tcopdebug.h
168 169
 */
#ifndef TCOP_DONTUSENEWLINE
B
Bruce Momjian 已提交
170
static int	UseNewLine = 1;		/* Use newlines query delimiters (the default) */
171
#else
172
static int	UseNewLine = 0;		/* Use EOF as query delimiters */
173
#endif   /* TCOP_DONTUSENEWLINE */
174 175 176


/* ----------------------------------------------------------------
177
 *		decls for routines only used in this file
178 179
 * ----------------------------------------------------------------
 */
180
static int	InteractiveBackend(StringInfo inBuf);
181
static int	interactive_getc(void);
182 183
static int	SocketBackend(StringInfo inBuf);
static int	ReadCommand(StringInfo inBuf);
184
static List *pg_rewrite_query(Query *query);
185
static bool check_log_statement(List *stmt_list);
186 187
static int	errdetail_execute(List *raw_parsetree_list);
static int	errdetail_params(ParamListInfo params);
188
static void start_xact_command(void);
189
static void finish_xact_command(void);
190 191 192
static bool IsTransactionExitStmt(Node *parsetree);
static bool IsTransactionExitStmtList(List *parseTrees);
static bool IsTransactionStmtList(List *parseTrees);
193
static void drop_unnamed_stmt(void);
194
static void SigHupHandler(SIGNAL_ARGS);
195
static void log_disconnections(int code, Datum arg);
196 197 198


/* ----------------------------------------------------------------
199
 *		routines to obtain user input
200 201 202 203
 * ----------------------------------------------------------------
 */

/* ----------------
204
 *	InteractiveBackend() is called for user interactive connections
205 206 207
 *
 *	the string entered by the user is placed in its parameter inBuf,
 *	and we act like a Q message was received.
208
 *
209
 *	EOF is returned if end-of-file input is seen; time to shut down.
210 211 212
 * ----------------
 */

213
static int
214
InteractiveBackend(StringInfo inBuf)
215
{
216 217 218
	int			c;				/* character read from getc() */
	bool		end = false;	/* end-of-input flag */
	bool		backslashSeen = false;	/* have we seen a \ ? */
219

220 221
	/*
	 * display a prompt and obtain input from the user
222
	 */
223
	printf("backend> ");
224
	fflush(stdout);
225

226
	resetStringInfo(inBuf);
227

228
	if (UseNewLine)
229
	{
230
		/*
B
Bruce Momjian 已提交
231 232
		 * if we are using \n as a delimiter, then read characters until the
		 * \n.
233 234
		 */
		while ((c = interactive_getc()) != EOF)
235
		{
236
			if (c == '\n')
237
			{
238
				if (backslashSeen)
239
				{
240 241 242 243
					/* discard backslash from inBuf */
					inBuf->data[--inBuf->len] = '\0';
					backslashSeen = false;
					continue;
244 245
				}
				else
246 247 248 249 250
				{
					/* keep the newline character */
					appendStringInfoChar(inBuf, '\n');
					break;
				}
251
			}
252 253 254 255
			else if (c == '\\')
				backslashSeen = true;
			else
				backslashSeen = false;
256

257
			appendStringInfoChar(inBuf, (char) c);
258 259
		}

260 261 262 263 264
		if (c == EOF)
			end = true;
	}
	else
	{
265
		/*
266
		 * otherwise read characters until EOF.
267
		 */
268 269 270 271 272 273
		while ((c = interactive_getc()) != EOF)
			appendStringInfoChar(inBuf, (char) c);

		/* No input before EOF signal means time to quit. */
		if (inBuf->len == 0)
			end = true;
274 275
	}

276 277 278 279 280 281 282
	if (end)
		return EOF;

	/*
	 * otherwise we have a user query so process it.
	 */

283 284 285
	/* Add '\0' to make it look the same as message case. */
	appendStringInfoChar(inBuf, (char) '\0');

286 287
	/*
	 * if the query echo flag was given, print the query..
288 289
	 */
	if (EchoQuery)
290
		printf("statement: %s\n", inBuf->data);
291
	fflush(stdout);
292

293
	return 'Q';
294 295
}

296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313
/*
 * interactive_getc -- collect one character from stdin
 *
 * Even though we are not reading from a "client" process, we still want to
 * respond to signals, particularly SIGTERM/SIGQUIT.  Hence we must use
 * prepare_for_client_read and client_read_ended.
 */
static int
interactive_getc(void)
{
	int			c;

	prepare_for_client_read();
	c = getc(stdin);
	client_read_ended();
	return c;
}

314
/* ----------------
315
 *	SocketBackend()		Is called for frontend-backend connections
316
 *
317
 *	Returns the message type code, and loads message body data into inBuf.
318
 *
319
 *	EOF is returned if the connection is lost.
320 321
 * ----------------
 */
322
static int
323
SocketBackend(StringInfo inBuf)
324
{
325
	int			qtype;
326

327
	/*
328
	 * Get message type code from the frontend.
329
	 */
330
	qtype = pq_getbyte();
331

332 333
	if (qtype == EOF)			/* frontend disconnected */
	{
334 335 336
		ereport(COMMERROR,
				(errcode(ERRCODE_PROTOCOL_VIOLATION),
				 errmsg("unexpected EOF on client connection")));
337 338 339 340
		return qtype;
	}

	/*
B
Bruce Momjian 已提交
341 342 343
	 * Validate message type code before trying to read body; if we have lost
	 * sync, better to say "command unknown" than to run out of memory because
	 * we used garbage as a length word.
344
	 *
345 346
	 * This also gives us a place to set the doing_extended_query_message flag
	 * as soon as possible.
347
	 */
348
	switch (qtype)
349
	{
350
		case 'Q':				/* simple query */
351
			doing_extended_query_message = false;
352 353 354 355 356
			if (PG_PROTOCOL_MAJOR(FrontendProtocol) < 3)
			{
				/* old style without length word; convert */
				if (pq_getstring(inBuf))
				{
357 358
					ereport(COMMERROR,
							(errcode(ERRCODE_PROTOCOL_VIOLATION),
B
Bruce Momjian 已提交
359
							 errmsg("unexpected EOF on client connection")));
360 361 362
					return EOF;
				}
			}
363 364
			break;

365
		case 'F':				/* fastpath function call */
366 367
			/* we let fastpath.c cope with old-style input of this */
			doing_extended_query_message = false;
368
			break;
369

370
		case 'X':				/* terminate */
371
			doing_extended_query_message = false;
372
			ignore_till_sync = false;
373 374 375 376 377 378 379 380 381 382 383
			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)
384 385
				ereport(FATAL,
						(errcode(ERRCODE_PROTOCOL_VIOLATION),
B
Bruce Momjian 已提交
386
						 errmsg("invalid frontend message type %d", qtype)));
387 388 389 390 391 392 393 394 395
			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)
396 397
				ereport(FATAL,
						(errcode(ERRCODE_PROTOCOL_VIOLATION),
B
Bruce Momjian 已提交
398
						 errmsg("invalid frontend message type %d", qtype)));
399
			break;
400

401 402 403
		case 'd':				/* copy data */
		case 'c':				/* copy done */
		case 'f':				/* copy fail */
404 405 406
			doing_extended_query_message = false;
			/* these are only legal in protocol 3 */
			if (PG_PROTOCOL_MAJOR(FrontendProtocol) < 3)
407 408
				ereport(FATAL,
						(errcode(ERRCODE_PROTOCOL_VIOLATION),
B
Bruce Momjian 已提交
409
						 errmsg("invalid frontend message type %d", qtype)));
410
			break;
411

412
		default:
B
Bruce Momjian 已提交
413

414
			/*
B
Bruce Momjian 已提交
415 416 417
			 * 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.
418
			 */
419 420 421
			ereport(FATAL,
					(errcode(ERRCODE_PROTOCOL_VIOLATION),
					 errmsg("invalid frontend message type %d", qtype)));
422
			break;
423
	}
424

425
	/*
B
Bruce Momjian 已提交
426 427 428
	 * 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.
429 430 431 432 433 434 435
	 */
	if (PG_PROTOCOL_MAJOR(FrontendProtocol) >= 3)
	{
		if (pq_getmessage(inBuf, 0))
			return EOF;			/* suitable message already logged */
	}

436
	return qtype;
437 438 439
}

/* ----------------
440
 *		ReadCommand reads a command from either the frontend or
441 442 443
 *		standard input, places it in inBuf, and returns the
 *		message type code (first byte of the message).
 *		EOF is returned if end of file.
444 445
 * ----------------
 */
446
static int
447
ReadCommand(StringInfo inBuf)
448
{
449
	int			result;
450

451
	if (whereToSendOutput == DestRemote)
452
		result = SocketBackend(inBuf);
453
	else
454 455
		result = InteractiveBackend(inBuf);
	return result;
456 457
}

458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503
/*
 * 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();
	}
}

504 505 506 507 508 509

/*
 * 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.
510 511 512
 *
 * NOTE: this routine is no longer used for processing interactive queries,
 * but it is still needed for parsing of SQL function bodies.
513
 */
514
List *
B
Bruce Momjian 已提交
515
pg_parse_and_rewrite(const char *query_string,	/* string to execute */
516
					 Oid *paramTypes,	/* parameter types */
B
Bruce Momjian 已提交
517
					 int numParams)		/* number of parameters */
518
{
519
	List	   *raw_parsetree_list;
520
	List	   *querytree_list;
521
	ListCell   *list_item;
522

523 524
	/*
	 * (1) parse the request string into a list of raw parse trees.
525
	 */
526
	raw_parsetree_list = pg_parse_query(query_string);
527

528 529
	/*
	 * (2) Do parse analysis and rule rewrite.
530 531 532 533
	 */
	querytree_list = NIL;
	foreach(list_item, raw_parsetree_list)
	{
B
Bruce Momjian 已提交
534
		Node	   *parsetree = (Node *) lfirst(list_item);
535

536
		querytree_list = list_concat(querytree_list,
B
Bruce Momjian 已提交
537
									 pg_analyze_and_rewrite(parsetree,
538
															query_string,
B
Bruce Momjian 已提交
539 540
															paramTypes,
															numParams));
541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558
	}

	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.
 */
559
List *
560
pg_parse_query(const char *query_string)
561
{
562
	List	   *raw_parsetree_list;
563

564 565
	TRACE_POSTGRESQL_QUERY_PARSE_START(query_string);

B
Rename:  
Bruce Momjian 已提交
566
	if (log_parser_stats)
567 568
		ResetUsage();

569
	raw_parsetree_list = raw_parser(query_string);
570

571 572 573
	if (log_parser_stats)
		ShowUsage("PARSER STATISTICS");

574 575 576 577 578 579 580 581 582 583 584 585 586
#ifdef COPY_PARSE_PLAN_TREES
	/* Optional debugging check: pass raw parsetrees through copyObject() */
	{
		List	   *new_list = (List *) copyObject(raw_parsetree_list);

		/* This checks both copyObject() and the equal() routines... */
		if (!equal(new_list, raw_parsetree_list))
			elog(WARNING, "copyObject() failed to produce an equal raw parse tree");
		else
			raw_parsetree_list = new_list;
	}
#endif

587 588
	TRACE_POSTGRESQL_QUERY_PARSE_DONE(query_string);

589 590 591
	return raw_parsetree_list;
}

592
/*
593 594
 * Given a raw parsetree (gram.y output), and optionally information about
 * types of parameter symbols ($n), perform parse analysis and rule rewriting.
595 596 597 598 599 600
 *
 * 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.
 */
601
List *
602 603
pg_analyze_and_rewrite(Node *parsetree, const char *query_string,
					   Oid *paramTypes, int numParams)
604
{
605
	Query	   *query;
606 607
	List	   *querytree_list;

608 609
	TRACE_POSTGRESQL_QUERY_REWRITE_START(query_string);

610 611
	/*
	 * (1) Perform parse analysis.
612
	 */
B
Rename:  
Bruce Momjian 已提交
613
	if (log_parser_stats)
614 615
		ResetUsage();

616
	query = parse_analyze(parsetree, query_string, paramTypes, numParams);
617

B
Rename:  
Bruce Momjian 已提交
618
	if (log_parser_stats)
619
		ShowUsage("PARSE ANALYSIS STATISTICS");
620

621 622
	/*
	 * (2) Rewrite the queries, as necessary
623
	 */
624
	querytree_list = pg_rewrite_query(query);
625

626 627
	TRACE_POSTGRESQL_QUERY_REWRITE_DONE(query_string);

628 629 630
	return querytree_list;
}

631 632 633 634 635 636 637 638 639 640 641 642 643 644 645 646 647 648 649 650 651 652 653 654 655 656 657 658 659 660 661 662 663 664 665 666 667 668 669 670 671 672 673 674 675 676
/*
 * Do parse analysis and rewriting.  This is the same as pg_analyze_and_rewrite
 * except that external-parameter resolution is determined by parser callback
 * hooks instead of a fixed list of parameter datatypes.
 */
List *
pg_analyze_and_rewrite_params(Node *parsetree,
							  const char *query_string,
							  ParserSetupHook parserSetup,
							  void *parserSetupArg)
{
	ParseState *pstate;
	Query	   *query;
	List	   *querytree_list;

	Assert(query_string != NULL); /* required as of 8.4 */

	TRACE_POSTGRESQL_QUERY_REWRITE_START(query_string);

	/*
	 * (1) Perform parse analysis.
	 */
	if (log_parser_stats)
		ResetUsage();

	pstate = make_parsestate(NULL);
	pstate->p_sourcetext = query_string;
	(*parserSetup) (pstate, parserSetupArg);

	query = transformStmt(pstate, parsetree);

	free_parsestate(pstate);

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

	/*
	 * (2) Rewrite the queries, as necessary
	 */
	querytree_list = pg_rewrite_query(query);

	TRACE_POSTGRESQL_QUERY_REWRITE_DONE(query_string);

	return querytree_list;
}

677
/*
678
 * Perform rewriting of a query produced by parse analysis.
679
 *
680 681
 * Note: query must just have come from the parser, because we do not do
 * AcquireRewriteLocks() on it.
682
 */
683
static List *
684
pg_rewrite_query(Query *query)
685
{
686
	List	   *querytree_list;
687

688
	if (Debug_print_parse)
689
		elog_node_display(LOG, "parse tree", query,
690
						  Debug_pretty_print);
691

692 693 694
	if (log_parser_stats)
		ResetUsage();

695 696 697 698 699 700 701 702 703
	if (query->commandType == CMD_UTILITY)
	{
		/* don't rewrite utilities, just dump 'em into result list */
		querytree_list = list_make1(query);
	}
	else
	{
		/* rewrite regular queries */
		querytree_list = QueryRewrite(query);
704 705
	}

B
Rename:  
Bruce Momjian 已提交
706
	if (log_parser_stats)
707
		ShowUsage("REWRITER STATISTICS");
708

709
#ifdef COPY_PARSE_PLAN_TREES
710 711 712
	/* Optional debugging check: pass querytree output through copyObject() */
	{
		List	   *new_list;
B
Bruce Momjian 已提交
713

714 715 716 717 718 719 720
		new_list = (List *) copyObject(querytree_list);
		/* This checks both copyObject() and the equal() routines... */
		if (!equal(new_list, querytree_list))
			elog(WARNING, "copyObject() failed to produce equal parse tree");
		else
			querytree_list = new_list;
	}
721 722
#endif

723
	if (Debug_print_rewritten)
724
		elog_node_display(LOG, "rewritten parse tree", querytree_list,
725
						  Debug_pretty_print);
726

727 728
	return querytree_list;
}
729 730


731 732 733 734
/*
 * Generate a plan for a single already-rewritten query.
 * This is a thin wrapper around planner() and takes the same parameters.
 */
735
PlannedStmt *
736
pg_plan_query(Query *querytree, int cursorOptions, ParamListInfo boundParams)
737
{
738
	PlannedStmt *plan;
739

740 741 742
	/* Utility commands have no plans. */
	if (querytree->commandType == CMD_UTILITY)
		return NULL;
743

744 745 746
	/* Planner must have a snapshot in case it calls user-defined functions. */
	Assert(ActiveSnapshotSet());

747 748
	TRACE_POSTGRESQL_QUERY_PLAN_START();

B
Rename:  
Bruce Momjian 已提交
749
	if (log_planner_stats)
750
		ResetUsage();
751

752
	/* call the optimizer */
753
	plan = planner(querytree, cursorOptions, boundParams);
754

B
Rename:  
Bruce Momjian 已提交
755
	if (log_planner_stats)
756
		ShowUsage("PLANNER STATISTICS");
757

758 759 760
#ifdef COPY_PARSE_PLAN_TREES
	/* Optional debugging check: pass plan output through copyObject() */
	{
761
		PlannedStmt *new_plan = (PlannedStmt *) copyObject(plan);
762

B
Bruce Momjian 已提交
763
		/*
B
Bruce Momjian 已提交
764 765
		 * equal() currently does not have routines to compare Plan nodes, so
		 * don't try to test equality here.  Perhaps fix someday?
766 767 768
		 */
#ifdef NOT_USED
		/* This checks both copyObject() and the equal() routines... */
B
Bruce Momjian 已提交
769
		if (!equal(new_plan, plan))
770
			elog(WARNING, "copyObject() failed to produce an equal plan tree");
771 772 773 774 775 776
		else
#endif
			plan = new_plan;
	}
#endif

777 778
	/*
	 * Print plan if debugging.
779
	 */
780
	if (Debug_print_plan)
781
		elog_node_display(LOG, "plan", plan, Debug_pretty_print);
782

783 784
	TRACE_POSTGRESQL_QUERY_PLAN_DONE();

785
	return plan;
786 787
}

788 789
/*
 * Generate plans for a list of already-rewritten queries.
790
 *
791 792
 * Normal optimizable statements generate PlannedStmt entries in the result
 * list.  Utility statements are simply represented by their statement nodes.
793 794
 */
List *
795
pg_plan_queries(List *querytrees, int cursorOptions, ParamListInfo boundParams)
796
{
797 798
	List	   *stmt_list = NIL;
	ListCell   *query_list;
799

800
	foreach(query_list, querytrees)
801
	{
802 803
		Query	   *query = (Query *) lfirst(query_list);
		Node	   *stmt;
804

805
		if (query->commandType == CMD_UTILITY)
806
		{
807 808 809 810 811
			/* Utility commands have no plans. */
			stmt = query->utilityStmt;
		}
		else
		{
812
			stmt = (Node *) pg_plan_query(query, cursorOptions, boundParams);
813 814
		}

815
		stmt_list = lappend(stmt_list, stmt);
816
	}
817

818
	return stmt_list;
819 820 821 822
}


/*
823
 * exec_simple_query
824
 *
825
 * Execute a "simple Query" protocol message.
826
 */
827
static void
828
exec_simple_query(const char *query_string)
829
{
B
Bruce Momjian 已提交
830
	CommandDest dest = whereToSendOutput;
831
	MemoryContext oldcontext;
832 833
	List	   *parsetree_list;
	ListCell   *parsetree_item;
834
	bool		save_log_statement_stats = log_statement_stats;
835
	bool		was_logged = false;
836
	bool		isTopLevel;
837
	char		msec_str[32];
B
Bruce Momjian 已提交
838

839

840 841 842
	/*
	 * Report query to various monitoring facilities.
	 */
843
	debug_query_string = query_string;
844

845 846
	pgstat_report_activity(query_string);

847 848
	TRACE_POSTGRESQL_QUERY_START(query_string);

849
	/*
850 851
	 * We use save_log_statement_stats so ShowUsage doesn't report incorrect
	 * results because ResetUsage wasn't called.
852
	 */
853 854 855
	if (save_log_statement_stats)
		ResetUsage();

856
	/*
B
Bruce Momjian 已提交
857 858
	 * Start up a transaction command.	All queries generated by the
	 * query_string will be in this same command block, *unless* we find a
B
Bruce Momjian 已提交
859 860 861
	 * 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 that this
	 * will normally change current memory context.)
862
	 */
863
	start_xact_command();
864 865

	/*
B
Bruce Momjian 已提交
866 867 868 869
	 * 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.)
870
	 */
871
	drop_unnamed_stmt();
872

873 874 875
	/*
	 * Switch to appropriate context for constructing parsetrees.
	 */
876
	oldcontext = MemoryContextSwitchTo(MessageContext);
877

B
Bruce Momjian 已提交
878
	/*
B
Bruce Momjian 已提交
879 880
	 * Do basic parsing of the query or queries (this should be safe even if
	 * we are in aborted transaction state!)
881
	 */
882
	parsetree_list = pg_parse_query(query_string);
883

884
	/* Log immediately if dictated by log_statement */
885
	if (check_log_statement(parsetree_list))
886 887 888
	{
		ereport(LOG,
				(errmsg("statement: %s", query_string),
889
				 errhidestmt(true),
890 891 892
				 errdetail_execute(parsetree_list)));
		was_logged = true;
	}
893

894
	/*
895
	 * Switch back to transaction context to enter the loop.
896 897 898
	 */
	MemoryContextSwitchTo(oldcontext);

899
	/*
B
Bruce Momjian 已提交
900 901 902 903
	 * We'll tell PortalRun it's a top-level command iff there's exactly one
	 * raw parsetree.  If more than one, it's effectively a transaction block
	 * and we want PreventTransactionChain to reject unsafe commands. (Note:
	 * we're assuming that query rewrite cannot add commands that are
904 905 906 907
	 * significant to PreventTransactionChain.)
	 */
	isTopLevel = (list_length(parsetree_list) == 1);

908
	/*
909
	 * Run through the raw parsetree(s) and process each one.
910
	 */
911
	foreach(parsetree_item, parsetree_list)
912
	{
B
Bruce Momjian 已提交
913
		Node	   *parsetree = (Node *) lfirst(parsetree_item);
914
		bool		snapshot_set = false;
915 916
		const char *commandTag;
		char		completionTag[COMPLETION_TAG_BUFSIZE];
B
Bruce Momjian 已提交
917
		List	   *querytree_list,
918 919
				   *plantree_list;
		Portal		portal;
920 921
		DestReceiver *receiver;
		int16		format;
922

923
		/*
B
Bruce Momjian 已提交
924 925 926 927
		 * 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.
928 929 930
		 */
		commandTag = CreateCommandTag(parsetree);

931
		set_ps_display(commandTag, false);
932

933
		BeginCommand(commandTag, dest);
934

935
		/*
936
		 * If we are in an aborted transaction, reject all commands except
B
Bruce Momjian 已提交
937 938 939 940 941
		 * COMMIT/ABORT.  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 commands in this
		 * state, but not many...)
942
		 */
943 944 945 946 947
		if (IsAbortedTransactionBlockState() &&
			!IsTransactionExitStmt(parsetree))
			ereport(ERROR,
					(errcode(ERRCODE_IN_FAILED_SQL_TRANSACTION),
					 errmsg("current transaction is aborted, "
B
Bruce Momjian 已提交
948
						"commands ignored until end of transaction block")));
949

950
		/* Make sure we are in a transaction command */
951
		start_xact_command();
952

953
		/* If we got a cancel signal in parsing or prior command, quit */
954
		CHECK_FOR_INTERRUPTS();
955

956 957 958 959 960 961 962 963 964
		/*
		 * Set up a snapshot if parse analysis/planning will need one.
		 */
		if (analyze_requires_snapshot(parsetree))
		{
			PushActiveSnapshot(GetTransactionSnapshot());
			snapshot_set = true;
		}

965
		/*
966
		 * OK to analyze, rewrite, and plan this query.
967
		 *
B
Bruce Momjian 已提交
968 969
		 * Switch to appropriate context for constructing querytrees (again,
		 * these must outlive the execution context).
970
		 */
971
		oldcontext = MemoryContextSwitchTo(MessageContext);
972

973 974
		querytree_list = pg_analyze_and_rewrite(parsetree, query_string,
												NULL, 0);
V
Vadim B. Mikheev 已提交
975

976
		plantree_list = pg_plan_queries(querytree_list, 0, NULL);
977 978 979 980

		/* Done with the snapshot used for parsing/planning */
		if (snapshot_set)
			PopActiveSnapshot();
981 982 983 984

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

985
		/*
B
Bruce Momjian 已提交
986 987
		 * Create unnamed portal to run the query or queries in. If there
		 * already is one, silently drop it.
988
		 */
989
		portal = CreatePortal("", true, true);
990 991
		/* Don't display the portal in pg_cursors */
		portal->visible = false;
992

993 994
		/*
		 * We don't have to copy anything into the portal, because everything
995
		 * we are passing here is in MessageContext, which will outlive the
996 997
		 * portal anyway.
		 */
998
		PortalDefineQuery(portal,
999
						  NULL,
1000 1001 1002
						  query_string,
						  commandTag,
						  plantree_list,
1003
						  NULL);
1004

1005
		/*
1006
		 * Start the portal.  No parameters here.
1007
		 */
1008
		PortalStart(portal, NULL, InvalidSnapshot);
1009

1010
		/*
B
Bruce Momjian 已提交
1011 1012 1013 1014
		 * Select the appropriate output format: text unless we are doing 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...)
1015 1016 1017 1018 1019 1020 1021 1022 1023 1024 1025 1026
		 */
		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 已提交
1027
					format = 1; /* BINARY */
1028 1029 1030 1031 1032 1033 1034
			}
		}
		PortalSetResultFormat(portal, 1, &format);

		/*
		 * Now we can create the destination receiver object.
		 */
1035 1036 1037
		receiver = CreateDestReceiver(dest);
		if (dest == DestRemote)
			SetRemoteDestReceiverParams(receiver, portal);
1038 1039 1040 1041 1042 1043 1044

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

		/*
B
Bruce Momjian 已提交
1045
		 * Run the portal to completion, and then drop it (and the receiver).
1046
		 */
1047 1048
		(void) PortalRun(portal,
						 FETCH_ALL,
1049
						 isTopLevel,
1050 1051
						 receiver,
						 receiver,
1052
						 completionTag);
1053

1054
		(*receiver->rDestroy) (receiver);
1055

1056
		PortalDrop(portal, false);
1057

1058
		if (IsA(parsetree, TransactionStmt))
1059
		{
1060
			/*
B
Bruce Momjian 已提交
1061 1062
			 * If this was a transaction control statement, commit it. We will
			 * start a new xact command for the next command (if any).
1063
			 */
1064
			finish_xact_command();
1065
		}
1066
		else if (lnext(parsetree_item) == NULL)
1067
		{
1068
			/*
B
Bruce Momjian 已提交
1069 1070 1071 1072 1073 1074 1075 1076
			 * 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.
1077
			 */
1078
			finish_xact_command();
1079
		}
1080
		else
1081
		{
1082
			/*
B
Bruce Momjian 已提交
1083 1084
			 * We need a CommandCounterIncrement after every query, except
			 * those that start or end a transaction block.
1085 1086
			 */
			CommandCounterIncrement();
1087
		}
1088 1089

		/*
B
Bruce Momjian 已提交
1090 1091 1092 1093
		 * Tell client that we're done with this query.  Note we emit 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.)
1094
		 */
1095
		EndCommand(completionTag, dest);
B
Bruce Momjian 已提交
1096
	}							/* end loop over parsetrees */
1097

1098 1099 1100
	/*
	 * Close down transaction statement, if one is open.
	 */
1101
	finish_xact_command();
1102

1103 1104 1105
	/*
	 * If there were no parsetrees, return EmptyQueryResponse message.
	 */
1106
	if (!parsetree_list)
1107 1108
		NullCommand(dest);

1109
	/*
1110
	 * Emit duration logging if appropriate.
1111
	 */
1112
	switch (check_log_duration(msec_str, was_logged))
1113
	{
1114
		case 1:
1115
			ereport(LOG,
1116 1117
					(errmsg("duration: %s ms", msec_str),
					 errhidestmt(true)));
1118 1119
			break;
		case 2:
1120 1121 1122
			ereport(LOG,
					(errmsg("duration: %s ms  statement: %s",
							msec_str, query_string),
1123
					 errhidestmt(true),
1124
					 errdetail_execute(parsetree_list)));
1125
			break;
1126
	}
1127

1128 1129 1130
	if (save_log_statement_stats)
		ShowUsage("QUERY STATISTICS");

1131 1132
	TRACE_POSTGRESQL_QUERY_DONE(query_string);

1133
	debug_query_string = NULL;
1134 1135
}

1136 1137 1138 1139 1140 1141 1142 1143
/*
 * 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 已提交
1144 1145
				   Oid *paramTypes,		/* parameter types */
				   int numParams)		/* number of parameters */
1146 1147 1148
{
	MemoryContext oldcontext;
	List	   *parsetree_list;
1149
	Node	   *raw_parse_tree;
1150 1151
	const char *commandTag;
	List	   *querytree_list,
1152
			   *stmt_list;
1153
	bool		is_named;
1154
	bool		fully_planned;
1155
	bool		save_log_statement_stats = log_statement_stats;
1156
	char		msec_str[32];
1157 1158 1159 1160 1161 1162 1163 1164

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

	pgstat_report_activity(query_string);

1165
	set_ps_display("PARSE", false);
1166 1167 1168 1169

	if (save_log_statement_stats)
		ResetUsage();

1170 1171 1172 1173
	ereport(DEBUG2,
			(errmsg("parse %s: %s",
					*stmt_name ? stmt_name : "<unnamed>",
					query_string)));
1174

1175
	/*
B
Bruce Momjian 已提交
1176 1177 1178
	 * 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.
1179
	 */
1180
	start_xact_command();
1181 1182 1183 1184

	/*
	 * Switch to appropriate context for constructing parsetrees.
	 *
B
Bruce Momjian 已提交
1185 1186 1187
	 * 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
1188
	 * statement's plancache entry; then the reset of MessageContext releases
B
Bruce Momjian 已提交
1189 1190 1191
	 * 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
1192 1193
	 * copying parse/plan trees.  So in this case, we create the plancache
	 * entry's context here, and do all the parsing work therein.
1194 1195 1196 1197 1198 1199 1200 1201 1202 1203
	 */
	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 */
1204 1205
		drop_unnamed_stmt();
		/* Create context for parsing/planning */
1206
		unnamed_stmt_context =
1207
			AllocSetContextCreate(CacheMemoryContext,
1208 1209 1210 1211 1212 1213 1214 1215
								  "unnamed prepared statement",
								  ALLOCSET_DEFAULT_MINSIZE,
								  ALLOCSET_DEFAULT_INITSIZE,
								  ALLOCSET_DEFAULT_MAXSIZE);
		oldcontext = MemoryContextSwitchTo(unnamed_stmt_context);
	}

	/*
B
Bruce Momjian 已提交
1216 1217
	 * Do basic parsing of the query or queries (this should be safe even if
	 * we are in aborted transaction state!)
1218 1219 1220 1221
	 */
	parsetree_list = pg_parse_query(query_string);

	/*
B
Bruce Momjian 已提交
1222 1223 1224
	 * 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.
1225
	 */
1226
	if (list_length(parsetree_list) > 1)
1227 1228
		ereport(ERROR,
				(errcode(ERRCODE_SYNTAX_ERROR),
B
Bruce Momjian 已提交
1229
		errmsg("cannot insert multiple commands into a prepared statement")));
1230 1231 1232

	if (parsetree_list != NIL)
	{
1233
		Query	   *query;
1234
		bool		snapshot_set = false;
B
Bruce Momjian 已提交
1235
		int			i;
1236

1237 1238
		raw_parse_tree = (Node *) linitial(parsetree_list);

1239 1240 1241
		/*
		 * Get the command name for possible use in status display.
		 */
1242
		commandTag = CreateCommandTag(raw_parse_tree);
1243 1244 1245

		/*
		 * If we are in an aborted transaction, reject all commands except
B
Bruce Momjian 已提交
1246 1247 1248 1249 1250
		 * 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 commands in this
		 * state, but not many...)
1251
		 */
1252
		if (IsAbortedTransactionBlockState() &&
1253
			!IsTransactionExitStmt(raw_parse_tree))
1254 1255 1256
			ereport(ERROR,
					(errcode(ERRCODE_IN_FAILED_SQL_TRANSACTION),
					 errmsg("current transaction is aborted, "
B
Bruce Momjian 已提交
1257
						"commands ignored until end of transaction block")));
1258

1259 1260 1261 1262 1263 1264 1265 1266 1267
		/*
		 * Set up a snapshot if parse analysis/planning will need one.
		 */
		if (analyze_requires_snapshot(raw_parse_tree))
		{
			PushActiveSnapshot(GetTransactionSnapshot());
			snapshot_set = true;
		}

1268 1269
		/*
		 * OK to analyze, rewrite, and plan this query.  Note that the
B
Bruce Momjian 已提交
1270 1271
		 * originally specified parameter set is not required to be complete,
		 * so we have to use parse_analyze_varparams().
1272
		 *
B
Bruce Momjian 已提交
1273 1274
		 * XXX must use copyObject here since parse analysis scribbles on its
		 * input, and we need the unmodified raw parse tree for possible
1275
		 * replanning later.
1276 1277 1278 1279
		 */
		if (log_parser_stats)
			ResetUsage();

1280 1281 1282 1283
		query = parse_analyze_varparams(copyObject(raw_parse_tree),
										query_string,
										&paramTypes,
										&numParams);
1284 1285

		/*
1286
		 * Check all parameter types got determined.
1287 1288 1289
		 */
		for (i = 0; i < numParams; i++)
		{
B
Bruce Momjian 已提交
1290
			Oid			ptype = paramTypes[i];
1291 1292

			if (ptype == InvalidOid || ptype == UNKNOWNOID)
1293 1294
				ereport(ERROR,
						(errcode(ERRCODE_INDETERMINATE_DATATYPE),
B
Bruce Momjian 已提交
1295 1296
					 errmsg("could not determine data type of parameter $%d",
							i + 1)));
1297 1298 1299 1300 1301
		}

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

1302
		querytree_list = pg_rewrite_query(query);
1303

1304
		/*
B
Bruce Momjian 已提交
1305 1306
		 * If this is the unnamed statement and it has parameters, defer query
		 * planning until Bind.  Otherwise do it now.
1307 1308
		 */
		if (!is_named && numParams > 0)
1309 1310 1311 1312
		{
			stmt_list = querytree_list;
			fully_planned = false;
		}
1313
		else
1314
		{
1315
			stmt_list = pg_plan_queries(querytree_list, 0, NULL);
1316 1317
			fully_planned = true;
		}
1318 1319 1320 1321

		/* Done with the snapshot used for parsing/planning */
		if (snapshot_set)
			PopActiveSnapshot();
1322 1323 1324
	}
	else
	{
B
Bruce Momjian 已提交
1325
		/* Empty input string.	This is legal. */
1326
		raw_parse_tree = NULL;
1327
		commandTag = NULL;
1328 1329
		stmt_list = NIL;
		fully_planned = true;
1330 1331 1332 1333 1334 1335 1336 1337 1338 1339 1340
	}

	/* 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,
1341
							   raw_parse_tree,
1342 1343
							   query_string,
							   commandTag,
1344 1345
							   paramTypes,
							   numParams,
B
Bruce Momjian 已提交
1346
							   0,		/* default cursor options */
1347
							   stmt_list,
1348
							   false);
1349 1350 1351
	}
	else
	{
1352 1353 1354 1355
		/*
		 * paramTypes and query_string need to be copied into
		 * unnamed_stmt_context.  The rest is there already
		 */
B
Bruce Momjian 已提交
1356
		Oid		   *newParamTypes;
1357 1358 1359 1360 1361 1362 1363 1364 1365

		if (numParams > 0)
		{
			newParamTypes = (Oid *) palloc(numParams * sizeof(Oid));
			memcpy(newParamTypes, paramTypes, numParams * sizeof(Oid));
		}
		else
			newParamTypes = NULL;

1366 1367 1368
		unnamed_stmt_psrc = FastCreateCachedPlan(raw_parse_tree,
												 pstrdup(query_string),
												 commandTag,
1369
												 newParamTypes,
1370
												 numParams,
B
Bruce Momjian 已提交
1371
												 0,		/* cursor options */
1372 1373 1374 1375 1376 1377
												 stmt_list,
												 fully_planned,
												 true,
												 unnamed_stmt_context);
		/* context now belongs to the plancache entry */
		unnamed_stmt_context = NULL;
1378 1379 1380 1381 1382
	}

	MemoryContextSwitchTo(oldcontext);

	/*
B
Bruce Momjian 已提交
1383 1384 1385
	 * 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.
1386 1387 1388 1389 1390 1391
	 */
	CommandCounterIncrement();

	/*
	 * Send ParseComplete.
	 */
1392
	if (whereToSendOutput == DestRemote)
1393 1394
		pq_putemptymessage('1');

1395 1396 1397
	/*
	 * Emit duration logging if appropriate.
	 */
1398 1399 1400 1401
	switch (check_log_duration(msec_str, false))
	{
		case 1:
			ereport(LOG,
1402 1403
					(errmsg("duration: %s ms", msec_str),
					 errhidestmt(true)));
1404 1405 1406 1407 1408 1409
			break;
		case 2:
			ereport(LOG,
					(errmsg("duration: %s ms  parse %s: %s",
							msec_str,
							*stmt_name ? stmt_name : "<unnamed>",
1410 1411
							query_string),
					 errhidestmt(true)));
1412 1413
			break;
	}
1414

1415 1416 1417 1418 1419 1420 1421 1422 1423 1424 1425 1426 1427 1428 1429 1430
	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;
1431 1432
	int			numPFormats;
	int16	   *pformats = NULL;
1433
	int			numParams;
1434 1435
	int			numRFormats;
	int16	   *rformats = NULL;
1436 1437
	CachedPlanSource *psrc;
	CachedPlan *cplan;
1438
	Portal		portal;
1439 1440
	char	   *query_string;
	char	   *saved_stmt_name;
1441
	ParamListInfo params;
1442
	List	   *plan_list;
1443
	MemoryContext oldContext;
1444
	bool		save_log_statement_stats = log_statement_stats;
1445
	bool		snapshot_set = false;
1446 1447 1448 1449 1450 1451 1452 1453 1454 1455 1456 1457 1458
	char		msec_str[32];

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

	ereport(DEBUG2,
			(errmsg("bind %s to %s",
					*portal_name ? portal_name : "<unnamed>",
					*stmt_name ? stmt_name : "<unnamed>")));

	/* Find prepared statement */
	if (stmt_name[0] != '\0')
1459 1460 1461
	{
		PreparedStatement *pstmt;

1462
		pstmt = FetchPreparedStatement(stmt_name, true);
1463 1464
		psrc = pstmt->plansource;
	}
1465 1466 1467
	else
	{
		/* special-case the unnamed statement */
1468 1469
		psrc = unnamed_stmt_psrc;
		if (!psrc)
1470 1471 1472 1473 1474 1475 1476 1477
			ereport(ERROR,
					(errcode(ERRCODE_UNDEFINED_PSTATEMENT),
					 errmsg("unnamed prepared statement does not exist")));
	}

	/*
	 * Report query to various monitoring facilities.
	 */
1478
	debug_query_string = psrc->query_string;
1479

1480
	pgstat_report_activity(psrc->query_string);
1481

1482
	set_ps_display("BIND", false);
1483

1484 1485 1486
	if (save_log_statement_stats)
		ResetUsage();

1487
	/*
B
Bruce Momjian 已提交
1488 1489 1490
	 * 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.
1491
	 */
1492
	start_xact_command();
1493

1494 1495 1496 1497 1498 1499 1500
	/* Switch back to message context */
	MemoryContextSwitchTo(MessageContext);

	/* Get the parameter format codes */
	numPFormats = pq_getmsgint(input_message, 2);
	if (numPFormats > 0)
	{
B
Bruce Momjian 已提交
1501 1502
		int			i;

1503 1504 1505 1506 1507 1508 1509 1510 1511
		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)
1512 1513
		ereport(ERROR,
				(errcode(ERRCODE_PROTOCOL_VIOLATION),
B
Bruce Momjian 已提交
1514 1515
			errmsg("bind message has %d parameter formats but %d parameters",
				   numPFormats, numParams)));
1516

1517
	if (numParams != psrc->num_params)
1518 1519 1520
		ereport(ERROR,
				(errcode(ERRCODE_PROTOCOL_VIOLATION),
				 errmsg("bind message supplies %d parameters, but prepared statement \"%s\" requires %d",
B
Bruce Momjian 已提交
1521
						numParams, stmt_name, psrc->num_params)));
1522

1523 1524
	/*
	 * If we are in aborted transaction state, the only portals we can
1525 1526 1527 1528 1529
	 * actually run are those containing COMMIT or ROLLBACK commands. We
	 * disallow binding anything else to avoid problems with infrastructure
	 * that expects to run inside a valid transaction.	We also disallow
	 * binding any parameters, since we can't risk calling user-defined I/O
	 * functions.
1530 1531
	 */
	if (IsAbortedTransactionBlockState() &&
1532
		(!IsTransactionExitStmt(psrc->raw_parse_tree) ||
1533 1534 1535 1536 1537 1538
		 numParams != 0))
		ereport(ERROR,
				(errcode(ERRCODE_IN_FAILED_SQL_TRANSACTION),
				 errmsg("current transaction is aborted, "
						"commands ignored until end of transaction block")));

1539
	/*
B
Bruce Momjian 已提交
1540 1541
	 * Create the portal.  Allow silent replacement of an existing portal only
	 * if the unnamed portal is specified.
1542 1543 1544 1545 1546 1547
	 */
	if (portal_name[0] == '\0')
		portal = CreatePortal(portal_name, true, true);
	else
		portal = CreatePortal(portal_name, false, false);

1548 1549 1550 1551 1552 1553 1554 1555
	/*
	 * Prepare to copy stuff into the portal's memory context.  We do all this
	 * copying first, because it could possibly fail (out-of-memory) and we
	 * don't want a failure to occur between RevalidateCachedPlan and
	 * PortalDefineQuery; that would result in leaking our plancache refcount.
	 */
	oldContext = MemoryContextSwitchTo(PortalGetHeapMemory(portal));

1556 1557
	/* Copy the plan's query string into the portal */
	query_string = pstrdup(psrc->query_string);
1558 1559 1560 1561 1562 1563 1564

	/* Likewise make a copy of the statement name, unless it's unnamed */
	if (stmt_name[0])
		saved_stmt_name = pstrdup(stmt_name);
	else
		saved_stmt_name = NULL;

1565 1566 1567 1568 1569 1570 1571 1572 1573 1574 1575
	/*
	 * Set a snapshot if we have parameters to fetch (since the input
	 * functions might need it) or the query isn't a utility command (and
	 * hence could require redoing parse analysis and planning).
	 */
	if (numParams > 0 || analyze_requires_snapshot(psrc->raw_parse_tree))
	{
		PushActiveSnapshot(GetTransactionSnapshot());
		snapshot_set = true;
	}

1576 1577 1578 1579 1580
	/*
	 * Fetch parameters, if any, and store in the portal's memory context.
	 */
	if (numParams > 0)
	{
1581
		int			paramno;
1582

1583 1584
		/* sizeof(ParamListInfoData) includes the first array element */
		params = (ParamListInfo) palloc(sizeof(ParamListInfoData) +
B
Bruce Momjian 已提交
1585
								   (numParams - 1) *sizeof(ParamExternData));
1586 1587 1588 1589 1590
		/* we have static list of params, so no hooks needed */
		params->paramFetch = NULL;
		params->paramFetchArg = NULL;
		params->parserSetup = NULL;
		params->parserSetupArg = NULL;
1591
		params->numParams = numParams;
1592

1593
		for (paramno = 0; paramno < numParams; paramno++)
1594
		{
1595
			Oid			ptype = psrc->param_types[paramno];
1596
			int32		plength;
1597
			Datum		pval;
1598
			bool		isNull;
1599 1600 1601
			StringInfoData pbuf;
			char		csave;
			int16		pformat;
1602

1603 1604 1605
			plength = pq_getmsgint(input_message, 4);
			isNull = (plength == -1);

1606 1607
			if (!isNull)
			{
1608
				const char *pvalue = pq_getmsgbytes(input_message, plength);
1609 1610 1611

				/*
				 * Rather than copying data around, we just set up a phony
1612 1613 1614 1615 1616
				 * 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.
1617 1618 1619 1620 1621 1622 1623 1624
				 */
				pbuf.data = (char *) pvalue;
				pbuf.maxlen = plength + 1;
				pbuf.len = plength;
				pbuf.cursor = 0;

				csave = pbuf.data[plength];
				pbuf.data[plength] = '\0';
1625 1626 1627 1628 1629 1630
			}
			else
			{
				pbuf.data = NULL;		/* keep compiler quiet */
				csave = 0;
			}
1631

1632
			if (numPFormats > 1)
1633
				pformat = pformats[paramno];
1634 1635 1636 1637 1638
			else if (numPFormats > 0)
				pformat = pformats[0];
			else
				pformat = 0;	/* default = text */

1639
			if (pformat == 0)	/* text mode */
1640 1641 1642
			{
				Oid			typinput;
				Oid			typioparam;
1643
				char	   *pstring;
1644

1645
				getTypeInputInfo(ptype, &typinput, &typioparam);
1646

1647 1648 1649 1650 1651 1652 1653
				/*
				 * We have to do encoding conversion before calling the
				 * typinput routine.
				 */
				if (isNull)
					pstring = NULL;
				else
1654
					pstring = pg_client_to_server(pbuf.data, plength);
1655

1656
				pval = OidInputFunctionCall(typinput, pstring, typioparam, -1);
1657

1658 1659 1660 1661
				/* Free result of encoding conversion, if any */
				if (pstring && pstring != pbuf.data)
					pfree(pstring);
			}
B
Bruce Momjian 已提交
1662
			else if (pformat == 1)		/* binary mode */
1663 1664 1665 1666 1667 1668 1669 1670 1671 1672 1673 1674
			{
				Oid			typreceive;
				Oid			typioparam;
				StringInfo	bufptr;

				/*
				 * Call the parameter type's binary input converter
				 */
				getTypeBinaryInputInfo(ptype, &typreceive, &typioparam);

				if (isNull)
					bufptr = NULL;
1675
				else
1676 1677
					bufptr = &pbuf;

1678
				pval = OidReceiveFunctionCall(typreceive, bufptr, typioparam, -1);
1679 1680 1681

				/* Trouble if it didn't eat the whole buffer */
				if (!isNull && pbuf.cursor != pbuf.len)
1682
					ereport(ERROR,
1683 1684
							(errcode(ERRCODE_INVALID_BINARY_REPRESENTATION),
							 errmsg("incorrect binary data format in bind parameter %d",
1685
									paramno + 1)));
1686 1687 1688 1689 1690 1691 1692
			}
			else
			{
				ereport(ERROR,
						(errcode(ERRCODE_INVALID_PARAMETER_VALUE),
						 errmsg("unsupported format code: %d",
								pformat)));
1693
				pval = 0;		/* keep compiler quiet */
1694
			}
1695

1696 1697
			/* Restore message buffer contents */
			if (!isNull)
1698
				pbuf.data[plength] = csave;
1699

1700
			params->params[paramno].value = pval;
1701
			params->params[paramno].isnull = isNull;
B
Bruce Momjian 已提交
1702

1703 1704 1705 1706 1707 1708 1709
			/*
			 * We mark the params as CONST.  This has no effect if we already
			 * did planning, but if we didn't, it licenses the planner to
			 * substitute the parameters directly into the one-shot plan we
			 * will generate below.
			 */
			params->params[paramno].pflags = PARAM_FLAG_CONST;
1710
			params->params[paramno].ptype = ptype;
1711 1712 1713 1714 1715
		}
	}
	else
		params = NULL;

1716 1717 1718
	/* Done storing stuff in portal's context */
	MemoryContextSwitchTo(oldContext);

1719 1720 1721 1722
	/* Get the result format codes */
	numRFormats = pq_getmsgint(input_message, 2);
	if (numRFormats > 0)
	{
B
Bruce Momjian 已提交
1723
		int			i;
1724

1725 1726 1727 1728 1729
		rformats = (int16 *) palloc(numRFormats * sizeof(int16));
		for (i = 0; i < numRFormats; i++)
			rformats[i] = pq_getmsgint(input_message, 2);
	}

1730 1731
	pq_getmsgend(input_message);

1732
	if (psrc->fully_planned)
1733
	{
1734 1735
		/*
		 * Revalidate the cached plan; this may result in replanning.  Any
B
Bruce Momjian 已提交
1736 1737
		 * cruft will be generated in MessageContext.  The plan refcount will
		 * be assigned to the Portal, so it will be released at portal
1738 1739 1740 1741
		 * destruction.
		 */
		cplan = RevalidateCachedPlan(psrc, false);
		plan_list = cplan->stmt_list;
1742 1743
	}
	else
1744
	{
1745 1746 1747 1748 1749 1750 1751 1752 1753
		List	   *query_list;

		/*
		 * Revalidate the cached plan; this may result in redoing parse
		 * analysis and rewriting (but not planning).  Any cruft will be
		 * generated in MessageContext.  The plan refcount is assigned to
		 * CurrentResourceOwner.
		 */
		cplan = RevalidateCachedPlan(psrc, true);
1754

1755 1756 1757 1758 1759 1760 1761 1762 1763 1764 1765 1766 1767 1768
		/*
		 * We didn't plan the query before, so do it now.  This allows the
		 * planner to make use of the concrete parameter values we now have.
		 * Because we use PARAM_FLAG_CONST, the plan is good only for this set
		 * of param values, and so we generate the plan in the portal's own
		 * memory context where it will be thrown away after use. As in
		 * exec_parse_message, we make no attempt to recover planner temporary
		 * memory until the end of the operation.
		 *
		 * XXX because the planner has a bad habit of scribbling on its input,
		 * we have to make a copy of the parse trees.  FIXME someday.
		 */
		oldContext = MemoryContextSwitchTo(PortalGetHeapMemory(portal));
		query_list = copyObject(cplan->stmt_list);
1769
		plan_list = pg_plan_queries(query_list, 0, params);
1770
		MemoryContextSwitchTo(oldContext);
1771 1772 1773 1774 1775

		/* We no longer need the cached plan refcount ... */
		ReleaseCachedPlan(cplan, true);
		/* ... and we don't want the portal to depend on it, either */
		cplan = NULL;
1776 1777 1778
	}

	/*
1779 1780 1781 1782
	 * Now we can define the portal.
	 *
	 * DO NOT put any code that could possibly throw an error between the
	 * above "RevalidateCachedPlan(psrc, false)" call and here.
1783 1784
	 */
	PortalDefineQuery(portal,
1785 1786
					  saved_stmt_name,
					  query_string,
1787
					  psrc->commandTag,
1788
					  plan_list,
1789
					  cplan);
1790

1791 1792 1793 1794 1795 1796 1797
	/* Done with the snapshot used for parameter I/O and parsing/planning */
	if (snapshot_set)
		PopActiveSnapshot();

	/*
	 * And we're ready to start portal execution.
	 */
1798
	PortalStart(portal, params, InvalidSnapshot);
1799

1800 1801 1802 1803 1804
	/*
	 * Apply the result format requests to the portal.
	 */
	PortalSetResultFormat(portal, numRFormats, rformats);

1805 1806 1807
	/*
	 * Send BindComplete.
	 */
1808
	if (whereToSendOutput == DestRemote)
1809
		pq_putemptymessage('2');
1810 1811 1812 1813

	/*
	 * Emit duration logging if appropriate.
	 */
1814 1815 1816 1817
	switch (check_log_duration(msec_str, false))
	{
		case 1:
			ereport(LOG,
1818 1819
					(errmsg("duration: %s ms", msec_str),
					 errhidestmt(true)));
1820 1821 1822
			break;
		case 2:
			ereport(LOG,
1823
					(errmsg("duration: %s ms  bind %s%s%s: %s",
1824 1825
							msec_str,
							*stmt_name ? stmt_name : "<unnamed>",
1826 1827
							*portal_name ? "/" : "",
							*portal_name ? portal_name : "",
1828
							psrc->query_string),
1829
					 errhidestmt(true),
1830 1831 1832
					 errdetail_params(params)));
			break;
	}
1833 1834 1835 1836 1837

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

	debug_query_string = NULL;
1838 1839 1840 1841 1842 1843 1844 1845
}

/*
 * exec_execute_message
 *
 * Process an "Execute" message for a portal
 */
static void
1846
exec_execute_message(const char *portal_name, long max_rows)
1847
{
B
Bruce Momjian 已提交
1848
	CommandDest dest;
1849
	DestReceiver *receiver;
1850 1851 1852
	Portal		portal;
	bool		completed;
	char		completionTag[COMPLETION_TAG_BUFSIZE];
1853
	const char *sourceText;
1854
	const char *prepStmtName;
1855
	ParamListInfo portalParams;
1856
	bool		save_log_statement_stats = log_statement_stats;
1857 1858
	bool		is_xact_command;
	bool		execute_is_fetch;
1859 1860
	bool		was_logged = false;
	char		msec_str[32];
1861 1862 1863

	/* Adjust destination to tell printtup.c what to do */
	dest = whereToSendOutput;
1864 1865
	if (dest == DestRemote)
		dest = DestRemoteExecute;
1866 1867 1868

	portal = GetPortalByName(portal_name);
	if (!PortalIsValid(portal))
1869 1870 1871
		ereport(ERROR,
				(errcode(ERRCODE_UNDEFINED_CURSOR),
				 errmsg("portal \"%s\" does not exist", portal_name)));
1872 1873

	/*
B
Bruce Momjian 已提交
1874 1875
	 * If the original query was a null string, just return
	 * EmptyQueryResponse.
1876 1877 1878
	 */
	if (portal->commandTag == NULL)
	{
1879
		Assert(portal->stmts == NIL);
1880 1881 1882 1883
		NullCommand(dest);
		return;
	}

1884
	/* Does the portal contain a transaction command? */
1885
	is_xact_command = IsTransactionStmtList(portal->stmts);
1886

1887
	/*
B
Bruce Momjian 已提交
1888 1889 1890
	 * We must copy the sourceText and prepStmtName into MessageContext in
	 * case the portal is destroyed during finish_xact_command. Can avoid the
	 * copy if it's not an xact command, though.
1891 1892
	 */
	if (is_xact_command)
1893
	{
1894
		sourceText = pstrdup(portal->sourceText);
1895 1896 1897 1898
		if (portal->prepStmtName)
			prepStmtName = pstrdup(portal->prepStmtName);
		else
			prepStmtName = "<unnamed>";
B
Bruce Momjian 已提交
1899

1900 1901 1902 1903 1904 1905
		/*
		 * An xact command shouldn't have any parameters, which is a good
		 * thing because they wouldn't be around after finish_xact_command.
		 */
		portalParams = NULL;
	}
1906 1907
	else
	{
1908 1909 1910
		sourceText = portal->sourceText;
		if (portal->prepStmtName)
			prepStmtName = portal->prepStmtName;
1911
		else
1912 1913
			prepStmtName = "<unnamed>";
		portalParams = portal->portalParams;
1914
	}
1915

1916 1917 1918
	/*
	 * Report query to various monitoring facilities.
	 */
1919
	debug_query_string = sourceText;
1920

1921
	pgstat_report_activity(sourceText);
1922 1923 1924 1925 1926 1927

	set_ps_display(portal->commandTag, false);

	if (save_log_statement_stats)
		ResetUsage();

1928 1929
	BeginCommand(portal->commandTag, dest);

1930
	/*
B
Bruce Momjian 已提交
1931 1932
	 * Create dest receiver in MessageContext (we don't want it in transaction
	 * context, because that may get deleted if portal contains VACUUM).
1933
	 */
1934 1935 1936
	receiver = CreateDestReceiver(dest);
	if (dest == DestRemoteExecute)
		SetRemoteDestReceiverParams(receiver, portal);
1937

1938
	/*
B
Bruce Momjian 已提交
1939 1940
	 * Ensure we are in a transaction command (this should normally be the
	 * case already due to prior BIND).
1941
	 */
1942
	start_xact_command();
1943

1944 1945 1946 1947 1948 1949 1950 1951
	/*
	 * 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.
	 */
	execute_is_fetch = !portal->atStart;

1952
	/* Log immediately if dictated by log_statement */
1953
	if (check_log_statement(portal->stmts))
1954 1955
	{
		ereport(LOG,
1956
				(errmsg("%s %s%s%s: %s",
1957
						execute_is_fetch ?
1958 1959
						_("execute fetch from") :
						_("execute"),
1960 1961 1962
						prepStmtName,
						*portal_name ? "/" : "",
						*portal_name ? portal_name : "",
1963
						sourceText),
1964
				 errhidestmt(true),
1965 1966 1967 1968
				 errdetail_params(portalParams)));
		was_logged = true;
	}

1969 1970 1971 1972
	/*
	 * If we are in aborted transaction state, the only portals we can
	 * actually run are those containing COMMIT or ROLLBACK commands.
	 */
1973
	if (IsAbortedTransactionBlockState() &&
1974
		!IsTransactionExitStmtList(portal->stmts))
1975 1976 1977
		ereport(ERROR,
				(errcode(ERRCODE_IN_FAILED_SQL_TRANSACTION),
				 errmsg("current transaction is aborted, "
B
Bruce Momjian 已提交
1978
						"commands ignored until end of transaction block")));
1979 1980 1981 1982 1983 1984 1985 1986 1987 1988 1989 1990

	/* 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,
B
Bruce Momjian 已提交
1991
						  true, /* always top level */
1992 1993
						  receiver,
						  receiver,
1994 1995
						  completionTag);

1996
	(*receiver->rDestroy) (receiver);
1997

1998 1999
	if (completed)
	{
2000
		if (is_xact_command)
2001 2002
		{
			/*
B
Bruce Momjian 已提交
2003
			 * If this was a transaction control statement, commit it.	We
B
Bruce Momjian 已提交
2004
			 * will start a new xact command for the next command (if any).
2005
			 */
2006
			finish_xact_command();
2007 2008 2009 2010
		}
		else
		{
			/*
B
Bruce Momjian 已提交
2011 2012
			 * We need a CommandCounterIncrement after every query, except
			 * those that start or end a transaction block.
2013 2014 2015 2016 2017 2018 2019 2020 2021 2022
			 */
			CommandCounterIncrement();
		}

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

2027
	/*
2028
	 * Emit duration logging if appropriate.
2029
	 */
2030
	switch (check_log_duration(msec_str, was_logged))
2031
	{
2032
		case 1:
2033
			ereport(LOG,
2034 2035
					(errmsg("duration: %s ms", msec_str),
					 errhidestmt(true)));
2036 2037
			break;
		case 2:
2038
			ereport(LOG,
2039
					(errmsg("duration: %s ms  %s %s%s%s: %s",
2040 2041 2042 2043 2044 2045 2046
							msec_str,
							execute_is_fetch ?
							_("execute fetch from") :
							_("execute"),
							prepStmtName,
							*portal_name ? "/" : "",
							*portal_name ? portal_name : "",
2047
							sourceText),
2048
					 errhidestmt(true),
2049
					 errdetail_params(portalParams)));
2050
			break;
2051 2052 2053 2054 2055 2056 2057 2058 2059
	}

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

	debug_query_string = NULL;
}

/*
2060
 * check_log_statement
2061 2062
 *		Determine whether command should be logged because of log_statement
 *
2063 2064
 * parsetree_list can be either raw grammar output or a list of planned
 * statements
2065 2066
 */
static bool
2067
check_log_statement(List *stmt_list)
2068
{
2069
	ListCell   *stmt_item;
2070 2071 2072 2073 2074 2075 2076

	if (log_statement == LOGSTMT_NONE)
		return false;
	if (log_statement == LOGSTMT_ALL)
		return true;

	/* Else we have to inspect the statement(s) to see whether to log */
2077
	foreach(stmt_item, stmt_list)
2078
	{
2079
		Node	   *stmt = (Node *) lfirst(stmt_item);
2080

2081
		if (GetCommandLogLevel(stmt) <= log_statement)
2082 2083 2084 2085 2086 2087 2088 2089 2090 2091
			return true;
	}

	return false;
}

/*
 * check_log_duration
 *		Determine whether current command's duration should be logged
 *
2092 2093 2094 2095 2096
 * Returns:
 *		0 if no logging is needed
 *		1 if just the duration should be logged
 *		2 if duration and query details should be logged
 *
2097 2098
 * If logging is needed, the duration in msec is formatted into msec_str[],
 * which must be a 32-byte buffer.
2099 2100 2101
 *
 * was_logged should be TRUE if caller already logged query details (this
 * essentially prevents 2 from being returned).
2102
 */
2103 2104
int
check_log_duration(char *msec_str, bool was_logged)
2105
{
2106
	if (log_duration || log_min_duration_statement >= 0)
2107
	{
2108 2109 2110
		long		secs;
		int			usecs;
		int			msecs;
2111
		bool		exceeded;
2112

2113 2114 2115 2116
		TimestampDifference(GetCurrentStatementStartTimestamp(),
							GetCurrentTimestamp(),
							&secs, &usecs);
		msecs = usecs / 1000;
2117 2118

		/*
B
Bruce Momjian 已提交
2119 2120 2121
		 * This odd-looking test for log_min_duration_statement being exceeded
		 * is designed to avoid integer overflow with very long durations:
		 * don't compute secs * 1000 until we've verified it will fit in int.
2122
		 */
2123 2124 2125 2126 2127 2128
		exceeded = (log_min_duration_statement == 0 ||
					(log_min_duration_statement > 0 &&
					 (secs > log_min_duration_statement / 1000 ||
					  secs * 1000 + msecs >= log_min_duration_statement)));

		if (exceeded || log_duration)
2129
		{
2130 2131
			snprintf(msec_str, 32, "%ld.%03d",
					 secs * 1000 + msecs, usecs % 1000);
2132 2133 2134 2135
			if (exceeded && !was_logged)
				return 2;
			else
				return 1;
2136
		}
2137 2138
	}

2139
	return 0;
2140
}
2141

2142 2143 2144 2145 2146 2147 2148 2149 2150 2151 2152 2153 2154 2155 2156 2157 2158 2159 2160 2161 2162
/*
 * errdetail_execute
 *
 * Add an errdetail() line showing the query referenced by an EXECUTE, if any.
 * The argument is the raw parsetree list.
 */
static int
errdetail_execute(List *raw_parsetree_list)
{
	ListCell   *parsetree_item;

	foreach(parsetree_item, raw_parsetree_list)
	{
		Node	   *parsetree = (Node *) lfirst(parsetree_item);

		if (IsA(parsetree, ExecuteStmt))
		{
			ExecuteStmt *stmt = (ExecuteStmt *) parsetree;
			PreparedStatement *pstmt;

			pstmt = FetchPreparedStatement(stmt->name, false);
2163
			if (pstmt)
2164
			{
2165
				errdetail("prepare: %s", pstmt->plansource->query_string);
2166 2167 2168 2169 2170 2171 2172 2173 2174 2175 2176 2177 2178 2179 2180 2181 2182 2183 2184 2185 2186 2187 2188 2189 2190 2191 2192 2193 2194 2195 2196 2197 2198 2199 2200 2201 2202 2203 2204 2205 2206 2207 2208 2209 2210 2211 2212 2213 2214 2215 2216 2217 2218
				return 0;
			}
		}
	}

	return 0;
}

/*
 * errdetail_params
 *
 * Add an errdetail() line showing bind-parameter data, if available.
 */
static int
errdetail_params(ParamListInfo params)
{
	/* We mustn't call user-defined I/O functions when in an aborted xact */
	if (params && params->numParams > 0 && !IsAbortedTransactionBlockState())
	{
		StringInfoData param_str;
		MemoryContext oldcontext;
		int			paramno;

		/* Make sure any trash is generated in MessageContext */
		oldcontext = MemoryContextSwitchTo(MessageContext);

		initStringInfo(&param_str);

		for (paramno = 0; paramno < params->numParams; paramno++)
		{
			ParamExternData *prm = &params->params[paramno];
			Oid			typoutput;
			bool		typisvarlena;
			char	   *pstring;
			char	   *p;

			appendStringInfo(&param_str, "%s$%d = ",
							 paramno > 0 ? ", " : "",
							 paramno + 1);

			if (prm->isnull || !OidIsValid(prm->ptype))
			{
				appendStringInfoString(&param_str, "NULL");
				continue;
			}

			getTypeOutputInfo(prm->ptype, &typoutput, &typisvarlena);

			pstring = OidOutputFunctionCall(typoutput, prm->value);

			appendStringInfoCharMacro(&param_str, '\'');
			for (p = pstring; *p; p++)
			{
B
Bruce Momjian 已提交
2219
				if (*p == '\'') /* double single quotes */
2220 2221 2222 2223 2224 2225 2226 2227 2228 2229 2230 2231 2232 2233 2234 2235
					appendStringInfoCharMacro(&param_str, *p);
				appendStringInfoCharMacro(&param_str, *p);
			}
			appendStringInfoCharMacro(&param_str, '\'');

			pfree(pstring);
		}

		errdetail("parameters: %s", param_str.data);

		pfree(param_str.data);

		MemoryContextSwitchTo(oldcontext);
	}

	return 0;
2236 2237 2238 2239 2240 2241 2242 2243 2244 2245
}

/*
 * exec_describe_statement_message
 *
 * Process a "Describe" message for a prepared statement
 */
static void
exec_describe_statement_message(const char *stmt_name)
{
2246
	CachedPlanSource *psrc;
2247
	StringInfoData buf;
2248
	int			i;
2249

2250 2251 2252 2253
	/*
	 * Start up a transaction command. (Note that this will normally change
	 * current memory context.) Nothing happens if we are already in one.
	 */
2254
	start_xact_command();
2255 2256 2257 2258

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

2259 2260
	/* Find prepared statement */
	if (stmt_name[0] != '\0')
2261 2262 2263
	{
		PreparedStatement *pstmt;

2264
		pstmt = FetchPreparedStatement(stmt_name, true);
2265 2266
		psrc = pstmt->plansource;
	}
2267 2268 2269
	else
	{
		/* special-case the unnamed statement */
2270 2271
		psrc = unnamed_stmt_psrc;
		if (!psrc)
2272 2273
			ereport(ERROR,
					(errcode(ERRCODE_UNDEFINED_PSTATEMENT),
B
Bruce Momjian 已提交
2274
					 errmsg("unnamed prepared statement does not exist")));
2275 2276
	}

2277 2278 2279
	/* Prepared statements shouldn't have changeable result descs */
	Assert(psrc->fixed_result);

2280
	/*
2281
	 * If we are in aborted transaction state, we can't run
B
Bruce Momjian 已提交
2282 2283
	 * SendRowDescriptionMessage(), because that needs catalog accesses. (We
	 * can't do RevalidateCachedPlan, either, but that's a lesser problem.)
2284 2285 2286 2287 2288
	 * Hence, refuse to Describe statements that return data.  (We shouldn't
	 * just refuse all Describes, since that might break the ability of some
	 * clients to issue COMMIT or ROLLBACK commands, if they use code that
	 * blindly Describes whatever it does.)  We can Describe parameters
	 * without doing anything dangerous, so we don't restrict that.
2289 2290
	 */
	if (IsAbortedTransactionBlockState() &&
2291
		psrc->resultDesc)
2292 2293 2294 2295 2296
		ereport(ERROR,
				(errcode(ERRCODE_IN_FAILED_SQL_TRANSACTION),
				 errmsg("current transaction is aborted, "
						"commands ignored until end of transaction block")));

2297
	if (whereToSendOutput != DestRemote)
2298 2299
		return;					/* can't actually do anything... */

2300 2301 2302
	/*
	 * First describe the parameters...
	 */
B
Bruce Momjian 已提交
2303
	pq_beginmessage(&buf, 't'); /* parameter description message type */
2304
	pq_sendint(&buf, psrc->num_params, 2);
2305

2306
	for (i = 0; i < psrc->num_params; i++)
2307
	{
2308
		Oid			ptype = psrc->param_types[i];
2309 2310 2311 2312

		pq_sendint(&buf, (int) ptype, 4);
	}
	pq_endmessage(&buf);
2313 2314 2315 2316

	/*
	 * Next send RowDescription or NoData to describe the result...
	 */
2317 2318 2319 2320 2321 2322 2323 2324 2325 2326 2327 2328 2329 2330 2331
	if (psrc->resultDesc)
	{
		CachedPlan *cplan;
		List	   *tlist;

		/* Make sure the plan is up to date */
		cplan = RevalidateCachedPlan(psrc, true);

		/* Get the primary statement and find out what it returns */
		tlist = FetchStatementTargetList(PortalListGetPrimaryStmt(cplan->stmt_list));

		SendRowDescriptionMessage(psrc->resultDesc, tlist, NULL);

		ReleaseCachedPlan(cplan, true);
	}
2332 2333 2334
	else
		pq_putemptymessage('n');	/* NoData */

2335 2336 2337 2338 2339 2340 2341 2342 2343 2344 2345 2346
}

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

2347 2348 2349 2350
	/*
	 * Start up a transaction command. (Note that this will normally change
	 * current memory context.) Nothing happens if we are already in one.
	 */
2351
	start_xact_command();
2352 2353 2354 2355

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

2356 2357
	portal = GetPortalByName(portal_name);
	if (!PortalIsValid(portal))
2358 2359 2360
		ereport(ERROR,
				(errcode(ERRCODE_UNDEFINED_CURSOR),
				 errmsg("portal \"%s\" does not exist", portal_name)));
2361

2362 2363 2364
	/*
	 * If we are in aborted transaction state, we can't run
	 * SendRowDescriptionMessage(), because that needs catalog accesses.
B
Bruce Momjian 已提交
2365
	 * Hence, refuse to Describe portals that return data.	(We shouldn't just
2366 2367 2368 2369 2370 2371 2372 2373 2374 2375 2376
	 * refuse all Describes, since that might break the ability of some
	 * clients to issue COMMIT or ROLLBACK commands, if they use code that
	 * blindly Describes whatever it does.)
	 */
	if (IsAbortedTransactionBlockState() &&
		portal->tupDesc)
		ereport(ERROR,
				(errcode(ERRCODE_IN_FAILED_SQL_TRANSACTION),
				 errmsg("current transaction is aborted, "
						"commands ignored until end of transaction block")));

2377
	if (whereToSendOutput != DestRemote)
2378 2379 2380
		return;					/* can't actually do anything... */

	if (portal->tupDesc)
2381 2382
		SendRowDescriptionMessage(portal->tupDesc,
								  FetchPortalTargetList(portal),
2383
								  portal->formats);
2384 2385 2386 2387 2388
	else
		pq_putemptymessage('n');	/* NoData */
}


2389
/*
2390
 * Convenience routines for starting/committing a single command.
2391 2392
 */
static void
2393
start_xact_command(void)
2394
{
2395
	if (!xact_started)
2396
	{
2397 2398 2399
		ereport(DEBUG3,
				(errmsg_internal("StartTransactionCommand")));
		StartTransactionCommand();
2400 2401

		/* Set statement timeout running, if any */
2402
		/* NB: this mustn't be enabled until we are within an xact */
2403 2404
		if (StatementTimeout > 0)
			enable_sig_alarm(StatementTimeout, true);
2405 2406
		else
			cancel_from_timeout = false;
B
Bruce Momjian 已提交
2407

2408 2409 2410 2411 2412 2413 2414 2415 2416
		xact_started = true;
	}
}

static void
finish_xact_command(void)
{
	if (xact_started)
	{
2417 2418 2419 2420
		/* Cancel any active statement timeout before committing */
		disable_sig_alarm(true);

		/* Now commit the command */
2421 2422
		ereport(DEBUG3,
				(errmsg_internal("CommitTransactionCommand")));
2423

2424
		CommitTransactionCommand();
2425

2426 2427 2428 2429 2430 2431
#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

2432
#ifdef SHOW_MEMORY_STATS
2433
		/* Print mem stats after each commit for leak tracking */
2434
		MemoryContextStats(TopMemoryContext);
2435
#endif
2436 2437 2438

		xact_started = false;
	}
2439 2440 2441
}


2442 2443 2444 2445 2446
/*
 * Convenience routines for checking whether a statement is one of the
 * ones that we allow in transaction-aborted state.
 */

2447
/* Test a bare parsetree */
2448 2449 2450 2451 2452 2453 2454 2455 2456 2457 2458 2459 2460 2461 2462 2463
static bool
IsTransactionExitStmt(Node *parsetree)
{
	if (parsetree && IsA(parsetree, TransactionStmt))
	{
		TransactionStmt *stmt = (TransactionStmt *) parsetree;

		if (stmt->kind == TRANS_STMT_COMMIT ||
			stmt->kind == TRANS_STMT_PREPARE ||
			stmt->kind == TRANS_STMT_ROLLBACK ||
			stmt->kind == TRANS_STMT_ROLLBACK_TO)
			return true;
	}
	return false;
}

2464
/* Test a list that might contain Query nodes or bare parsetrees */
2465 2466 2467 2468 2469
static bool
IsTransactionExitStmtList(List *parseTrees)
{
	if (list_length(parseTrees) == 1)
	{
2470 2471 2472 2473 2474
		Node	   *stmt = (Node *) linitial(parseTrees);

		if (IsA(stmt, Query))
		{
			Query	   *query = (Query *) stmt;
2475

2476 2477 2478 2479 2480
			if (query->commandType == CMD_UTILITY &&
				IsTransactionExitStmt(query->utilityStmt))
				return true;
		}
		else if (IsTransactionExitStmt(stmt))
2481 2482 2483 2484 2485
			return true;
	}
	return false;
}

2486
/* Test a list that might contain Query nodes or bare parsetrees */
2487 2488 2489 2490 2491
static bool
IsTransactionStmtList(List *parseTrees)
{
	if (list_length(parseTrees) == 1)
	{
2492
		Node	   *stmt = (Node *) linitial(parseTrees);
2493

2494 2495 2496 2497 2498 2499 2500 2501 2502
		if (IsA(stmt, Query))
		{
			Query	   *query = (Query *) stmt;

			if (query->commandType == CMD_UTILITY &&
				IsA(query->utilityStmt, TransactionStmt))
				return true;
		}
		else if (IsA(stmt, TransactionStmt))
2503 2504 2505 2506 2507
			return true;
	}
	return false;
}

2508 2509 2510 2511 2512 2513 2514 2515
/* Release any existing unnamed prepared statement */
static void
drop_unnamed_stmt(void)
{
	/* Release any completed unnamed statement */
	if (unnamed_stmt_psrc)
		DropCachedPlan(unnamed_stmt_psrc);
	unnamed_stmt_psrc = NULL;
B
Bruce Momjian 已提交
2516

2517 2518 2519 2520 2521 2522 2523 2524 2525 2526
	/*
	 * If we failed while trying to build a prior unnamed statement, we may
	 * have a memory context that wasn't assigned to a completed plancache
	 * entry.  If so, drop it to avoid a permanent memory leak.
	 */
	if (unnamed_stmt_context)
		MemoryContextDelete(unnamed_stmt_context);
	unnamed_stmt_context = NULL;
}

2527

2528
/* --------------------------------
2529
 *		signal handler routines used in PostgresMain()
2530 2531 2532
 * --------------------------------
 */

2533
/*
T
Tom Lane 已提交
2534
 * quickdie() occurs when signalled SIGQUIT by the postmaster.
2535 2536 2537 2538
 *
 * Some backend has bought the farm,
 * so we need to stop what we're doing and exit.
 */
T
Tom Lane 已提交
2539
void
2540
quickdie(SIGNAL_ARGS)
2541
{
2542
	sigaddset(&BlockSig, SIGQUIT); /* prevent nested calls */
2543
	PG_SETMASK(&BlockSig);
B
Bruce Momjian 已提交
2544

2545 2546 2547 2548 2549 2550 2551 2552 2553
	/*
	 * If we're aborting out of client auth, don't risk trying to send
	 * anything to the client; we will likely violate the protocol,
	 * not to mention that we may have interrupted the guts of OpenSSL
	 * or some authentication library.
	 */
	if (ClientAuthInProgress && whereToSendOutput == DestRemote)
		whereToSendOutput = DestNone;

2554
	/*
B
Bruce Momjian 已提交
2555 2556
	 * Ideally this should be ereport(FATAL), but then we'd not get control
	 * back...
2557 2558 2559
	 */
	ereport(WARNING,
			(errcode(ERRCODE_CRASH_SHUTDOWN),
B
Bruce Momjian 已提交
2560
			 errmsg("terminating connection because of crash of another server process"),
B
Bruce Momjian 已提交
2561 2562 2563 2564
	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."),
2565
			 errhint("In a moment you should be able to reconnect to the"
2566
					 " database and repeat your command.")));
B
Bruce Momjian 已提交
2567

2568
	/*
2569 2570 2571 2572 2573 2574 2575 2576 2577 2578
	 * We DO NOT want to run proc_exit() callbacks -- 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.  Now that
	 * there's an atexit callback to prevent third-party code from breaking
	 * things by calling exit() directly, we have to reset the callbacks
	 * explicitly to make this work as intended.
	 */
	on_exit_reset();

	/*
2579
	 * Note we do exit(2) not exit(0).	This is to force the postmaster into a
B
Bruce Momjian 已提交
2580 2581
	 * 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
2582
	 * shared memory state.  (The "dead man switch" mechanism in pmsignal.c
2583 2584
	 * should ensure the postmaster sees this as a crash, too, but no harm in
	 * being doubly sure.)
2585
	 */
2586
	exit(2);
2587 2588
}

2589
/*
2590 2591
 * Shutdown signal from postmaster: abort transaction and exit
 * at soonest convenient time
2592
 */
2593
void
2594
die(SIGNAL_ARGS)
2595
{
2596 2597 2598
	int			save_errno = errno;

	/* Don't joggle the elbow of proc_exit */
B
Bruce Momjian 已提交
2599
	if (!proc_exit_inprogress)
2600
	{
2601
		InterruptPending = true;
2602
		ProcDiePending = true;
B
Bruce Momjian 已提交
2603

2604
		/*
B
Bruce Momjian 已提交
2605 2606
		 * If it's safe to interrupt, and we're waiting for input or a lock,
		 * service the interrupt immediately
2607
		 */
2608 2609
		if (ImmediateInterruptOK && InterruptHoldoffCount == 0 &&
			CritSectionCount == 0)
2610
		{
2611 2612 2613
			/* bump holdoff count to make ProcessInterrupts() a no-op */
			/* until we are done getting ready for it */
			InterruptHoldoffCount++;
2614
			LockWaitCancel();	/* prevent CheckDeadLock from running */
2615
			DisableNotifyInterrupt();
2616
			DisableCatchupInterrupt();
2617
			InterruptHoldoffCount--;
2618 2619
			ProcessInterrupts();
		}
2620
	}
2621 2622

	errno = save_errno;
2623 2624
}

2625
/*
2626 2627
 * Query-cancel signal from postmaster: abort current transaction
 * at soonest convenient time
2628
 */
2629
void
2630
StatementCancelHandler(SIGNAL_ARGS)
2631
{
2632 2633
	int			save_errno = errno;

B
Bruce Momjian 已提交
2634
	/*
2635
	 * Don't joggle the elbow of proc_exit
B
Bruce Momjian 已提交
2636
	 */
2637
	if (!proc_exit_inprogress)
2638
	{
2639 2640
		InterruptPending = true;
		QueryCancelPending = true;
B
Bruce Momjian 已提交
2641

2642
		/*
B
Bruce Momjian 已提交
2643 2644 2645
		 * If it's safe to interrupt, and we're waiting for a lock, service
		 * the interrupt immediately.  No point in interrupting if we're
		 * waiting for input, however.
2646
		 */
2647 2648
		if (InterruptHoldoffCount == 0 && CritSectionCount == 0 &&
			(DoingCommandRead || ImmediateInterruptOK))
2649
		{
2650 2651 2652
			/* bump holdoff count to make ProcessInterrupts() a no-op */
			/* until we are done getting ready for it */
			InterruptHoldoffCount++;
2653 2654 2655 2656 2657
			LockWaitCancel();	/* prevent CheckDeadLock from running */
			DisableNotifyInterrupt();
			DisableCatchupInterrupt();
			InterruptHoldoffCount--;
			ProcessInterrupts();
2658
		}
2659 2660
	}

2661
	errno = save_errno;
2662 2663
}

2664
/* signal handler for floating point exception */
2665
void
2666 2667
FloatExceptionHandler(SIGNAL_ARGS)
{
2668 2669 2670
	ereport(ERROR,
			(errcode(ERRCODE_FLOATING_POINT_EXCEPTION),
			 errmsg("floating-point exception"),
B
Bruce Momjian 已提交
2671 2672 2673
			 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.")));
2674 2675
}

2676
/* SIGHUP: set flag to re-read config file at next convenient time */
2677
static void
2678
SigHupHandler(SIGNAL_ARGS)
2679
{
2680
	got_SIGHUP = true;
2681 2682
}

2683

2684 2685 2686 2687 2688 2689 2690 2691 2692 2693
/*
 * 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)
{
2694 2695
	/* OK to accept interrupt now? */
	if (InterruptHoldoffCount != 0 || CritSectionCount != 0)
2696 2697 2698 2699 2700
		return;
	InterruptPending = false;
	if (ProcDiePending)
	{
		ProcDiePending = false;
B
Bruce Momjian 已提交
2701 2702
		QueryCancelPending = false;		/* ProcDie trumps QueryCancel */
		ImmediateInterruptOK = false;	/* not idle anymore */
2703
		DisableNotifyInterrupt();
2704
		DisableCatchupInterrupt();
2705 2706 2707
		/* As in quickdie, don't risk sending to client during auth */
		if (ClientAuthInProgress && whereToSendOutput == DestRemote)
			whereToSendOutput = DestNone;
2708 2709 2710 2711 2712 2713 2714
		if (IsAutoVacuumWorkerProcess())
			ereport(FATAL,
					(errcode(ERRCODE_ADMIN_SHUTDOWN),
					 errmsg("terminating autovacuum process due to administrator command")));
		else
			ereport(FATAL,
					(errcode(ERRCODE_ADMIN_SHUTDOWN),
B
Bruce Momjian 已提交
2715
			 errmsg("terminating connection due to administrator command")));
2716 2717 2718 2719
	}
	if (QueryCancelPending)
	{
		QueryCancelPending = false;
B
Bruce Momjian 已提交
2720
		ImmediateInterruptOK = false;	/* not idle anymore */
2721
		DisableNotifyInterrupt();
2722
		DisableCatchupInterrupt();
2723 2724 2725 2726 2727 2728 2729 2730
		/* As in quickdie, don't risk sending to client during auth */
		if (ClientAuthInProgress && whereToSendOutput == DestRemote)
			whereToSendOutput = DestNone;
		if (ClientAuthInProgress)
			ereport(ERROR,
					(errcode(ERRCODE_QUERY_CANCELED),
					 errmsg("canceling authentication due to timeout")));
		else if (cancel_from_timeout)
2731 2732 2733
			ereport(ERROR,
					(errcode(ERRCODE_QUERY_CANCELED),
					 errmsg("canceling statement due to statement timeout")));
2734 2735 2736 2737
		else if (IsAutoVacuumWorkerProcess())
			ereport(ERROR,
					(errcode(ERRCODE_QUERY_CANCELED),
					 errmsg("canceling autovacuum task")));
2738
		else
2739 2740 2741 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 2771 2772 2773 2774 2775 2776 2777 2778 2779 2780 2781 2782 2783 2784 2785 2786
		{
			int cancelMode = MyProc->recoveryConflictMode;

			/*
			 * XXXHS: We don't yet have a clean way to cancel an
			 * idle-in-transaction session, so make it FATAL instead.
			 * This isn't as bad as it looks because we don't issue a
			 * CONFLICT_MODE_ERROR for a session with proc->xmin == 0
			 * on cleanup conflicts. There's a possibility that we
			 * marked somebody as a conflict and then they go idle.
			 */
			if (DoingCommandRead && IsTransactionBlock() &&
				cancelMode == CONFLICT_MODE_ERROR)
			{
				cancelMode = CONFLICT_MODE_FATAL;
			}

			switch (cancelMode)
			{
				case CONFLICT_MODE_FATAL:
						Assert(RecoveryInProgress());
						ereport(FATAL,
							(errcode(ERRCODE_QUERY_CANCELED),
							 errmsg("canceling session due to conflict with recovery")));

				case CONFLICT_MODE_ERROR:
						/*
						 * We are aborting because we need to release
						 * locks. So we need to abort out of all
						 * subtransactions to make sure we release
						 * all locks at whatever their level.
						 *
						 * XXX Should we try to examine the
						 * transaction tree and cancel just enough
						 * subxacts to remove locks? Doubt it.
						 */
						Assert(RecoveryInProgress());
						AbortOutOfAnyTransaction();
						ereport(ERROR,
							(errcode(ERRCODE_QUERY_CANCELED),
							 errmsg("canceling statement due to conflict with recovery")));
						return;

				default:
						/* No conflict pending, so fall through */
						break;
			}

2787 2788 2789
			ereport(ERROR,
					(errcode(ERRCODE_QUERY_CANCELED),
					 errmsg("canceling statement due to user request")));
2790
		}
2791 2792 2793 2794
	}
	/* If we get here, do nothing (probably, QueryCancelPending was reset) */
}

2795

2796 2797 2798 2799 2800 2801
/*
 * 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
2802
 * before hitting the hardware limit.
2803 2804 2805 2806
 */
void
check_stack_depth(void)
{
B
Bruce Momjian 已提交
2807
	char		stack_top_loc;
2808
	long		stack_depth;
2809 2810 2811 2812

	/*
	 * Compute distance from PostgresMain's local variables to my own
	 */
2813
	stack_depth = (long) (stack_base_ptr - &stack_top_loc);
B
Bruce Momjian 已提交
2814

2815
	/*
B
Bruce Momjian 已提交
2816
	 * Take abs value, since stacks grow up on some machines, down on others
2817 2818 2819
	 */
	if (stack_depth < 0)
		stack_depth = -stack_depth;
B
Bruce Momjian 已提交
2820

2821 2822 2823
	/*
	 * Trouble?
	 *
2824 2825 2826 2827
	 * The test on stack_base_ptr prevents us from erroring out if called
	 * 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.
2828 2829 2830 2831 2832 2833 2834
	 */
	if (stack_depth > max_stack_depth_bytes &&
		stack_base_ptr != NULL)
	{
		ereport(ERROR,
				(errcode(ERRCODE_STATEMENT_TOO_COMPLEX),
				 errmsg("stack depth limit exceeded"),
B
Bruce Momjian 已提交
2835 2836
		 errhint("Increase the configuration parameter \"max_stack_depth\", "
		   "after ensuring the platform's stack depth limit is adequate.")));
2837 2838 2839
	}
}

2840
/* GUC assign hook for max_stack_depth */
2841 2842 2843
bool
assign_max_stack_depth(int newval, bool doit, GucSource source)
{
2844 2845 2846 2847 2848
	long		newval_bytes = newval * 1024L;
	long		stack_rlimit = get_stack_depth_rlimit();

	if (stack_rlimit > 0 && newval_bytes > stack_rlimit - STACK_DEPTH_SLOP)
	{
2849
		ereport(GUC_complaint_elevel(source),
2850 2851 2852 2853 2854 2855
				(errcode(ERRCODE_INVALID_PARAMETER_VALUE),
				 errmsg("\"max_stack_depth\" must not exceed %ldkB",
						(stack_rlimit - STACK_DEPTH_SLOP) / 1024L),
				 errhint("Increase the platform's stack depth limit via \"ulimit -s\" or local equivalent.")));
		return false;
	}
2856
	if (doit)
2857
		max_stack_depth_bytes = newval_bytes;
2858 2859 2860 2861
	return true;
}


2862 2863 2864 2865 2866 2867 2868 2869 2870 2871 2872 2873 2874 2875 2876 2877 2878 2879 2880 2881 2882 2883 2884 2885 2886 2887 2888 2889 2890 2891 2892 2893 2894 2895 2896
/*
 * 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);
}


2897 2898 2899
bool
set_plan_disabling_options(const char *arg, GucContext context, GucSource source)
{
B
Bruce Momjian 已提交
2900
	char	   *tmp = NULL;
2901 2902 2903

	switch (arg[0])
	{
B
Bruce Momjian 已提交
2904
		case 's':				/* seqscan */
2905 2906
			tmp = "enable_seqscan";
			break;
B
Bruce Momjian 已提交
2907
		case 'i':				/* indexscan */
2908 2909
			tmp = "enable_indexscan";
			break;
B
Bruce Momjian 已提交
2910
		case 'b':				/* bitmapscan */
2911 2912
			tmp = "enable_bitmapscan";
			break;
B
Bruce Momjian 已提交
2913
		case 't':				/* tidscan */
2914 2915
			tmp = "enable_tidscan";
			break;
B
Bruce Momjian 已提交
2916
		case 'n':				/* nestloop */
2917 2918
			tmp = "enable_nestloop";
			break;
B
Bruce Momjian 已提交
2919
		case 'm':				/* mergejoin */
2920 2921
			tmp = "enable_mergejoin";
			break;
B
Bruce Momjian 已提交
2922
		case 'h':				/* hashjoin */
2923 2924 2925 2926 2927 2928 2929 2930 2931 2932 2933 2934 2935 2936 2937 2938 2939 2940 2941
			tmp = "enable_hashjoin";
			break;
	}
	if (tmp)
	{
		SetConfigOption(tmp, "false", context, source);
		return true;
	}
	else
		return false;
}


const char *
get_stats_option_name(const char *arg)
{
	switch (arg[0])
	{
		case 'p':
B
Bruce Momjian 已提交
2942
			if (optarg[1] == 'a')		/* "parser" */
2943
				return "log_parser_stats";
B
Bruce Momjian 已提交
2944
			else if (optarg[1] == 'l')	/* "planner" */
2945 2946 2947
				return "log_planner_stats";
			break;

B
Bruce Momjian 已提交
2948
		case 'e':				/* "executor" */
2949 2950 2951 2952 2953 2954 2955 2956
			return "log_executor_stats";
			break;
	}

	return NULL;
}


2957
/* ----------------------------------------------------------------
2958 2959
 * process_postgres_switches
 *	   Parse command line arguments for PostgresMain
2960
 *
2961 2962 2963 2964 2965
 * This is called twice, once for the "secure" options coming from the
 * postmaster or command line, and once for the "insecure" options coming
 * from the client's startup packet.  The latter have the same syntax but
 * may be restricted in what they can do.
 *
2966
 * argv[0] is ignored in either case (it's assumed to be the program name).
2967 2968 2969 2970 2971 2972
 *
 * ctx is PGC_POSTMASTER for secure options, PGC_BACKEND for insecure options
 * coming from the client, or PGC_SUSET for insecure options coming from
 * a superuser client.
 *
 * Returns the database name extracted from the command line, if any.
2973 2974
 * ----------------------------------------------------------------
 */
2975
const char *
2976
process_postgres_switches(int argc, char *argv[], GucContext ctx)
2977
{
2978 2979
	const char *dbname;
	bool		secure = (ctx == PGC_POSTMASTER);
2980
	int			errs = 0;
2981
	GucSource	gucsource;
2982
	int			flag;
2983

2984
	if (secure)
2985
	{
2986
		gucsource = PGC_S_ARGV;			/* switches came from command line */
2987

2988 2989 2990 2991 2992 2993 2994 2995
		/* Ignore the initial --single argument, if present */
		if (argc > 1 && strcmp(argv[1], "--single") == 0)
		{
			argv++;
			argc--;
		}
	}
	else
2996
	{
2997
		gucsource = PGC_S_CLIENT;		/* switches came from client */
2998 2999
	}

3000
	/*
B
Bruce Momjian 已提交
3001 3002 3003
	 * Parse command-line options.	CAUTION: keep this in sync with
	 * postmaster/postmaster.c (the option sets should not conflict) and with
	 * the common help() function in main/main.c.
3004
	 */
3005
	while ((flag = getopt(argc, argv, "A:B:c:D:d:EeFf:h:ijk:lN:nOo:Pp:r:S:sTt:v:W:-:")) != -1)
3006
	{
3007 3008
		switch (flag)
		{
M
 
Marc G. Fournier 已提交
3009
			case 'A':
3010
				SetConfigOption("debug_assertions", optarg, ctx, gucsource);
M
 
Marc G. Fournier 已提交
3011
				break;
3012

3013
			case 'B':
3014
				SetConfigOption("shared_buffers", optarg, ctx, gucsource);
3015
				break;
3016

3017
			case 'D':
3018
				if (secure)
3019
					userDoption = strdup(optarg);
M
 
Marc G. Fournier 已提交
3020
				break;
3021

3022
			case 'd':
3023
				set_debug_options(atoi(optarg), ctx, gucsource);
3024
				break;
3025 3026

			case 'E':
3027
				EchoQuery = true;
3028
				break;
3029 3030

			case 'e':
3031
				SetConfigOption("datestyle", "euro", ctx, gucsource);
3032
				break;
3033 3034

			case 'F':
3035
				SetConfigOption("fsync", "false", ctx, gucsource);
3036
				break;
3037 3038

			case 'f':
3039 3040 3041
				if (!set_plan_disabling_options(optarg, ctx, gucsource))
					errs++;
				break;
3042

3043 3044
			case 'h':
				SetConfigOption("listen_addresses", optarg, ctx, gucsource);
3045 3046
				break;

3047 3048 3049
			case 'i':
				SetConfigOption("listen_addresses", "*", ctx, gucsource);
				break;
3050

3051
			case 'j':
3052 3053
				UseNewLine = 0;
				break;
3054

3055 3056 3057
			case 'k':
				SetConfigOption("unix_socket_directory", optarg, ctx, gucsource);
				break;
3058

3059 3060
			case 'l':
				SetConfigOption("ssl", "true", ctx, gucsource);
3061 3062
				break;

3063 3064 3065
			case 'N':
				SetConfigOption("max_connections", optarg, ctx, gucsource);
				break;
3066

3067 3068 3069 3070 3071 3072
			case 'n':
				/* ignored for consistency with postmaster */
				break;

			case 'O':
				SetConfigOption("allow_system_table_mods", "true", ctx, gucsource);
H
Hiroshi Inoue 已提交
3073 3074
				break;

T
Tom Lane 已提交
3075
			case 'o':
3076 3077
				errs++;
				break;
3078

3079 3080
			case 'P':
				SetConfigOption("ignore_system_indexes", "true", ctx, gucsource);
T
Tom Lane 已提交
3081 3082
				break;

3083
			case 'p':
3084 3085
				SetConfigOption("port", optarg, ctx, gucsource);
				break;
B
Bruce Momjian 已提交
3086

3087 3088
			case 'r':
				/* send output (stdout and stderr) to the given file */
3089
				if (secure)
3090
					strlcpy(OutputFileName, optarg, MAXPGPATH);
3091
				break;
3092

3093
			case 'S':
3094
				SetConfigOption("work_mem", optarg, ctx, gucsource);
3095
				break;
3096 3097

			case 's':
3098
				SetConfigOption("log_statement_stats", "true", ctx, gucsource);
M
 
Marc G. Fournier 已提交
3099 3100
				break;

3101 3102 3103 3104
			case 'T':
				/* ignored for consistency with postmaster */
				break;

3105
			case 't':
3106
				{
B
Bruce Momjian 已提交
3107 3108 3109
					const char *tmp = get_stats_option_name(optarg);

					if (tmp)
3110
						SetConfigOption(tmp, "true", ctx, gucsource);
3111
					else
B
Bruce Momjian 已提交
3112 3113
						errs++;
					break;
3114
				}
3115

3116
			case 'v':
3117 3118 3119 3120 3121 3122 3123
				/*
				 * -v is no longer used in normal operation, since
				 * FrontendProtocol is already set before we get here.
				 * We keep the switch only for possible use in standalone
				 * operation, in case we ever support using normal FE/BE
				 * protocol with a standalone backend.
				 */
3124 3125
				if (secure)
					FrontendProtocol = (ProtocolVersion) atoi(optarg);
3126 3127
				break;

M
 
Marc G. Fournier 已提交
3128
			case 'W':
3129 3130
				SetConfigOption("post_auth_delay", optarg, ctx, gucsource);
				break;
3131

3132
			case 'c':
3133
			case '-':
3134
				{
B
Bruce Momjian 已提交
3135 3136
					char	   *name,
							   *value;
3137

B
Bruce Momjian 已提交
3138 3139 3140 3141
					ParseLongOption(optarg, &name, &value);
					if (!value)
					{
						if (flag == '-')
3142 3143 3144 3145
							ereport(ERROR,
									(errcode(ERRCODE_SYNTAX_ERROR),
									 errmsg("--%s requires a value",
											optarg)));
B
Bruce Momjian 已提交
3146
						else
3147 3148 3149 3150
							ereport(ERROR,
									(errcode(ERRCODE_SYNTAX_ERROR),
									 errmsg("-c %s requires a value",
											optarg)));
B
Bruce Momjian 已提交
3151
					}
3152
					SetConfigOption(name, value, ctx, gucsource);
B
Bruce Momjian 已提交
3153 3154 3155 3156 3157
					free(name);
					if (value)
						free(value);
					break;
				}
3158

3159 3160
			default:
				errs++;
T
Tom Lane 已提交
3161
				break;
3162
		}
3163 3164
	}

3165
	/*
3166 3167
	 * Should be no more arguments except an optional database name, and
	 * that's only in the secure case.
3168
	 */
3169
	if (errs || argc - optind > 1 || (argc != optind && !secure))
3170
	{
3171 3172 3173 3174 3175
		/* spell the error message a bit differently depending on context */
		if (IsUnderPostmaster)
			ereport(FATAL,
					(errcode(ERRCODE_SYNTAX_ERROR),
				 errmsg("invalid command-line arguments for server process"),
3176
			   errhint("Try \"%s --help\" for more information.", progname)));
3177 3178 3179 3180
		else
			ereport(FATAL,
					(errcode(ERRCODE_SYNTAX_ERROR),
					 errmsg("%s: invalid command-line arguments",
3181 3182
							progname),
			   errhint("Try \"%s --help\" for more information.", progname)));
3183
	}
3184

3185 3186 3187 3188
	if (argc - optind == 1)
		dbname = strdup(argv[optind]);
	else
		dbname = NULL;
3189

3190 3191 3192 3193 3194 3195 3196 3197
	/*
	 * Reset getopt(3) library so that it will work correctly in subprocesses
	 * or when this function is called a second time with another array.
	 */
	optind = 1;
#ifdef HAVE_INT_OPTRESET
	optreset = 1;				/* some systems need this too */
#endif
3198

3199 3200
	return dbname;
}
3201

3202 3203 3204 3205 3206 3207 3208 3209 3210 3211 3212 3213 3214 3215 3216 3217 3218 3219 3220 3221 3222 3223 3224 3225 3226 3227 3228 3229 3230 3231 3232 3233 3234 3235 3236 3237 3238 3239 3240 3241 3242 3243 3244 3245 3246 3247 3248 3249 3250 3251 3252 3253 3254 3255 3256 3257 3258 3259 3260 3261 3262 3263 3264 3265 3266 3267 3268 3269 3270 3271 3272 3273 3274 3275 3276

/* ----------------------------------------------------------------
 * PostgresMain
 *	   postgres main loop -- all backends, interactive or otherwise start here
 *
 * 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.
 * ----------------------------------------------------------------
 */
int
PostgresMain(int argc, char *argv[], const char *username)
{
	const char *dbname;
	int			firstchar;
	char		stack_base;
	StringInfoData input_message;
	sigjmp_buf	local_sigjmp_buf;
	volatile bool send_ready_for_query = true;

	/*
	 * Initialize globals (already done if under postmaster, but not if
	 * standalone).
	 */
	if (!IsUnderPostmaster)
	{
		MyProcPid = getpid();

		MyStartTime = time(NULL);
	}

	/*
	 * Fire up essential subsystems: error and memory management
	 *
	 * If we are running under the postmaster, this is done already.
	 */
	if (!IsUnderPostmaster)
		MemoryContextInit();

	SetProcessingMode(InitProcessing);

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

	/* 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]);
	}

	if (pkglib_path[0] == '\0')
		get_pkglib_path(my_exec_path, pkglib_path);

	/*
	 * Set default values for command-line options.
	 */
	if (!IsUnderPostmaster)
		InitializeGUCOptions();

	/*
	 * Parse command-line options.
	 */
	dbname = process_postgres_switches(argc, argv, PGC_POSTMASTER);

	/* Must have gotten a database name, or have a default (the username) */
	if (dbname == NULL)
	{
		dbname = username;
		if (dbname == NULL)
			ereport(FATAL,
				(errcode(ERRCODE_INVALID_PARAMETER_VALUE),
				 errmsg("%s: no database nor user name specified",
3277
						progname)));
3278 3279
	}

3280 3281
	/* Acquire configuration parameters, unless inherited from postmaster */
	if (!IsUnderPostmaster)
3282
	{
3283
		if (!SelectConfigFiles(userDoption, progname))
3284
			proc_exit(1);
3285 3286
		/* If timezone is not set, determine what the OS uses */
		pg_timezone_initialize();
3287 3288
		/* If timezone_abbreviations is not set, select default */
		pg_timezone_abbrev_initialize();
3289
	}
3290

3291 3292 3293 3294 3295
	/*
	 * You might expect to see a setsid() call here, but it's not needed,
	 * because if we are under a postmaster then BackendInitialize() did it.
	 */

3296
	/*
3297
	 * Set up signal handlers and masks.
3298
	 *
3299 3300 3301
	 * Note that postmaster blocked all signals before forking child process,
	 * so there is no race condition whereby we might receive a signal before
	 * we have set up the handler.
T
Tom Lane 已提交
3302
	 *
B
Bruce Momjian 已提交
3303 3304 3305 3306 3307 3308
	 * Also note: it's best not to use any signals that are SIG_IGNored in the
	 * postmaster.	If such a signal arrives before we are able to change the
	 * handler to non-SIG_IGN, it'll get dropped.  Instead, make a dummy
	 * handler in the postmaster to reserve the signal. (Of course, this isn't
	 * an issue for signals that are locally generated, such as SIGALRM and
	 * SIGPIPE.)
3309
	 */
3310
	pqsignal(SIGHUP, SigHupHandler);	/* set flag to read config file */
B
Bruce Momjian 已提交
3311
	pqsignal(SIGINT, StatementCancelHandler);	/* cancel current query */
3312
	pqsignal(SIGTERM, die);		/* cancel current query and exit */
3313 3314 3315 3316 3317 3318 3319 3320 3321

	/*
	 * In a standalone backend, SIGQUIT can be generated from the keyboard
	 * easily, while SIGTERM cannot, so we make both signals do die() rather
	 * than quickdie().
	 */
	if (IsUnderPostmaster)
		pqsignal(SIGQUIT, quickdie);	/* hard crash time */
	else
B
Bruce Momjian 已提交
3322
		pqsignal(SIGQUIT, die); /* cancel current query and exit */
B
Bruce Momjian 已提交
3323
	pqsignal(SIGALRM, handle_sig_alarm);		/* timeout conditions */
3324 3325 3326 3327

	/*
	 * Ignore failure to write to frontend. Note: if frontend closes
	 * connection, we will notice it and exit cleanly when control next
B
Bruce Momjian 已提交
3328 3329
	 * returns to outer loop.  This seems safer than forcing exit in the midst
	 * of output during who-knows-what operation...
3330 3331
	 */
	pqsignal(SIGPIPE, SIG_IGN);
3332 3333
	pqsignal(SIGUSR1, procsignal_sigusr1_handler);
	pqsignal(SIGUSR2, SIG_IGN);
3334
	pqsignal(SIGFPE, FloatExceptionHandler);
3335 3336

	/*
B
Bruce Momjian 已提交
3337
	 * Reset some signals that are accepted by postmaster but not by backend
3338
	 */
B
Bruce Momjian 已提交
3339
	pqsignal(SIGCHLD, SIG_DFL); /* system() requires this on some platforms */
3340

3341 3342
	pqinitmask();

3343 3344 3345 3346 3347
	if (IsUnderPostmaster)
	{
		/* We allow SIGQUIT (quickdie) at all times */
		sigdelset(&BlockSig, SIGQUIT);
	}
3348

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

3351
	if (IsUnderPostmaster)
3352
	{
3353
		BaseInit();
3354
	}
3355
	else
3356
	{
3357
		/*
B
Bruce Momjian 已提交
3358 3359
		 * Validate we have been given a reasonable-looking DataDir (if under
		 * postmaster, assume postmaster did this already).
3360
		 */
3361
		Assert(DataDir);
3362 3363
		ValidatePgVersion(DataDir);

3364 3365 3366
		/* Change into DataDir (if under postmaster, was done already) */
		ChangeToDataDir();

3367
		/*
3368
		 * Create lockfile for data directory.
3369
		 */
3370
		CreateDataDirLockFile(false);
3371

3372
		BaseInit();
3373 3374 3375 3376 3377

		/*
		 * Start up xlog for standalone backend, and register to have it
		 * closed down at exit.
		 */
3378
		StartupXLOG();
3379
		on_shmem_exit(ShutdownXLOG, 0);
3380 3381
	}

3382
	/*
B
Bruce Momjian 已提交
3383 3384 3385 3386
	 * Create a per-backend PGPROC struct in shared memory, except in the
	 * EXEC_BACKEND case where this was done in SubPostmasterMain. We must do
	 * this before we can use LWLocks (and in the EXEC_BACKEND case we already
	 * had to do some stuff with LWLocks).
3387 3388 3389 3390 3391 3392 3393 3394
	 */
#ifdef EXEC_BACKEND
	if (!IsUnderPostmaster)
		InitProcess();
#else
	InitProcess();
#endif

3395 3396 3397
	/* We need to allow SIGINT, etc during the initial transaction */
	PG_SETMASK(&UnBlockSig);

3398
	/*
3399 3400
	 * General initialization.
	 *
3401 3402 3403
	 * 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.
3404
	 */
3405
	InitPostgres(dbname, InvalidOid, username, NULL);
3406

3407 3408 3409 3410 3411 3412 3413 3414 3415 3416 3417 3418 3419
	/*
	 * If the PostmasterContext is still around, recycle the space; we don't
	 * need it anymore after InitPostgres completes.  Note this does not trash
	 * *MyProcPort, because ConnCreate() allocated that space with malloc()
	 * ... else we'd need to copy the Port data first.  Also, subsidiary data
	 * such as the username isn't lost either; see ProcessStartupPacket().
	 */
	if (PostmasterContext)
	{
		MemoryContextDelete(PostmasterContext);
		PostmasterContext = NULL;
	}

3420
	SetProcessingMode(NormalProcessing);
3421

3422 3423 3424 3425 3426 3427
	/*
	 * Now all GUC states are fully set up.  Report them to client if
	 * appropriate.
	 */
	BeginReportingGUCOptions();

3428
	/*
B
Bruce Momjian 已提交
3429 3430
	 * Also set up handler to log session end; we have to wait till now to be
	 * sure Log_disconnections has its final value.
3431 3432 3433 3434
	 */
	if (IsUnderPostmaster && Log_disconnections)
		on_proc_exit(log_disconnections, 0);

3435
	/*
B
Bruce Momjian 已提交
3436 3437
	 * process any libraries that should be preloaded at backend start (this
	 * likewise can't be done until GUC settings are complete)
3438 3439 3440
	 */
	process_local_preload_libraries();

3441 3442
	/*
	 * Send this backend's cancellation info to the frontend.
3443
	 */
3444
	if (whereToSendOutput == DestRemote &&
M
 
Marc G. Fournier 已提交
3445 3446
		PG_PROTOCOL_MAJOR(FrontendProtocol) >= 2)
	{
3447
		StringInfoData buf;
B
Bruce Momjian 已提交
3448

3449
		pq_beginmessage(&buf, 'K');
3450 3451 3452
		pq_sendint(&buf, (int32) MyProcPid, sizeof(int32));
		pq_sendint(&buf, (int32) MyCancelKey, sizeof(int32));
		pq_endmessage(&buf);
M
 
Marc G. Fournier 已提交
3453 3454 3455
		/* Need not flush since ReadyForQuery will do it. */
	}

3456
	/* Welcome banner for standalone case */
3457
	if (whereToSendOutput == DestDebug)
3458
		printf("\nPostgreSQL stand-alone backend %s\n", PG_VERSION);
3459

3460 3461 3462
	/*
	 * Create the memory context we will use in the main loop.
	 *
3463 3464
	 * MessageContext is reset once per iteration of the main loop, ie, upon
	 * completion of processing of each command message from the client.
3465
	 */
3466 3467 3468 3469 3470
	MessageContext = AllocSetContextCreate(TopMemoryContext,
										   "MessageContext",
										   ALLOCSET_DEFAULT_MINSIZE,
										   ALLOCSET_DEFAULT_INITSIZE,
										   ALLOCSET_DEFAULT_MAXSIZE);
3471

3472
	/*
3473
	 * Remember stand-alone backend startup time
3474 3475
	 */
	if (!IsUnderPostmaster)
3476
		PgStartTime = GetCurrentTimestamp();
3477

3478 3479
	/*
	 * POSTGRES main processing loop begins here
3480
	 *
B
Bruce Momjian 已提交
3481 3482
	 * If an exception is encountered, processing resumes here so we abort the
	 * current transaction and start a new one.
3483
	 *
3484 3485 3486 3487 3488 3489 3490
	 * 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
	 * 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 recovering from an error
	 * during error recovery.  (If we get into an infinite loop thereby, it
	 * will soon be stopped by overflow of elog.c's internal state stack.)
3491 3492
	 */

3493
	if (sigsetjmp(local_sigjmp_buf, 1) != 0)
3494
	{
3495
		/*
3496
		 * NOTE: if you are tempted to add more code in this if-block,
3497
		 * consider the high probability that it should be in
B
Bruce Momjian 已提交
3498
		 * AbortTransaction() instead.	The only stuff done directly here
B
Bruce Momjian 已提交
3499 3500
		 * should be stuff that is guaranteed to apply *only* for outer-level
		 * error recovery, such as adjusting the FE/BE protocol status.
3501 3502 3503 3504 3505 3506 3507 3508 3509
		 */

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

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

		/*
B
Bruce Momjian 已提交
3510 3511
		 * Forget any pending QueryCancel request, since we're returning to
		 * the idle loop anyway, and cancel the statement timer if running.
3512 3513
		 */
		QueryCancelPending = false;
3514
		disable_sig_alarm(true);
B
Bruce Momjian 已提交
3515
		QueryCancelPending = false;		/* again in case timeout occurred */
3516 3517

		/*
B
Bruce Momjian 已提交
3518 3519 3520
		 * 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.
3521
		 */
3522
		DoingCommandRead = false;
3523
		DisableNotifyInterrupt();
3524
		DisableCatchupInterrupt();
3525

3526 3527 3528
		/* Make sure libpq is in a good state */
		pq_comm_reset();

3529 3530
		/* Report the error to the client and/or server log */
		EmitErrorReport();
3531

3532
		/*
B
Bruce Momjian 已提交
3533 3534
		 * Make sure debug_query_string gets reset before we possibly clobber
		 * the storage it points at.
3535
		 */
3536
		debug_query_string = NULL;
3537

3538
		/*
3539
		 * Abort the current transaction in order to recover.
3540
		 */
3541
		AbortCurrentTransaction();
3542 3543

		/*
B
Bruce Momjian 已提交
3544 3545
		 * Now return to normal top-level context and clear ErrorContext for
		 * next time.
3546 3547
		 */
		MemoryContextSwitchTo(TopMemoryContext);
3548
		FlushErrorState();
3549

3550
		/*
B
Bruce Momjian 已提交
3551 3552
		 * If we were handling an extended-query-protocol message, initiate
		 * skip till next Sync.  This also causes us not to issue
B
Bruce Momjian 已提交
3553
		 * ReadyForQuery (until we get Sync).
3554 3555 3556
		 */
		if (doing_extended_query_message)
			ignore_till_sync = true;
3557

3558 3559
		/* We don't have a transaction command open anymore */
		xact_started = false;
3560

3561
		/* Now we can allow interrupts again */
3562
		RESUME_INTERRUPTS();
3563
	}
3564

3565 3566
	/* We can now handle ereport(ERROR) */
	PG_exception_stack = &local_sigjmp_buf;
3567

3568
	if (!ignore_till_sync)
B
Bruce Momjian 已提交
3569
		send_ready_for_query = true;	/* initially, or after error */
3570

3571 3572
	/*
	 * Non-error queries loop here.
3573 3574 3575 3576
	 */

	for (;;)
	{
3577
		/*
B
Bruce Momjian 已提交
3578 3579
		 * At top of loop, reset extended-query-message flag, so that any
		 * errors encountered in "idle" state don't provoke skip.
3580 3581 3582
		 */
		doing_extended_query_message = false;

3583
		/*
B
Bruce Momjian 已提交
3584 3585
		 * Release storage left over from prior query cycle, and create a new
		 * query input buffer in the cleared MessageContext.
3586
		 */
3587 3588
		MemoryContextSwitchTo(MessageContext);
		MemoryContextResetAndDeleteChildren(MessageContext);
3589

3590
		initStringInfo(&input_message);
3591

3592
		/*
B
Bruce Momjian 已提交
3593 3594
		 * (1) If we've reached idle state, tell the frontend we're ready for
		 * a new query.
3595
		 *
3596
		 * Note: this includes fflush()'ing the last of the prior output.
3597 3598 3599
		 *
		 * 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 已提交
3600 3601 3602
		 * those every time through the message loop because it'd slow down
		 * processing of batched messages, and because we don't want to report
		 * uncommitted updates (that confuses autovacuum).
B
Bruce Momjian 已提交
3603
		 */
3604
		if (send_ready_for_query)
3605
		{
3606
			if (IsTransactionOrTransactionBlock())
3607
			{
3608
				set_ps_display("idle in transaction", false);
3609 3610 3611 3612
				pgstat_report_activity("<IDLE> in transaction");
			}
			else
			{
3613
				pgstat_report_stat(false);
3614

3615
				set_ps_display("idle", false);
3616 3617
				pgstat_report_activity("<IDLE>");
			}
3618

3619
			ReadyForQuery(whereToSendOutput);
3620
			send_ready_for_query = false;
3621
		}
3622

3623
		/*
B
Bruce Momjian 已提交
3624 3625 3626 3627
		 * (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.)
3628
		 */
3629 3630
		QueryCancelPending = false;		/* forget any earlier CANCEL signal */
		DoingCommandRead = true;
3631

3632 3633
		/*
		 * (3) read a command (loop blocks here)
3634
		 */
3635
		firstchar = ReadCommand(&input_message);
3636

3637 3638
		/*
		 * (4) disable async signal conditions again.
3639
		 */
3640
		DoingCommandRead = false;
3641

3642
		/*
B
Bruce Momjian 已提交
3643 3644
		 * (5) check for any other interesting events that happened while we
		 * slept.
3645 3646 3647 3648 3649 3650 3651
		 */
		if (got_SIGHUP)
		{
			got_SIGHUP = false;
			ProcessConfigFile(PGC_SIGHUP);
		}

3652
		/*
B
Bruce Momjian 已提交
3653 3654
		 * (6) process the command.  But ignore it if we're skipping till
		 * Sync.
3655
		 */
3656
		if (ignore_till_sync && firstchar != EOF)
3657 3658
			continue;

3659 3660
		switch (firstchar)
		{
3661
			case 'Q':			/* simple query */
3662
				{
3663 3664
					const char *query_string;

3665 3666 3667
					/* Set statement_timestamp() */
					SetCurrentStatementStartTimestamp();

3668 3669
					query_string = pq_getmsgstring(&input_message);
					pq_getmsgend(&input_message);
3670

3671
					exec_simple_query(query_string);
3672

3673
					send_ready_for_query = true;
3674
				}
3675 3676
				break;

3677 3678 3679 3680 3681 3682 3683
			case 'P':			/* parse */
				{
					const char *stmt_name;
					const char *query_string;
					int			numParams;
					Oid		   *paramTypes = NULL;

3684 3685 3686
					/* Set statement_timestamp() */
					SetCurrentStatementStartTimestamp();

3687 3688 3689
					stmt_name = pq_getmsgstring(&input_message);
					query_string = pq_getmsgstring(&input_message);
					numParams = pq_getmsgint(&input_message, 2);
3690 3691
					if (numParams > 0)
					{
B
Bruce Momjian 已提交
3692
						int			i;
3693 3694 3695

						paramTypes = (Oid *) palloc(numParams * sizeof(Oid));
						for (i = 0; i < numParams; i++)
3696
							paramTypes[i] = pq_getmsgint(&input_message, 4);
3697
					}
3698
					pq_getmsgend(&input_message);
3699 3700 3701 3702 3703 3704 3705

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

			case 'B':			/* bind */
3706 3707
				/* Set statement_timestamp() */
				SetCurrentStatementStartTimestamp();
B
Bruce Momjian 已提交
3708

3709
				/*
B
Bruce Momjian 已提交
3710 3711
				 * this message is complex enough that it seems best to put
				 * the field extraction out-of-line
3712
				 */
3713
				exec_bind_message(&input_message);
3714 3715 3716 3717 3718
				break;

			case 'E':			/* execute */
				{
					const char *portal_name;
3719
					int			max_rows;
3720

3721 3722 3723
					/* Set statement_timestamp() */
					SetCurrentStatementStartTimestamp();

3724
					portal_name = pq_getmsgstring(&input_message);
3725
					max_rows = pq_getmsgint(&input_message, 4);
3726
					pq_getmsgend(&input_message);
3727

3728
					exec_execute_message(portal_name, max_rows);
3729 3730 3731
				}
				break;

3732
			case 'F':			/* fastpath function call */
3733 3734 3735
				/* Set statement_timestamp() */
				SetCurrentStatementStartTimestamp();

3736
				/* Tell the collector what we're doing */
3737 3738
				pgstat_report_activity("<FASTPATH> function call");

3739
				/* start an xact for this function invocation */
3740
				start_xact_command();
3741

3742 3743
				/*
				 * Note: we may at this point be inside an aborted
B
Bruce Momjian 已提交
3744 3745
				 * transaction.  We can't throw error for that until we've
				 * finished reading the function-call message, so
3746 3747 3748 3749 3750
				 * HandleFunctionRequest() must check for it after doing so.
				 * Be careful not to do anything that assumes we're inside a
				 * valid transaction here.
				 */

3751 3752 3753
				/* switch back to message context */
				MemoryContextSwitchTo(MessageContext);

3754
				if (HandleFunctionRequest(&input_message) == EOF)
3755 3756
				{
					/* lost frontend connection during F message input */
B
Bruce Momjian 已提交
3757

3758
					/*
3759
					 * Reset whereToSendOutput to prevent ereport from
B
Bruce Momjian 已提交
3760
					 * attempting to send any more messages to client.
3761
					 */
3762 3763
					if (whereToSendOutput == DestRemote)
						whereToSendOutput = DestNone;
3764

3765
					proc_exit(0);
3766
				}
3767 3768

				/* commit the function-invocation transaction */
3769
				finish_xact_command();
3770

3771
				send_ready_for_query = true;
3772 3773
				break;

B
Bruce Momjian 已提交
3774
			case 'C':			/* close */
3775
				{
B
Bruce Momjian 已提交
3776
					int			close_type;
3777 3778
					const char *close_target;

3779 3780 3781
					close_type = pq_getmsgbyte(&input_message);
					close_target = pq_getmsgstring(&input_message);
					pq_getmsgend(&input_message);
3782 3783 3784 3785 3786 3787 3788 3789 3790

					switch (close_type)
					{
						case 'S':
							if (close_target[0] != '\0')
								DropPreparedStatement(close_target, false);
							else
							{
								/* special-case the unnamed statement */
3791
								drop_unnamed_stmt();
3792 3793 3794 3795 3796 3797 3798 3799 3800 3801 3802 3803
							}
							break;
						case 'P':
							{
								Portal		portal;

								portal = GetPortalByName(close_target);
								if (PortalIsValid(portal))
									PortalDrop(portal, false);
							}
							break;
						default:
3804 3805
							ereport(ERROR,
									(errcode(ERRCODE_PROTOCOL_VIOLATION),
B
Bruce Momjian 已提交
3806 3807
								   errmsg("invalid CLOSE message subtype %d",
										  close_type)));
3808 3809 3810
							break;
					}

3811
					if (whereToSendOutput == DestRemote)
B
Bruce Momjian 已提交
3812
						pq_putemptymessage('3');		/* CloseComplete */
3813 3814 3815 3816 3817
				}
				break;

			case 'D':			/* describe */
				{
B
Bruce Momjian 已提交
3818
					int			describe_type;
3819 3820
					const char *describe_target;

3821 3822 3823
					/* Set statement_timestamp() (needed for xact) */
					SetCurrentStatementStartTimestamp();

3824 3825 3826
					describe_type = pq_getmsgbyte(&input_message);
					describe_target = pq_getmsgstring(&input_message);
					pq_getmsgend(&input_message);
3827 3828 3829 3830 3831 3832 3833 3834 3835 3836

					switch (describe_type)
					{
						case 'S':
							exec_describe_statement_message(describe_target);
							break;
						case 'P':
							exec_describe_portal_message(describe_target);
							break;
						default:
3837 3838
							ereport(ERROR,
									(errcode(ERRCODE_PROTOCOL_VIOLATION),
B
Bruce Momjian 已提交
3839 3840
								errmsg("invalid DESCRIBE message subtype %d",
									   describe_type)));
3841 3842 3843 3844 3845
							break;
					}
				}
				break;

B
Bruce Momjian 已提交
3846
			case 'H':			/* flush */
3847
				pq_getmsgend(&input_message);
3848
				if (whereToSendOutput == DestRemote)
3849 3850 3851
					pq_flush();
				break;

B
Bruce Momjian 已提交
3852
			case 'S':			/* sync */
3853
				pq_getmsgend(&input_message);
3854
				finish_xact_command();
3855
				send_ready_for_query = true;
3856 3857
				break;

3858
				/*
B
Bruce Momjian 已提交
3859 3860 3861
				 * 'X' means that the frontend is closing down the socket. EOF
				 * means unexpected loss of frontend connection. Either way,
				 * perform normal shutdown.
3862 3863
				 */
			case 'X':
3864
			case EOF:
B
Bruce Momjian 已提交
3865

3866
				/*
B
Bruce Momjian 已提交
3867 3868
				 * Reset whereToSendOutput to prevent ereport from attempting
				 * to send any more messages to client.
3869
				 */
3870 3871
				if (whereToSendOutput == DestRemote)
					whereToSendOutput = DestNone;
B
Bruce Momjian 已提交
3872

3873 3874
				/*
				 * NOTE: if you are tempted to add more code here, DON'T!
B
Bruce Momjian 已提交
3875
				 * Whatever you had in mind to do should be set up as an
B
Bruce Momjian 已提交
3876 3877 3878
				 * on_proc_exit or on_shmem_exit callback, instead. Otherwise
				 * it will fail to be called during other backend-shutdown
				 * scenarios.
3879
				 */
3880
				proc_exit(0);
3881

B
Bruce Momjian 已提交
3882 3883 3884 3885
			case 'd':			/* copy data */
			case 'c':			/* copy done */
			case 'f':			/* copy fail */

3886
				/*
B
Bruce Momjian 已提交
3887
				 * Accept but ignore these messages, per protocol spec; we
B
Bruce Momjian 已提交
3888 3889
				 * probably got here because a COPY failed, and the frontend
				 * is still sending data.
3890 3891 3892
				 */
				break;

3893
			default:
3894 3895 3896 3897
				ereport(FATAL,
						(errcode(ERRCODE_PROTOCOL_VIOLATION),
						 errmsg("invalid frontend message type %d",
								firstchar)));
3898
		}
3899
	}							/* end of input-reading loop */
3900

3901 3902
	/* can't get here because the above loop never exits */
	Assert(false);
3903

3904
	return 1;					/* keep compiler quiet */
3905 3906
}

3907 3908 3909 3910 3911 3912 3913 3914 3915 3916 3917 3918 3919 3920 3921 3922 3923 3924 3925 3926 3927 3928 3929 3930 3931

/*
 * Obtain platform stack depth limit (in bytes)
 *
 * Return -1 if unlimited or not known
 */
long
get_stack_depth_rlimit(void)
{
#if defined(HAVE_GETRLIMIT) && defined(RLIMIT_STACK)
	static long val = 0;

	/* This won't change after process launch, so check just once */
	if (val == 0)
	{
		struct rlimit rlim;

		if (getrlimit(RLIMIT_STACK, &rlim) < 0)
			val = -1;
		else if (rlim.rlim_cur == RLIM_INFINITY)
			val = -1;
		else
			val = rlim.rlim_cur;
	}
	return val;
B
Bruce Momjian 已提交
3932
#else							/* no getrlimit */
3933 3934 3935
#if defined(WIN32) || defined(__CYGWIN__)
	/* On Windows we set the backend stack size in src/backend/Makefile */
	return WIN32_STACK_RLIMIT;
B
Bruce Momjian 已提交
3936
#else							/* not windows ... give up */
3937 3938
	return -1;
#endif
3939
#endif
3940 3941
}

3942

3943 3944
static struct rusage Save_r;
static struct timeval Save_t;
3945 3946

void
3947
ResetUsage(void)
3948
{
3949
	getrusage(RUSAGE_SELF, &Save_r);
3950
	gettimeofday(&Save_t, NULL);
3951 3952 3953
}

void
3954
ShowUsage(const char *title)
3955
{
3956
	StringInfoData str;
3957 3958 3959 3960
	struct timeval user,
				sys;
	struct timeval elapse_t;
	struct rusage r;
3961 3962

	getrusage(RUSAGE_SELF, &r);
3963
	gettimeofday(&elapse_t, NULL);
3964 3965
	memcpy((char *) &user, (char *) &r.ru_utime, sizeof(user));
	memcpy((char *) &sys, (char *) &r.ru_stime, sizeof(sys));
3966 3967 3968 3969 3970 3971 3972 3973 3974 3975 3976 3977 3978 3979 3980 3981 3982 3983
	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
B
Bruce Momjian 已提交
3984 3985 3986 3987
	 * 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.
3988
	 */
3989
	initStringInfo(&str);
3990

3991 3992
	appendStringInfo(&str, "! system usage stats:\n");
	appendStringInfo(&str,
B
Bruce Momjian 已提交
3993
				"!\t%ld.%06ld elapsed %ld.%06ld user %ld.%06ld system sec\n",
3994 3995 3996
					 (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 已提交
3997
					 (long) (r.ru_utime.tv_usec - Save_r.ru_utime.tv_usec),
3998
					 (long) (r.ru_stime.tv_sec - Save_r.ru_stime.tv_sec),
B
Bruce Momjian 已提交
3999
					 (long) (r.ru_stime.tv_usec - Save_r.ru_stime.tv_usec));
4000
	appendStringInfo(&str,
B
Bruce Momjian 已提交
4001
					 "!\t[%ld.%06ld user %ld.%06ld sys total]\n",
4002 4003 4004 4005
					 (long) user.tv_sec,
					 (long) user.tv_usec,
					 (long) sys.tv_sec,
					 (long) sys.tv_usec);
4006
#if defined(HAVE_GETRUSAGE)
4007
	appendStringInfo(&str,
B
Bruce Momjian 已提交
4008 4009
					 "!\t%ld/%ld [%ld/%ld] filesystem blocks in/out\n",
					 r.ru_inblock - Save_r.ru_inblock,
4010
	/* they only drink coffee at dec */
B
Bruce Momjian 已提交
4011 4012
					 r.ru_oublock - Save_r.ru_oublock,
					 r.ru_inblock, r.ru_oublock);
4013
	appendStringInfo(&str,
B
Bruce Momjian 已提交
4014
			  "!\t%ld/%ld [%ld/%ld] page faults/reclaims, %ld [%ld] swaps\n",
B
Bruce Momjian 已提交
4015 4016 4017 4018 4019
					 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);
4020
	appendStringInfo(&str,
B
Bruce Momjian 已提交
4021
		 "!\t%ld [%ld] signals rcvd, %ld/%ld [%ld/%ld] messages rcvd/sent\n",
B
Bruce Momjian 已提交
4022 4023 4024 4025 4026
					 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);
4027
	appendStringInfo(&str,
B
Bruce Momjian 已提交
4028
			 "!\t%ld/%ld [%ld/%ld] voluntary/involuntary context switches\n",
B
Bruce Momjian 已提交
4029 4030 4031
					 r.ru_nvcsw - Save_r.ru_nvcsw,
					 r.ru_nivcsw - Save_r.ru_nivcsw,
					 r.ru_nvcsw, r.ru_nivcsw);
4032
#endif   /* HAVE_GETRUSAGE */
4033 4034

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

4038 4039 4040
	ereport(LOG,
			(errmsg_internal("%s", title),
			 errdetail("%s", str.data)));
4041 4042

	pfree(str.data);
4043
}
4044 4045 4046 4047

/*
 * on_proc_exit handler to log end of session
 */
B
Bruce Momjian 已提交
4048
static void
4049
log_disconnections(int code, Datum arg)
4050
{
B
Bruce Momjian 已提交
4051
	Port	   *port = MyProcPort;
4052 4053 4054
	long		secs;
	int			usecs;
	int			msecs;
B
Bruce Momjian 已提交
4055 4056 4057
	int			hours,
				minutes,
				seconds;
4058

4059 4060 4061 4062
	TimestampDifference(port->SessionStartTime,
						GetCurrentTimestamp(),
						&secs, &usecs);
	msecs = usecs / 1000;
4063

4064 4065 4066 4067
	hours = secs / SECS_PER_HOUR;
	secs %= SECS_PER_HOUR;
	minutes = secs / SECS_PER_MINUTE;
	seconds = secs % SECS_PER_MINUTE;
4068

4069
	ereport(LOG,
4070
			(errmsg("disconnection: session time: %d:%02d:%02d.%03d "
4071
					"user=%s database=%s host=%s%s%s",
4072
					hours, minutes, seconds, msecs,
4073
					port->user_name, port->database_name, port->remote_host,
B
Bruce Momjian 已提交
4074
				  port->remote_port[0] ? " port=" : "", port->remote_port)));
4075
}