postgres.c 96.3 KB
Newer Older
1 2
/*-------------------------------------------------------------------------
 *
3
 * postgres.c
4
 *	  POSTGRES C Backend Interface
5
 *
6
 * Portions Copyright (c) 1996-2006, 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.511 2006/10/07 16:43:28 tgl Exp $
12 13
 *
 * NOTES
14 15
 *	  this is the "main" module of the postgres backend and
 *	  hence the main module of the "traffic cop".
16 17 18
 *
 *-------------------------------------------------------------------------
 */
B
Bruce Momjian 已提交
19

20 21
#include "postgres.h"

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

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

61
#include "pgstat.h"
M
 
Marc G. Fournier 已提交
62

63 64 65
extern int	optind;
extern char *optarg;

66
/* ----------------
67
 *		global variables
68 69
 * ----------------
 */
B
Bruce Momjian 已提交
70
const char *debug_query_string; /* for pgmonitor and log_min_error_statement */
71

72
/* Note: whereToSendOutput is initialized for the bootstrap/standalone case */
73
CommandDest whereToSendOutput = DestDebug;
74

75
/* flag for logging end of session */
B
Bruce Momjian 已提交
76
bool		Log_disconnections = false;
77

78 79
LogStmtLevel log_statement = LOGSTMT_NONE;

80 81 82
/* GUC variable for maximum stack depth (measured in kilobytes) */
int			max_stack_depth = 2048;

83 84 85 86
/* wait N seconds to allow attach from a debugger */
int			PostAuthDelay = 0;


87

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

93
/* max_stack_depth converted to bytes for speed of checking */
94
static long max_stack_depth_bytes = 2048 * 1024L;
95

N
Neil Conway 已提交
96 97 98 99
/*
 * Stack base pointer -- initialized by PostgresMain. This is not static
 * so that PL/Java can modify it.
 */
B
Bruce Momjian 已提交
100
char	   *stack_base_ptr = NULL;
101 102


103 104 105 106 107
/*
 * 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?)
 */
108
static volatile sig_atomic_t got_SIGHUP = false;
109

110 111 112 113 114 115
/*
 * 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;

116 117 118 119 120 121 122
/*
 * 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;

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

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


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

/*
 * people who want to use EOF should #define DONTUSENEWLINE in
 * tcop/tcopdebug.h
144 145
 */
#ifndef TCOP_DONTUSENEWLINE
B
Bruce Momjian 已提交
146
static int	UseNewLine = 1;		/* Use newlines query delimiters (the default) */
147
#else
148
static int	UseNewLine = 0;		/* Use EOF as query delimiters */
149
#endif   /* TCOP_DONTUSENEWLINE */
150 151 152


/* ----------------------------------------------------------------
153
 *		decls for routines only used in this file
154 155
 * ----------------------------------------------------------------
 */
156 157 158
static int	InteractiveBackend(StringInfo inBuf);
static int	SocketBackend(StringInfo inBuf);
static int	ReadCommand(StringInfo inBuf);
159
static List *pg_rewrite_queries(List *querytree_list);
160 161 162 163
static bool check_log_statement_raw(List *raw_parsetree_list);
static bool check_log_statement_cooked(List *parsetree_list);
static int	errdetail_execute(List *raw_parsetree_list);
static int	errdetail_params(ParamListInfo params);
164
static void start_xact_command(void);
165
static void finish_xact_command(void);
166 167 168
static bool IsTransactionExitStmt(Node *parsetree);
static bool IsTransactionExitStmtList(List *parseTrees);
static bool IsTransactionStmtList(List *parseTrees);
169
static void SigHupHandler(SIGNAL_ARGS);
170
static void log_disconnections(int code, Datum arg);
171 172 173


/* ----------------------------------------------------------------
174
 *		routines to obtain user input
175 176 177 178
 * ----------------------------------------------------------------
 */

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

188
static int
189
InteractiveBackend(StringInfo inBuf)
190
{
191 192 193
	int			c;				/* character read from getc() */
	bool		end = false;	/* end-of-input flag */
	bool		backslashSeen = false;	/* have we seen a \ ? */
194

195 196
	/*
	 * display a prompt and obtain input from the user
197
	 */
198
	printf("backend> ");
199
	fflush(stdout);
200

201 202 203
	/* Reset inBuf to empty */
	inBuf->len = 0;
	inBuf->data[0] = '\0';
204
	inBuf->cursor = 0;
205

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

237
				appendStringInfoChar(inBuf, (char) c);
238 239 240 241 242 243 244
			}

			if (c == EOF)
				end = true;
		}
		else
		{
245 246
			/*
			 * otherwise read characters until EOF.
247 248
			 */
			while ((c = getc(stdin)) != EOF)
249
				appendStringInfoChar(inBuf, (char) c);
250

251
			if (inBuf->len == 0)
252 253 254 255
				end = true;
		}

		if (end)
256
			return EOF;
257

258 259
		/*
		 * otherwise we have a user query so process it.
260 261 262 263
		 */
		break;
	}

264 265 266
	/* Add '\0' to make it look the same as message case. */
	appendStringInfoChar(inBuf, (char) '\0');

267 268
	/*
	 * if the query echo flag was given, print the query..
269 270
	 */
	if (EchoQuery)
271
		printf("statement: %s\n", inBuf->data);
272
	fflush(stdout);
273

274
	return 'Q';
275 276 277
}

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

290
	/*
291
	 * Get message type code from the frontend.
292
	 */
293
	qtype = pq_getbyte();
294

295 296
	if (qtype == EOF)			/* frontend disconnected */
	{
297 298 299
		ereport(COMMERROR,
				(errcode(ERRCODE_PROTOCOL_VIOLATION),
				 errmsg("unexpected EOF on client connection")));
300 301 302 303
		return qtype;
	}

	/*
B
Bruce Momjian 已提交
304 305 306
	 * 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.
307
	 *
308 309
	 * This also gives us a place to set the doing_extended_query_message flag
	 * as soon as possible.
310
	 */
311
	switch (qtype)
312
	{
313
		case 'Q':				/* simple query */
314
			doing_extended_query_message = false;
315 316 317 318 319
			if (PG_PROTOCOL_MAJOR(FrontendProtocol) < 3)
			{
				/* old style without length word; convert */
				if (pq_getstring(inBuf))
				{
320 321
					ereport(COMMERROR,
							(errcode(ERRCODE_PROTOCOL_VIOLATION),
B
Bruce Momjian 已提交
322
							 errmsg("unexpected EOF on client connection")));
323 324 325
					return EOF;
				}
			}
326 327
			break;

328
		case 'F':				/* fastpath function call */
329 330
			/* we let fastpath.c cope with old-style input of this */
			doing_extended_query_message = false;
331
			break;
332

333
		case 'X':				/* terminate */
334
			doing_extended_query_message = false;
335
			ignore_till_sync = false;
336 337 338 339 340 341 342 343 344 345 346
			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)
347 348
				ereport(FATAL,
						(errcode(ERRCODE_PROTOCOL_VIOLATION),
B
Bruce Momjian 已提交
349
						 errmsg("invalid frontend message type %d", qtype)));
350 351 352 353 354 355 356 357 358
			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)
359 360
				ereport(FATAL,
						(errcode(ERRCODE_PROTOCOL_VIOLATION),
B
Bruce Momjian 已提交
361
						 errmsg("invalid frontend message type %d", qtype)));
362
			break;
363

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

375
		default:
B
Bruce Momjian 已提交
376

377
			/*
B
Bruce Momjian 已提交
378 379 380
			 * 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.
381
			 */
382 383 384
			ereport(FATAL,
					(errcode(ERRCODE_PROTOCOL_VIOLATION),
					 errmsg("invalid frontend message type %d", qtype)));
385
			break;
386
	}
387

388
	/*
B
Bruce Momjian 已提交
389 390 391
	 * 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.
392 393 394 395 396 397 398
	 */
	if (PG_PROTOCOL_MAJOR(FrontendProtocol) >= 3)
	{
		if (pq_getmessage(inBuf, 0))
			return EOF;			/* suitable message already logged */
	}

399
	return qtype;
400 401 402
}

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

414
	if (whereToSendOutput == DestRemote)
415
		result = SocketBackend(inBuf);
416
	else
417 418
		result = InteractiveBackend(inBuf);
	return result;
419 420
}

421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466
/*
 * 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();
	}
}

467 468 469 470 471 472

/*
 * 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.
473 474 475
 *
 * NOTE: this routine is no longer used for processing interactive queries,
 * but it is still needed for parsing of SQL function bodies.
476
 */
477
List *
B
Bruce Momjian 已提交
478
pg_parse_and_rewrite(const char *query_string,	/* string to execute */
479
					 Oid *paramTypes,	/* parameter types */
B
Bruce Momjian 已提交
480
					 int numParams)		/* number of parameters */
481
{
482
	List	   *raw_parsetree_list;
483
	List	   *querytree_list;
484
	ListCell   *list_item;
485

486 487
	/*
	 * (1) parse the request string into a list of raw parse trees.
488
	 */
489
	raw_parsetree_list = pg_parse_query(query_string);
490

491 492
	/*
	 * (2) Do parse analysis and rule rewrite.
493 494 495 496
	 */
	querytree_list = NIL;
	foreach(list_item, raw_parsetree_list)
	{
B
Bruce Momjian 已提交
497
		Node	   *parsetree = (Node *) lfirst(list_item);
498

499
		querytree_list = list_concat(querytree_list,
B
Bruce Momjian 已提交
500
									 pg_analyze_and_rewrite(parsetree,
501
															query_string,
B
Bruce Momjian 已提交
502 503
															paramTypes,
															numParams));
504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521
	}

	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.
 */
522
List *
523
pg_parse_query(const char *query_string)
524
{
525
	List	   *raw_parsetree_list;
526

B
Rename:  
Bruce Momjian 已提交
527
	if (log_parser_stats)
528 529
		ResetUsage();

530
	raw_parsetree_list = raw_parser(query_string);
531

532 533 534 535 536 537
	if (log_parser_stats)
		ShowUsage("PARSER STATISTICS");

	return raw_parsetree_list;
}

538
/*
539 540
 * Given a raw parsetree (gram.y output), and optionally information about
 * types of parameter symbols ($n), perform parse analysis and rule rewriting.
541 542 543 544 545 546
 *
 * 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.
 */
547
List *
548 549
pg_analyze_and_rewrite(Node *parsetree, const char *query_string,
					   Oid *paramTypes, int numParams)
550 551 552
{
	List	   *querytree_list;

553 554
	/*
	 * (1) Perform parse analysis.
555
	 */
B
Rename:  
Bruce Momjian 已提交
556
	if (log_parser_stats)
557 558
		ResetUsage();

559 560
	querytree_list = parse_analyze(parsetree, query_string,
								   paramTypes, numParams);
561

B
Rename:  
Bruce Momjian 已提交
562
	if (log_parser_stats)
563
		ShowUsage("PARSE ANALYSIS STATISTICS");
564

565 566
	/*
	 * (2) Rewrite the queries, as necessary
567 568 569 570 571 572 573 574
	 */
	querytree_list = pg_rewrite_queries(querytree_list);

	return querytree_list;
}

/*
 * Perform rewriting of a list of queries produced by parse analysis.
575 576 577
 *
 * Note: queries must just have come from the parser, because we do not do
 * AcquireRewriteLocks() on them.
578
 */
579
static List *
580 581 582
pg_rewrite_queries(List *querytree_list)
{
	List	   *new_list = NIL;
583
	ListCell   *list_item;
584 585 586 587 588

	if (log_parser_stats)
		ResetUsage();

	/*
B
Bruce Momjian 已提交
589 590
	 * rewritten queries are collected in new_list.  Note there may be more or
	 * fewer than in the original list.
591
	 */
592
	foreach(list_item, querytree_list)
593
	{
594
		Query	   *querytree = (Query *) lfirst(list_item);
595

596
		if (Debug_print_parse)
597
			elog_node_display(DEBUG1, "parse tree", querytree,
598
							  Debug_pretty_print);
599 600 601

		if (querytree->commandType == CMD_UTILITY)
		{
602 603
			/* don't rewrite utilities, just dump 'em into new_list */
			new_list = lappend(new_list, querytree);
604
		}
605
		else
606
		{
607
			/* rewrite regular queries */
608 609
			List	   *rewritten = QueryRewrite(querytree);

610
			new_list = list_concat(new_list, rewritten);
611 612 613 614 615
		}
	}

	querytree_list = new_list;

B
Rename:  
Bruce Momjian 已提交
616
	if (log_parser_stats)
617
		ShowUsage("REWRITER STATISTICS");
618

619
#ifdef COPY_PARSE_PLAN_TREES
B
Bruce Momjian 已提交
620 621

	/*
B
Bruce Momjian 已提交
622
	 * Optional debugging check: pass querytree output through copyObject()
B
Bruce Momjian 已提交
623
	 */
624 625
	new_list = (List *) copyObject(querytree_list);
	/* This checks both copyObject() and the equal() routines... */
B
Bruce Momjian 已提交
626
	if (!equal(new_list, querytree_list))
627
		elog(WARNING, "copyObject() failed to produce an equal parse tree");
628 629
	else
		querytree_list = new_list;
630 631
#endif

632
	if (Debug_print_rewritten)
633
		elog_node_display(DEBUG1, "rewritten parse tree", querytree_list,
634
						  Debug_pretty_print);
635

636 637
	return querytree_list;
}
638 639


640
/* Generate a plan for a single already-rewritten query. */
641
Plan *
642
pg_plan_query(Query *querytree, ParamListInfo boundParams)
643 644
{
	Plan	   *plan;
645

646 647 648
	/* Utility commands have no plans. */
	if (querytree->commandType == CMD_UTILITY)
		return NULL;
649

B
Rename:  
Bruce Momjian 已提交
650
	if (log_planner_stats)
651
		ResetUsage();
652

653
	/* call the optimizer */
654
	plan = planner(querytree, false, 0, boundParams);
655

B
Rename:  
Bruce Momjian 已提交
656
	if (log_planner_stats)
657
		ShowUsage("PLANNER STATISTICS");
658

659 660 661
#ifdef COPY_PARSE_PLAN_TREES
	/* Optional debugging check: pass plan output through copyObject() */
	{
B
Bruce Momjian 已提交
662
		Plan	   *new_plan = (Plan *) copyObject(plan);
663

B
Bruce Momjian 已提交
664
		/*
B
Bruce Momjian 已提交
665 666
		 * equal() currently does not have routines to compare Plan nodes, so
		 * don't try to test equality here.  Perhaps fix someday?
667 668 669
		 */
#ifdef NOT_USED
		/* This checks both copyObject() and the equal() routines... */
B
Bruce Momjian 已提交
670
		if (!equal(new_plan, plan))
671
			elog(WARNING, "copyObject() failed to produce an equal plan tree");
672 673 674 675 676 677
		else
#endif
			plan = new_plan;
	}
#endif

678 679
	/*
	 * Print plan if debugging.
680
	 */
681
	if (Debug_print_plan)
682
		elog_node_display(DEBUG1, "plan", plan, Debug_pretty_print);
683

684
	return plan;
685 686
}

687 688
/*
 * Generate plans for a list of already-rewritten queries.
689
 *
690 691 692 693 694 695 696 697 698
 * If needSnapshot is TRUE, we haven't yet set a snapshot for the current
 * query.  A snapshot must be set before invoking the planner, since it
 * might try to evaluate user-defined functions.  But we must not set a
 * snapshot if the list contains only utility statements, because some
 * utility statements depend on not having frozen the snapshot yet.
 * (We assume that such statements cannot appear together with plannable
 * statements in the rewriter's output.)
 */
List *
699 700
pg_plan_queries(List *querytrees, ParamListInfo boundParams,
				bool needSnapshot)
701 702
{
	List	   *plan_list = NIL;
703
	ListCell   *query_list;
704 705 706 707 708 709 710 711 712 713 714 715 716 717 718

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

		if (query->commandType == CMD_UTILITY)
		{
			/* Utility commands have no plans. */
			plan = NULL;
		}
		else
		{
			if (needSnapshot)
			{
719
				ActiveSnapshot = CopySnapshot(GetTransactionSnapshot());
720 721
				needSnapshot = false;
			}
722
			plan = pg_plan_query(query, boundParams);
723 724 725 726 727 728 729 730 731 732
		}

		plan_list = lappend(plan_list, plan);
	}

	return plan_list;
}


/*
733
 * exec_simple_query
734
 *
735
 * Execute a "simple Query" protocol message.
736
 */
737
static void
738
exec_simple_query(const char *query_string)
739
{
B
Bruce Momjian 已提交
740
	CommandDest dest = whereToSendOutput;
741
	MemoryContext oldcontext;
742 743
	List	   *parsetree_list;
	ListCell   *parsetree_item;
744
	bool		save_log_statement_stats = log_statement_stats;
745
	bool		was_logged = false;
746
	char		msec_str[32];
B
Bruce Momjian 已提交
747

748 749 750
	/*
	 * Report query to various monitoring facilities.
	 */
751
	debug_query_string = query_string;
752

753 754
	pgstat_report_activity(query_string);

755
	/*
756 757
	 * We use save_log_statement_stats so ShowUsage doesn't report incorrect
	 * results because ResetUsage wasn't called.
758
	 */
759 760 761
	if (save_log_statement_stats)
		ResetUsage();

762
	/*
B
Bruce Momjian 已提交
763 764
	 * 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 已提交
765 766 767
	 * 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.)
768
	 */
769
	start_xact_command();
770 771

	/*
B
Bruce Momjian 已提交
772 773 774 775
	 * 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.)
776 777 778 779 780 781 782 783
	 */
	unnamed_stmt_pstmt = NULL;
	if (unnamed_stmt_context)
	{
		DropDependentPortals(unnamed_stmt_context);
		MemoryContextDelete(unnamed_stmt_context);
	}
	unnamed_stmt_context = NULL;
784

785 786 787
	/*
	 * Switch to appropriate context for constructing parsetrees.
	 */
788
	oldcontext = MemoryContextSwitchTo(MessageContext);
789

790 791
	QueryContext = CurrentMemoryContext;

B
Bruce Momjian 已提交
792
	/*
B
Bruce Momjian 已提交
793 794
	 * Do basic parsing of the query or queries (this should be safe even if
	 * we are in aborted transaction state!)
795
	 */
796
	parsetree_list = pg_parse_query(query_string);
797

798
	/* Log immediately if dictated by log_statement */
799 800 801 802 803 804 805
	if (check_log_statement_raw(parsetree_list))
	{
		ereport(LOG,
				(errmsg("statement: %s", query_string),
				 errdetail_execute(parsetree_list)));
		was_logged = true;
	}
806

807
	/*
808
	 * Switch back to transaction context to enter the loop.
809 810 811 812
	 */
	MemoryContextSwitchTo(oldcontext);

	/*
813
	 * Run through the raw parsetree(s) and process each one.
814
	 */
815
	foreach(parsetree_item, parsetree_list)
816
	{
B
Bruce Momjian 已提交
817
		Node	   *parsetree = (Node *) lfirst(parsetree_item);
818 819
		const char *commandTag;
		char		completionTag[COMPLETION_TAG_BUFSIZE];
B
Bruce Momjian 已提交
820
		List	   *querytree_list,
821 822
				   *plantree_list;
		Portal		portal;
823 824
		DestReceiver *receiver;
		int16		format;
825

826
		/*
B
Bruce Momjian 已提交
827 828 829 830
		 * 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.
831 832 833
		 */
		commandTag = CreateCommandTag(parsetree);

834
		set_ps_display(commandTag, false);
835

836
		BeginCommand(commandTag, dest);
837

838
		/*
839
		 * If we are in an aborted transaction, reject all commands except
B
Bruce Momjian 已提交
840 841 842 843 844
		 * 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...)
845
		 */
846 847 848 849 850
		if (IsAbortedTransactionBlockState() &&
			!IsTransactionExitStmt(parsetree))
			ereport(ERROR,
					(errcode(ERRCODE_IN_FAILED_SQL_TRANSACTION),
					 errmsg("current transaction is aborted, "
B
Bruce Momjian 已提交
851
						"commands ignored until end of transaction block")));
852

853
		/* Make sure we are in a transaction command */
854
		start_xact_command();
855

856
		/* If we got a cancel signal in parsing or prior command, quit */
857
		CHECK_FOR_INTERRUPTS();
858 859

		/*
860
		 * OK to analyze, rewrite, and plan this query.
861
		 *
B
Bruce Momjian 已提交
862 863
		 * Switch to appropriate context for constructing querytrees (again,
		 * these must outlive the execution context).
864
		 */
865
		oldcontext = MemoryContextSwitchTo(MessageContext);
866

867 868
		querytree_list = pg_analyze_and_rewrite(parsetree, query_string,
												NULL, 0);
V
Vadim B. Mikheev 已提交
869

870
		plantree_list = pg_plan_queries(querytree_list, NULL, true);
871 872 873 874

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

875
		/*
B
Bruce Momjian 已提交
876 877
		 * Create unnamed portal to run the query or queries in. If there
		 * already is one, silently drop it.
878
		 */
879
		portal = CreatePortal("", true, true);
880 881
		/* Don't display the portal in pg_cursors */
		portal->visible = false;
882

883
		PortalDefineQuery(portal,
884
						  NULL,
885 886 887 888 889
						  query_string,
						  commandTag,
						  querytree_list,
						  plantree_list,
						  MessageContext);
890

891
		/*
892
		 * Start the portal.  No parameters here.
893
		 */
894
		PortalStart(portal, NULL, InvalidSnapshot);
895

896
		/*
B
Bruce Momjian 已提交
897 898 899 900
		 * 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...)
901 902 903 904 905 906 907 908 909 910 911 912
		 */
		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 已提交
913
					format = 1; /* BINARY */
914 915 916 917 918 919 920 921 922 923 924 925 926 927 928
			}
		}
		PortalSetResultFormat(portal, 1, &format);

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

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

		/*
B
Bruce Momjian 已提交
929
		 * Run the portal to completion, and then drop it (and the receiver).
930
		 */
931 932
		(void) PortalRun(portal,
						 FETCH_ALL,
933 934
						 receiver,
						 receiver,
935
						 completionTag);
936

937
		(*receiver->rDestroy) (receiver);
938

939
		PortalDrop(portal, false);
940

941
		if (IsA(parsetree, TransactionStmt))
942
		{
943
			/*
B
Bruce Momjian 已提交
944 945
			 * If this was a transaction control statement, commit it. We will
			 * start a new xact command for the next command (if any).
946
			 */
947
			finish_xact_command();
948
		}
949
		else if (lnext(parsetree_item) == NULL)
950
		{
951
			/*
B
Bruce Momjian 已提交
952 953 954 955 956 957 958 959
			 * 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.
960
			 */
961
			finish_xact_command();
962
		}
963
		else
964
		{
965
			/*
B
Bruce Momjian 已提交
966 967
			 * We need a CommandCounterIncrement after every query, except
			 * those that start or end a transaction block.
968 969
			 */
			CommandCounterIncrement();
970
		}
971 972

		/*
B
Bruce Momjian 已提交
973 974 975 976
		 * 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.)
977
		 */
978
		EndCommand(completionTag, dest);
B
Bruce Momjian 已提交
979
	}							/* end loop over parsetrees */
980

981 982 983
	/*
	 * Close down transaction statement, if one is open.
	 */
984
	finish_xact_command();
985

986 987 988
	/*
	 * If there were no parsetrees, return EmptyQueryResponse message.
	 */
989
	if (!parsetree_list)
990 991
		NullCommand(dest);

992
	QueryContext = NULL;
993

994
	/*
995
	 * Emit duration logging if appropriate.
996
	 */
997
	switch (check_log_duration(msec_str, was_logged))
998
	{
999
		case 1:
1000 1001
			ereport(LOG,
					(errmsg("duration: %s ms", msec_str)));
1002 1003
			break;
		case 2:
1004 1005 1006 1007
			ereport(LOG,
					(errmsg("duration: %s ms  statement: %s",
							msec_str, query_string),
					 errdetail_execute(parsetree_list)));
1008
			break;
1009
	}
1010

1011 1012 1013
	if (save_log_statement_stats)
		ShowUsage("QUERY STATISTICS");

1014
	debug_query_string = NULL;
1015 1016
}

1017 1018 1019 1020 1021 1022 1023 1024
/*
 * 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 已提交
1025 1026
				   Oid *paramTypes,		/* parameter types */
				   int numParams)		/* number of parameters */
1027 1028 1029 1030 1031 1032 1033 1034 1035
{
	MemoryContext oldcontext;
	List	   *parsetree_list;
	const char *commandTag;
	List	   *querytree_list,
			   *plantree_list,
			   *param_list;
	bool		is_named;
	bool		save_log_statement_stats = log_statement_stats;
1036
	char		msec_str[32];
1037 1038 1039 1040 1041 1042 1043 1044

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

	pgstat_report_activity(query_string);

1045
	set_ps_display("PARSE", false);
1046 1047 1048 1049

	if (save_log_statement_stats)
		ResetUsage();

1050 1051 1052 1053
	ereport(DEBUG2,
			(errmsg("parse %s: %s",
					*stmt_name ? stmt_name : "<unnamed>",
					query_string)));
1054

1055
	/*
B
Bruce Momjian 已提交
1056 1057 1058
	 * 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.
1059
	 */
1060
	start_xact_command();
1061 1062 1063 1064

	/*
	 * Switch to appropriate context for constructing parsetrees.
	 *
B
Bruce Momjian 已提交
1065 1066 1067
	 * 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
B
Bruce Momjian 已提交
1068 1069 1070 1071 1072
	 * statement's private context; then the reset of MessageContext releases
	 * temporary space used by parsing and planning.  For an unnamed prepared
	 * statement, we assume the statement isn't going to hang around long, so
	 * getting rid of temp space quickly is probably not worth the costs of
	 * copying parse/plan trees.  So in this case, we set up a special context
1073
	 * for the unnamed statement, and do all the parsing work therein.
1074 1075 1076 1077 1078 1079 1080 1081 1082 1083 1084 1085 1086 1087 1088 1089 1090 1091 1092 1093 1094 1095 1096 1097 1098 1099 1100 1101 1102 1103
	 */
	is_named = (stmt_name[0] != '\0');
	if (is_named)
	{
		/* Named prepared statement --- parse in MessageContext */
		oldcontext = MemoryContextSwitchTo(MessageContext);
	}
	else
	{
		/* Unnamed prepared statement --- release any prior unnamed stmt */
		unnamed_stmt_pstmt = NULL;
		if (unnamed_stmt_context)
		{
			DropDependentPortals(unnamed_stmt_context);
			MemoryContextDelete(unnamed_stmt_context);
		}
		unnamed_stmt_context = NULL;
		/* create context for parsing/planning */
		unnamed_stmt_context =
			AllocSetContextCreate(TopMemoryContext,
								  "unnamed prepared statement",
								  ALLOCSET_DEFAULT_MINSIZE,
								  ALLOCSET_DEFAULT_INITSIZE,
								  ALLOCSET_DEFAULT_MAXSIZE);
		oldcontext = MemoryContextSwitchTo(unnamed_stmt_context);
	}

	QueryContext = CurrentMemoryContext;

	/*
B
Bruce Momjian 已提交
1104 1105
	 * Do basic parsing of the query or queries (this should be safe even if
	 * we are in aborted transaction state!)
1106 1107 1108 1109
	 */
	parsetree_list = pg_parse_query(query_string);

	/*
B
Bruce Momjian 已提交
1110 1111 1112
	 * 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.
1113
	 */
1114
	if (list_length(parsetree_list) > 1)
1115 1116
		ereport(ERROR,
				(errcode(ERRCODE_SYNTAX_ERROR),
B
Bruce Momjian 已提交
1117
		errmsg("cannot insert multiple commands into a prepared statement")));
1118 1119 1120

	if (parsetree_list != NIL)
	{
1121
		Node	   *parsetree = (Node *) linitial(parsetree_list);
B
Bruce Momjian 已提交
1122
		int			i;
1123 1124 1125 1126 1127 1128 1129 1130

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

		/*
		 * If we are in an aborted transaction, reject all commands except
B
Bruce Momjian 已提交
1131 1132 1133 1134 1135
		 * 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...)
1136
		 */
1137 1138 1139 1140 1141
		if (IsAbortedTransactionBlockState() &&
			!IsTransactionExitStmt(parsetree))
			ereport(ERROR,
					(errcode(ERRCODE_IN_FAILED_SQL_TRANSACTION),
					 errmsg("current transaction is aborted, "
B
Bruce Momjian 已提交
1142
						"commands ignored until end of transaction block")));
1143 1144 1145

		/*
		 * OK to analyze, rewrite, and plan this query.  Note that the
B
Bruce Momjian 已提交
1146 1147
		 * originally specified parameter set is not required to be complete,
		 * so we have to use parse_analyze_varparams().
1148 1149 1150 1151 1152
		 */
		if (log_parser_stats)
			ResetUsage();

		querytree_list = parse_analyze_varparams(parsetree,
1153
												 query_string,
1154 1155 1156 1157 1158 1159 1160 1161 1162 1163
												 &paramTypes,
												 &numParams);

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

			if (ptype == InvalidOid || ptype == UNKNOWNOID)
1167 1168
				ereport(ERROR,
						(errcode(ERRCODE_INDETERMINATE_DATATYPE),
B
Bruce Momjian 已提交
1169 1170
					 errmsg("could not determine data type of parameter $%d",
							i + 1)));
1171
			param_list = lappend_oid(param_list, ptype);
1172 1173 1174 1175 1176 1177 1178
		}

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

		querytree_list = pg_rewrite_queries(querytree_list);

1179
		/*
B
Bruce Momjian 已提交
1180 1181
		 * If this is the unnamed statement and it has parameters, defer query
		 * planning until Bind.  Otherwise do it now.
1182 1183 1184 1185 1186
		 */
		if (!is_named && numParams > 0)
			plantree_list = NIL;
		else
			plantree_list = pg_plan_queries(querytree_list, NULL, true);
1187 1188 1189
	}
	else
	{
B
Bruce Momjian 已提交
1190
		/* Empty input string.	This is legal. */
1191 1192 1193 1194 1195 1196 1197 1198 1199 1200 1201 1202 1203 1204 1205 1206 1207 1208 1209
		commandTag = NULL;
		querytree_list = NIL;
		plantree_list = NIL;
		param_list = NIL;
	}

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

	/*
	 * Store the query as a prepared statement.  See above comments.
	 */
	if (is_named)
	{
		StorePreparedStatement(stmt_name,
							   query_string,
							   commandTag,
							   querytree_list,
							   plantree_list,
1210 1211
							   param_list,
							   false);
1212 1213 1214 1215 1216 1217 1218 1219 1220 1221 1222 1223 1224
	}
	else
	{
		PreparedStatement *pstmt;

		pstmt = (PreparedStatement *) palloc0(sizeof(PreparedStatement));
		/* query_string needs to be copied into unnamed_stmt_context */
		pstmt->query_string = pstrdup(query_string);
		/* the rest is there already */
		pstmt->commandTag = commandTag;
		pstmt->query_list = querytree_list;
		pstmt->plan_list = plantree_list;
		pstmt->argtype_list = param_list;
1225
		pstmt->from_sql = false;
1226 1227 1228 1229 1230 1231 1232 1233 1234 1235
		pstmt->context = unnamed_stmt_context;
		/* Now the unnamed statement is complete and valid */
		unnamed_stmt_pstmt = pstmt;
	}

	MemoryContextSwitchTo(oldcontext);

	QueryContext = NULL;

	/*
B
Bruce Momjian 已提交
1236 1237 1238
	 * 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.
1239 1240 1241 1242 1243 1244
	 */
	CommandCounterIncrement();

	/*
	 * Send ParseComplete.
	 */
1245
	if (whereToSendOutput == DestRemote)
1246 1247
		pq_putemptymessage('1');

1248 1249 1250
	/*
	 * Emit duration logging if appropriate.
	 */
1251 1252 1253 1254 1255 1256 1257 1258 1259 1260 1261 1262 1263 1264
	switch (check_log_duration(msec_str, false))
	{
		case 1:
			ereport(LOG,
					(errmsg("duration: %s ms", msec_str)));
			break;
		case 2:
			ereport(LOG,
					(errmsg("duration: %s ms  parse %s: %s",
							msec_str,
							*stmt_name ? stmt_name : "<unnamed>",
							query_string)));
			break;
	}
1265

1266 1267 1268 1269 1270 1271 1272 1273 1274 1275 1276 1277 1278 1279 1280 1281
	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;
1282 1283
	int			numPFormats;
	int16	   *pformats = NULL;
1284
	int			numParams;
1285 1286
	int			numRFormats;
	int16	   *rformats = NULL;
1287 1288 1289
	PreparedStatement *pstmt;
	Portal		portal;
	ParamListInfo params;
1290
	List	   *plan_list;
1291 1292 1293 1294 1295 1296 1297 1298 1299 1300 1301 1302 1303 1304 1305 1306 1307 1308 1309 1310 1311 1312 1313 1314 1315 1316 1317 1318 1319 1320
	MemoryContext qContext;
	bool		save_log_statement_stats = log_statement_stats;
	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')
		pstmt = FetchPreparedStatement(stmt_name, true);
	else
	{
		/* special-case the unnamed statement */
		pstmt = unnamed_stmt_pstmt;
		if (!pstmt)
			ereport(ERROR,
					(errcode(ERRCODE_UNDEFINED_PSTATEMENT),
					 errmsg("unnamed prepared statement does not exist")));
	}

	/*
	 * Report query to various monitoring facilities.
	 */
	debug_query_string = "bind message";
1321

1322
	pgstat_report_activity(pstmt->query_string ? pstmt->query_string : "<BIND>");
1323

1324
	set_ps_display("BIND", false);
1325

1326 1327 1328
	if (save_log_statement_stats)
		ResetUsage();

1329
	/*
B
Bruce Momjian 已提交
1330 1331 1332
	 * 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.
1333
	 */
1334
	start_xact_command();
1335

1336 1337 1338 1339 1340 1341 1342
	/* Switch back to message context */
	MemoryContextSwitchTo(MessageContext);

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

1345 1346 1347 1348 1349 1350 1351 1352 1353
		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)
1354 1355
		ereport(ERROR,
				(errcode(ERRCODE_PROTOCOL_VIOLATION),
B
Bruce Momjian 已提交
1356 1357
			errmsg("bind message has %d parameter formats but %d parameters",
				   numPFormats, numParams)));
1358

1359
	if (numParams != list_length(pstmt->argtype_list))
1360 1361 1362
		ereport(ERROR,
				(errcode(ERRCODE_PROTOCOL_VIOLATION),
				 errmsg("bind message supplies %d parameters, but prepared statement \"%s\" requires %d",
B
Bruce Momjian 已提交
1363
				   numParams, stmt_name, list_length(pstmt->argtype_list))));
1364

1365 1366
	/*
	 * If we are in aborted transaction state, the only portals we can
1367 1368 1369 1370 1371
	 * 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.
1372 1373 1374 1375 1376 1377 1378 1379 1380
	 */
	if (IsAbortedTransactionBlockState() &&
		(!IsTransactionExitStmtList(pstmt->query_list) ||
		 numParams != 0))
		ereport(ERROR,
				(errcode(ERRCODE_IN_FAILED_SQL_TRANSACTION),
				 errmsg("current transaction is aborted, "
						"commands ignored until end of transaction block")));

1381
	/*
B
Bruce Momjian 已提交
1382 1383
	 * Create the portal.  Allow silent replacement of an existing portal only
	 * if the unnamed portal is specified.
1384 1385 1386 1387 1388 1389 1390 1391 1392 1393 1394
	 */
	if (portal_name[0] == '\0')
		portal = CreatePortal(portal_name, true, true);
	else
		portal = CreatePortal(portal_name, false, false);

	/*
	 * Fetch parameters, if any, and store in the portal's memory context.
	 */
	if (numParams > 0)
	{
1395
		ListCell   *l;
1396
		MemoryContext oldContext;
1397
		int			paramno;
1398 1399 1400

		oldContext = MemoryContextSwitchTo(PortalGetHeapMemory(portal));

1401 1402
		/* sizeof(ParamListInfoData) includes the first array element */
		params = (ParamListInfo) palloc(sizeof(ParamListInfoData) +
B
Bruce Momjian 已提交
1403
								   (numParams - 1) *sizeof(ParamExternData));
1404
		params->numParams = numParams;
1405

1406
		paramno = 0;
1407 1408
		foreach(l, pstmt->argtype_list)
		{
1409
			Oid			ptype = lfirst_oid(l);
1410
			int32		plength;
1411
			Datum		pval;
1412
			bool		isNull;
1413 1414 1415
			StringInfoData pbuf;
			char		csave;
			int16		pformat;
1416

1417 1418 1419
			plength = pq_getmsgint(input_message, 4);
			isNull = (plength == -1);

1420 1421
			if (!isNull)
			{
1422
				const char *pvalue = pq_getmsgbytes(input_message, plength);
1423 1424 1425

				/*
				 * Rather than copying data around, we just set up a phony
1426 1427 1428 1429 1430
				 * 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.
1431 1432 1433 1434 1435 1436 1437 1438
				 */
				pbuf.data = (char *) pvalue;
				pbuf.maxlen = plength + 1;
				pbuf.len = plength;
				pbuf.cursor = 0;

				csave = pbuf.data[plength];
				pbuf.data[plength] = '\0';
1439 1440 1441 1442 1443 1444
			}
			else
			{
				pbuf.data = NULL;		/* keep compiler quiet */
				csave = 0;
			}
1445

1446
			if (numPFormats > 1)
1447
				pformat = pformats[paramno];
1448 1449 1450 1451 1452
			else if (numPFormats > 0)
				pformat = pformats[0];
			else
				pformat = 0;	/* default = text */

1453
			if (pformat == 0)	/* text mode */
1454 1455 1456
			{
				Oid			typinput;
				Oid			typioparam;
1457
				char	   *pstring;
1458

1459
				getTypeInputInfo(ptype, &typinput, &typioparam);
1460

1461 1462 1463 1464 1465 1466 1467
				/*
				 * We have to do encoding conversion before calling the
				 * typinput routine.
				 */
				if (isNull)
					pstring = NULL;
				else
1468
					pstring = pg_client_to_server(pbuf.data, plength);
1469

1470
				pval = OidInputFunctionCall(typinput, pstring, typioparam, -1);
1471

1472 1473 1474 1475
				/* Free result of encoding conversion, if any */
				if (pstring && pstring != pbuf.data)
					pfree(pstring);
			}
B
Bruce Momjian 已提交
1476
			else if (pformat == 1)		/* binary mode */
1477 1478 1479 1480 1481 1482 1483 1484 1485 1486 1487 1488
			{
				Oid			typreceive;
				Oid			typioparam;
				StringInfo	bufptr;

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

				if (isNull)
					bufptr = NULL;
1489
				else
1490 1491
					bufptr = &pbuf;

1492
				pval = OidReceiveFunctionCall(typreceive, bufptr, typioparam, -1);
1493 1494 1495

				/* Trouble if it didn't eat the whole buffer */
				if (!isNull && pbuf.cursor != pbuf.len)
1496
					ereport(ERROR,
1497 1498
							(errcode(ERRCODE_INVALID_BINARY_REPRESENTATION),
							 errmsg("incorrect binary data format in bind parameter %d",
1499
									paramno + 1)));
1500 1501 1502 1503 1504 1505 1506
			}
			else
			{
				ereport(ERROR,
						(errcode(ERRCODE_INVALID_PARAMETER_VALUE),
						 errmsg("unsupported format code: %d",
								pformat)));
1507
				pval = 0;		/* keep compiler quiet */
1508
			}
1509

1510 1511
			/* Restore message buffer contents */
			if (!isNull)
1512
				pbuf.data[plength] = csave;
1513

1514
			params->params[paramno].value = pval;
1515
			params->params[paramno].isnull = isNull;
B
Bruce Momjian 已提交
1516

1517 1518 1519 1520 1521 1522 1523
			/*
			 * 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;
1524
			params->params[paramno].ptype = ptype;
1525

1526
			paramno++;
1527 1528 1529 1530 1531 1532 1533
		}

		MemoryContextSwitchTo(oldContext);
	}
	else
		params = NULL;

1534 1535 1536 1537
	/* Get the result format codes */
	numRFormats = pq_getmsgint(input_message, 2);
	if (numRFormats > 0)
	{
B
Bruce Momjian 已提交
1538
		int			i;
1539

1540 1541 1542 1543 1544
		rformats = (int16 *) palloc(numRFormats * sizeof(int16));
		for (i = 0; i < numRFormats; i++)
			rformats[i] = pq_getmsgint(input_message, 2);
	}

1545 1546 1547
	pq_getmsgend(input_message);

	/*
B
Bruce Momjian 已提交
1548
	 * If we didn't plan the query before, do it now.  This allows the planner
1549 1550 1551
	 * 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
B
Bruce Momjian 已提交
1552 1553 1554
	 * 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.
1555
	 *
B
Bruce Momjian 已提交
1556 1557 1558 1559
	 * XXX because the planner has a bad habit of scribbling on its input, we
	 * have to make a copy of the parse trees, just in case someone binds and
	 * executes an unnamed statement multiple times; this also means that the
	 * portal's queryContext becomes its own heap context rather than the
1560
	 * prepared statement's context.  FIXME someday
1561
	 */
1562
	if (pstmt->plan_list == NIL && pstmt->query_list != NIL)
1563
	{
1564
		MemoryContext oldContext;
1565

1566 1567
		qContext = PortalGetHeapMemory(portal);
		oldContext = MemoryContextSwitchTo(qContext);
1568 1569 1570
		plan_list = pg_plan_queries(copyObject(pstmt->query_list),
									params,
									true);
1571 1572
		MemoryContextSwitchTo(oldContext);
	}
1573
	else
1574
	{
1575
		plan_list = pstmt->plan_list;
1576 1577
		qContext = pstmt->context;
	}
1578 1579 1580 1581 1582

	/*
	 * Define portal and start execution.
	 */
	PortalDefineQuery(portal,
1583
					  *pstmt->stmt_name ? pstmt->stmt_name : NULL,
1584 1585 1586
					  pstmt->query_string,
					  pstmt->commandTag,
					  pstmt->query_list,
1587
					  plan_list,
1588
					  qContext);
1589

1590
	PortalStart(portal, params, InvalidSnapshot);
1591

1592 1593 1594 1595 1596
	/*
	 * Apply the result format requests to the portal.
	 */
	PortalSetResultFormat(portal, numRFormats, rformats);

1597 1598 1599
	/*
	 * Send BindComplete.
	 */
1600
	if (whereToSendOutput == DestRemote)
1601
		pq_putemptymessage('2');
1602 1603 1604 1605

	/*
	 * Emit duration logging if appropriate.
	 */
1606 1607 1608 1609 1610 1611 1612 1613
	switch (check_log_duration(msec_str, false))
	{
		case 1:
			ereport(LOG,
					(errmsg("duration: %s ms", msec_str)));
			break;
		case 2:
			ereport(LOG,
1614
					(errmsg("duration: %s ms  bind %s%s%s: %s",
1615 1616
							msec_str,
							*stmt_name ? stmt_name : "<unnamed>",
1617 1618
							*portal_name ? "/" : "",
							*portal_name ? portal_name : "",
1619 1620 1621 1622
							pstmt->query_string ? pstmt->query_string : "<source not stored>"),
					 errdetail_params(params)));
			break;
	}
1623 1624 1625 1626 1627

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

	debug_query_string = NULL;
1628 1629 1630 1631 1632 1633 1634 1635
}

/*
 * exec_execute_message
 *
 * Process an "Execute" message for a portal
 */
static void
1636
exec_execute_message(const char *portal_name, long max_rows)
1637
{
B
Bruce Momjian 已提交
1638
	CommandDest dest;
1639
	DestReceiver *receiver;
1640 1641 1642
	Portal		portal;
	bool		completed;
	char		completionTag[COMPLETION_TAG_BUFSIZE];
1643
	const char *sourceText;
1644
	const char *prepStmtName;
1645
	ParamListInfo portalParams;
1646
	bool		save_log_statement_stats = log_statement_stats;
1647 1648
	bool		is_xact_command;
	bool		execute_is_fetch;
1649 1650
	bool		was_logged = false;
	char		msec_str[32];
1651 1652 1653

	/* Adjust destination to tell printtup.c what to do */
	dest = whereToSendOutput;
1654 1655
	if (dest == DestRemote)
		dest = DestRemoteExecute;
1656 1657 1658

	portal = GetPortalByName(portal_name);
	if (!PortalIsValid(portal))
1659 1660 1661
		ereport(ERROR,
				(errcode(ERRCODE_UNDEFINED_CURSOR),
				 errmsg("portal \"%s\" does not exist", portal_name)));
1662 1663

	/*
B
Bruce Momjian 已提交
1664 1665
	 * If the original query was a null string, just return
	 * EmptyQueryResponse.
1666 1667 1668 1669 1670 1671 1672 1673
	 */
	if (portal->commandTag == NULL)
	{
		Assert(portal->parseTrees == NIL);
		NullCommand(dest);
		return;
	}

1674 1675 1676 1677 1678 1679 1680 1681 1682 1683 1684 1685
	/*
	 * Report query to various monitoring facilities.
	 */
	debug_query_string = "execute message";

	pgstat_report_activity(portal->sourceText ? portal->sourceText : "<EXECUTE>");

	set_ps_display(portal->commandTag, false);

	if (save_log_statement_stats)
		ResetUsage();

1686 1687 1688 1689 1690 1691 1692 1693 1694 1695 1696
	/* Does the portal contain a transaction command? */
	is_xact_command = IsTransactionStmtList(portal->parseTrees);

	/*
	 * 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;

1697
	/*
B
Bruce Momjian 已提交
1698 1699 1700
	 * 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.
1701 1702
	 */
	if (is_xact_command)
1703
	{
1704
		sourceText = pstrdup(portal->sourceText);
1705 1706 1707 1708
		if (portal->prepStmtName)
			prepStmtName = pstrdup(portal->prepStmtName);
		else
			prepStmtName = "<unnamed>";
B
Bruce Momjian 已提交
1709

1710 1711 1712 1713 1714 1715
		/*
		 * 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;
	}
1716 1717
	else
	{
1718 1719 1720
		sourceText = portal->sourceText;
		if (portal->prepStmtName)
			prepStmtName = portal->prepStmtName;
1721
		else
1722 1723
			prepStmtName = "<unnamed>";
		portalParams = portal->portalParams;
1724
	}
1725

1726 1727
	BeginCommand(portal->commandTag, dest);

1728
	/*
B
Bruce Momjian 已提交
1729 1730
	 * Create dest receiver in MessageContext (we don't want it in transaction
	 * context, because that may get deleted if portal contains VACUUM).
1731 1732 1733
	 */
	receiver = CreateDestReceiver(dest, portal);

1734
	/*
B
Bruce Momjian 已提交
1735 1736
	 * Ensure we are in a transaction command (this should normally be the
	 * case already due to prior BIND).
1737
	 */
1738
	start_xact_command();
1739

1740 1741 1742 1743 1744 1745
	/* Log immediately if dictated by log_statement */
	if (check_log_statement_cooked(portal->parseTrees))
	{
		ereport(LOG,
				(errmsg("%s %s%s%s%s%s",
						execute_is_fetch ?
1746 1747
						_("execute fetch from") :
						_("execute"),
1748 1749 1750 1751 1752 1753 1754 1755 1756
						prepStmtName,
						*portal_name ? "/" : "",
						*portal_name ? portal_name : "",
						sourceText ? ": " : "",
						sourceText ? sourceText : ""),
				 errdetail_params(portalParams)));
		was_logged = true;
	}

1757 1758 1759 1760
	/*
	 * If we are in aborted transaction state, the only portals we can
	 * actually run are those containing COMMIT or ROLLBACK commands.
	 */
1761 1762 1763 1764 1765
	if (IsAbortedTransactionBlockState() &&
		!IsTransactionExitStmtList(portal->parseTrees))
		ereport(ERROR,
				(errcode(ERRCODE_IN_FAILED_SQL_TRANSACTION),
				 errmsg("current transaction is aborted, "
B
Bruce Momjian 已提交
1766
						"commands ignored until end of transaction block")));
1767 1768 1769 1770 1771 1772 1773 1774 1775 1776 1777 1778

	/* 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,
1779 1780
						  receiver,
						  receiver,
1781 1782
						  completionTag);

1783
	(*receiver->rDestroy) (receiver);
1784

1785 1786
	if (completed)
	{
1787
		if (is_xact_command)
1788 1789
		{
			/*
B
Bruce Momjian 已提交
1790
			 * If this was a transaction control statement, commit it.	We
B
Bruce Momjian 已提交
1791
			 * will start a new xact command for the next command (if any).
1792
			 */
1793
			finish_xact_command();
1794 1795 1796 1797
		}
		else
		{
			/*
B
Bruce Momjian 已提交
1798 1799
			 * We need a CommandCounterIncrement after every query, except
			 * those that start or end a transaction block.
1800 1801 1802 1803 1804 1805 1806 1807 1808 1809
			 */
			CommandCounterIncrement();
		}

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

1814
	/*
1815
	 * Emit duration logging if appropriate.
1816
	 */
1817
	switch (check_log_duration(msec_str, was_logged))
1818
	{
1819
		case 1:
1820 1821
			ereport(LOG,
					(errmsg("duration: %s ms", msec_str)));
1822 1823
			break;
		case 2:
1824 1825 1826 1827 1828 1829 1830 1831 1832 1833 1834 1835
			ereport(LOG,
					(errmsg("duration: %s ms  %s %s%s%s%s%s",
							msec_str,
							execute_is_fetch ?
							_("execute fetch from") :
							_("execute"),
							prepStmtName,
							*portal_name ? "/" : "",
							*portal_name ? portal_name : "",
							sourceText ? ": " : "",
							sourceText ? sourceText : ""),
					 errdetail_params(portalParams)));
1836
			break;
1837 1838 1839 1840 1841 1842 1843 1844 1845 1846 1847 1848 1849 1850 1851 1852 1853 1854 1855 1856 1857 1858 1859 1860 1861 1862 1863 1864 1865 1866 1867 1868 1869 1870 1871 1872 1873 1874 1875 1876 1877 1878 1879 1880 1881 1882 1883 1884 1885 1886 1887 1888 1889 1890 1891 1892 1893 1894 1895 1896 1897 1898 1899 1900 1901 1902
	}

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

	debug_query_string = NULL;
}

/*
 * check_log_statement_raw
 *		Determine whether command should be logged because of log_statement
 *
 * raw_parsetree_list is the raw grammar output
 */
static bool
check_log_statement_raw(List *raw_parsetree_list)
{
	ListCell   *parsetree_item;

	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 */
	foreach(parsetree_item, raw_parsetree_list)
	{
		Node	   *parsetree = (Node *) lfirst(parsetree_item);

		if (GetCommandLogLevel(parsetree) <= log_statement)
			return true;
	}

	return false;
}

/*
 * check_log_statement_cooked
 *		As above, but work from already-analyzed querytrees
 */
static bool
check_log_statement_cooked(List *parsetree_list)
{
	ListCell   *parsetree_item;

	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 */
	foreach(parsetree_item, parsetree_list)
	{
		Query	   *parsetree = (Query *) lfirst(parsetree_item);

		if (GetQueryLogLevel(parsetree) <= log_statement)
			return true;
	}

	return false;
}

/*
 * check_log_duration
 *		Determine whether current command's duration should be logged
 *
1903 1904 1905 1906 1907
 * Returns:
 *		0 if no logging is needed
 *		1 if just the duration should be logged
 *		2 if duration and query details should be logged
 *
1908 1909
 * If logging is needed, the duration in msec is formatted into msec_str[],
 * which must be a 32-byte buffer.
1910 1911 1912
 *
 * was_logged should be TRUE if caller already logged query details (this
 * essentially prevents 2 from being returned).
1913
 */
1914 1915
int
check_log_duration(char *msec_str, bool was_logged)
1916
{
1917
	if (log_duration || log_min_duration_statement >= 0)
1918
	{
1919 1920 1921
		long		secs;
		int			usecs;
		int			msecs;
1922
		bool		exceeded;
1923

1924 1925 1926 1927
		TimestampDifference(GetCurrentStatementStartTimestamp(),
							GetCurrentTimestamp(),
							&secs, &usecs);
		msecs = usecs / 1000;
1928 1929

		/*
B
Bruce Momjian 已提交
1930 1931 1932
		 * 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.
1933
		 */
1934 1935 1936 1937 1938 1939
		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)
1940
		{
1941 1942
			snprintf(msec_str, 32, "%ld.%03d",
					 secs * 1000 + msecs, usecs % 1000);
1943 1944 1945 1946
			if (exceeded && !was_logged)
				return 2;
			else
				return 1;
1947
		}
1948 1949
	}

1950
	return 0;
1951
}
1952

1953 1954 1955 1956 1957 1958 1959 1960 1961 1962 1963 1964 1965 1966 1967 1968 1969 1970 1971 1972 1973 1974 1975 1976 1977 1978 1979 1980 1981 1982 1983 1984 1985 1986 1987 1988 1989 1990 1991 1992 1993 1994 1995 1996 1997 1998 1999 2000 2001 2002 2003 2004 2005 2006 2007 2008 2009 2010 2011 2012 2013 2014 2015 2016 2017 2018 2019 2020 2021 2022 2023 2024 2025 2026 2027 2028 2029
/*
 * 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);
			if (pstmt && pstmt->query_string)
			{
				errdetail("prepare: %s", pstmt->query_string);
				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 已提交
2030
				if (*p == '\'') /* double single quotes */
2031 2032 2033 2034 2035 2036 2037 2038 2039 2040 2041 2042 2043 2044 2045 2046
					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;
2047 2048 2049 2050 2051 2052 2053 2054 2055 2056 2057
}

/*
 * exec_describe_statement_message
 *
 * Process a "Describe" message for a prepared statement
 */
static void
exec_describe_statement_message(const char *stmt_name)
{
	PreparedStatement *pstmt;
2058
	TupleDesc	tupdesc;
2059
	ListCell   *l;
2060 2061
	StringInfoData buf;

2062 2063 2064 2065
	/*
	 * Start up a transaction command. (Note that this will normally change
	 * current memory context.) Nothing happens if we are already in one.
	 */
2066
	start_xact_command();
2067 2068 2069 2070

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

2071 2072 2073 2074 2075 2076 2077 2078
	/* Find prepared statement */
	if (stmt_name[0] != '\0')
		pstmt = FetchPreparedStatement(stmt_name, true);
	else
	{
		/* special-case the unnamed statement */
		pstmt = unnamed_stmt_pstmt;
		if (!pstmt)
2079 2080
			ereport(ERROR,
					(errcode(ERRCODE_UNDEFINED_PSTATEMENT),
B
Bruce Momjian 已提交
2081
					 errmsg("unnamed prepared statement does not exist")));
2082 2083
	}

2084 2085
	/*
	 * If we are in aborted transaction state, we can't safely create a result
B
Bruce Momjian 已提交
2086
	 * tupledesc, because that needs catalog accesses.	Hence, refuse to
2087 2088 2089 2090 2091 2092 2093 2094 2095 2096 2097 2098 2099
	 * 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.
	 */
	if (IsAbortedTransactionBlockState() &&
		PreparedStatementReturnsTuples(pstmt))
		ereport(ERROR,
				(errcode(ERRCODE_IN_FAILED_SQL_TRANSACTION),
				 errmsg("current transaction is aborted, "
						"commands ignored until end of transaction block")));

2100
	if (whereToSendOutput != DestRemote)
2101 2102
		return;					/* can't actually do anything... */

2103 2104 2105
	/*
	 * First describe the parameters...
	 */
B
Bruce Momjian 已提交
2106
	pq_beginmessage(&buf, 't'); /* parameter description message type */
2107
	pq_sendint(&buf, list_length(pstmt->argtype_list), 2);
2108 2109 2110

	foreach(l, pstmt->argtype_list)
	{
2111
		Oid			ptype = lfirst_oid(l);
2112 2113 2114 2115

		pq_sendint(&buf, (int) ptype, 4);
	}
	pq_endmessage(&buf);
2116 2117 2118 2119 2120 2121

	/*
	 * Next send RowDescription or NoData to describe the result...
	 */
	tupdesc = FetchPreparedStatementResultDesc(pstmt);
	if (tupdesc)
2122 2123 2124
		SendRowDescriptionMessage(tupdesc,
								  FetchPreparedStatementTargetList(pstmt),
								  NULL);
2125 2126 2127
	else
		pq_putemptymessage('n');	/* NoData */

2128 2129 2130 2131 2132 2133 2134 2135 2136 2137 2138 2139
}

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

2140 2141 2142 2143
	/*
	 * Start up a transaction command. (Note that this will normally change
	 * current memory context.) Nothing happens if we are already in one.
	 */
2144
	start_xact_command();
2145 2146 2147 2148

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

2149 2150
	portal = GetPortalByName(portal_name);
	if (!PortalIsValid(portal))
2151 2152 2153
		ereport(ERROR,
				(errcode(ERRCODE_UNDEFINED_CURSOR),
				 errmsg("portal \"%s\" does not exist", portal_name)));
2154

2155 2156 2157
	/*
	 * If we are in aborted transaction state, we can't run
	 * SendRowDescriptionMessage(), because that needs catalog accesses.
B
Bruce Momjian 已提交
2158
	 * Hence, refuse to Describe portals that return data.	(We shouldn't just
2159 2160 2161 2162 2163 2164 2165 2166 2167 2168 2169
	 * 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")));

2170
	if (whereToSendOutput != DestRemote)
2171 2172 2173
		return;					/* can't actually do anything... */

	if (portal->tupDesc)
2174 2175
		SendRowDescriptionMessage(portal->tupDesc,
								  FetchPortalTargetList(portal),
2176
								  portal->formats);
2177 2178 2179 2180 2181
	else
		pq_putemptymessage('n');	/* NoData */
}


2182
/*
2183
 * Convenience routines for starting/committing a single command.
2184 2185
 */
static void
2186
start_xact_command(void)
2187
{
2188
	if (!xact_started)
2189
	{
2190 2191 2192
		ereport(DEBUG3,
				(errmsg_internal("StartTransactionCommand")));
		StartTransactionCommand();
2193 2194

		/* Set statement timeout running, if any */
2195
		/* NB: this mustn't be enabled until we are within an xact */
2196 2197
		if (StatementTimeout > 0)
			enable_sig_alarm(StatementTimeout, true);
2198 2199
		else
			cancel_from_timeout = false;
B
Bruce Momjian 已提交
2200

2201 2202 2203 2204 2205 2206 2207 2208 2209
		xact_started = true;
	}
}

static void
finish_xact_command(void)
{
	if (xact_started)
	{
2210 2211 2212 2213
		/* Cancel any active statement timeout before committing */
		disable_sig_alarm(true);

		/* Now commit the command */
2214 2215
		ereport(DEBUG3,
				(errmsg_internal("CommitTransactionCommand")));
2216

2217
		CommitTransactionCommand();
2218

2219 2220 2221 2222 2223 2224
#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

2225
#ifdef SHOW_MEMORY_STATS
2226
		/* Print mem stats after each commit for leak tracking */
2227 2228
		if (ShowStats)
			MemoryContextStats(TopMemoryContext);
2229
#endif
2230 2231 2232

		xact_started = false;
	}
2233 2234 2235
}


2236 2237 2238 2239 2240 2241 2242 2243 2244 2245 2246 2247 2248 2249 2250 2251 2252 2253 2254 2255 2256 2257 2258 2259 2260 2261 2262 2263 2264 2265 2266 2267 2268 2269 2270 2271 2272 2273 2274 2275 2276 2277 2278 2279 2280 2281 2282 2283 2284 2285
/*
 * Convenience routines for checking whether a statement is one of the
 * ones that we allow in transaction-aborted state.
 */

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;
}

static bool
IsTransactionExitStmtList(List *parseTrees)
{
	if (list_length(parseTrees) == 1)
	{
		Query	   *query = (Query *) linitial(parseTrees);

		if (query->commandType == CMD_UTILITY &&
			IsTransactionExitStmt(query->utilityStmt))
			return true;
	}
	return false;
}

static bool
IsTransactionStmtList(List *parseTrees)
{
	if (list_length(parseTrees) == 1)
	{
		Query	   *query = (Query *) linitial(parseTrees);

		if (query->commandType == CMD_UTILITY &&
			query->utilityStmt && IsA(query->utilityStmt, TransactionStmt))
			return true;
	}
	return false;
}


2286
/* --------------------------------
2287
 *		signal handler routines used in PostgresMain()
2288 2289 2290
 * --------------------------------
 */

2291
/*
T
Tom Lane 已提交
2292
 * quickdie() occurs when signalled SIGQUIT by the postmaster.
2293 2294 2295 2296
 *
 * Some backend has bought the farm,
 * so we need to stop what we're doing and exit.
 */
T
Tom Lane 已提交
2297
void
2298
quickdie(SIGNAL_ARGS)
2299
{
2300
	PG_SETMASK(&BlockSig);
B
Bruce Momjian 已提交
2301

2302
	/*
B
Bruce Momjian 已提交
2303 2304
	 * Ideally this should be ereport(FATAL), but then we'd not get control
	 * back...
2305 2306 2307
	 */
	ereport(WARNING,
			(errcode(ERRCODE_CRASH_SHUTDOWN),
B
Bruce Momjian 已提交
2308
			 errmsg("terminating connection because of crash of another server process"),
B
Bruce Momjian 已提交
2309 2310 2311 2312
	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."),
2313
			 errhint("In a moment you should be able to reconnect to the"
2314
					 " database and repeat your command.")));
B
Bruce Momjian 已提交
2315

2316
	/*
2317
	 * DO NOT proc_exit() -- we're here because shared memory may be
B
Bruce Momjian 已提交
2318 2319
	 * corrupted, so we don't want to try to clean up our transaction. Just
	 * nail the windows shut and get out of town.
2320
	 *
B
Bruce Momjian 已提交
2321 2322 2323 2324
	 * Note we do exit(1) not exit(0).	This is to force the postmaster into a
	 * system reset cycle if some idiot DBA sends a manual SIGQUIT to a random
	 * backend.  This is necessary precisely because we don't clean up our
	 * shared memory state.
2325
	 */
2326
	exit(1);
2327 2328
}

2329
/*
2330 2331
 * Shutdown signal from postmaster: abort transaction and exit
 * at soonest convenient time
2332
 */
2333
void
2334
die(SIGNAL_ARGS)
2335
{
2336 2337 2338
	int			save_errno = errno;

	/* Don't joggle the elbow of proc_exit */
B
Bruce Momjian 已提交
2339
	if (!proc_exit_inprogress)
2340
	{
2341
		InterruptPending = true;
2342
		ProcDiePending = true;
B
Bruce Momjian 已提交
2343

2344
		/*
B
Bruce Momjian 已提交
2345 2346
		 * If it's safe to interrupt, and we're waiting for input or a lock,
		 * service the interrupt immediately
2347
		 */
2348 2349
		if (ImmediateInterruptOK && InterruptHoldoffCount == 0 &&
			CritSectionCount == 0)
2350
		{
2351 2352 2353
			/* bump holdoff count to make ProcessInterrupts() a no-op */
			/* until we are done getting ready for it */
			InterruptHoldoffCount++;
2354
			DisableNotifyInterrupt();
2355
			DisableCatchupInterrupt();
2356
			/* Make sure CheckDeadLock won't run while shutting down... */
2357
			LockWaitCancel();
2358
			InterruptHoldoffCount--;
2359 2360
			ProcessInterrupts();
		}
2361
	}
2362 2363

	errno = save_errno;
2364 2365
}

2366
/*
2367
 * Timeout or shutdown signal from postmaster during client authentication.
2368
 * Simply exit(0).
2369 2370 2371
 *
 * XXX: possible future improvement: try to send a message indicating
 * why we are disconnecting.  Problem is to be sure we don't block while
2372
 * doing so, nor mess up the authentication message exchange.
2373 2374 2375 2376 2377 2378 2379
 */
void
authdie(SIGNAL_ARGS)
{
	exit(0);
}

2380
/*
2381 2382
 * Query-cancel signal from postmaster: abort current transaction
 * at soonest convenient time
2383
 */
2384
void
2385
StatementCancelHandler(SIGNAL_ARGS)
2386
{
2387 2388
	int			save_errno = errno;

B
Bruce Momjian 已提交
2389
	/*
2390
	 * Don't joggle the elbow of proc_exit
B
Bruce Momjian 已提交
2391
	 */
2392
	if (!proc_exit_inprogress)
2393
	{
2394 2395
		InterruptPending = true;
		QueryCancelPending = true;
B
Bruce Momjian 已提交
2396

2397
		/*
B
Bruce Momjian 已提交
2398 2399 2400
		 * 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.
2401
		 */
2402
		if (ImmediateInterruptOK && InterruptHoldoffCount == 0 &&
2403
			CritSectionCount == 0)
2404
		{
2405 2406 2407 2408 2409 2410
			/* bump holdoff count to make ProcessInterrupts() a no-op */
			/* until we are done getting ready for it */
			InterruptHoldoffCount++;
			if (LockWaitCancel())
			{
				DisableNotifyInterrupt();
2411
				DisableCatchupInterrupt();
T
Tom Lane 已提交
2412
				InterruptHoldoffCount--;
2413 2414 2415 2416
				ProcessInterrupts();
			}
			else
				InterruptHoldoffCount--;
2417
		}
2418 2419
	}

2420
	errno = save_errno;
2421 2422
}

2423
/* signal handler for floating point exception */
2424
void
2425 2426
FloatExceptionHandler(SIGNAL_ARGS)
{
2427 2428 2429
	ereport(ERROR,
			(errcode(ERRCODE_FLOATING_POINT_EXCEPTION),
			 errmsg("floating-point exception"),
B
Bruce Momjian 已提交
2430 2431 2432
			 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.")));
2433 2434
}

2435
/* SIGHUP: set flag to re-read config file at next convenient time */
2436
static void
2437
SigHupHandler(SIGNAL_ARGS)
2438
{
2439
	got_SIGHUP = true;
2440 2441
}

2442

2443 2444 2445 2446 2447 2448 2449 2450 2451 2452
/*
 * 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)
{
2453 2454
	/* OK to accept interrupt now? */
	if (InterruptHoldoffCount != 0 || CritSectionCount != 0)
2455 2456 2457 2458 2459
		return;
	InterruptPending = false;
	if (ProcDiePending)
	{
		ProcDiePending = false;
B
Bruce Momjian 已提交
2460 2461
		QueryCancelPending = false;		/* ProcDie trumps QueryCancel */
		ImmediateInterruptOK = false;	/* not idle anymore */
2462
		DisableNotifyInterrupt();
2463
		DisableCatchupInterrupt();
2464 2465
		ereport(FATAL,
				(errcode(ERRCODE_ADMIN_SHUTDOWN),
B
Bruce Momjian 已提交
2466
			 errmsg("terminating connection due to administrator command")));
2467 2468 2469 2470
	}
	if (QueryCancelPending)
	{
		QueryCancelPending = false;
B
Bruce Momjian 已提交
2471
		ImmediateInterruptOK = false;	/* not idle anymore */
2472
		DisableNotifyInterrupt();
2473
		DisableCatchupInterrupt();
2474 2475 2476 2477 2478 2479 2480 2481
		if (cancel_from_timeout)
			ereport(ERROR,
					(errcode(ERRCODE_QUERY_CANCELED),
					 errmsg("canceling statement due to statement timeout")));
		else
			ereport(ERROR,
					(errcode(ERRCODE_QUERY_CANCELED),
					 errmsg("canceling statement due to user request")));
2482 2483 2484 2485
	}
	/* If we get here, do nothing (probably, QueryCancelPending was reset) */
}

2486

2487 2488 2489 2490 2491 2492 2493 2494 2495 2496 2497 2498 2499
/*
 * check_stack_depth: check for excessively deep recursion
 *
 * This should be called someplace in any recursive routine that might possibly
 * recurse deep enough to overflow the stack.  Most Unixen treat stack
 * overflow as an unrecoverable SIGSEGV, so we want to error out ourselves
 * before hitting the hardware limit.  Unfortunately we have no direct way
 * to detect the hardware limit, so we have to rely on the admin to set a
 * GUC variable for it ...
 */
void
check_stack_depth(void)
{
B
Bruce Momjian 已提交
2500
	char		stack_top_loc;
2501
	long		stack_depth;
2502 2503 2504 2505

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

2508
	/*
B
Bruce Momjian 已提交
2509
	 * Take abs value, since stacks grow up on some machines, down on others
2510 2511 2512
	 */
	if (stack_depth < 0)
		stack_depth = -stack_depth;
B
Bruce Momjian 已提交
2513

2514 2515 2516
	/*
	 * Trouble?
	 *
2517 2518 2519 2520
	 * 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.
2521 2522 2523 2524 2525 2526 2527
	 */
	if (stack_depth > max_stack_depth_bytes &&
		stack_base_ptr != NULL)
	{
		ereport(ERROR,
				(errcode(ERRCODE_STATEMENT_TOO_COMPLEX),
				 errmsg("stack depth limit exceeded"),
2528 2529
				 errhint("Increase the configuration parameter \"max_stack_depth\", "
						 "after ensuring the platform's stack depth limit is adequate.")));
2530 2531 2532 2533 2534 2535 2536 2537 2538
	}
}

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


2544 2545 2546 2547 2548 2549 2550 2551 2552 2553 2554 2555 2556 2557 2558 2559 2560 2561 2562 2563 2564 2565 2566 2567 2568 2569 2570 2571 2572 2573 2574 2575 2576 2577 2578
/*
 * 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);
}


2579 2580 2581
bool
set_plan_disabling_options(const char *arg, GucContext context, GucSource source)
{
B
Bruce Momjian 已提交
2582
	char	   *tmp = NULL;
2583 2584 2585

	switch (arg[0])
	{
B
Bruce Momjian 已提交
2586
		case 's':				/* seqscan */
2587 2588
			tmp = "enable_seqscan";
			break;
B
Bruce Momjian 已提交
2589
		case 'i':				/* indexscan */
2590 2591
			tmp = "enable_indexscan";
			break;
B
Bruce Momjian 已提交
2592
		case 'b':				/* bitmapscan */
2593 2594
			tmp = "enable_bitmapscan";
			break;
B
Bruce Momjian 已提交
2595
		case 't':				/* tidscan */
2596 2597
			tmp = "enable_tidscan";
			break;
B
Bruce Momjian 已提交
2598
		case 'n':				/* nestloop */
2599 2600
			tmp = "enable_nestloop";
			break;
B
Bruce Momjian 已提交
2601
		case 'm':				/* mergejoin */
2602 2603
			tmp = "enable_mergejoin";
			break;
B
Bruce Momjian 已提交
2604
		case 'h':				/* hashjoin */
2605 2606 2607 2608 2609 2610 2611 2612 2613 2614 2615 2616 2617 2618 2619 2620 2621 2622 2623
			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 已提交
2624
			if (optarg[1] == 'a')		/* "parser" */
2625
				return "log_parser_stats";
B
Bruce Momjian 已提交
2626
			else if (optarg[1] == 'l')	/* "planner" */
2627 2628 2629
				return "log_planner_stats";
			break;

B
Bruce Momjian 已提交
2630
		case 'e':				/* "executor" */
2631 2632 2633 2634 2635 2636 2637 2638
			return "log_executor_stats";
			break;
	}

	return NULL;
}


2639
/* ----------------------------------------------------------------
2640
 * PostgresMain
B
Bruce Momjian 已提交
2641
 *	   postgres main loop -- all backends, interactive or otherwise start here
2642
 *
2643 2644 2645 2646
 * 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.
2647 2648 2649
 * ----------------------------------------------------------------
 */
int
2650
PostgresMain(int argc, char *argv[], const char *username)
2651
{
2652
	int			flag;
2653
	const char *dbname = NULL;
2654
	char	   *userDoption = NULL;
2655
	bool		secure;
2656
	int			errs = 0;
B
Bruce Momjian 已提交
2657 2658
	int			debug_flag = -1;	/* -1 means not given */
	List	   *guc_names = NIL;	/* for SUSET options */
2659 2660
	List	   *guc_values = NIL;
	GucContext	ctx;
2661
	GucSource	gucsource;
2662
	bool		am_superuser;
2663
	int			firstchar;
2664
	char		stack_base;
B
Bruce Momjian 已提交
2665
	StringInfoData input_message;
2666
	sigjmp_buf	local_sigjmp_buf;
2667
	volatile bool send_ready_for_query = true;
B
Bruce Momjian 已提交
2668

2669 2670 2671 2672
#define PendingConfigOption(name,val) \
	(guc_names = lappend(guc_names, pstrdup(name)), \
	 guc_values = lappend(guc_values, pstrdup(val)))

2673 2674 2675 2676 2677 2678
	/*
	 * initialize globals (already done if under postmaster, but not if
	 * standalone; cheap enough to do over)
	 */
	MyProcPid = getpid();

2679 2680 2681 2682 2683
	/*
	 * Fire up essential subsystems: error and memory management
	 *
	 * If we are running under the postmaster, this is done already.
	 */
2684
	if (!IsUnderPostmaster)
2685 2686
		MemoryContextInit();

2687
	set_ps_display("startup", false);
2688

2689 2690
	SetProcessingMode(InitProcessing);

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

2694 2695 2696 2697 2698 2699 2700
	/* Compute paths, if we didn't inherit them from postmaster */
	if (my_exec_path[0] == '\0')
	{
		if (find_my_exec(argv[0], my_exec_path) < 0)
			elog(FATAL, "%s: could not locate my own executable path",
				 argv[0]);
	}
B
Bruce Momjian 已提交
2701

B
Bruce Momjian 已提交
2702 2703
	if (pkglib_path[0] == '\0')
		get_pkglib_path(my_exec_path, pkglib_path);
2704

2705
	/*
2706
	 * Set default values for command-line options.
2707
	 */
2708
	EchoQuery = false;
2709

2710
	if (!IsUnderPostmaster)
2711
		InitializeGUCOptions();
2712

2713 2714 2715 2716 2717 2718 2719 2720 2721 2722 2723 2724 2725 2726 2727 2728 2729
	/* ----------------
	 *	parse command line arguments
	 *
	 *	There are now two styles of command line layout for the backend:
	 *
	 *	For interactive use (not started from postmaster) the format is
	 *		postgres [switches] [databasename]
	 *	If the databasename is omitted it is taken to be the user name.
	 *
	 *	When started from the postmaster, the format is
	 *		postgres [secure switches] -p databasename [insecure switches]
	 *	Switches appearing after -p came from the client (via "options"
	 *	field of connection request).  For security reasons we restrict
	 *	what these switches can do.
	 * ----------------
	 */

2730 2731 2732 2733 2734 2735 2736
	/* Ignore the initial --single argument, if present */
	if (argc > 1 && strcmp(argv[1], "--single") == 0)
	{
		argv++;
		argc--;
	}

2737 2738
	/* all options are allowed until '-p' */
	secure = true;
2739
	ctx = PGC_POSTMASTER;
2740
	gucsource = PGC_S_ARGV;		/* initial switches came from command line */
2741

2742
	while ((flag = getopt(argc, argv, "A:B:c:D:d:EeFf:h:ijk:lN:nOo:Pp:r:S:sTt:v:W:y:-:")) != -1)
2743
	{
2744 2745
		switch (flag)
		{
M
 
Marc G. Fournier 已提交
2746
			case 'A':
2747
				SetConfigOption("debug_assertions", optarg, ctx, gucsource);
M
 
Marc G. Fournier 已提交
2748
				break;
2749

2750
			case 'B':
2751
				SetConfigOption("shared_buffers", optarg, ctx, gucsource);
2752
				break;
2753

2754
			case 'D':
2755
				if (secure)
2756
					userDoption = optarg;
M
 
Marc G. Fournier 已提交
2757
				break;
2758

2759
			case 'd':
2760
				debug_flag = atoi(optarg);
2761
				break;
2762 2763

			case 'E':
2764
				EchoQuery = true;
2765
				break;
2766 2767

			case 'e':
2768
				SetConfigOption("datestyle", "euro", ctx, gucsource);
2769
				break;
2770 2771

			case 'F':
2772
				SetConfigOption("fsync", "false", ctx, gucsource);
2773
				break;
2774 2775

			case 'f':
2776 2777 2778
				if (!set_plan_disabling_options(optarg, ctx, gucsource))
					errs++;
				break;
2779

2780 2781
			case 'h':
				SetConfigOption("listen_addresses", optarg, ctx, gucsource);
2782 2783
				break;

2784 2785 2786
			case 'i':
				SetConfigOption("listen_addresses", "*", ctx, gucsource);
				break;
2787

2788
			case 'j':
2789 2790
				UseNewLine = 0;
				break;
2791

2792 2793 2794
			case 'k':
				SetConfigOption("unix_socket_directory", optarg, ctx, gucsource);
				break;
2795

2796 2797
			case 'l':
				SetConfigOption("ssl", "true", ctx, gucsource);
2798 2799
				break;

2800 2801 2802
			case 'N':
				SetConfigOption("max_connections", optarg, ctx, gucsource);
				break;
2803

2804 2805 2806 2807 2808 2809
			case 'n':
				/* ignored for consistency with postmaster */
				break;

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

T
Tom Lane 已提交
2812
			case 'o':
2813 2814
				errs++;
				break;
2815

2816 2817
			case 'P':
				SetConfigOption("ignore_system_indexes", "true", ctx, gucsource);
T
Tom Lane 已提交
2818 2819
				break;

2820
			case 'p':
2821 2822
				SetConfigOption("port", optarg, ctx, gucsource);
				break;
B
Bruce Momjian 已提交
2823

2824 2825
			case 'r':
				/* send output (stdout and stderr) to the given file */
2826
				if (secure)
2827
					StrNCpy(OutputFileName, optarg, MAXPGPATH);
2828
				break;
2829

2830
			case 'S':
2831
				SetConfigOption("work_mem", optarg, ctx, gucsource);
2832
				break;
2833 2834

			case 's':
B
Bruce Momjian 已提交
2835

2836
				/*
2837 2838
				 * Since log options are SUSET, we need to postpone unless
				 * still in secure context
2839
				 */
2840 2841 2842 2843 2844
				if (ctx == PGC_BACKEND)
					PendingConfigOption("log_statement_stats", "true");
				else
					SetConfigOption("log_statement_stats", "true",
									ctx, gucsource);
M
 
Marc G. Fournier 已提交
2845 2846
				break;

2847 2848 2849 2850
			case 'T':
				/* ignored for consistency with postmaster */
				break;

2851
			case 't':
2852
				{
B
Bruce Momjian 已提交
2853 2854 2855 2856 2857 2858 2859 2860 2861
					const char *tmp = get_stats_option_name(optarg);

					if (tmp)
					{
						if (ctx == PGC_BACKEND)
							PendingConfigOption(tmp, "true");
						else
							SetConfigOption(tmp, "true", ctx, gucsource);
					}
2862
					else
B
Bruce Momjian 已提交
2863 2864
						errs++;
					break;
2865
				}
2866

2867
			case 'v':
2868 2869
				if (secure)
					FrontendProtocol = (ProtocolVersion) atoi(optarg);
2870 2871
				break;

M
 
Marc G. Fournier 已提交
2872
			case 'W':
2873 2874
				SetConfigOption("post_auth_delay", optarg, ctx, gucsource);
				break;
2875

2876 2877

			case 'y':
B
Bruce Momjian 已提交
2878

2879
				/*
2880 2881
				 * y - special flag passed if backend was forked by a
				 * postmaster.
M
 
Marc G. Fournier 已提交
2882
				 */
2883 2884 2885 2886 2887 2888 2889 2890
				if (secure)
				{
					dbname = strdup(optarg);

					secure = false;		/* subsequent switches are NOT secure */
					ctx = PGC_BACKEND;
					gucsource = PGC_S_CLIENT;
				}
M
 
Marc G. Fournier 已提交
2891 2892
				break;

2893
			case 'c':
2894
			case '-':
2895
				{
B
Bruce Momjian 已提交
2896 2897
					char	   *name,
							   *value;
2898

B
Bruce Momjian 已提交
2899 2900 2901 2902
					ParseLongOption(optarg, &name, &value);
					if (!value)
					{
						if (flag == '-')
2903 2904 2905 2906
							ereport(ERROR,
									(errcode(ERRCODE_SYNTAX_ERROR),
									 errmsg("--%s requires a value",
											optarg)));
B
Bruce Momjian 已提交
2907
						else
2908 2909 2910 2911
							ereport(ERROR,
									(errcode(ERRCODE_SYNTAX_ERROR),
									 errmsg("-c %s requires a value",
											optarg)));
B
Bruce Momjian 已提交
2912 2913
					}

2914
					/*
B
Bruce Momjian 已提交
2915 2916
					 * If a SUSET option, must postpone evaluation, unless we
					 * are still reading secure switches.
2917 2918 2919 2920 2921
					 */
					if (ctx == PGC_BACKEND && IsSuperuserConfigOption(name))
						PendingConfigOption(name, value);
					else
						SetConfigOption(name, value, ctx, gucsource);
B
Bruce Momjian 已提交
2922 2923 2924 2925 2926
					free(name);
					if (value)
						free(value);
					break;
				}
2927

2928 2929
			default:
				errs++;
T
Tom Lane 已提交
2930
				break;
2931
		}
2932 2933
	}

2934
	/*
B
Bruce Momjian 已提交
2935 2936
	 * Process any additional GUC variable settings passed in startup packet.
	 * These are handled exactly like command-line variables.
2937 2938 2939 2940 2941 2942 2943 2944 2945 2946 2947 2948 2949 2950 2951 2952 2953 2954 2955 2956 2957 2958 2959
	 */
	if (MyProcPort != NULL)
	{
		ListCell   *gucopts = list_head(MyProcPort->guc_options);

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

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

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

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

2960 2961
	/* Acquire configuration parameters, unless inherited from postmaster */
	if (!IsUnderPostmaster)
2962
	{
2963 2964
		if (!SelectConfigFiles(userDoption, argv[0]))
			proc_exit(1);
2965 2966
		/* If timezone is not set, determine what the OS uses */
		pg_timezone_initialize();
2967 2968
		/* If timezone_abbreviations is not set, select default */
		pg_timezone_abbrev_initialize();
2969
	}
2970

2971 2972 2973
	if (PostAuthDelay)
		pg_usleep(PostAuthDelay * 1000000L);

2974
	/*
2975
	 * Set up signal handlers and masks.
2976
	 *
2977 2978 2979
	 * 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 已提交
2980
	 *
B
Bruce Momjian 已提交
2981 2982 2983 2984 2985 2986
	 * 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.)
2987
	 */
2988
	pqsignal(SIGHUP, SigHupHandler);	/* set flag to read config file */
B
Bruce Momjian 已提交
2989
	pqsignal(SIGINT, StatementCancelHandler);	/* cancel current query */
2990
	pqsignal(SIGTERM, die);		/* cancel current query and exit */
2991
	pqsignal(SIGQUIT, quickdie);	/* hard crash time */
B
Bruce Momjian 已提交
2992
	pqsignal(SIGALRM, handle_sig_alarm);		/* timeout conditions */
2993 2994 2995 2996

	/*
	 * Ignore failure to write to frontend. Note: if frontend closes
	 * connection, we will notice it and exit cleanly when control next
B
Bruce Momjian 已提交
2997 2998
	 * returns to outer loop.  This seems safer than forcing exit in the midst
	 * of output during who-knows-what operation...
2999 3000
	 */
	pqsignal(SIGPIPE, SIG_IGN);
3001 3002
	pqsignal(SIGUSR1, CatchupInterruptHandler);
	pqsignal(SIGUSR2, NotifyInterruptHandler);
3003
	pqsignal(SIGFPE, FloatExceptionHandler);
3004 3005

	/*
B
Bruce Momjian 已提交
3006
	 * Reset some signals that are accepted by postmaster but not by backend
3007
	 */
B
Bruce Momjian 已提交
3008
	pqsignal(SIGCHLD, SIG_DFL); /* system() requires this on some platforms */
3009

3010 3011
	pqinitmask();

T
Tom Lane 已提交
3012
	/* We allow SIGQUIT (quickdie) at all times */
3013
#ifdef HAVE_SIGPROCMASK
T
Tom Lane 已提交
3014
	sigdelset(&BlockSig, SIGQUIT);
3015
#else
T
Tom Lane 已提交
3016
	BlockSig &= ~(sigmask(SIGQUIT));
3017 3018
#endif

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

3021
	if (IsUnderPostmaster)
3022
	{
3023
		/* noninteractive case: nothing should be left after switches */
3024
		if (errs || argc != optind || dbname == NULL)
3025
		{
3026 3027
			ereport(FATAL,
					(errcode(ERRCODE_SYNTAX_ERROR),
B
Bruce Momjian 已提交
3028 3029
				 errmsg("invalid command-line arguments for server process"),
			   errhint("Try \"%s --help\" for more information.", argv[0])));
3030
		}
3031

3032
		BaseInit();
3033
	}
3034
	else
3035
	{
3036 3037 3038
		/* interactive case: database name can be last arg on command line */
		if (errs || argc - optind > 1)
		{
3039 3040 3041 3042
			ereport(FATAL,
					(errcode(ERRCODE_SYNTAX_ERROR),
					 errmsg("%s: invalid command-line arguments",
							argv[0]),
B
Bruce Momjian 已提交
3043
			   errhint("Try \"%s --help\" for more information.", argv[0])));
3044 3045
		}
		else if (argc - optind == 1)
3046 3047
			dbname = argv[optind];
		else if ((dbname = username) == NULL)
3048
		{
3049 3050 3051 3052
			ereport(FATAL,
					(errcode(ERRCODE_INVALID_PARAMETER_VALUE),
					 errmsg("%s: no database nor user name specified",
							argv[0])));
3053
		}
3054

3055
		/*
B
Bruce Momjian 已提交
3056 3057
		 * Validate we have been given a reasonable-looking DataDir (if under
		 * postmaster, assume postmaster did this already).
3058
		 */
3059
		Assert(DataDir);
3060 3061
		ValidatePgVersion(DataDir);

3062 3063 3064
		/* Change into DataDir (if under postmaster, was done already) */
		ChangeToDataDir();

3065
		/*
3066
		 * Create lockfile for data directory.
3067
		 */
3068
		CreateDataDirLockFile(false);
3069

3070
		BaseInit();
3071 3072 3073 3074 3075

		/*
		 * Start up xlog for standalone backend, and register to have it
		 * closed down at exit.
		 */
3076
		StartupXLOG();
3077
		on_shmem_exit(ShutdownXLOG, 0);
3078 3079

		/*
B
Bruce Momjian 已提交
3080 3081
		 * Read any existing FSM cache file, and register to write one out at
		 * exit.
3082 3083 3084
		 */
		LoadFreeSpaceMap();
		on_shmem_exit(DumpFreeSpaceMap, 0);
3085 3086

		/*
B
Bruce Momjian 已提交
3087 3088
		 * We have to build the flat file for pg_database, but not for the
		 * user and group tables, since we won't try to do authentication.
3089 3090
		 */
		BuildFlatFiles(true);
3091 3092
	}

3093
	/*
B
Bruce Momjian 已提交
3094 3095 3096 3097
	 * 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).
3098 3099 3100 3101 3102 3103 3104 3105
	 */
#ifdef EXEC_BACKEND
	if (!IsUnderPostmaster)
		InitProcess();
#else
	InitProcess();
#endif

3106
	/*
3107 3108
	 * General initialization.
	 *
3109 3110 3111
	 * 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.
3112
	 */
3113 3114
	ereport(DEBUG3,
			(errmsg_internal("InitPostgres")));
3115
	am_superuser = InitPostgres(dbname, username);
3116

3117
	SetProcessingMode(NormalProcessing);
3118

3119
	/*
3120 3121
	 * Now that we know if client is a superuser, we can try to apply SUSET
	 * GUC options that came from the client.
3122 3123 3124 3125 3126 3127 3128 3129 3130 3131 3132 3133 3134 3135 3136 3137 3138 3139 3140 3141 3142 3143 3144 3145 3146 3147 3148 3149
	 */
	ctx = am_superuser ? PGC_SUSET : PGC_USERSET;

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

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

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

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

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

3150
	/*
B
Bruce Momjian 已提交
3151 3152
	 * Also set up handler to log session end; we have to wait till now to be
	 * sure Log_disconnections has its final value.
3153 3154 3155 3156
	 */
	if (IsUnderPostmaster && Log_disconnections)
		on_proc_exit(log_disconnections, 0);

3157
	/*
B
Bruce Momjian 已提交
3158 3159
	 * process any libraries that should be preloaded at backend start (this
	 * likewise can't be done until GUC settings are complete)
3160 3161 3162
	 */
	process_local_preload_libraries();

3163 3164
	/*
	 * Send this backend's cancellation info to the frontend.
3165
	 */
3166
	if (whereToSendOutput == DestRemote &&
M
 
Marc G. Fournier 已提交
3167 3168
		PG_PROTOCOL_MAJOR(FrontendProtocol) >= 2)
	{
3169
		StringInfoData buf;
B
Bruce Momjian 已提交
3170

3171
		pq_beginmessage(&buf, 'K');
3172 3173 3174
		pq_sendint(&buf, (int32) MyProcPid, sizeof(int32));
		pq_sendint(&buf, (int32) MyCancelKey, sizeof(int32));
		pq_endmessage(&buf);
M
 
Marc G. Fournier 已提交
3175 3176 3177
		/* Need not flush since ReadyForQuery will do it. */
	}

3178
	/* Welcome banner for standalone case */
3179
	if (whereToSendOutput == DestDebug)
3180
		printf("\nPostgreSQL stand-alone backend %s\n", PG_VERSION);
3181

3182 3183 3184
	/*
	 * Create the memory context we will use in the main loop.
	 *
3185 3186
	 * MessageContext is reset once per iteration of the main loop, ie, upon
	 * completion of processing of each command message from the client.
3187
	 */
3188 3189 3190 3191 3192
	MessageContext = AllocSetContextCreate(TopMemoryContext,
										   "MessageContext",
										   ALLOCSET_DEFAULT_MINSIZE,
										   ALLOCSET_DEFAULT_INITSIZE,
										   ALLOCSET_DEFAULT_MAXSIZE);
3193

3194
	/*
3195
	 * Remember stand-alone backend startup time
3196 3197
	 */
	if (!IsUnderPostmaster)
3198
		PgStartTime = GetCurrentTimestamp();
3199

3200 3201
	/*
	 * POSTGRES main processing loop begins here
3202
	 *
B
Bruce Momjian 已提交
3203 3204
	 * If an exception is encountered, processing resumes here so we abort the
	 * current transaction and start a new one.
3205
	 *
3206 3207 3208 3209 3210 3211 3212
	 * 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.)
3213 3214
	 */

3215
	if (sigsetjmp(local_sigjmp_buf, 1) != 0)
3216
	{
3217
		/*
3218
		 * NOTE: if you are tempted to add more code in this if-block,
3219
		 * consider the high probability that it should be in
B
Bruce Momjian 已提交
3220
		 * AbortTransaction() instead.	The only stuff done directly here
B
Bruce Momjian 已提交
3221 3222
		 * should be stuff that is guaranteed to apply *only* for outer-level
		 * error recovery, such as adjusting the FE/BE protocol status.
3223 3224 3225 3226 3227 3228 3229 3230 3231
		 */

		/* 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 已提交
3232 3233
		 * Forget any pending QueryCancel request, since we're returning to
		 * the idle loop anyway, and cancel the statement timer if running.
3234 3235
		 */
		QueryCancelPending = false;
3236
		disable_sig_alarm(true);
B
Bruce Momjian 已提交
3237
		QueryCancelPending = false;		/* again in case timeout occurred */
3238 3239

		/*
B
Bruce Momjian 已提交
3240 3241 3242
		 * 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.
3243
		 */
3244
		DoingCommandRead = false;
3245
		DisableNotifyInterrupt();
3246
		DisableCatchupInterrupt();
3247

3248 3249 3250
		/* Make sure libpq is in a good state */
		pq_comm_reset();

3251 3252
		/* Report the error to the client and/or server log */
		EmitErrorReport();
3253

3254
		/*
B
Bruce Momjian 已提交
3255 3256
		 * Make sure debug_query_string gets reset before we possibly clobber
		 * the storage it points at.
3257
		 */
3258
		debug_query_string = NULL;
3259

3260
		/*
3261
		 * Abort the current transaction in order to recover.
3262
		 */
3263
		AbortCurrentTransaction();
3264 3265

		/*
B
Bruce Momjian 已提交
3266 3267
		 * Now return to normal top-level context and clear ErrorContext for
		 * next time.
3268 3269
		 */
		MemoryContextSwitchTo(TopMemoryContext);
3270
		FlushErrorState();
3271
		QueryContext = NULL;
3272

3273
		/*
B
Bruce Momjian 已提交
3274 3275
		 * If we were handling an extended-query-protocol message, initiate
		 * skip till next Sync.  This also causes us not to issue
B
Bruce Momjian 已提交
3276
		 * ReadyForQuery (until we get Sync).
3277 3278 3279
		 */
		if (doing_extended_query_message)
			ignore_till_sync = true;
3280

3281 3282
		/* We don't have a transaction command open anymore */
		xact_started = false;
3283

3284
		/* Now we can allow interrupts again */
3285
		RESUME_INTERRUPTS();
3286
	}
3287

3288 3289
	/* We can now handle ereport(ERROR) */
	PG_exception_stack = &local_sigjmp_buf;
3290

3291
	PG_SETMASK(&UnBlockSig);
3292

3293
	if (!ignore_till_sync)
B
Bruce Momjian 已提交
3294
		send_ready_for_query = true;	/* initially, or after error */
3295

3296 3297
	/*
	 * Non-error queries loop here.
3298 3299 3300 3301
	 */

	for (;;)
	{
3302
		/*
B
Bruce Momjian 已提交
3303 3304
		 * At top of loop, reset extended-query-message flag, so that any
		 * errors encountered in "idle" state don't provoke skip.
3305 3306 3307
		 */
		doing_extended_query_message = false;

3308
		/*
B
Bruce Momjian 已提交
3309 3310
		 * Release storage left over from prior query cycle, and create a new
		 * query input buffer in the cleared MessageContext.
3311
		 */
3312 3313
		MemoryContextSwitchTo(MessageContext);
		MemoryContextResetAndDeleteChildren(MessageContext);
3314

3315
		initStringInfo(&input_message);
3316

3317
		/*
B
Bruce Momjian 已提交
3318 3319
		 * (1) If we've reached idle state, tell the frontend we're ready for
		 * a new query.
3320
		 *
3321
		 * Note: this includes fflush()'ing the last of the prior output.
3322 3323 3324
		 *
		 * 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 已提交
3325 3326 3327
		 * 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 已提交
3328
		 */
3329
		if (send_ready_for_query)
3330
		{
3331
			if (IsTransactionOrTransactionBlock())
3332
			{
3333
				set_ps_display("idle in transaction", false);
3334 3335 3336 3337
				pgstat_report_activity("<IDLE> in transaction");
			}
			else
			{
3338 3339
				pgstat_report_tabstat();

3340
				set_ps_display("idle", false);
3341 3342
				pgstat_report_activity("<IDLE>");
			}
3343

3344
			ReadyForQuery(whereToSendOutput);
3345
			send_ready_for_query = false;
3346
		}
3347

3348
		/*
B
Bruce Momjian 已提交
3349 3350 3351 3352
		 * (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.)
3353
		 */
3354 3355
		QueryCancelPending = false;		/* forget any earlier CANCEL signal */
		DoingCommandRead = true;
3356

3357 3358
		/*
		 * (3) read a command (loop blocks here)
3359
		 */
3360
		firstchar = ReadCommand(&input_message);
3361

3362 3363
		/*
		 * (4) disable async signal conditions again.
3364
		 */
3365
		DoingCommandRead = false;
3366

3367
		/*
B
Bruce Momjian 已提交
3368 3369
		 * (5) check for any other interesting events that happened while we
		 * slept.
3370 3371 3372 3373 3374 3375 3376
		 */
		if (got_SIGHUP)
		{
			got_SIGHUP = false;
			ProcessConfigFile(PGC_SIGHUP);
		}

3377
		/*
B
Bruce Momjian 已提交
3378 3379
		 * (6) process the command.  But ignore it if we're skipping till
		 * Sync.
3380
		 */
3381
		if (ignore_till_sync && firstchar != EOF)
3382 3383
			continue;

3384 3385
		switch (firstchar)
		{
3386
			case 'Q':			/* simple query */
3387
				{
3388 3389
					const char *query_string;

3390 3391 3392
					/* Set statement_timestamp() */
					SetCurrentStatementStartTimestamp();

3393 3394
					query_string = pq_getmsgstring(&input_message);
					pq_getmsgend(&input_message);
3395

3396
					exec_simple_query(query_string);
3397

3398
					send_ready_for_query = true;
3399
				}
3400 3401
				break;

3402 3403 3404 3405 3406 3407 3408
			case 'P':			/* parse */
				{
					const char *stmt_name;
					const char *query_string;
					int			numParams;
					Oid		   *paramTypes = NULL;

3409 3410 3411
					/* Set statement_timestamp() */
					SetCurrentStatementStartTimestamp();

3412 3413 3414
					stmt_name = pq_getmsgstring(&input_message);
					query_string = pq_getmsgstring(&input_message);
					numParams = pq_getmsgint(&input_message, 2);
3415 3416
					if (numParams > 0)
					{
B
Bruce Momjian 已提交
3417
						int			i;
3418 3419 3420

						paramTypes = (Oid *) palloc(numParams * sizeof(Oid));
						for (i = 0; i < numParams; i++)
3421
							paramTypes[i] = pq_getmsgint(&input_message, 4);
3422
					}
3423
					pq_getmsgend(&input_message);
3424 3425 3426 3427 3428 3429 3430

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

			case 'B':			/* bind */
3431 3432
				/* Set statement_timestamp() */
				SetCurrentStatementStartTimestamp();
B
Bruce Momjian 已提交
3433

3434
				/*
B
Bruce Momjian 已提交
3435 3436
				 * this message is complex enough that it seems best to put
				 * the field extraction out-of-line
3437
				 */
3438
				exec_bind_message(&input_message);
3439 3440 3441 3442 3443
				break;

			case 'E':			/* execute */
				{
					const char *portal_name;
3444
					int			max_rows;
3445

3446 3447 3448
					/* Set statement_timestamp() */
					SetCurrentStatementStartTimestamp();

3449
					portal_name = pq_getmsgstring(&input_message);
3450
					max_rows = pq_getmsgint(&input_message, 4);
3451
					pq_getmsgend(&input_message);
3452

3453
					exec_execute_message(portal_name, max_rows);
3454 3455 3456
				}
				break;

3457
			case 'F':			/* fastpath function call */
3458 3459 3460
				/* Set statement_timestamp() */
				SetCurrentStatementStartTimestamp();

3461
				/* Tell the collector what we're doing */
3462 3463
				pgstat_report_activity("<FASTPATH> function call");

3464
				/* start an xact for this function invocation */
3465
				start_xact_command();
3466

3467 3468
				/*
				 * Note: we may at this point be inside an aborted
B
Bruce Momjian 已提交
3469 3470
				 * transaction.  We can't throw error for that until we've
				 * finished reading the function-call message, so
3471 3472 3473 3474 3475
				 * HandleFunctionRequest() must check for it after doing so.
				 * Be careful not to do anything that assumes we're inside a
				 * valid transaction here.
				 */

3476 3477 3478
				/* switch back to message context */
				MemoryContextSwitchTo(MessageContext);

3479
				if (HandleFunctionRequest(&input_message) == EOF)
3480 3481
				{
					/* lost frontend connection during F message input */
B
Bruce Momjian 已提交
3482

3483
					/*
3484
					 * Reset whereToSendOutput to prevent ereport from
B
Bruce Momjian 已提交
3485
					 * attempting to send any more messages to client.
3486
					 */
3487 3488
					if (whereToSendOutput == DestRemote)
						whereToSendOutput = DestNone;
3489

3490
					proc_exit(0);
3491
				}
3492 3493

				/* commit the function-invocation transaction */
3494
				finish_xact_command();
3495

3496
				send_ready_for_query = true;
3497 3498
				break;

B
Bruce Momjian 已提交
3499
			case 'C':			/* close */
3500
				{
B
Bruce Momjian 已提交
3501
					int			close_type;
3502 3503
					const char *close_target;

3504 3505 3506
					close_type = pq_getmsgbyte(&input_message);
					close_target = pq_getmsgstring(&input_message);
					pq_getmsgend(&input_message);
3507 3508 3509 3510 3511 3512 3513 3514 3515 3516 3517 3518 3519 3520 3521 3522 3523 3524 3525 3526 3527 3528 3529 3530 3531 3532 3533 3534

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

								portal = GetPortalByName(close_target);
								if (PortalIsValid(portal))
									PortalDrop(portal, false);
							}
							break;
						default:
3535 3536
							ereport(ERROR,
									(errcode(ERRCODE_PROTOCOL_VIOLATION),
B
Bruce Momjian 已提交
3537 3538
								   errmsg("invalid CLOSE message subtype %d",
										  close_type)));
3539 3540 3541
							break;
					}

3542
					if (whereToSendOutput == DestRemote)
B
Bruce Momjian 已提交
3543
						pq_putemptymessage('3');		/* CloseComplete */
3544 3545 3546 3547 3548
				}
				break;

			case 'D':			/* describe */
				{
B
Bruce Momjian 已提交
3549
					int			describe_type;
3550 3551
					const char *describe_target;

3552 3553 3554
					/* Set statement_timestamp() (needed for xact) */
					SetCurrentStatementStartTimestamp();

3555 3556 3557
					describe_type = pq_getmsgbyte(&input_message);
					describe_target = pq_getmsgstring(&input_message);
					pq_getmsgend(&input_message);
3558 3559 3560 3561 3562 3563 3564 3565 3566 3567

					switch (describe_type)
					{
						case 'S':
							exec_describe_statement_message(describe_target);
							break;
						case 'P':
							exec_describe_portal_message(describe_target);
							break;
						default:
3568 3569
							ereport(ERROR,
									(errcode(ERRCODE_PROTOCOL_VIOLATION),
B
Bruce Momjian 已提交
3570 3571
								errmsg("invalid DESCRIBE message subtype %d",
									   describe_type)));
3572 3573 3574 3575 3576
							break;
					}
				}
				break;

B
Bruce Momjian 已提交
3577
			case 'H':			/* flush */
3578
				pq_getmsgend(&input_message);
3579
				if (whereToSendOutput == DestRemote)
3580 3581 3582
					pq_flush();
				break;

B
Bruce Momjian 已提交
3583
			case 'S':			/* sync */
3584
				pq_getmsgend(&input_message);
3585
				finish_xact_command();
3586
				send_ready_for_query = true;
3587 3588
				break;

3589
				/*
B
Bruce Momjian 已提交
3590 3591 3592
				 * 'X' means that the frontend is closing down the socket. EOF
				 * means unexpected loss of frontend connection. Either way,
				 * perform normal shutdown.
3593 3594
				 */
			case 'X':
3595
			case EOF:
B
Bruce Momjian 已提交
3596

3597
				/*
B
Bruce Momjian 已提交
3598 3599
				 * Reset whereToSendOutput to prevent ereport from attempting
				 * to send any more messages to client.
3600
				 */
3601 3602
				if (whereToSendOutput == DestRemote)
					whereToSendOutput = DestNone;
B
Bruce Momjian 已提交
3603

3604 3605
				/*
				 * NOTE: if you are tempted to add more code here, DON'T!
B
Bruce Momjian 已提交
3606
				 * Whatever you had in mind to do should be set up as an
B
Bruce Momjian 已提交
3607 3608 3609
				 * on_proc_exit or on_shmem_exit callback, instead. Otherwise
				 * it will fail to be called during other backend-shutdown
				 * scenarios.
3610
				 */
3611
				proc_exit(0);
3612

B
Bruce Momjian 已提交
3613 3614 3615 3616
			case 'd':			/* copy data */
			case 'c':			/* copy done */
			case 'f':			/* copy fail */

3617
				/*
B
Bruce Momjian 已提交
3618
				 * Accept but ignore these messages, per protocol spec; we
B
Bruce Momjian 已提交
3619 3620
				 * probably got here because a COPY failed, and the frontend
				 * is still sending data.
3621 3622 3623
				 */
				break;

3624
			default:
3625 3626 3627 3628
				ereport(FATAL,
						(errcode(ERRCODE_PROTOCOL_VIOLATION),
						 errmsg("invalid frontend message type %d",
								firstchar)));
3629
		}
3630
	}							/* end of input-reading loop */
3631

3632 3633
	/* can't get here because the above loop never exits */
	Assert(false);
3634

3635
	return 1;					/* keep compiler quiet */
3636 3637
}

3638
#ifndef HAVE_GETRUSAGE
B
Bruce Momjian 已提交
3639 3640
#include "rusagestub.h"
#else
3641
#include <sys/resource.h>
3642
#endif   /* HAVE_GETRUSAGE */
3643

3644 3645
static struct rusage Save_r;
static struct timeval Save_t;
3646 3647

void
3648
ResetUsage(void)
3649
{
3650
	getrusage(RUSAGE_SELF, &Save_r);
3651
	gettimeofday(&Save_t, NULL);
3652
	ResetBufferUsage();
3653
	/* ResetTupleCount(); */
3654 3655 3656
}

void
3657
ShowUsage(const char *title)
3658
{
3659
	StringInfoData str;
3660 3661 3662 3663
	struct timeval user,
				sys;
	struct timeval elapse_t;
	struct rusage r;
B
Bruce Momjian 已提交
3664
	char	   *bufusage;
3665 3666

	getrusage(RUSAGE_SELF, &r);
3667
	gettimeofday(&elapse_t, NULL);
3668 3669
	memcpy((char *) &user, (char *) &r.ru_utime, sizeof(user));
	memcpy((char *) &sys, (char *) &r.ru_stime, sizeof(sys));
3670 3671 3672 3673 3674 3675 3676 3677 3678 3679 3680 3681 3682 3683 3684 3685 3686 3687
	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 已提交
3688 3689 3690 3691
	 * 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.
3692
	 */
3693
	initStringInfo(&str);
3694

3695 3696
	appendStringInfo(&str, "! system usage stats:\n");
	appendStringInfo(&str,
B
Bruce Momjian 已提交
3697
				"!\t%ld.%06ld elapsed %ld.%06ld user %ld.%06ld system sec\n",
3698 3699 3700
					 (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 已提交
3701
					 (long) (r.ru_utime.tv_usec - Save_r.ru_utime.tv_usec),
3702
					 (long) (r.ru_stime.tv_sec - Save_r.ru_stime.tv_sec),
B
Bruce Momjian 已提交
3703
					 (long) (r.ru_stime.tv_usec - Save_r.ru_stime.tv_usec));
3704
	appendStringInfo(&str,
B
Bruce Momjian 已提交
3705
					 "!\t[%ld.%06ld user %ld.%06ld sys total]\n",
3706 3707 3708 3709
					 (long) user.tv_sec,
					 (long) user.tv_usec,
					 (long) sys.tv_sec,
					 (long) sys.tv_usec);
3710
#if defined(HAVE_GETRUSAGE)
3711
	appendStringInfo(&str,
B
Bruce Momjian 已提交
3712 3713
					 "!\t%ld/%ld [%ld/%ld] filesystem blocks in/out\n",
					 r.ru_inblock - Save_r.ru_inblock,
3714
	/* they only drink coffee at dec */
B
Bruce Momjian 已提交
3715 3716
					 r.ru_oublock - Save_r.ru_oublock,
					 r.ru_inblock, r.ru_oublock);
3717
	appendStringInfo(&str,
B
Bruce Momjian 已提交
3718
			  "!\t%ld/%ld [%ld/%ld] page faults/reclaims, %ld [%ld] swaps\n",
B
Bruce Momjian 已提交
3719 3720 3721 3722 3723
					 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);
3724
	appendStringInfo(&str,
B
Bruce Momjian 已提交
3725
		 "!\t%ld [%ld] signals rcvd, %ld/%ld [%ld/%ld] messages rcvd/sent\n",
B
Bruce Momjian 已提交
3726 3727 3728 3729 3730
					 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);
3731
	appendStringInfo(&str,
B
Bruce Momjian 已提交
3732
			 "!\t%ld/%ld [%ld/%ld] voluntary/involuntary context switches\n",
B
Bruce Momjian 已提交
3733 3734 3735
					 r.ru_nvcsw - Save_r.ru_nvcsw,
					 r.ru_nivcsw - Save_r.ru_nivcsw,
					 r.ru_nvcsw, r.ru_nivcsw);
3736
#endif   /* HAVE_GETRUSAGE */
3737 3738

	bufusage = ShowBufferUsage();
3739
	appendStringInfo(&str, "! buffer usage stats:\n%s", bufusage);
3740 3741 3742
	pfree(bufusage);

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

3746 3747 3748
	ereport(LOG,
			(errmsg_internal("%s", title),
			 errdetail("%s", str.data)));
3749 3750

	pfree(str.data);
3751
}
3752 3753 3754 3755

/*
 * on_proc_exit handler to log end of session
 */
B
Bruce Momjian 已提交
3756
static void
3757
log_disconnections(int code, Datum arg)
3758
{
B
Bruce Momjian 已提交
3759
	Port	   *port = MyProcPort;
3760 3761 3762
	long		secs;
	int			usecs;
	int			msecs;
B
Bruce Momjian 已提交
3763 3764 3765
	int			hours,
				minutes,
				seconds;
3766

3767 3768 3769 3770
	TimestampDifference(port->SessionStartTime,
						GetCurrentTimestamp(),
						&secs, &usecs);
	msecs = usecs / 1000;
3771

3772 3773 3774 3775
	hours = secs / SECS_PER_HOUR;
	secs %= SECS_PER_HOUR;
	minutes = secs / SECS_PER_MINUTE;
	seconds = secs % SECS_PER_MINUTE;
3776

3777
	ereport(LOG,
3778
			(errmsg("disconnection: session time: %d:%02d:%02d.%03d "
3779
					"user=%s database=%s host=%s%s%s",
3780
					hours, minutes, seconds, msecs,
3781
					port->user_name, port->database_name, port->remote_host,
B
Bruce Momjian 已提交
3782
				  port->remote_port[0] ? " port=" : "", port->remote_port)));
3783
}