postgres.c 80.1 KB
Newer Older
1 2
/*-------------------------------------------------------------------------
 *
3
 * postgres.c
4
 *	  POSTGRES C Backend Interface
5
 *
B
Bruce Momjian 已提交
6
 * Portions Copyright (c) 1996-2003, PostgreSQL Global Development Group
B
Add:  
Bruce Momjian 已提交
7
 * Portions Copyright (c) 1994, Regents of the University of California
8 9 10
 *
 *
 * IDENTIFICATION
J
Jan Wieck 已提交
11
 *	  $PostgreSQL: pgsql/src/backend/tcop/postgres.c,v 1.389 2004/02/06 19:36:18 wieck 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>
24 25
#include <time.h>
#include <sys/time.h>
B
Bruce Momjian 已提交
26
#include <fcntl.h>
27
#include <sys/socket.h>
28
#include <errno.h>
29
#if HAVE_SYS_SELECT_H
30
#include <sys/select.h>
31
#endif
32
#ifdef HAVE_GETOPT_H
B
Bruce Momjian 已提交
33
#include <getopt.h>
34
#endif
35

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

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

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

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

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

81
/* note: these declarations had better match tcopprot.h */
82
sigjmp_buf	Warn_restart;
83

84
bool		Warn_restart_ready = false;
85
bool		InError = false;
86

87 88 89 90 91 92 93 94 95
/*
 * Flags for expensive function optimization -- JMH 3/9/92
 */
int			XfuncMode = 0;

/* ----------------
 *		private variables
 * ----------------
 */
96

97 98 99 100 101 102 103
/*
 * 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?)
 */
static volatile bool got_SIGHUP = false;

104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130
/*
 * 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;

/*
 * 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
131 132
 */
#ifndef TCOP_DONTUSENEWLINE
133
static int	UseNewLine = 1;		/* Use newlines query delimiters (the
134
								 * default) */
B
Bruce Momjian 已提交
135

136
#else
137
static int	UseNewLine = 0;		/* Use EOF as query delimiters */
138
#endif   /* TCOP_DONTUSENEWLINE */
139 140 141


/* ----------------------------------------------------------------
142
 *		decls for routines only used in this file
143 144
 * ----------------------------------------------------------------
 */
145 146 147
static int	InteractiveBackend(StringInfo inBuf);
static int	SocketBackend(StringInfo inBuf);
static int	ReadCommand(StringInfo inBuf);
148
static void start_xact_command(void);
149
static void finish_xact_command(void);
150 151
static void SigHupHandler(SIGNAL_ARGS);
static void FloatExceptionHandler(SIGNAL_ARGS);
152 153 154


/* ----------------------------------------------------------------
155
 *		routines to obtain user input
156 157 158 159
 * ----------------------------------------------------------------
 */

/* ----------------
160
 *	InteractiveBackend() is called for user interactive connections
161 162 163
 *
 *	the string entered by the user is placed in its parameter inBuf,
 *	and we act like a Q message was received.
164
 *
165
 *	EOF is returned if end-of-file input is seen; time to shut down.
166 167 168
 * ----------------
 */

169
static int
170
InteractiveBackend(StringInfo inBuf)
171
{
172 173 174
	int			c;				/* character read from getc() */
	bool		end = false;	/* end-of-input flag */
	bool		backslashSeen = false;	/* have we seen a \ ? */
175

176 177
	/*
	 * display a prompt and obtain input from the user
178
	 */
179
	printf("backend> ");
180
	fflush(stdout);
181

182 183 184
	/* Reset inBuf to empty */
	inBuf->len = 0;
	inBuf->data[0] = '\0';
185
	inBuf->cursor = 0;
186

187 188 189 190
	for (;;)
	{
		if (UseNewLine)
		{
191 192 193
			/*
			 * if we are using \n as a delimiter, then read characters
			 * until the \n.
194 195 196 197 198 199 200
			 */
			while ((c = getc(stdin)) != EOF)
			{
				if (c == '\n')
				{
					if (backslashSeen)
					{
201 202 203
						/* discard backslash from inBuf */
						inBuf->data[--inBuf->len] = '\0';
						backslashSeen = false;
204 205 206 207 208
						continue;
					}
					else
					{
						/* keep the newline character */
209
						appendStringInfoChar(inBuf, '\n');
210 211 212 213 214 215 216 217
						break;
					}
				}
				else if (c == '\\')
					backslashSeen = true;
				else
					backslashSeen = false;

218
				appendStringInfoChar(inBuf, (char) c);
219 220 221 222 223 224 225
			}

			if (c == EOF)
				end = true;
		}
		else
		{
226 227
			/*
			 * otherwise read characters until EOF.
228 229
			 */
			while ((c = getc(stdin)) != EOF)
230
				appendStringInfoChar(inBuf, (char) c);
231

232
			if (inBuf->len == 0)
233 234 235 236
				end = true;
		}

		if (end)
237
			return EOF;
238

239 240
		/*
		 * otherwise we have a user query so process it.
241 242 243 244
		 */
		break;
	}

245 246 247
	/* Add '\0' to make it look the same as message case. */
	appendStringInfoChar(inBuf, (char) '\0');

248 249
	/*
	 * if the query echo flag was given, print the query..
250 251
	 */
	if (EchoQuery)
252
		printf("statement: %s\n", inBuf->data);
253
	fflush(stdout);
254

255
	return 'Q';
256 257 258
}

/* ----------------
259
 *	SocketBackend()		Is called for frontend-backend connections
260
 *
261
 *	Returns the message type code, and loads message body data into inBuf.
262
 *
263
 *	EOF is returned if the connection is lost.
264 265
 * ----------------
 */
266
static int
267
SocketBackend(StringInfo inBuf)
268
{
269
	int			qtype;
270

271
	/*
272
	 * Get message type code from the frontend.
273
	 */
274
	qtype = pq_getbyte();
275

276 277
	if (qtype == EOF)			/* frontend disconnected */
	{
278 279 280
		ereport(COMMERROR,
				(errcode(ERRCODE_PROTOCOL_VIOLATION),
				 errmsg("unexpected EOF on client connection")));
281 282 283 284 285
		return qtype;
	}

	/*
	 * Validate message type code before trying to read body; if we have
B
Bruce Momjian 已提交
286 287
	 * lost sync, better to say "command unknown" than to run out of
	 * memory because we used garbage as a length word.
288 289 290
	 *
	 * This also gives us a place to set the doing_extended_query_message
	 * flag as soon as possible.
291
	 */
292
	switch (qtype)
293
	{
294
		case 'Q':				/* simple query */
295
			doing_extended_query_message = false;
296 297 298 299 300
			if (PG_PROTOCOL_MAJOR(FrontendProtocol) < 3)
			{
				/* old style without length word; convert */
				if (pq_getstring(inBuf))
				{
301 302
					ereport(COMMERROR,
							(errcode(ERRCODE_PROTOCOL_VIOLATION),
B
Bruce Momjian 已提交
303
						 errmsg("unexpected EOF on client connection")));
304 305 306
					return EOF;
				}
			}
307 308
			break;

309
		case 'F':				/* fastpath function call */
310 311
			/* we let fastpath.c cope with old-style input of this */
			doing_extended_query_message = false;
312
			break;
313

314
		case 'X':				/* terminate */
315
			doing_extended_query_message = false;
316
			ignore_till_sync = false;
317 318 319 320 321 322 323 324 325 326 327
			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)
328 329
				ereport(FATAL,
						(errcode(ERRCODE_PROTOCOL_VIOLATION),
B
Bruce Momjian 已提交
330
					 errmsg("invalid frontend message type %d", qtype)));
331 332 333 334 335 336 337 338 339
			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)
340 341
				ereport(FATAL,
						(errcode(ERRCODE_PROTOCOL_VIOLATION),
B
Bruce Momjian 已提交
342
					 errmsg("invalid frontend message type %d", qtype)));
343
			break;
344

345 346 347
		case 'd':				/* copy data */
		case 'c':				/* copy done */
		case 'f':				/* copy fail */
348 349 350
			doing_extended_query_message = false;
			/* these are only legal in protocol 3 */
			if (PG_PROTOCOL_MAJOR(FrontendProtocol) < 3)
351 352
				ereport(FATAL,
						(errcode(ERRCODE_PROTOCOL_VIOLATION),
B
Bruce Momjian 已提交
353
					 errmsg("invalid frontend message type %d", qtype)));
354
			break;
355

356
		default:
B
Bruce Momjian 已提交
357

358
			/*
B
Bruce Momjian 已提交
359 360 361
			 * 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.
362
			 */
363 364 365
			ereport(FATAL,
					(errcode(ERRCODE_PROTOCOL_VIOLATION),
					 errmsg("invalid frontend message type %d", qtype)));
366
			break;
367
	}
368

369 370 371 372 373 374 375 376 377 378 379
	/*
	 * In protocol version 3, all frontend messages have a length word
	 * next after the type code; we can read the message contents
	 * independently of the type.
	 */
	if (PG_PROTOCOL_MAJOR(FrontendProtocol) >= 3)
	{
		if (pq_getmessage(inBuf, 0))
			return EOF;			/* suitable message already logged */
	}

380
	return qtype;
381 382 383
}

/* ----------------
384
 *		ReadCommand reads a command from either the frontend or
385 386 387
 *		standard input, places it in inBuf, and returns the
 *		message type code (first byte of the message).
 *		EOF is returned if end of file.
388 389
 * ----------------
 */
390
static int
391
ReadCommand(StringInfo inBuf)
392
{
393
	int			result;
394

395
	if (whereToSendOutput == Remote)
396
		result = SocketBackend(inBuf);
397
	else
398 399
		result = InteractiveBackend(inBuf);
	return result;
400 401
}

402 403 404 405 406 407

/*
 * 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.
408 409 410
 *
 * NOTE: this routine is no longer used for processing interactive queries,
 * but it is still needed for parsing of SQL function bodies.
411
 */
412
List *
B
Bruce Momjian 已提交
413
pg_parse_and_rewrite(const char *query_string,	/* string to execute */
414
					 Oid *paramTypes,	/* parameter types */
B
Bruce Momjian 已提交
415
					 int numParams)		/* number of parameters */
416
{
417
	List	   *raw_parsetree_list;
418
	List	   *querytree_list;
419 420
	List	   *list_item;

421 422
	/*
	 * (1) parse the request string into a list of raw parse trees.
423
	 */
424
	raw_parsetree_list = pg_parse_query(query_string);
425

426 427
	/*
	 * (2) Do parse analysis and rule rewrite.
428 429 430 431
	 */
	querytree_list = NIL;
	foreach(list_item, raw_parsetree_list)
	{
B
Bruce Momjian 已提交
432
		Node	   *parsetree = (Node *) lfirst(list_item);
433 434

		querytree_list = nconc(querytree_list,
435 436 437
							   pg_analyze_and_rewrite(parsetree,
													  paramTypes,
													  numParams));
438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455
	}

	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.
 */
456
List *
457
pg_parse_query(const char *query_string)
458 459
{
	List	   *raw_parsetree_list;
460

B
Rename:  
Bruce Momjian 已提交
461
	if (log_statement)
462
		ereport(LOG,
B
Bruce Momjian 已提交
463
				(errmsg("statement: %s", query_string)));
464

B
Rename:  
Bruce Momjian 已提交
465
	if (log_parser_stats)
466 467
		ResetUsage();

468
	raw_parsetree_list = raw_parser(query_string);
469

B
Rename:  
Bruce Momjian 已提交
470
	if (log_parser_stats)
471
		ShowUsage("PARSER STATISTICS");
472 473 474 475 476

	return raw_parsetree_list;
}

/*
477 478
 * Given a raw parsetree (gram.y output), and optionally information about
 * types of parameter symbols ($n), perform parse analysis and rule rewriting.
479 480 481 482 483 484
 *
 * 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.
 */
485
List *
486
pg_analyze_and_rewrite(Node *parsetree, Oid *paramTypes, int numParams)
487 488 489
{
	List	   *querytree_list;

490 491
	/*
	 * (1) Perform parse analysis.
492
	 */
B
Rename:  
Bruce Momjian 已提交
493
	if (log_parser_stats)
494 495
		ResetUsage();

496
	querytree_list = parse_analyze(parsetree, paramTypes, numParams);
497

B
Rename:  
Bruce Momjian 已提交
498
	if (log_parser_stats)
499
		ShowUsage("PARSE ANALYSIS STATISTICS");
500

501 502
	/*
	 * (2) Rewrite the queries, as necessary
503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521
	 */
	querytree_list = pg_rewrite_queries(querytree_list);

	return querytree_list;
}

/*
 * Perform rewriting of a list of queries produced by parse analysis.
 */
List *
pg_rewrite_queries(List *querytree_list)
{
	List	   *new_list = NIL;
	List	   *list_item;

	if (log_parser_stats)
		ResetUsage();

	/*
B
Bruce Momjian 已提交
522 523
	 * rewritten queries are collected in new_list.  Note there may be
	 * more or fewer than in the original list.
524
	 */
525
	foreach(list_item, querytree_list)
526
	{
527
		Query	   *querytree = (Query *) lfirst(list_item);
528

529
		if (Debug_print_parse)
530
			elog_node_display(DEBUG1, "parse tree", querytree,
531
							  Debug_pretty_print);
532 533 534

		if (querytree->commandType == CMD_UTILITY)
		{
535 536
			/* don't rewrite utilities, just dump 'em into new_list */
			new_list = lappend(new_list, querytree);
537
		}
538
		else
539
		{
540
			/* rewrite regular queries */
541 542
			List	   *rewritten = QueryRewrite(querytree);

543
			new_list = nconc(new_list, rewritten);
544 545 546 547 548
		}
	}

	querytree_list = new_list;

B
Rename:  
Bruce Momjian 已提交
549
	if (log_parser_stats)
550
		ShowUsage("REWRITER STATISTICS");
551

552
#ifdef COPY_PARSE_PLAN_TREES
B
Bruce Momjian 已提交
553 554 555 556 557

	/*
	 * Optional debugging check: pass querytree output through
	 * copyObject()
	 */
558 559
	new_list = (List *) copyObject(querytree_list);
	/* This checks both copyObject() and the equal() routines... */
B
Bruce Momjian 已提交
560
	if (!equal(new_list, querytree_list))
561
		elog(WARNING, "copyObject() failed to produce an equal parse tree");
562 563
	else
		querytree_list = new_list;
564 565
#endif

566
	if (Debug_print_rewritten)
567
		elog_node_display(DEBUG1, "rewritten parse tree", querytree_list,
568
						  Debug_pretty_print);
569

570 571
	return querytree_list;
}
572 573


574
/* Generate a plan for a single already-rewritten query. */
575 576 577 578
Plan *
pg_plan_query(Query *querytree)
{
	Plan	   *plan;
579

580 581 582
	/* Utility commands have no plans. */
	if (querytree->commandType == CMD_UTILITY)
		return NULL;
583

B
Rename:  
Bruce Momjian 已提交
584
	if (log_planner_stats)
585
		ResetUsage();
586

587
	/* call the optimizer */
588
	plan = planner(querytree, false, 0);
589

B
Rename:  
Bruce Momjian 已提交
590
	if (log_planner_stats)
591
		ShowUsage("PLANNER STATISTICS");
592

593 594 595
#ifdef COPY_PARSE_PLAN_TREES
	/* Optional debugging check: pass plan output through copyObject() */
	{
B
Bruce Momjian 已提交
596
		Plan	   *new_plan = (Plan *) copyObject(plan);
597

B
Bruce Momjian 已提交
598 599
		/*
		 * equal() currently does not have routines to compare Plan nodes,
600 601 602 603
		 * so don't try to test equality here.  Perhaps fix someday?
		 */
#ifdef NOT_USED
		/* This checks both copyObject() and the equal() routines... */
B
Bruce Momjian 已提交
604
		if (!equal(new_plan, plan))
605
			elog(WARNING, "copyObject() failed to produce an equal plan tree");
606 607 608 609 610 611
		else
#endif
			plan = new_plan;
	}
#endif

612 613
	/*
	 * Print plan if debugging.
614
	 */
615
	if (Debug_print_plan)
616
		elog_node_display(DEBUG1, "plan", plan, Debug_pretty_print);
617

618
	return plan;
619 620
}

621 622
/*
 * Generate plans for a list of already-rewritten queries.
623
 *
624 625 626 627 628 629 630 631 632 633 634 635 636 637 638 639 640 641 642 643 644 645 646 647 648 649 650 651 652 653 654 655 656 657 658 659 660 661 662 663 664 665
 * 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 *
pg_plan_queries(List *querytrees, bool needSnapshot)
{
	List	   *plan_list = NIL;
	List	   *query_list;

	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)
			{
				SetQuerySnapshot();
				needSnapshot = false;
			}
			plan = pg_plan_query(query);
		}

		plan_list = lappend(plan_list, plan);
	}

	return plan_list;
}


/*
666
 * exec_simple_query
667
 *
668
 * Execute a "simple Query" protocol message.
669
 */
670
static void
671
exec_simple_query(const char *query_string)
672
{
B
Bruce Momjian 已提交
673
	CommandDest dest = whereToSendOutput;
674
	MemoryContext oldcontext;
675 676
	List	   *parsetree_list,
			   *parsetree_item;
B
Bruce Momjian 已提交
677 678
	struct timeval start_t,
				stop_t;
B
Rename:  
Bruce Momjian 已提交
679
	bool		save_log_duration = log_duration;
B
Bruce Momjian 已提交
680
	int			save_log_min_duration_statement = log_min_duration_statement;
681
	bool		save_log_statement_stats = log_statement_stats;
682

683 684 685
	/*
	 * Report query to various monitoring facilities.
	 */
686
	debug_query_string = query_string;
687

688 689
	pgstat_report_activity(query_string);

690
	/*
B
Bruce Momjian 已提交
691 692 693 694
	 * We use save_log_* so "SET log_duration = true"  and "SET
	 * log_min_duration_statement = true" don't report incorrect time
	 * because gettimeofday() wasn't called. Similarly,
	 * log_statement_stats has to be captured once.
695
	 */
696
	if (save_log_duration || save_log_min_duration_statement != -1)
697
		gettimeofday(&start_t, NULL);
698

699 700 701
	if (save_log_statement_stats)
		ResetUsage();

702
	/*
B
Bruce Momjian 已提交
703 704 705 706
	 * Start up a transaction command.	All queries generated by the
	 * query_string will be in this same command block, *unless* we find a
	 * BEGIN/COMMIT/ABORT statement; we have to force a new xact command
	 * after one of those, else bad things will happen in xact.c. (Note
707
	 * that this will normally change current memory context.)
708 709
	 */
	start_xact_command();
710 711

	/*
B
Bruce Momjian 已提交
712 713 714 715
	 * 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.)
716 717 718 719 720 721 722 723
	 */
	unnamed_stmt_pstmt = NULL;
	if (unnamed_stmt_context)
	{
		DropDependentPortals(unnamed_stmt_context);
		MemoryContextDelete(unnamed_stmt_context);
	}
	unnamed_stmt_context = NULL;
724

725 726 727
	/*
	 * Switch to appropriate context for constructing parsetrees.
	 */
728
	oldcontext = MemoryContextSwitchTo(MessageContext);
729

730 731
	QueryContext = CurrentMemoryContext;

B
Bruce Momjian 已提交
732
	/*
B
Bruce Momjian 已提交
733 734
	 * Do basic parsing of the query or queries (this should be safe even
	 * if we are in aborted transaction state!)
735
	 */
736
	parsetree_list = pg_parse_query(query_string);
737

738
	/*
739
	 * Switch back to transaction context to enter the loop.
740 741 742 743
	 */
	MemoryContextSwitchTo(oldcontext);

	/*
744
	 * Run through the raw parsetree(s) and process each one.
745
	 */
746
	foreach(parsetree_item, parsetree_list)
747
	{
B
Bruce Momjian 已提交
748
		Node	   *parsetree = (Node *) lfirst(parsetree_item);
749 750
		const char *commandTag;
		char		completionTag[COMPLETION_TAG_BUFSIZE];
B
Bruce Momjian 已提交
751
		List	   *querytree_list,
752 753
				   *plantree_list;
		Portal		portal;
754 755
		DestReceiver *receiver;
		int16		format;
756

757
		/*
B
Bruce Momjian 已提交
758 759 760 761
		 * 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.
762 763 764 765 766
		 */
		commandTag = CreateCommandTag(parsetree);

		set_ps_display(commandTag);

767
		BeginCommand(commandTag, dest);
768

769
		/*
770
		 * If we are in an aborted transaction, reject all commands except
771 772
		 * COMMIT/ABORT.  It is important that this test occur before we
		 * try to do parse analysis, rewrite, or planning, since all those
B
Bruce Momjian 已提交
773 774 775
		 * 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...)
776 777
		 */
		if (IsAbortedTransactionBlockState())
778
		{
B
Bruce Momjian 已提交
779
			bool		allowit = false;
780

781
			if (IsA(parsetree, TransactionStmt))
782 783 784
			{
				TransactionStmt *stmt = (TransactionStmt *) parsetree;

785 786
				if (stmt->kind == TRANS_STMT_COMMIT ||
					stmt->kind == TRANS_STMT_ROLLBACK)
787
					allowit = true;
788
			}
789

B
Bruce Momjian 已提交
790
			if (!allowit)
791 792 793
				ereport(ERROR,
						(errcode(ERRCODE_IN_FAILED_SQL_TRANSACTION),
						 errmsg("current transaction is aborted, "
794
					 "commands ignored until end of transaction block")));
795
		}
796

797
		/* Make sure we are in a transaction command */
798
		start_xact_command();
799

800
		/* If we got a cancel signal in parsing or prior command, quit */
801
		CHECK_FOR_INTERRUPTS();
802 803

		/*
804
		 * OK to analyze, rewrite, and plan this query.
805
		 *
B
Bruce Momjian 已提交
806 807
		 * Switch to appropriate context for constructing querytrees (again,
		 * these must outlive the execution context).
808
		 */
809
		oldcontext = MemoryContextSwitchTo(MessageContext);
810

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

813 814 815 816 817
		plantree_list = pg_plan_queries(querytree_list, true);

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

818
		/*
B
Bruce Momjian 已提交
819 820
		 * Create unnamed portal to run the query or queries in. If there
		 * already is one, silently drop it.
821
		 */
822
		portal = CreatePortal("", true, true);
823

824 825 826 827 828 829
		PortalDefineQuery(portal,
						  query_string,
						  commandTag,
						  querytree_list,
						  plantree_list,
						  MessageContext);
830

831
		/*
832
		 * Start the portal.  No parameters here.
833 834
		 */
		PortalStart(portal, NULL);
835

836 837
		/*
		 * Select the appropriate output format: text unless we are doing
B
Bruce Momjian 已提交
838 839 840
		 * 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...)
841 842 843 844 845 846 847 848 849 850 851 852
		 */
		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 已提交
853
					format = 1; /* BINARY */
854 855 856 857 858 859 860 861 862 863 864 865 866 867 868
			}
		}
		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 已提交
869 870
		 * Run the portal to completion, and then drop it (and the
		 * receiver).
871
		 */
872 873
		(void) PortalRun(portal,
						 FETCH_ALL,
874 875
						 receiver,
						 receiver,
876
						 completionTag);
877

878
		(*receiver->rDestroy) (receiver);
879

880
		PortalDrop(portal, false);
881

882
		if (IsA(parsetree, TransactionStmt))
883
		{
884
			/*
B
Bruce Momjian 已提交
885 886 887
			 * If this was a transaction control statement, commit it. We
			 * will start a new xact command for the next command (if
			 * any).
888
			 */
889
			finish_xact_command();
890
		}
891
		else if (lnext(parsetree_item) == NIL)
892
		{
893
			/*
B
Bruce Momjian 已提交
894 895 896 897 898 899 900 901 902
			 * 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.
903
			 */
904
			finish_xact_command();
905
		}
906
		else
907
		{
908
			/*
B
Bruce Momjian 已提交
909 910
			 * We need a CommandCounterIncrement after every query, except
			 * those that start or end a transaction block.
911 912
			 */
			CommandCounterIncrement();
913
		}
914 915 916

		/*
		 * Tell client that we're done with this query.  Note we emit
B
Bruce Momjian 已提交
917 918 919 920
		 * 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.)
921
		 */
922
		EndCommand(completionTag, dest);
B
Bruce Momjian 已提交
923
	}							/* end loop over parsetrees */
924

925 926 927 928 929
	/*
	 * Close down transaction statement, if one is open.
	 */
	finish_xact_command();

930 931 932
	/*
	 * If there were no parsetrees, return EmptyQueryResponse message.
	 */
933
	if (!parsetree_list)
934 935
		NullCommand(dest);

936
	QueryContext = NULL;
937

938
	/*
B
Bruce Momjian 已提交
939 940
	 * Combine processing here as we need to calculate the query duration
	 * in both instances.
941
	 */
942
	if (save_log_duration || save_log_min_duration_statement != -1)
943
	{
B
Bruce Momjian 已提交
944 945
		long		usecs;

946
		gettimeofday(&stop_t, NULL);
947 948 949 950 951
		if (stop_t.tv_usec < start_t.tv_usec)
		{
			stop_t.tv_sec--;
			stop_t.tv_usec += 1000000;
		}
B
Bruce Momjian 已提交
952 953
		usecs = (long) (stop_t.tv_sec - start_t.tv_sec) * 1000000 + (long) (stop_t.tv_usec - start_t.tv_usec);

B
Bruce Momjian 已提交
954 955 956 957 958 959 960
		if (save_log_duration)
			ereport(LOG,
					(errmsg("duration: %ld.%03ld ms",
							(long) ((stop_t.tv_sec - start_t.tv_sec) * 1000 +
							(stop_t.tv_usec - start_t.tv_usec) / 1000),
							(long) (stop_t.tv_usec - start_t.tv_usec) % 1000)));

B
Bruce Momjian 已提交
961
		/*
962 963
		 * Output a duration_statement to the log if the query has exceeded
		 * the min duration, or if we are to print all durations.
B
Bruce Momjian 已提交
964
		 */
B
Bruce Momjian 已提交
965 966 967
		if (save_log_min_duration_statement == 0 ||
			(save_log_min_duration_statement > 0 &&
			 usecs >= save_log_min_duration_statement * 1000))
968
			ereport(LOG,
B
Bruce Momjian 已提交
969
					(errmsg("duration: %ld.%03ld ms  statement: %s",
970 971 972
							(long) ((stop_t.tv_sec - start_t.tv_sec) * 1000 +
							(stop_t.tv_usec - start_t.tv_usec) / 1000),
							(long) (stop_t.tv_usec - start_t.tv_usec) % 1000,
B
Bruce Momjian 已提交
973
							query_string)));
974
	}
975

976 977 978
	if (save_log_statement_stats)
		ShowUsage("QUERY STATISTICS");

979
	debug_query_string = NULL;
980 981
}

982 983 984 985 986 987 988 989
/*
 * 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 已提交
990 991
				   Oid *paramTypes,		/* parameter types */
				   int numParams)		/* number of parameters */
992 993 994 995 996 997 998 999 1000 1001 1002 1003 1004 1005 1006 1007 1008 1009 1010 1011 1012 1013 1014 1015 1016 1017 1018 1019 1020 1021 1022 1023
{
	MemoryContext oldcontext;
	List	   *parsetree_list;
	const char *commandTag;
	List	   *querytree_list,
			   *plantree_list,
			   *param_list;
	bool		is_named;
	bool		save_log_statement_stats = log_statement_stats;

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

	pgstat_report_activity(query_string);

	set_ps_display("PARSE");

	if (save_log_statement_stats)
		ResetUsage();

	/*
	 * Start up a transaction command so we can run parse analysis etc.
	 * (Note that this will normally change current memory context.)
	 * Nothing happens if we are already in one.
	 */
	start_xact_command();

	/*
	 * Switch to appropriate context for constructing parsetrees.
	 *
B
Bruce Momjian 已提交
1024 1025 1026 1027 1028 1029 1030 1031 1032 1033
	 * We have two strategies depending on whether the prepared statement is
	 * named or not.  For a named prepared statement, we do parsing in
	 * MessageContext and copy the finished trees into the prepared
	 * statement's private context; then the reset of MessageContext
	 * releases temporary space used by parsing and planning.  For an
	 * unnamed prepared statement, we assume the statement isn't going to
	 * hang around long, so getting rid of temp space quickly is probably
	 * not worth the costs of copying parse/plan trees.  So in this case,
	 * we set up a special context for the unnamed statement, and do all
	 * the parsing/planning therein.
1034 1035 1036 1037 1038 1039 1040 1041 1042 1043 1044 1045 1046 1047 1048 1049 1050 1051 1052 1053 1054 1055 1056 1057 1058 1059 1060 1061 1062 1063 1064 1065 1066 1067 1068 1069
	 */
	is_named = (stmt_name[0] != '\0');
	if (is_named)
	{
		/* Named prepared statement --- parse in MessageContext */
		oldcontext = MemoryContextSwitchTo(MessageContext);
	}
	else
	{
		/* Unnamed prepared statement --- release any prior unnamed stmt */
		unnamed_stmt_pstmt = NULL;
		if (unnamed_stmt_context)
		{
			DropDependentPortals(unnamed_stmt_context);
			MemoryContextDelete(unnamed_stmt_context);
		}
		unnamed_stmt_context = NULL;
		/* create context for parsing/planning */
		unnamed_stmt_context =
			AllocSetContextCreate(TopMemoryContext,
								  "unnamed prepared statement",
								  ALLOCSET_DEFAULT_MINSIZE,
								  ALLOCSET_DEFAULT_INITSIZE,
								  ALLOCSET_DEFAULT_MAXSIZE);
		oldcontext = MemoryContextSwitchTo(unnamed_stmt_context);
	}

	QueryContext = CurrentMemoryContext;

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

	/*
B
Bruce Momjian 已提交
1070 1071 1072
	 * 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.
1073 1074
	 */
	if (length(parsetree_list) > 1)
1075 1076 1077
		ereport(ERROR,
				(errcode(ERRCODE_SYNTAX_ERROR),
				 errmsg("cannot insert multiple commands into a prepared statement")));
1078 1079 1080

	if (parsetree_list != NIL)
	{
B
Bruce Momjian 已提交
1081 1082
		Node	   *parsetree = (Node *) lfirst(parsetree_list);
		int			i;
1083 1084 1085 1086 1087 1088 1089 1090

		/*
		 * 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 已提交
1091 1092 1093 1094
		 * 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
1095 1096 1097 1098 1099 1100 1101 1102 1103 1104 1105 1106 1107 1108 1109 1110
		 * commands in this state, but not many...)
		 */
		if (IsAbortedTransactionBlockState())
		{
			bool		allowit = false;

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

				if (stmt->kind == TRANS_STMT_COMMIT ||
					stmt->kind == TRANS_STMT_ROLLBACK)
					allowit = true;
			}

			if (!allowit)
1111 1112 1113
				ereport(ERROR,
						(errcode(ERRCODE_IN_FAILED_SQL_TRANSACTION),
						 errmsg("current transaction is aborted, "
1114
					 "commands ignored until end of transaction block")));
1115 1116 1117 1118 1119 1120 1121 1122 1123 1124 1125 1126 1127 1128 1129 1130 1131 1132 1133 1134 1135
		}

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

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

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

			if (ptype == InvalidOid || ptype == UNKNOWNOID)
1139 1140
				ereport(ERROR,
						(errcode(ERRCODE_INDETERMINATE_DATATYPE),
1141
				  errmsg("could not determine data type of parameter $%d",
B
Bruce Momjian 已提交
1142
						 i + 1)));
1143 1144 1145 1146 1147 1148 1149 1150 1151 1152 1153 1154
			param_list = lappendo(param_list, ptype);
		}

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

		querytree_list = pg_rewrite_queries(querytree_list);

		plantree_list = pg_plan_queries(querytree_list, true);
	}
	else
	{
B
Bruce Momjian 已提交
1155
		/* Empty input string.	This is legal. */
1156 1157 1158 1159 1160 1161 1162 1163 1164 1165 1166 1167 1168 1169 1170 1171 1172 1173 1174 1175 1176 1177 1178 1179 1180 1181 1182 1183 1184 1185 1186 1187 1188 1189 1190 1191 1192 1193 1194 1195 1196 1197 1198
		commandTag = NULL;
		querytree_list = NIL;
		plantree_list = NIL;
		param_list = NIL;
	}

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

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

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

	MemoryContextSwitchTo(oldcontext);

	QueryContext = NULL;

	/*
B
Bruce Momjian 已提交
1199 1200 1201 1202
	 * 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.
1203 1204 1205 1206 1207 1208 1209 1210 1211 1212 1213 1214 1215 1216 1217 1218 1219 1220 1221 1222 1223 1224 1225 1226 1227
	 */
	CommandCounterIncrement();

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

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

	debug_query_string = NULL;
}

/*
 * exec_bind_message
 *
 * Process a "Bind" message to create a portal from a prepared statement
 */
static void
exec_bind_message(StringInfo input_message)
{
	const char *portal_name;
	const char *stmt_name;
1228 1229
	int			numPFormats;
	int16	   *pformats = NULL;
1230
	int			numParams;
1231 1232 1233
	int			numRFormats;
	int16	   *rformats = NULL;
	int			i;
1234 1235 1236 1237 1238 1239 1240 1241 1242
	PreparedStatement *pstmt;
	Portal		portal;
	ParamListInfo params;

	pgstat_report_activity("<BIND>");

	set_ps_display("BIND");

	/*
B
Bruce Momjian 已提交
1243 1244 1245
	 * 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.
1246 1247 1248
	 */
	start_xact_command();

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

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

1256 1257 1258 1259 1260 1261 1262 1263 1264 1265 1266 1267 1268
	/* Get the parameter format codes */
	numPFormats = pq_getmsgint(input_message, 2);
	if (numPFormats > 0)
	{
		pformats = (int16 *) palloc(numPFormats * sizeof(int16));
		for (i = 0; i < numPFormats; i++)
			pformats[i] = pq_getmsgint(input_message, 2);
	}

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

	if (numPFormats > 1 && numPFormats != numParams)
1269 1270
		ereport(ERROR,
				(errcode(ERRCODE_PROTOCOL_VIOLATION),
B
Bruce Momjian 已提交
1271 1272
		errmsg("bind message has %d parameter formats but %d parameters",
			   numPFormats, numParams)));
1273 1274 1275 1276 1277 1278 1279 1280 1281

	/* 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)
1282 1283
			ereport(ERROR,
					(errcode(ERRCODE_UNDEFINED_PSTATEMENT),
B
Bruce Momjian 已提交
1284
				   errmsg("unnamed prepared statement does not exist")));
1285 1286 1287
	}

	if (numParams != length(pstmt->argtype_list))
1288 1289 1290
		ereport(ERROR,
				(errcode(ERRCODE_PROTOCOL_VIOLATION),
				 errmsg("bind message supplies %d parameters, but prepared statement \"%s\" requires %d",
B
Bruce Momjian 已提交
1291
					numParams, stmt_name, length(pstmt->argtype_list))));
1292 1293 1294 1295 1296 1297 1298 1299 1300 1301 1302 1303 1304 1305 1306 1307 1308 1309 1310 1311

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

	PortalDefineQuery(portal,
					  pstmt->query_string,
					  pstmt->commandTag,
					  pstmt->query_list,
					  pstmt->plan_list,
					  pstmt->context);

	/*
	 * Fetch parameters, if any, and store in the portal's memory context.
	 *
B
Bruce Momjian 已提交
1312 1313 1314
	 * In an aborted transaction, we can't risk calling user-defined
	 * functions, but we can't fail to Bind either, so bind all parameters
	 * to null values.
1315 1316 1317
	 */
	if (numParams > 0)
	{
B
Bruce Momjian 已提交
1318 1319
		bool		isaborted = IsAbortedTransactionBlockState();
		List	   *l;
1320 1321 1322 1323 1324 1325 1326
		MemoryContext oldContext;

		oldContext = MemoryContextSwitchTo(PortalGetHeapMemory(portal));

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

1327
		i = 0;
1328 1329 1330
		foreach(l, pstmt->argtype_list)
		{
			Oid			ptype = lfirsto(l);
1331
			int32		plength;
1332 1333
			bool		isNull;

1334 1335 1336
			plength = pq_getmsgint(input_message, 4);
			isNull = (plength == -1);

1337 1338
			if (!isNull)
			{
1339
				const char *pvalue = pq_getmsgbytes(input_message, plength);
1340 1341

				if (isaborted)
1342 1343
				{
					/* We don't bother to check the format in this case */
1344
					isNull = true;
1345
				}
1346 1347
				else
				{
B
Bruce Momjian 已提交
1348
					int16		pformat;
1349
					StringInfoData pbuf;
B
Bruce Momjian 已提交
1350
					char		csave;
1351 1352 1353 1354 1355 1356

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

1359
					/*
B
Bruce Momjian 已提交
1360 1361 1362 1363 1364 1365 1366
					 * Rather than copying data around, we just set up a
					 * phony StringInfo pointing to the correct portion of
					 * the message buffer.	We assume we can scribble on
					 * the message buffer so as to maintain the convention
					 * that StringInfos have a trailing null.  This is
					 * grotty but is a big win when dealing with very
					 * large parameter strings.
1367 1368 1369 1370 1371 1372 1373 1374 1375
					 */
					pbuf.data = (char *) pvalue;
					pbuf.maxlen = plength + 1;
					pbuf.len = plength;
					pbuf.cursor = 0;

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

1376 1377 1378 1379 1380 1381 1382
					if (pformat == 0)
					{
						Oid			typInput;
						Oid			typElem;
						char	   *pstring;

						getTypeInputInfo(ptype, &typInput, &typElem);
B
Bruce Momjian 已提交
1383

1384
						/*
B
Bruce Momjian 已提交
1385 1386
						 * We have to do encoding conversion before
						 * calling the typinput routine.
1387 1388 1389 1390 1391 1392 1393 1394 1395 1396 1397 1398 1399 1400 1401
						 */
						pstring = (char *)
							pg_client_to_server((unsigned char *) pbuf.data,
												plength);
						params[i].value =
							OidFunctionCall3(typInput,
											 CStringGetDatum(pstring),
											 ObjectIdGetDatum(typElem),
											 Int32GetDatum(-1));
						/* Free result of encoding conversion, if any */
						if (pstring != pbuf.data)
							pfree(pstring);
					}
					else if (pformat == 1)
					{
1402 1403 1404
						Oid			typReceive;
						Oid			typElem;

B
Bruce Momjian 已提交
1405 1406 1407 1408
						/*
						 * Call the parameter type's binary input
						 * converter
						 */
1409 1410 1411 1412 1413 1414 1415 1416 1417
						getTypeBinaryInputInfo(ptype, &typReceive, &typElem);

						params[i].value =
							OidFunctionCall2(typReceive,
											 PointerGetDatum(&pbuf),
											 ObjectIdGetDatum(typElem));

						/* Trouble if it didn't eat the whole buffer */
						if (pbuf.cursor != pbuf.len)
1418 1419 1420
							ereport(ERROR,
									(errcode(ERRCODE_INVALID_BINARY_REPRESENTATION),
									 errmsg("incorrect binary data format in bind parameter %d",
B
Bruce Momjian 已提交
1421
											i + 1)));
1422 1423 1424
					}
					else
					{
1425 1426 1427 1428
						ereport(ERROR,
								(errcode(ERRCODE_INVALID_PARAMETER_VALUE),
								 errmsg("unsupported format code: %d",
										pformat)));
1429
					}
1430 1431 1432

					/* Restore message buffer contents */
					pbuf.data[plength] = csave;
1433 1434
				}
			}
1435

1436 1437 1438 1439 1440 1441 1442 1443 1444 1445 1446 1447 1448 1449
			params[i].kind = PARAM_NUM;
			params[i].id = i + 1;
			params[i].isnull = isNull;

			i++;
		}

		params[i].kind = PARAM_INVALID;

		MemoryContextSwitchTo(oldContext);
	}
	else
		params = NULL;

1450 1451 1452 1453 1454 1455 1456 1457 1458
	/* Get the result format codes */
	numRFormats = pq_getmsgint(input_message, 2);
	if (numRFormats > 0)
	{
		rformats = (int16 *) palloc(numRFormats * sizeof(int16));
		for (i = 0; i < numRFormats; i++)
			rformats[i] = pq_getmsgint(input_message, 2);
	}

1459 1460 1461 1462 1463 1464 1465
	pq_getmsgend(input_message);

	/*
	 * Start portal execution.
	 */
	PortalStart(portal, params);

1466 1467 1468 1469 1470
	/*
	 * Apply the result format requests to the portal.
	 */
	PortalSetResultFormat(portal, numRFormats, rformats);

1471 1472 1473 1474 1475 1476 1477 1478 1479 1480 1481 1482 1483
	/*
	 * Send BindComplete.
	 */
	if (whereToSendOutput == Remote)
		pq_putemptymessage('2');
}

/*
 * exec_execute_message
 *
 * Process an "Execute" message for a portal
 */
static void
1484
exec_execute_message(const char *portal_name, long max_rows)
1485
{
B
Bruce Momjian 已提交
1486
	CommandDest dest;
1487
	DestReceiver *receiver;
1488 1489 1490 1491 1492 1493 1494 1495 1496
	Portal		portal;
	bool		is_trans_stmt = false;
	bool		is_trans_exit = false;
	bool		completed;
	char		completionTag[COMPLETION_TAG_BUFSIZE];

	/* Adjust destination to tell printtup.c what to do */
	dest = whereToSendOutput;
	if (dest == Remote)
1497
		dest = RemoteExecute;
1498 1499 1500

	portal = GetPortalByName(portal_name);
	if (!PortalIsValid(portal))
1501 1502 1503
		ereport(ERROR,
				(errcode(ERRCODE_UNDEFINED_CURSOR),
				 errmsg("portal \"%s\" does not exist", portal_name)));
1504 1505

	/*
B
Bruce Momjian 已提交
1506 1507
	 * If the original query was a null string, just return
	 * EmptyQueryResponse.
1508 1509 1510 1511 1512 1513 1514 1515 1516 1517 1518 1519 1520 1521 1522 1523 1524 1525 1526 1527 1528 1529 1530 1531 1532 1533
	 */
	if (portal->commandTag == NULL)
	{
		Assert(portal->parseTrees == NIL);
		NullCommand(dest);
		return;
	}

	if (portal->sourceText)
	{
		debug_query_string = portal->sourceText;
		pgstat_report_activity(portal->sourceText);
	}
	else
	{
		debug_query_string = "execute message";
		pgstat_report_activity("<EXECUTE>");
	}

	set_ps_display(portal->commandTag);

	BeginCommand(portal->commandTag, dest);

	/* Check for transaction-control commands */
	if (length(portal->parseTrees) == 1)
	{
B
Bruce Momjian 已提交
1534
		Query	   *query = (Query *) lfirst(portal->parseTrees);
1535 1536 1537 1538 1539 1540 1541 1542 1543 1544 1545 1546 1547 1548

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

			is_trans_stmt = true;
			if (stmt->kind == TRANS_STMT_COMMIT ||
				stmt->kind == TRANS_STMT_ROLLBACK)
				is_trans_exit = true;
		}
	}

1549
	/*
B
Bruce Momjian 已提交
1550 1551 1552
	 * Create dest receiver in MessageContext (we don't want it in
	 * transaction context, because that may get deleted if portal
	 * contains VACUUM).
1553 1554 1555
	 */
	receiver = CreateDestReceiver(dest, portal);

1556
	/*
B
Bruce Momjian 已提交
1557 1558
	 * Ensure we are in a transaction command (this should normally be the
	 * case already due to prior BIND).
1559 1560 1561 1562 1563 1564 1565 1566 1567 1568
	 */
	start_xact_command();

	/*
	 * If we are in aborted transaction state, the only portals we can
	 * actually run are those containing COMMIT or ROLLBACK commands.
	 */
	if (IsAbortedTransactionBlockState())
	{
		if (!is_trans_exit)
1569 1570 1571
			ereport(ERROR,
					(errcode(ERRCODE_IN_FAILED_SQL_TRANSACTION),
					 errmsg("current transaction is aborted, "
1572
					 "commands ignored until end of transaction block")));
1573 1574 1575 1576 1577 1578 1579 1580 1581 1582 1583 1584 1585
	}

	/* 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,
1586 1587
						  receiver,
						  receiver,
1588 1589
						  completionTag);

1590
	(*receiver->rDestroy) (receiver);
1591

1592 1593 1594 1595 1596
	if (completed)
	{
		if (is_trans_stmt)
		{
			/*
B
Bruce Momjian 已提交
1597 1598 1599
			 * If this was a transaction control statement, commit it.	We
			 * will start a new xact command for the next command (if
			 * any).
1600
			 */
1601
			finish_xact_command();
1602 1603 1604 1605
		}
		else
		{
			/*
B
Bruce Momjian 已提交
1606 1607
			 * We need a CommandCounterIncrement after every query, except
			 * those that start or end a transaction block.
1608 1609 1610 1611 1612 1613 1614 1615 1616 1617 1618 1619 1620 1621 1622 1623 1624 1625 1626 1627 1628 1629 1630 1631 1632 1633
			 */
			CommandCounterIncrement();
		}

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

	debug_query_string = NULL;
}

/*
 * exec_describe_statement_message
 *
 * Process a "Describe" message for a prepared statement
 */
static void
exec_describe_statement_message(const char *stmt_name)
{
	PreparedStatement *pstmt;
1634
	TupleDesc	tupdesc;
1635 1636 1637 1638 1639 1640 1641 1642 1643 1644 1645
	List	   *l;
	StringInfoData buf;

	/* Find prepared statement */
	if (stmt_name[0] != '\0')
		pstmt = FetchPreparedStatement(stmt_name, true);
	else
	{
		/* special-case the unnamed statement */
		pstmt = unnamed_stmt_pstmt;
		if (!pstmt)
1646 1647
			ereport(ERROR,
					(errcode(ERRCODE_UNDEFINED_PSTATEMENT),
B
Bruce Momjian 已提交
1648
				   errmsg("unnamed prepared statement does not exist")));
1649 1650 1651 1652 1653
	}

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

1654 1655 1656
	/*
	 * First describe the parameters...
	 */
B
Bruce Momjian 已提交
1657
	pq_beginmessage(&buf, 't'); /* parameter description message type */
1658
	pq_sendint(&buf, length(pstmt->argtype_list), 2);
1659 1660 1661 1662 1663 1664 1665 1666

	foreach(l, pstmt->argtype_list)
	{
		Oid			ptype = lfirsto(l);

		pq_sendint(&buf, (int) ptype, 4);
	}
	pq_endmessage(&buf);
1667 1668 1669 1670 1671 1672 1673

	/*
	 * Next send RowDescription or NoData to describe the result...
	 */
	tupdesc = FetchPreparedStatementResultDesc(pstmt);
	if (tupdesc)
	{
B
Bruce Momjian 已提交
1674
		List	   *targetlist;
1675 1676 1677 1678 1679

		if (ChoosePortalStrategy(pstmt->query_list) == PORTAL_ONE_SELECT)
			targetlist = ((Query *) lfirst(pstmt->query_list))->targetList;
		else
			targetlist = NIL;
1680
		SendRowDescriptionMessage(tupdesc, targetlist, NULL);
1681 1682 1683 1684
	}
	else
		pq_putemptymessage('n');	/* NoData */

1685 1686 1687 1688 1689 1690 1691 1692 1693 1694 1695 1696 1697 1698
}

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

	portal = GetPortalByName(portal_name);
	if (!PortalIsValid(portal))
1699 1700 1701
		ereport(ERROR,
				(errcode(ERRCODE_UNDEFINED_CURSOR),
				 errmsg("portal \"%s\" does not exist", portal_name)));
1702 1703 1704 1705 1706

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

	if (portal->tupDesc)
1707
	{
B
Bruce Momjian 已提交
1708
		List	   *targetlist;
1709 1710

		if (portal->strategy == PORTAL_ONE_SELECT)
1711
			targetlist = ((Query *) lfirst(portal->parseTrees))->targetList;
1712 1713
		else
			targetlist = NIL;
1714 1715
		SendRowDescriptionMessage(portal->tupDesc, targetlist,
								  portal->formats);
1716
	}
1717 1718 1719 1720 1721
	else
		pq_putemptymessage('n');	/* NoData */
}


1722 1723 1724 1725 1726 1727
/*
 * Convenience routines for starting/committing a single command.
 */
static void
start_xact_command(void)
{
1728 1729
	if (!xact_started)
	{
1730 1731
		ereport(DEBUG3,
				(errmsg_internal("StartTransactionCommand")));
1732
		StartTransactionCommand();
1733 1734 1735 1736

		/* Set statement timeout running, if any */
		if (StatementTimeout > 0)
			enable_sig_alarm(StatementTimeout, true);
1737

1738 1739
		xact_started = true;
	}
1740 1741 1742
}

static void
1743
finish_xact_command(void)
1744
{
1745 1746 1747 1748
	if (xact_started)
	{
		/* Invoke IMMEDIATE constraint triggers */
		DeferredTriggerEndQuery();
1749

1750 1751
		/* Cancel any active statement timeout before committing */
		disable_sig_alarm(true);
1752

1753
		/* Now commit the command */
1754 1755
		ereport(DEBUG3,
				(errmsg_internal("CommitTransactionCommand")));
1756

1757
		CommitTransactionCommand();
1758

1759 1760 1761 1762 1763 1764
#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

1765
#ifdef SHOW_MEMORY_STATS
1766
		/* Print mem stats after each commit for leak tracking */
1767 1768
		if (ShowStats)
			MemoryContextStats(TopMemoryContext);
1769
#endif
1770 1771 1772

		xact_started = false;
	}
1773 1774 1775
}


1776
/* --------------------------------
1777
 *		signal handler routines used in PostgresMain()
1778 1779 1780
 * --------------------------------
 */

1781
/*
T
Tom Lane 已提交
1782
 * quickdie() occurs when signalled SIGQUIT by the postmaster.
1783 1784 1785 1786
 *
 * Some backend has bought the farm,
 * so we need to stop what we're doing and exit.
 */
T
Tom Lane 已提交
1787
void
1788
quickdie(SIGNAL_ARGS)
1789
{
1790
	PG_SETMASK(&BlockSig);
B
Bruce Momjian 已提交
1791

1792
	/*
B
Bruce Momjian 已提交
1793 1794
	 * Ideally this should be ereport(FATAL), but then we'd not get
	 * control back (perhaps could fix by doing local sigsetjmp?)
1795 1796 1797
	 */
	ereport(WARNING,
			(errcode(ERRCODE_CRASH_SHUTDOWN),
1798 1799
		errmsg("terminating connection because of crash of another server process"),
	   errdetail("The postmaster has commanded this server process to roll back"
B
Bruce Momjian 已提交
1800
				 " the current transaction and exit, because another"
1801
				 " server process exited abnormally and possibly corrupted"
B
Bruce Momjian 已提交
1802
				 " shared memory."),
1803
			 errhint("In a moment you should be able to reconnect to the"
1804
					 " database and repeat your command.")));
B
Bruce Momjian 已提交
1805

1806
	/*
1807 1808 1809 1810
	 * DO NOT proc_exit() -- we're here because shared memory may be
	 * corrupted, so we don't want to try to clean up our transaction.
	 * Just nail the windows shut and get out of town.
	 *
B
Bruce Momjian 已提交
1811 1812 1813 1814
	 * 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.
1815
	 */
1816
	exit(1);
1817 1818
}

1819
/*
1820 1821
 * Shutdown signal from postmaster: abort transaction and exit
 * at soonest convenient time
1822
 */
1823
void
1824
die(SIGNAL_ARGS)
1825
{
1826 1827 1828
	int			save_errno = errno;

	/* Don't joggle the elbow of proc_exit */
B
Bruce Momjian 已提交
1829
	if (!proc_exit_inprogress)
1830
	{
1831
		InterruptPending = true;
1832
		ProcDiePending = true;
B
Bruce Momjian 已提交
1833

1834
		/*
B
Bruce Momjian 已提交
1835 1836
		 * If it's safe to interrupt, and we're waiting for input or a
		 * lock, service the interrupt immediately
1837
		 */
1838 1839
		if (ImmediateInterruptOK && InterruptHoldoffCount == 0 &&
			CritSectionCount == 0)
1840
		{
1841 1842 1843
			/* bump holdoff count to make ProcessInterrupts() a no-op */
			/* until we are done getting ready for it */
			InterruptHoldoffCount++;
1844
			DisableNotifyInterrupt();
1845
			/* Make sure CheckDeadLock won't run while shutting down... */
1846
			LockWaitCancel();
1847
			InterruptHoldoffCount--;
1848 1849
			ProcessInterrupts();
		}
1850
	}
1851 1852

	errno = save_errno;
1853 1854
}

1855
/*
1856
 * Timeout or shutdown signal from postmaster during client authentication.
1857
 * Simply exit(0).
1858 1859 1860
 *
 * XXX: possible future improvement: try to send a message indicating
 * why we are disconnecting.  Problem is to be sure we don't block while
1861
 * doing so, nor mess up the authentication message exchange.
1862 1863 1864 1865 1866 1867 1868
 */
void
authdie(SIGNAL_ARGS)
{
	exit(0);
}

1869
/*
1870 1871
 * Query-cancel signal from postmaster: abort current transaction
 * at soonest convenient time
1872
 */
1873
static void
1874
StatementCancelHandler(SIGNAL_ARGS)
1875
{
1876 1877
	int			save_errno = errno;

B
Bruce Momjian 已提交
1878 1879 1880 1881
	/*
	 * Don't joggle the elbow of proc_exit, nor an already-in-progress
	 * abort
	 */
1882
	if (!proc_exit_inprogress && !InError)
1883
	{
1884 1885
		InterruptPending = true;
		QueryCancelPending = true;
B
Bruce Momjian 已提交
1886

1887
		/*
1888
		 * If it's safe to interrupt, and we're waiting for a lock,
B
Bruce Momjian 已提交
1889 1890
		 * service the interrupt immediately.  No point in interrupting if
		 * we're waiting for input, however.
1891
		 */
1892
		if (ImmediateInterruptOK && InterruptHoldoffCount == 0 &&
1893
			CritSectionCount == 0)
1894
		{
1895 1896 1897 1898 1899 1900
			/* bump holdoff count to make ProcessInterrupts() a no-op */
			/* until we are done getting ready for it */
			InterruptHoldoffCount++;
			if (LockWaitCancel())
			{
				DisableNotifyInterrupt();
T
Tom Lane 已提交
1901
				InterruptHoldoffCount--;
1902 1903 1904 1905
				ProcessInterrupts();
			}
			else
				InterruptHoldoffCount--;
1906
		}
1907 1908
	}

1909
	errno = save_errno;
1910 1911
}

1912 1913 1914 1915
/* signal handler for floating point exception */
static void
FloatExceptionHandler(SIGNAL_ARGS)
{
1916 1917 1918
	ereport(ERROR,
			(errcode(ERRCODE_FLOATING_POINT_EXCEPTION),
			 errmsg("floating-point exception"),
B
Bruce Momjian 已提交
1919 1920 1921
		   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.")));
1922 1923
}

1924
/* SIGHUP: set flag to re-read config file at next convenient time */
1925
static void
1926
SigHupHandler(SIGNAL_ARGS)
1927
{
1928
	got_SIGHUP = true;
1929 1930
}

1931

1932 1933 1934 1935 1936 1937 1938 1939 1940 1941
/*
 * 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)
{
1942 1943
	/* OK to accept interrupt now? */
	if (InterruptHoldoffCount != 0 || CritSectionCount != 0)
1944 1945 1946 1947 1948
		return;
	InterruptPending = false;
	if (ProcDiePending)
	{
		ProcDiePending = false;
B
Bruce Momjian 已提交
1949 1950
		QueryCancelPending = false;		/* ProcDie trumps QueryCancel */
		ImmediateInterruptOK = false;	/* not idle anymore */
1951
		DisableNotifyInterrupt();
1952 1953
		ereport(FATAL,
				(errcode(ERRCODE_ADMIN_SHUTDOWN),
B
Bruce Momjian 已提交
1954
		 errmsg("terminating connection due to administrator command")));
1955 1956 1957 1958
	}
	if (QueryCancelPending)
	{
		QueryCancelPending = false;
B
Bruce Momjian 已提交
1959
		ImmediateInterruptOK = false;	/* not idle anymore */
1960
		DisableNotifyInterrupt();
1961 1962 1963
		ereport(ERROR,
				(errcode(ERRCODE_QUERY_CANCELED),
				 errmsg("canceling query due to user request")));
1964 1965 1966 1967
	}
	/* If we get here, do nothing (probably, QueryCancelPending was reset) */
}

1968

1969 1970
static void
usage(char *progname)
1971
{
1972
	printf(gettext("%s is the PostgreSQL stand-alone backend.  It is not\nintended to be used by normal users.\n\n"), progname);
1973

1974 1975
	printf(gettext("Usage:\n  %s [OPTION]... [DBNAME]\n\n"), progname);
	printf(gettext("Options:\n"));
M
 
Marc G. Fournier 已提交
1976
#ifdef USE_ASSERT_CHECKING
1977
	printf(gettext("  -A 1|0          enable/disable run-time assert checking\n"));
M
 
Marc G. Fournier 已提交
1978
#endif
1979 1980 1981 1982 1983 1984 1985 1986 1987 1988 1989
	printf(gettext("  -B NBUFFERS     number of shared buffers\n"));
	printf(gettext("  -c NAME=VALUE   set run-time parameter\n"));
	printf(gettext("  -d 0-5          debugging level (0 is off)\n"));
	printf(gettext("  -D DATADIR      database directory\n"));
	printf(gettext("  -e              use European date input format (DMY)\n"));
	printf(gettext("  -E              echo query before execution\n"));
	printf(gettext("  -F              turn fsync off\n"));
	printf(gettext("  -N              do not use newline as interactive query delimiter\n"));
	printf(gettext("  -o FILENAME     send stdout and stderr to given file\n"));
	printf(gettext("  -P              disable system indexes\n"));
	printf(gettext("  -s              show statistics after each query\n"));
1990
	printf(gettext("  -S WORK-MEM     set amount of memory for sorts (in kbytes)\n"));
1991
	printf(gettext("  --describe-config  describe configuration parameters, then exit\n"));
1992 1993 1994 1995 1996 1997 1998 1999 2000
	printf(gettext("  --help          show this help, then exit\n"));
	printf(gettext("  --version       output version information, then exit\n"));
	printf(gettext("\nDeveloper options:\n"));
	printf(gettext("  -f s|i|n|m|h    forbid use of some plan types\n"));
	printf(gettext("  -i              do not execute queries\n"));
	printf(gettext("  -O              allow system table structure changes\n"));
	printf(gettext("  -t pa|pl|ex     show timings after each query\n"));
	printf(gettext("  -W NUM          wait NUM seconds to allow attach from a debugger\n"));
	printf(gettext("\nReport bugs to <pgsql-bugs@postgresql.org>.\n"));
2001 2002
}

2003 2004


2005
/* ----------------------------------------------------------------
2006
 * PostgresMain
B
Bruce Momjian 已提交
2007
 *	   postgres main loop -- all backends, interactive or otherwise start here
2008
 *
2009 2010 2011 2012
 * 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.
2013 2014 2015
 * ----------------------------------------------------------------
 */
int
2016
PostgresMain(int argc, char *argv[], const char *username)
2017
{
2018
	int			flag;
2019
	const char *dbname = NULL;
2020
	char	   *potential_DataDir = NULL;
2021
	bool		secure;
2022
	int			errs = 0;
2023
	int			debug_flag = 0;
B
Bruce Momjian 已提交
2024 2025
	GucContext	ctx,
				debug_context;
2026
	GucSource	gucsource;
2027
	char	   *tmp;
2028
	int			firstchar;
2029
	StringInfoData	input_message;
2030
	volatile bool send_rfq = true;
2031

2032
	/*
B
Bruce Momjian 已提交
2033 2034
	 * Catch standard options before doing much else.  This even works on
	 * systems without getopt_long.
2035 2036 2037
	 */
	if (!IsUnderPostmaster && argc > 1)
	{
B
Bruce Momjian 已提交
2038
		if (strcmp(argv[1], "--help") == 0 || strcmp(argv[1], "-?") == 0)
2039 2040 2041 2042
		{
			usage(argv[0]);
			exit(0);
		}
B
Bruce Momjian 已提交
2043
		if (strcmp(argv[1], "--version") == 0 || strcmp(argv[1], "-V") == 0)
2044 2045 2046 2047
		{
			puts("postgres (PostgreSQL) " PG_VERSION);
			exit(0);
		}
B
Bruce Momjian 已提交
2048
	}
2049

2050 2051 2052 2053 2054 2055
	/*
	 * initialize globals (already done if under postmaster, but not if
	 * standalone; cheap enough to do over)
	 */
	MyProcPid = getpid();

2056 2057 2058 2059 2060
	/*
	 * Fire up essential subsystems: error and memory management
	 *
	 * If we are running under the postmaster, this is done already.
	 */
2061
	if (!IsUnderPostmaster)
2062 2063
		MemoryContextInit();

2064 2065
	set_ps_display("startup");

2066 2067
	SetProcessingMode(InitProcessing);

2068
	/*
2069
	 * Set default values for command-line options.
2070
	 */
2071
	EchoQuery = false;
2072

2073
	if (!IsUnderPostmaster)
2074
	{
2075
		InitializeGUCOptions();
2076
		potential_DataDir = getenv("PGDATA");
2077
	}
2078

2079 2080 2081 2082 2083 2084 2085 2086 2087 2088 2089 2090 2091 2092 2093 2094 2095
	/* ----------------
	 *	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.
	 * ----------------
	 */

2096 2097
	/* all options are allowed until '-p' */
	secure = true;
2098
	ctx = debug_context = PGC_POSTMASTER;
2099
	gucsource = PGC_S_ARGV;		/* initial switches came from command line */
2100

2101
	while ((flag = getopt(argc, argv, "A:B:c:D:d:Eef:FiNOPo:p:S:st:v:W:x:-:")) != -1)
2102 2103
		switch (flag)
		{
M
 
Marc G. Fournier 已提交
2104 2105
			case 'A':
#ifdef USE_ASSERT_CHECKING
2106
				SetConfigOption("debug_assertions", optarg, ctx, gucsource);
M
 
Marc G. Fournier 已提交
2107
#else
2108 2109 2110
				ereport(WARNING,
						(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
						 errmsg("assert checking is not compiled in")));
M
 
Marc G. Fournier 已提交
2111 2112
#endif
				break;
2113

2114
			case 'B':
2115 2116 2117

				/*
				 * specify the size of buffer pool
2118
				 */
2119
				SetConfigOption("shared_buffers", optarg, ctx, gucsource);
2120
				break;
2121

2122
			case 'D':			/* PGDATA directory */
2123
				if (secure)
2124
					potential_DataDir = optarg;
M
 
Marc G. Fournier 已提交
2125
				break;
2126

2127
			case 'd':			/* debug level */
2128
				{
2129
					/*
B
Bruce Momjian 已提交
2130 2131 2132 2133 2134
					 * Client option can't decrease debug level. We have
					 * to do the test here because we group priv and
					 * client set GUC calls below, after we know the final
					 * debug value.
					 */
2135
					if (ctx != PGC_BACKEND || atoi(optarg) > debug_flag)
2136
					{
2137
						debug_flag = atoi(optarg);
B
Bruce Momjian 已提交
2138 2139
						debug_context = ctx;	/* save context for use
												 * below */
2140 2141 2142 2143
						/* Set server debugging level. */
						if (debug_flag != 0)
						{
							char	   *debugstr = palloc(strlen("debug") + strlen(optarg) + 1);
B
Bruce Momjian 已提交
2144

2145 2146 2147
							sprintf(debugstr, "debug%s", optarg);
							SetConfigOption("log_min_messages", debugstr, ctx, gucsource);
							pfree(debugstr);
B
Bruce Momjian 已提交
2148

2149 2150
						}
						else
B
Bruce Momjian 已提交
2151

2152 2153
							/*
							 * -d0 allows user to prevent postmaster debug
B
Bruce Momjian 已提交
2154 2155 2156
							 * from propagating to backend.  It would be
							 * nice to set it to the postgresql.conf value
							 * here.
2157 2158 2159
							 */
							SetConfigOption("log_min_messages", "notice",
											ctx, gucsource);
2160 2161
					}
				}
2162
				break;
2163 2164

			case 'E':
2165 2166 2167

				/*
				 * E - echo the query the user entered
2168
				 */
2169
				EchoQuery = true;
2170
				break;
2171 2172

			case 'e':
2173 2174

				/*
2175
				 * Use European date input format (DMY)
2176
				 */
2177
				SetConfigOption("datestyle", "euro", ctx, gucsource);
2178
				break;
2179 2180

			case 'F':
2181 2182 2183

				/*
				 * turn off fsync
2184
				 */
2185
				SetConfigOption("fsync", "false", ctx, gucsource);
2186
				break;
2187 2188

			case 'f':
2189 2190 2191

				/*
				 * f - forbid generation of certain plans
2192
				 */
2193
				tmp = NULL;
2194 2195 2196
				switch (optarg[0])
				{
					case 's':	/* seqscan */
2197
						tmp = "enable_seqscan";
2198 2199
						break;
					case 'i':	/* indexscan */
2200
						tmp = "enable_indexscan";
2201 2202
						break;
					case 't':	/* tidscan */
2203
						tmp = "enable_tidscan";
2204 2205
						break;
					case 'n':	/* nestloop */
2206
						tmp = "enable_nestloop";
2207 2208
						break;
					case 'm':	/* mergejoin */
2209
						tmp = "enable_mergejoin";
2210 2211
						break;
					case 'h':	/* hashjoin */
2212
						tmp = "enable_hashjoin";
2213 2214 2215 2216
						break;
					default:
						errs++;
				}
2217
				if (tmp)
2218
					SetConfigOption(tmp, "false", ctx, gucsource);
2219 2220
				break;

2221
			case 'N':
2222 2223 2224

				/*
				 * N - Don't use newline as a query delimiter
2225 2226 2227
				 */
				UseNewLine = 0;
				break;
2228

2229
			case 'O':
2230 2231 2232

				/*
				 * allow system table structure modifications
2233
				 */
2234 2235
				if (secure)		/* XXX safe to allow from client??? */
					allowSystemTableMods = true;
2236 2237
				break;

H
Hiroshi Inoue 已提交
2238
			case 'P':
2239 2240 2241

				/*
				 * ignore system indexes
2242 2243 2244 2245
				 *
				 * As of PG 7.4 this is safe to allow from the client,
				 * since it only disables reading the system indexes,
				 * not writing them.  Worst case consequence is slowness.
H
Hiroshi Inoue 已提交
2246
				 */
2247
				IgnoreSystemIndexes(true);
H
Hiroshi Inoue 已提交
2248 2249
				break;

T
Tom Lane 已提交
2250
			case 'o':
2251 2252 2253

				/*
				 * o - send output (stdout and stderr) to the given file
T
Tom Lane 已提交
2254
				 */
2255 2256
				if (secure)
					StrNCpy(OutputFileName, optarg, MAXPGPATH);
T
Tom Lane 已提交
2257 2258
				break;

2259
			case 'p':
2260 2261 2262
				/*
				 * p - special flag passed if backend was forked by a
				 * postmaster.
2263
				 */
2264 2265
				if (secure)
				{
2266
					dbname = strdup(optarg);
2267

B
Bruce Momjian 已提交
2268 2269
					secure = false;		/* subsequent switches are NOT
										 * secure */
2270
					ctx = PGC_BACKEND;
2271
					gucsource = PGC_S_CLIENT;
2272
				}
2273
				break;
2274

2275
			case 'S':
2276 2277 2278

				/*
				 * S - amount of sort memory to use in 1k bytes
2279
				 */
2280
				SetConfigOption("work_mem", optarg, ctx, gucsource);
2281
				break;
2282 2283

			case 's':
2284 2285 2286

				/*
				 * s - report usage statistics (timings) after each query
2287
				 */
2288
				SetConfigOption("log_statement_stats", "true", ctx, gucsource);
M
 
Marc G. Fournier 已提交
2289 2290
				break;

2291
			case 't':
2292
				/* ---------------
2293 2294 2295 2296 2297 2298 2299 2300 2301
				 *	tell postgres to report usage statistics (timings) for
				 *	each query
				 *
				 *	-tpa[rser] = print stats for parser time of each query
				 *	-tpl[anner] = print stats for planner time of each query
				 *	-te[xecutor] = print stats for executor time of each query
				 *	caution: -s can not be used together with -t.
				 * ----------------
				 */
2302
				tmp = NULL;
2303 2304 2305 2306
				switch (optarg[0])
				{
					case 'p':
						if (optarg[1] == 'a')
B
Rename:  
Bruce Momjian 已提交
2307
							tmp = "log_parser_stats";
2308
						else if (optarg[1] == 'l')
B
Rename:  
Bruce Momjian 已提交
2309
							tmp = "log_planner_stats";
2310 2311 2312 2313
						else
							errs++;
						break;
					case 'e':
2314
						tmp = "log_executor_stats";
2315 2316 2317 2318 2319
						break;
					default:
						errs++;
						break;
				}
2320
				if (tmp)
2321
					SetConfigOption(tmp, "true", ctx, gucsource);
2322 2323
				break;

2324
			case 'v':
2325 2326
				if (secure)
					FrontendProtocol = (ProtocolVersion) atoi(optarg);
2327 2328
				break;

M
 
Marc G. Fournier 已提交
2329
			case 'W':
2330 2331 2332

				/*
				 * wait N seconds to allow attach from a debugger
M
 
Marc G. Fournier 已提交
2333 2334 2335 2336
				 */
				sleep(atoi(optarg));
				break;

2337
			case 'x':
B
Bruce Momjian 已提交
2338
#ifdef NOT_USED					/* planner/xfunc.h */
2339 2340 2341 2342 2343 2344 2345

				/*
				 * control joey hellerstein's expensive function
				 * optimization
				 */
				if (XfuncMode != 0)
				{
B
Bruce Momjian 已提交
2346
					elog(WARNING, "only one -x flag is allowed");
2347 2348 2349 2350 2351 2352 2353 2354 2355 2356 2357 2358 2359 2360 2361 2362 2363
					errs++;
					break;
				}
				if (strcmp(optarg, "off") == 0)
					XfuncMode = XFUNC_OFF;
				else if (strcmp(optarg, "nor") == 0)
					XfuncMode = XFUNC_NOR;
				else if (strcmp(optarg, "nopull") == 0)
					XfuncMode = XFUNC_NOPULL;
				else if (strcmp(optarg, "nopm") == 0)
					XfuncMode = XFUNC_NOPM;
				else if (strcmp(optarg, "pullall") == 0)
					XfuncMode = XFUNC_PULLALL;
				else if (strcmp(optarg, "wait") == 0)
					XfuncMode = XFUNC_WAIT;
				else
				{
B
Bruce Momjian 已提交
2364
					elog(WARNING, "use -x {off,nor,nopull,nopm,pullall,wait}");
2365 2366
					errs++;
				}
2367
#endif
2368
				break;
2369

2370
			case 'c':
2371
			case '-':
2372
				{
B
Bruce Momjian 已提交
2373 2374
					char	   *name,
							   *value;
2375

B
Bruce Momjian 已提交
2376 2377 2378 2379
					ParseLongOption(optarg, &name, &value);
					if (!value)
					{
						if (flag == '-')
2380 2381 2382 2383
							ereport(ERROR,
									(errcode(ERRCODE_SYNTAX_ERROR),
									 errmsg("--%s requires a value",
											optarg)));
B
Bruce Momjian 已提交
2384
						else
2385 2386 2387 2388
							ereport(ERROR,
									(errcode(ERRCODE_SYNTAX_ERROR),
									 errmsg("-c %s requires a value",
											optarg)));
B
Bruce Momjian 已提交
2389 2390
					}

2391
					SetConfigOption(name, value, ctx, gucsource);
B
Bruce Momjian 已提交
2392 2393 2394 2395 2396
					free(name);
					if (value)
						free(value);
					break;
				}
2397

2398 2399
			default:
				errs++;
T
Tom Lane 已提交
2400
				break;
2401 2402
		}

2403

2404
	/*
2405 2406
	 * -d is not the same as setting log_min_messages because it enables
	 * other output options.
2407 2408
	 */
	if (debug_flag >= 1)
2409
		SetConfigOption("log_connections", "true", debug_context, gucsource);
2410
	if (debug_flag >= 2)
2411
		SetConfigOption("log_statement", "true", debug_context, gucsource);
2412
	if (debug_flag >= 3)
2413
		SetConfigOption("debug_print_parse", "true", debug_context, gucsource);
2414
	if (debug_flag >= 4)
2415
		SetConfigOption("debug_print_plan", "true", debug_context, gucsource);
2416
	if (debug_flag >= 5)
2417
		SetConfigOption("debug_print_rewritten", "true", debug_context, gucsource);
2418

2419
	/*
B
Bruce Momjian 已提交
2420 2421
	 * Process any additional GUC variable settings passed in startup
	 * packet.
2422 2423 2424
	 */
	if (MyProcPort != NULL)
	{
B
Bruce Momjian 已提交
2425
		List	   *gucopts = MyProcPort->guc_options;
2426 2427 2428 2429 2430 2431 2432 2433 2434 2435 2436 2437 2438 2439

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

			name = lfirst(gucopts);
			gucopts = lnext(gucopts);
			value = lfirst(gucopts);
			gucopts = lnext(gucopts);
			SetConfigOption(name, value, PGC_BACKEND, PGC_S_CLIENT);
		}
	}

2440 2441 2442
	/*
	 * Post-processing for command line options.
	 */
B
Rename:  
Bruce Momjian 已提交
2443 2444
	if (log_statement_stats &&
		(log_parser_stats || log_planner_stats || log_executor_stats))
2445
	{
2446 2447
		ereport(WARNING,
				(errcode(ERRCODE_INVALID_PARAMETER_VALUE),
2448
				 errmsg("statement-level statistics are disabled because parser, planner, or executor statistics are on")));
2449
		SetConfigOption("log_statement_stats", "false", ctx, gucsource);
2450 2451
	}

2452
	if (!IsUnderPostmaster || ExecBackend)
2453
	{
2454 2455
		if (!potential_DataDir)
		{
2456 2457 2458 2459 2460
			fprintf(stderr,
					gettext("%s does not know where to find the database system data.\n"
							"You must specify the directory that contains the database system\n"
							"either by specifying the -D invocation option or by setting the\n"
							"PGDATA environment variable.\n"),
2461 2462 2463 2464
					argv[0]);
			proc_exit(1);
		}
		SetDataDir(potential_DataDir);
2465
	}
2466
	Assert(DataDir);
2467

2468 2469 2470
	/* Acquire configuration parameters */
	if (IsUnderPostmaster)
	{
2471
#ifdef EXEC_BACKEND
2472
		read_nondefault_variables();
2473
#endif
2474
	} else
2475
		ProcessConfigFile(PGC_POSTMASTER);
2476

2477
	/*
2478
	 * Set up signal handlers and masks.
2479
	 *
2480
	 * Note that postmaster blocked all signals before forking child process,
B
Bruce Momjian 已提交
2481 2482
	 * so there is no race condition whereby we might receive a signal
	 * before we have set up the handler.
T
Tom Lane 已提交
2483 2484
	 *
	 * Also note: it's best not to use any signals that are SIG_IGNored in
B
Bruce Momjian 已提交
2485
	 * the postmaster.	If such a signal arrives before we are able to
2486
	 * change the handler to non-SIG_IGN, it'll get dropped.  Instead,
B
Bruce Momjian 已提交
2487 2488
	 * make a dummy handler in the postmaster to reserve the signal. (Of
	 * course, this isn't an issue for signals that are locally generated,
2489
	 * such as SIGALRM and SIGPIPE.)
2490
	 */
2491
	pqsignal(SIGHUP, SigHupHandler);	/* set flag to read config file */
B
Bruce Momjian 已提交
2492
	pqsignal(SIGINT, StatementCancelHandler);	/* cancel current query */
2493
	pqsignal(SIGTERM, die);		/* cancel current query and exit */
2494
	pqsignal(SIGQUIT, quickdie);	/* hard crash time */
B
Bruce Momjian 已提交
2495
	pqsignal(SIGALRM, handle_sig_alarm);		/* timeout conditions */
2496 2497 2498 2499 2500

	/*
	 * Ignore failure to write to frontend. Note: if frontend closes
	 * connection, we will notice it and exit cleanly when control next
	 * returns to outer loop.  This seems safer than forcing exit in the
2501 2502 2503
	 * midst of output during who-knows-what operation...
	 */
	pqsignal(SIGPIPE, SIG_IGN);
B
Bruce Momjian 已提交
2504
	pqsignal(SIGUSR1, SIG_IGN); /* this signal available for use */
2505

2506
	pqsignal(SIGUSR2, Async_NotifyHandler);		/* flush also sinval cache */
2507
	pqsignal(SIGFPE, FloatExceptionHandler);
2508 2509

	/*
B
Bruce Momjian 已提交
2510 2511
	 * Reset some signals that are accepted by postmaster but not by
	 * backend
2512
	 */
2513 2514
	pqsignal(SIGCHLD, SIG_DFL); /* system() requires this on some
								 * platforms */
2515

2516 2517
	pqinitmask();

T
Tom Lane 已提交
2518
	/* We allow SIGQUIT (quickdie) at all times */
2519
#ifdef HAVE_SIGPROCMASK
T
Tom Lane 已提交
2520
	sigdelset(&BlockSig, SIGQUIT);
2521
#else
T
Tom Lane 已提交
2522
	BlockSig &= ~(sigmask(SIGQUIT));
2523 2524
#endif

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

2527

2528
	if (IsUnderPostmaster)
2529
	{
2530
		/* noninteractive case: nothing should be left after switches */
2531
		if (errs || argc != optind || dbname == NULL)
2532
		{
2533 2534
			ereport(FATAL,
					(errcode(ERRCODE_SYNTAX_ERROR),
2535 2536
					 errmsg("invalid command-line arguments for server process"),
					 errhint("Try \"%s --help\" for more information.", argv[0])));
2537
		}
2538

2539 2540 2541
		XLOGPathInit();

		BaseInit();
2542
	}
2543
	else
2544
	{
2545 2546 2547
		/* interactive case: database name can be last arg on command line */
		if (errs || argc - optind > 1)
		{
2548 2549 2550 2551
			ereport(FATAL,
					(errcode(ERRCODE_SYNTAX_ERROR),
					 errmsg("%s: invalid command-line arguments",
							argv[0]),
2552
					 errhint("Try \"%s --help\" for more information.", argv[0])));
2553 2554
		}
		else if (argc - optind == 1)
2555 2556
			dbname = argv[optind];
		else if ((dbname = username) == NULL)
2557
		{
2558 2559 2560 2561
			ereport(FATAL,
					(errcode(ERRCODE_INVALID_PARAMETER_VALUE),
					 errmsg("%s: no database nor user name specified",
							argv[0])));
2562
		}
2563

2564 2565 2566 2567 2568
		/*
		 * On some systems our dynloader code needs the executable's
		 * pathname.  (If under postmaster, this was done already.)
		 */
		if (FindExec(pg_pathname, argv[0], "postgres") < 0)
2569 2570 2571
			ereport(FATAL,
					(errmsg("%s: could not locate postgres executable",
							argv[0])));
2572

2573
		/*
2574 2575
		 * Validate we have been given a reasonable-looking DataDir (if
		 * under postmaster, assume postmaster did this already).
2576 2577 2578
		 */
		ValidatePgVersion(DataDir);

2579
		/*
2580
		 * Create lockfile for data directory.
2581
		 */
2582
		CreateDataDirLockFile(DataDir, false);
2583

2584
		XLOGPathInit();
2585
		BaseInit();
2586 2587 2588 2589 2590

		/*
		 * Start up xlog for standalone backend, and register to have it
		 * closed down at exit.
		 */
2591
		StartupXLOG();
2592
		on_shmem_exit(ShutdownXLOG, 0);
2593 2594 2595 2596 2597 2598 2599

		/*
		 * Read any existing FSM cache file, and register to write one out
		 * at exit.
		 */
		LoadFreeSpaceMap();
		on_shmem_exit(DumpFreeSpaceMap, 0);
2600 2601
	}

2602
	/*
2603 2604 2605 2606 2607
	 * General initialization.
	 *
	 * NOTE: if you are tempted to add code in this vicinity, consider
	 * putting it inside InitPostgres() instead.  In particular, anything
	 * that involves database access should be there, not here.
2608
	 */
2609 2610
	ereport(DEBUG3,
			(errmsg_internal("InitPostgres")));
2611
	InitPostgres(dbname, username);
2612

2613
	SetProcessingMode(NormalProcessing);
2614

2615 2616
	/*
	 * Send this backend's cancellation info to the frontend.
2617
	 */
M
 
Marc G. Fournier 已提交
2618 2619 2620
	if (whereToSendOutput == Remote &&
		PG_PROTOCOL_MAJOR(FrontendProtocol) >= 2)
	{
2621
		StringInfoData buf;
B
Bruce Momjian 已提交
2622

2623
		pq_beginmessage(&buf, 'K');
2624 2625 2626
		pq_sendint(&buf, (int32) MyProcPid, sizeof(int32));
		pq_sendint(&buf, (int32) MyCancelKey, sizeof(int32));
		pq_endmessage(&buf);
M
 
Marc G. Fournier 已提交
2627 2628 2629
		/* Need not flush since ReadyForQuery will do it. */
	}

2630 2631
	/* Welcome banner for standalone case */
	if (whereToSendOutput == Debug)
2632
		printf("\nPostgreSQL stand-alone backend %s\n", PG_VERSION);
2633

2634 2635 2636
	/*
	 * Create the memory context we will use in the main loop.
	 *
2637 2638
	 * MessageContext is reset once per iteration of the main loop, ie, upon
	 * completion of processing of each command message from the client.
2639
	 */
2640 2641 2642 2643 2644
	MessageContext = AllocSetContextCreate(TopMemoryContext,
										   "MessageContext",
										   ALLOCSET_DEFAULT_MINSIZE,
										   ALLOCSET_DEFAULT_INITSIZE,
										   ALLOCSET_DEFAULT_MAXSIZE);
2645

2646 2647 2648 2649 2650 2651 2652
	/* ----------
	 * Tell the statistics collector that we're alive and
	 * to which database we belong.
	 * ----------
	 */
	pgstat_bestart();

2653 2654
	/*
	 * POSTGRES main processing loop begins here
2655
	 *
2656 2657
	 * If an exception is encountered, processing resumes here so we abort
	 * the current transaction and start a new one.
2658 2659 2660 2661
	 */

	if (sigsetjmp(Warn_restart, 1) != 0)
	{
2662
		/*
2663
		 * NOTE: if you are tempted to add more code in this if-block,
B
Bruce Momjian 已提交
2664 2665
		 * consider the probability that it should be in
		 * AbortTransaction() instead.
2666
		 *
2667 2668
		 * Make sure we're not interrupted while cleaning up.  Also forget
		 * any pending QueryCancel request, since we're aborting anyway.
B
Bruce Momjian 已提交
2669 2670
		 * Force InterruptHoldoffCount to a known state in case we
		 * ereport'd from inside a holdoff section.
2671 2672 2673
		 */
		ImmediateInterruptOK = false;
		QueryCancelPending = false;
2674 2675
		InterruptHoldoffCount = 1;
		CritSectionCount = 0;	/* should be unnecessary, but... */
2676
		disable_sig_alarm(true);
B
Bruce Momjian 已提交
2677
		QueryCancelPending = false;		/* again in case timeout occurred */
2678
		DisableNotifyInterrupt();
2679
		debug_query_string = NULL;
2680 2681

		/*
2682 2683 2684 2685 2686 2687
		 * Make sure we are in a valid memory context during recovery.
		 *
		 * We use ErrorContext in hopes that it will have some free space
		 * even if we're otherwise up against it...
		 */
		MemoryContextSwitchTo(ErrorContext);
2688

2689
		/* Do the recovery */
2690 2691
		ereport(DEBUG2,
				(errmsg_internal("AbortCurrentTransaction")));
2692
		AbortCurrentTransaction();
2693 2694

		/*
2695 2696
		 * Now return to normal top-level context and clear ErrorContext
		 * for next time.
2697 2698 2699
		 */
		MemoryContextSwitchTo(TopMemoryContext);
		MemoryContextResetAndDeleteChildren(ErrorContext);
2700 2701
		PortalContext = NULL;
		QueryContext = NULL;
2702 2703 2704 2705 2706

		/*
		 * Clear flag to indicate that we got out of error recovery mode
		 * successfully.  (Flag was set in elog.c before longjmp().)
		 */
2707
		InError = false;
2708 2709
		xact_started = false;

J
Jan Wieck 已提交
2710 2711 2712 2713 2714
		/*
		 * Clear flag that causes accounting for cost based vacuum.
		 */
		VacuumCostActive = false;

2715 2716
		/*
		 * If we were handling an extended-query-protocol message,
B
Bruce Momjian 已提交
2717 2718
		 * initiate skip till next Sync.  This also causes us not to issue
		 * ReadyForQuery (until we get Sync).
2719 2720 2721
		 */
		if (doing_extended_query_message)
			ignore_till_sync = true;
2722 2723

		/*
2724
		 * Exit interrupt holdoff section we implicitly established above.
2725
		 */
2726
		RESUME_INTERRUPTS();
2727
	}
2728

2729
	Warn_restart_ready = true;	/* we can now handle ereport(ERROR) */
2730

2731
	PG_SETMASK(&UnBlockSig);
2732

2733 2734
	if (!ignore_till_sync)
		send_rfq = true;		/* initially, or after error */
2735

2736 2737
	/*
	 * Non-error queries loop here.
2738 2739 2740 2741
	 */

	for (;;)
	{
2742
		/*
B
Bruce Momjian 已提交
2743 2744
		 * At top of loop, reset extended-query-message flag, so that any
		 * errors encountered in "idle" state don't provoke skip.
2745 2746 2747
		 */
		doing_extended_query_message = false;

2748
		/*
B
Bruce Momjian 已提交
2749
		 * Release storage left over from prior query cycle, and create a
2750
		 * new query input buffer in the cleared MessageContext.
2751
		 */
2752 2753
		MemoryContextSwitchTo(MessageContext);
		MemoryContextResetAndDeleteChildren(MessageContext);
2754

2755
		initStringInfo(&input_message);
2756

2757
		/*
2758 2759
		 * (1) If we've reached idle state, tell the frontend we're ready
		 * for a new query.
2760
		 *
2761
		 * Note: this includes fflush()'ing the last of the prior output.
2762 2763 2764 2765 2766
		 *
		 * This is also a good time to send collected statistics to the
		 * collector, and to update the PS stats display.  We avoid doing
		 * those every time through the message loop because it'd slow down
		 * processing of batched messages.
B
Bruce Momjian 已提交
2767
		 */
2768 2769
		if (send_rfq)
		{
2770
			pgstat_report_tabstat();
B
Bruce Momjian 已提交
2771

2772
			if (IsTransactionOrTransactionBlock())
2773 2774 2775 2776 2777 2778 2779 2780 2781
			{
				set_ps_display("idle in transaction");
				pgstat_report_activity("<IDLE> in transaction");
			}
			else
			{
				set_ps_display("idle");
				pgstat_report_activity("<IDLE>");
			}
2782

2783 2784
			ReadyForQuery(whereToSendOutput);
			send_rfq = false;
2785
		}
2786

2787 2788 2789 2790
		/*
		 * (2) deal with pending asynchronous NOTIFY from other backends,
		 * and enable async.c's signal handler to execute NOTIFY directly.
		 * Then set up other stuff needed before blocking for input.
2791
		 */
B
Bruce Momjian 已提交
2792 2793
		QueryCancelPending = false;		/* forget any earlier CANCEL
										 * signal */
2794 2795 2796

		EnableNotifyInterrupt();

2797 2798 2799 2800 2801 2802
		/* 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();

2803 2804
		/*
		 * (3) read a command (loop blocks here)
2805
		 */
2806
		firstchar = ReadCommand(&input_message);
2807

2808 2809
		/*
		 * (4) disable async signal conditions again.
2810
		 */
2811
		ImmediateInterruptOK = false;
B
Bruce Momjian 已提交
2812
		QueryCancelPending = false;		/* forget any CANCEL signal */
2813

2814 2815
		DisableNotifyInterrupt();

2816 2817 2818
		/*
		 * (5) check for any other interesting events that happened while
		 * we slept.
2819 2820 2821 2822
		 */
		if (got_SIGHUP)
		{
			got_SIGHUP = false;
2823 2824 2825
#ifdef EXEC_BACKEND
			read_nondefault_variables();
#else
2826
			ProcessConfigFile(PGC_SIGHUP);
2827
#endif
2828 2829
		}

2830
		/*
B
Bruce Momjian 已提交
2831 2832
		 * (6) process the command.  But ignore it if we're skipping till
		 * Sync.
2833
		 */
2834
		if (ignore_till_sync && firstchar != EOF)
2835 2836
			continue;

2837 2838
		switch (firstchar)
		{
2839
			case 'Q':			/* simple query */
2840
				{
2841 2842
					const char *query_string;

2843 2844
					query_string = pq_getmsgstring(&input_message);
					pq_getmsgend(&input_message);
2845

2846
					exec_simple_query(query_string);
2847

2848 2849
					send_rfq = true;
				}
2850 2851
				break;

2852 2853 2854 2855 2856 2857 2858
			case 'P':			/* parse */
				{
					const char *stmt_name;
					const char *query_string;
					int			numParams;
					Oid		   *paramTypes = NULL;

2859 2860 2861
					stmt_name = pq_getmsgstring(&input_message);
					query_string = pq_getmsgstring(&input_message);
					numParams = pq_getmsgint(&input_message, 2);
2862 2863
					if (numParams > 0)
					{
B
Bruce Momjian 已提交
2864
						int			i;
2865 2866 2867

						paramTypes = (Oid *) palloc(numParams * sizeof(Oid));
						for (i = 0; i < numParams; i++)
2868
							paramTypes[i] = pq_getmsgint(&input_message, 4);
2869
					}
2870
					pq_getmsgend(&input_message);
2871 2872 2873 2874 2875 2876 2877

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

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

2879
				/*
B
Bruce Momjian 已提交
2880 2881
				 * this message is complex enough that it seems best to
				 * put the field extraction out-of-line
2882
				 */
2883
				exec_bind_message(&input_message);
2884 2885 2886 2887 2888
				break;

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

2891 2892 2893
					portal_name = pq_getmsgstring(&input_message);
					max_rows = pq_getmsgint(&input_message, 4);
					pq_getmsgend(&input_message);
2894

2895
					exec_execute_message(portal_name, max_rows);
2896 2897 2898
				}
				break;

2899 2900
			case 'F':			/* fastpath function call */
				/* Tell the collector what we're doing */
2901 2902
				pgstat_report_activity("<FASTPATH> function call");

2903
				/* start an xact for this function invocation */
2904
				start_xact_command();
2905

2906 2907 2908
				/* switch back to message context */
				MemoryContextSwitchTo(MessageContext);

2909
				if (HandleFunctionRequest(&input_message) == EOF)
2910 2911
				{
					/* lost frontend connection during F message input */
B
Bruce Momjian 已提交
2912

2913
					/*
2914
					 * Reset whereToSendOutput to prevent ereport from
B
Bruce Momjian 已提交
2915
					 * attempting to send any more messages to client.
2916 2917 2918 2919
					 */
					if (whereToSendOutput == Remote)
						whereToSendOutput = None;

2920
					proc_exit(0);
2921
				}
2922 2923

				/* commit the function-invocation transaction */
2924
				finish_xact_command();
2925

2926
				send_rfq = true;
2927 2928
				break;

B
Bruce Momjian 已提交
2929
			case 'C':			/* close */
2930
				{
B
Bruce Momjian 已提交
2931
					int			close_type;
2932 2933
					const char *close_target;

2934 2935 2936
					close_type = pq_getmsgbyte(&input_message);
					close_target = pq_getmsgstring(&input_message);
					pq_getmsgend(&input_message);
2937 2938 2939 2940 2941 2942 2943 2944 2945 2946 2947 2948 2949 2950 2951 2952 2953 2954 2955 2956 2957 2958 2959 2960 2961 2962 2963 2964

					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:
2965 2966
							ereport(ERROR,
									(errcode(ERRCODE_PROTOCOL_VIOLATION),
B
Bruce Momjian 已提交
2967 2968
							   errmsg("invalid CLOSE message subtype %d",
									  close_type)));
2969 2970 2971 2972
							break;
					}

					if (whereToSendOutput == Remote)
B
Bruce Momjian 已提交
2973
						pq_putemptymessage('3');		/* CloseComplete */
2974 2975 2976 2977 2978
				}
				break;

			case 'D':			/* describe */
				{
B
Bruce Momjian 已提交
2979
					int			describe_type;
2980 2981
					const char *describe_target;

2982 2983 2984
					describe_type = pq_getmsgbyte(&input_message);
					describe_target = pq_getmsgstring(&input_message);
					pq_getmsgend(&input_message);
2985 2986 2987 2988 2989 2990 2991 2992 2993 2994

					switch (describe_type)
					{
						case 'S':
							exec_describe_statement_message(describe_target);
							break;
						case 'P':
							exec_describe_portal_message(describe_target);
							break;
						default:
2995 2996
							ereport(ERROR,
									(errcode(ERRCODE_PROTOCOL_VIOLATION),
B
Bruce Momjian 已提交
2997 2998
							errmsg("invalid DESCRIBE message subtype %d",
								   describe_type)));
2999 3000 3001 3002 3003
							break;
					}
				}
				break;

B
Bruce Momjian 已提交
3004
			case 'H':			/* flush */
3005
				pq_getmsgend(&input_message);
3006 3007 3008 3009
				if (whereToSendOutput == Remote)
					pq_flush();
				break;

B
Bruce Momjian 已提交
3010
			case 'S':			/* sync */
3011
				pq_getmsgend(&input_message);
3012
				finish_xact_command();
3013 3014 3015
				send_rfq = true;
				break;

3016
				/*
B
Bruce Momjian 已提交
3017 3018 3019
				 * 'X' means that the frontend is closing down the socket.
				 * EOF means unexpected loss of frontend connection.
				 * Either way, perform normal shutdown.
3020 3021
				 */
			case 'X':
3022
			case EOF:
B
Bruce Momjian 已提交
3023

3024
				/*
B
Bruce Momjian 已提交
3025 3026
				 * Reset whereToSendOutput to prevent ereport from
				 * attempting to send any more messages to client.
3027 3028 3029
				 */
				if (whereToSendOutput == Remote)
					whereToSendOutput = None;
B
Bruce Momjian 已提交
3030

3031 3032
				/*
				 * NOTE: if you are tempted to add more code here, DON'T!
B
Bruce Momjian 已提交
3033 3034
				 * Whatever you had in mind to do should be set up as an
				 * on_proc_exit or on_shmem_exit callback, instead.
3035 3036 3037 3038
				 * Otherwise it will fail to be called during other
				 * backend-shutdown scenarios.
				 */
				proc_exit(0);
3039

B
Bruce Momjian 已提交
3040 3041 3042 3043
			case 'd':			/* copy data */
			case 'c':			/* copy done */
			case 'f':			/* copy fail */

3044
				/*
B
Bruce Momjian 已提交
3045 3046
				 * Accept but ignore these messages, per protocol spec; we
				 * probably got here because a COPY failed, and the
3047 3048 3049 3050
				 * frontend is still sending data.
				 */
				break;

3051
			default:
3052 3053 3054 3055
				ereport(FATAL,
						(errcode(ERRCODE_PROTOCOL_VIOLATION),
						 errmsg("invalid frontend message type %d",
								firstchar)));
3056
		}
3057
	}							/* end of input-reading loop */
3058

3059 3060
	/* can't get here because the above loop never exits */
	Assert(false);
3061

3062
	return 1;					/* keep compiler quiet */
3063 3064
}

3065
#ifndef HAVE_GETRUSAGE
B
Bruce Momjian 已提交
3066 3067
#include "rusagestub.h"
#else
3068
#include <sys/resource.h>
3069
#endif   /* HAVE_GETRUSAGE */
3070

3071 3072
static struct rusage Save_r;
static struct timeval Save_t;
3073 3074

void
3075
ResetUsage(void)
3076
{
3077
	getrusage(RUSAGE_SELF, &Save_r);
3078
	gettimeofday(&Save_t, NULL);
3079
	ResetBufferUsage();
3080
	/* ResetTupleCount(); */
3081 3082 3083
}

void
3084
ShowUsage(const char *title)
3085
{
3086
	StringInfoData str;
3087 3088 3089 3090
	struct timeval user,
				sys;
	struct timeval elapse_t;
	struct rusage r;
B
Bruce Momjian 已提交
3091
	char	   *bufusage;
3092 3093

	getrusage(RUSAGE_SELF, &r);
3094
	gettimeofday(&elapse_t, NULL);
3095 3096
	memcpy((char *) &user, (char *) &r.ru_utime, sizeof(user));
	memcpy((char *) &sys, (char *) &r.ru_stime, sizeof(sys));
3097 3098 3099 3100 3101 3102 3103 3104 3105 3106 3107 3108 3109 3110 3111 3112 3113 3114 3115 3116 3117 3118 3119 3120
	if (elapse_t.tv_usec < Save_t.tv_usec)
	{
		elapse_t.tv_sec--;
		elapse_t.tv_usec += 1000000;
	}
	if (r.ru_utime.tv_usec < Save_r.ru_utime.tv_usec)
	{
		r.ru_utime.tv_sec--;
		r.ru_utime.tv_usec += 1000000;
	}
	if (r.ru_stime.tv_usec < Save_r.ru_stime.tv_usec)
	{
		r.ru_stime.tv_sec--;
		r.ru_stime.tv_usec += 1000000;
	}

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

3123 3124
	appendStringInfo(&str, "! system usage stats:\n");
	appendStringInfo(&str,
3125
			"!\t%ld.%06ld elapsed %ld.%06ld user %ld.%06ld system sec\n",
3126 3127 3128
					 (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 已提交
3129
				   (long) (r.ru_utime.tv_usec - Save_r.ru_utime.tv_usec),
3130
					 (long) (r.ru_stime.tv_sec - Save_r.ru_stime.tv_sec),
B
Bruce Momjian 已提交
3131
				  (long) (r.ru_stime.tv_usec - Save_r.ru_stime.tv_usec));
3132
	appendStringInfo(&str,
B
Bruce Momjian 已提交
3133
					 "!\t[%ld.%06ld user %ld.%06ld sys total]\n",
3134 3135 3136 3137
					 (long) user.tv_sec,
					 (long) user.tv_usec,
					 (long) sys.tv_sec,
					 (long) sys.tv_usec);
3138
/* BeOS has rusage but only has some fields, and not these... */
3139
#if defined(HAVE_GETRUSAGE)
3140
	appendStringInfo(&str,
B
Bruce Momjian 已提交
3141 3142
					 "!\t%ld/%ld [%ld/%ld] filesystem blocks in/out\n",
					 r.ru_inblock - Save_r.ru_inblock,
3143
	/* they only drink coffee at dec */
B
Bruce Momjian 已提交
3144 3145
					 r.ru_oublock - Save_r.ru_oublock,
					 r.ru_inblock, r.ru_oublock);
3146
	appendStringInfo(&str,
3147
		  "!\t%ld/%ld [%ld/%ld] page faults/reclaims, %ld [%ld] swaps\n",
B
Bruce Momjian 已提交
3148 3149 3150 3151 3152
					 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);
3153
	appendStringInfo(&str,
3154
	 "!\t%ld [%ld] signals rcvd, %ld/%ld [%ld/%ld] messages rcvd/sent\n",
B
Bruce Momjian 已提交
3155 3156 3157 3158 3159
					 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);
3160
	appendStringInfo(&str,
3161
		 "!\t%ld/%ld [%ld/%ld] voluntary/involuntary context switches\n",
B
Bruce Momjian 已提交
3162 3163 3164
					 r.ru_nvcsw - Save_r.ru_nvcsw,
					 r.ru_nivcsw - Save_r.ru_nivcsw,
					 r.ru_nvcsw, r.ru_nivcsw);
3165
#endif   /* HAVE_GETRUSAGE */
3166 3167

	bufusage = ShowBufferUsage();
3168
	appendStringInfo(&str, "! buffer usage stats:\n%s", bufusage);
3169 3170 3171
	pfree(bufusage);

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

3175 3176 3177
	ereport(LOG,
			(errmsg_internal("%s", title),
			 errdetail("%s", str.data)));
3178 3179

	pfree(str.data);
3180
}