1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 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 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 617 618 619 620 621 622 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 666 667 668 669 670 671 672 673 674 675 676 677 678 679 680 681 682 683 684 685 686 687 688 689 690 691 692 693 694 695 696 697 698 699 700 701 702 703 704 705 706 707 708 709 710 711 712 713 714 715 716 717 718 719 720 721 722 723 724 725 726 727 728 729 730 731 732 733 734 735 736 737 738 739 740 741 742 743 744 745 746 747 748 749 750 751 752 753 754 755 756 757 758 759 760 761 762 763 764 765 766 767 768 769 770 771 772 773 774 775 776 777 778 779 780 781 782 783 784 785 786 787 788 789 790 791 792 793 794 795 796 797 798 799 800 801 802 803 804
|
/*--------------------------------------------------------------------
* Symbols referenced in this file:
* - debug_query_string
* - whereToSendOutput
* - ProcessInterrupts
* - check_stack_depth
* - stack_is_too_deep
* - stack_base_ptr
* - max_stack_depth_bytes
* - max_stack_depth
*--------------------------------------------------------------------
*/
/*-------------------------------------------------------------------------
*
* postgres.c
* POSTGRES C Backend Interface
*
* Portions Copyright (c) 1996-2023, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California
*
*
* IDENTIFICATION
* src/backend/tcop/postgres.c
*
* NOTES
* this is the "main" module of the postgres backend and
* hence the main module of the "traffic cop".
*
*-------------------------------------------------------------------------
*/
#include "postgres.h"
#include <fcntl.h>
#include <limits.h>
#include <signal.h>
#include <unistd.h>
#include <sys/resource.h>
#include <sys/socket.h>
#include <sys/time.h>
#ifdef USE_VALGRIND
#include <valgrind/valgrind.h>
#endif
#include "access/parallel.h"
#include "access/printtup.h"
#include "access/xact.h"
#include "catalog/pg_type.h"
#include "commands/async.h"
#include "commands/prepare.h"
#include "common/pg_prng.h"
#include "jit/jit.h"
#include "libpq/libpq.h"
#include "libpq/pqformat.h"
#include "libpq/pqsignal.h"
#include "mb/pg_wchar.h"
#include "mb/stringinfo_mb.h"
#include "miscadmin.h"
#include "nodes/print.h"
#include "optimizer/optimizer.h"
#include "parser/analyze.h"
#include "parser/parser.h"
#include "pg_getopt.h"
#include "pg_trace.h"
#include "pgstat.h"
#include "postmaster/autovacuum.h"
#include "postmaster/interrupt.h"
#include "postmaster/postmaster.h"
#include "replication/logicallauncher.h"
#include "replication/logicalworker.h"
#include "replication/slot.h"
#include "replication/walsender.h"
#include "rewrite/rewriteHandler.h"
#include "storage/bufmgr.h"
#include "storage/ipc.h"
#include "storage/pmsignal.h"
#include "storage/proc.h"
#include "storage/procsignal.h"
#include "storage/sinval.h"
#include "tcop/fastpath.h"
#include "tcop/pquery.h"
#include "tcop/tcopprot.h"
#include "tcop/utility.h"
#include "utils/guc_hooks.h"
#include "utils/lsyscache.h"
#include "utils/memutils.h"
#include "utils/ps_status.h"
#include "utils/snapmgr.h"
#include "utils/timeout.h"
#include "utils/timestamp.h"
/* ----------------
* global variables
* ----------------
*/
__thread const char *debug_query_string;
/* client-supplied query string */
/* Note: whereToSendOutput is initialized for the bootstrap/standalone case */
__thread CommandDest whereToSendOutput = DestDebug;
/* flag for logging end of session */
/* GUC variable for maximum stack depth (measured in kilobytes) */
__thread int max_stack_depth = 100;
/* wait N seconds to allow attach from a debugger */
/* Time between checks that the client is still connected. */
/* ----------------
* private typedefs etc
* ----------------
*/
/* type of argument for bind_param_error_callback */
typedef struct BindParamCbData
{
const char *portalName;
int paramno; /* zero-based param number, or -1 initially */
const char *paramval; /* textual input string, if available */
} BindParamCbData;
/* ----------------
* private variables
* ----------------
*/
/* max_stack_depth converted to bytes for speed of checking */
static __thread long max_stack_depth_bytes = 100 * 1024L;
/*
* Stack base pointer -- initialized by PostmasterMain and inherited by
* subprocesses (but see also InitPostmasterChild).
*/
static __thread char *stack_base_ptr = NULL;
/*
* Flag to keep track of whether we have started a transaction.
* For extended query protocol this has to be remembered across messages.
*/
/*
* Flag to indicate that we are doing the outer loop's read-from-client,
* as opposed to any random read from client that might happen within
* commands like COPY FROM STDIN.
*/
/*
* Flags to implement skip-till-Sync-after-error behavior for messages of
* the extended query protocol.
*/
/*
* 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.
*/
/* assorted command-line switches */
/* -D switch */
/* -E switch */
/* -j switch */
/* whether or not, and why, we were canceled by conflict with recovery */
/* reused buffer to pass to SendRowDescriptionMessage() */
/* ----------------------------------------------------------------
* decls for routines only used in this file
* ----------------------------------------------------------------
*/
static int InteractiveBackend(StringInfo inBuf);
static int interactive_getc(void);
static int SocketBackend(StringInfo inBuf);
static int ReadCommand(StringInfo inBuf);
static void forbidden_in_wal_sender(char firstchar);
static bool check_log_statement(List *stmt_list);
static int errdetail_execute(List *raw_parsetree_list);
static int errdetail_params(ParamListInfo params);
static int errdetail_abort(void);
static int errdetail_recovery_conflict(void);
static void bind_param_error_callback(void *arg);
static void start_xact_command(void);
static void finish_xact_command(void);
static bool IsTransactionExitStmt(Node *parsetree);
static bool IsTransactionExitStmtList(List *pstmts);
static bool IsTransactionStmtList(List *pstmts);
static void drop_unnamed_stmt(void);
static void log_disconnections(int code, Datum arg);
static void enable_statement_timeout(void);
static void disable_statement_timeout(void);
/* ----------------------------------------------------------------
* infrastructure for valgrind debugging
* ----------------------------------------------------------------
*/
#ifdef USE_VALGRIND
/* This variable should be set at the top of the main loop. */
static unsigned int old_valgrind_error_count;
/*
* If Valgrind detected any errors since old_valgrind_error_count was updated,
* report the current query as the cause. This should be called at the end
* of message processing.
*/
static void
valgrind_report_error_query(const char *query)
{
unsigned int valgrind_error_count = VALGRIND_COUNT_ERRORS;
if (unlikely(valgrind_error_count != old_valgrind_error_count) &&
query != NULL)
VALGRIND_PRINTF("Valgrind detected %u error(s) during execution of \"%s\"\n",
valgrind_error_count - old_valgrind_error_count,
query);
}
#else /* !USE_VALGRIND */
#define valgrind_report_error_query(query) ((void) 0)
#endif /* USE_VALGRIND */
/* ----------------------------------------------------------------
* routines to obtain user input
* ----------------------------------------------------------------
*/
/* ----------------
* InteractiveBackend() is called for user interactive connections
*
* the string entered by the user is placed in its parameter inBuf,
* and we act like a Q message was received.
*
* EOF is returned if end-of-file input is seen; time to shut down.
* ----------------
*/
/*
* interactive_getc -- collect one character from stdin
*
* Even though we are not reading from a "client" process, we still want to
* respond to signals, particularly SIGTERM/SIGQUIT.
*/
/* ----------------
* SocketBackend() Is called for frontend-backend connections
*
* Returns the message type code, and loads message body data into inBuf.
*
* EOF is returned if the connection is lost.
* ----------------
*/
/* ----------------
* ReadCommand reads a command from either the frontend or
* standard input, places it in inBuf, and returns the
* message type code (first byte of the message).
* EOF is returned if end of file.
* ----------------
*/
/*
* ProcessClientReadInterrupt() - Process interrupts specific to client reads
*
* This is called just before and after low-level reads.
* 'blocked' is true if no data was available to read and we plan to retry,
* false if about to read or done reading.
*
* Must preserve errno!
*/
/*
* ProcessClientWriteInterrupt() - Process interrupts specific to client writes
*
* This is called just before and after low-level writes.
* 'blocked' is true if no data could be written and we plan to retry,
* false if about to write or done writing.
*
* Must preserve errno!
*/
/*
* Do raw parsing (only).
*
* A list of parsetrees (RawStmt nodes) 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.
*/
#ifdef COPY_PARSE_PLAN_TREES
#endif
#ifdef WRITE_READ_PARSE_PLAN_TREES
#endif
/*
* Given a raw parsetree (gram.y output), and optionally information about
* types of parameter symbols ($n), perform parse analysis and rule rewriting.
*
* 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.
*/
/*
* Do parse analysis and rewriting. This is the same as
* pg_analyze_and_rewrite_fixedparams except that it's okay to deduce
* information about $n symbol datatypes from context.
*/
/*
* Do parse analysis and rewriting. This is the same as
* pg_analyze_and_rewrite_fixedparams except that, instead of a fixed list of
* parameter datatypes, a parser callback is supplied that can do
* external-parameter resolution and possibly other things.
*/
/*
* Perform rewriting of a query produced by parse analysis.
*
* Note: query must just have come from the parser, because we do not do
* AcquireRewriteLocks() on it.
*/
#ifdef COPY_PARSE_PLAN_TREES
#endif
#ifdef WRITE_READ_PARSE_PLAN_TREES
#endif
/*
* Generate a plan for a single already-rewritten query.
* This is a thin wrapper around planner() and takes the same parameters.
*/
#ifdef COPY_PARSE_PLAN_TREES
#ifdef NOT_USED
#endif
#endif
#ifdef WRITE_READ_PARSE_PLAN_TREES
#ifdef NOT_USED
#endif
#endif
/*
* Generate plans for a list of already-rewritten queries.
*
* For normal optimizable statements, invoke the planner. For utility
* statements, just make a wrapper PlannedStmt node.
*
* The result is a list of PlannedStmt nodes.
*/
/*
* exec_simple_query
*
* Execute a "simple Query" protocol message.
*/
/*
* exec_parse_message
*
* Execute a "Parse" protocol message.
*/
/*
* exec_bind_message
*
* Process a "Bind" message to create a portal from a prepared statement
*/
/*
* exec_execute_message
*
* Process an "Execute" message for a portal
*/
/*
* check_log_statement
* Determine whether command should be logged because of log_statement
*
* stmt_list can be either raw grammar output or a list of planned
* statements
*/
/*
* check_log_duration
* Determine whether current command's duration should be logged
* We also check if this statement in this transaction must be logged
* (regardless of its duration).
*
* Returns:
* 0 if no logging is needed
* 1 if just the duration should be logged
* 2 if duration and query details should be logged
*
* If logging is needed, the duration in msec is formatted into msec_str[],
* which must be a 32-byte buffer.
*
* was_logged should be true if caller already logged query details (this
* essentially prevents 2 from being returned).
*/
/*
* errdetail_execute
*
* Add an errdetail() line showing the query referenced by an EXECUTE, if any.
* The argument is the raw parsetree list.
*/
/*
* errdetail_params
*
* Add an errdetail() line showing bind-parameter data, if available.
* Note that this is only used for statement logging, so it is controlled
* by log_parameter_max_length not log_parameter_max_length_on_error.
*/
/*
* errdetail_abort
*
* Add an errdetail() line showing abort reason, if any.
*/
/*
* errdetail_recovery_conflict
*
* Add an errdetail() line showing conflict source.
*/
/*
* bind_param_error_callback
*
* Error context callback used while parsing parameters in a Bind message
*/
/*
* exec_describe_statement_message
*
* Process a "Describe" message for a prepared statement
*/
/*
* exec_describe_portal_message
*
* Process a "Describe" message for a portal
*/
/*
* Convenience routines for starting/committing a single command.
*/
#ifdef MEMORY_CONTEXT_CHECKING
#endif
#ifdef SHOW_MEMORY_STATS
#endif
/*
* Convenience routines for checking whether a statement is one of the
* ones that we allow in transaction-aborted state.
*/
/* Test a bare parsetree */
/* Test a list that contains PlannedStmt nodes */
/* Test a list that contains PlannedStmt nodes */
/* Release any existing unnamed prepared statement */
/* --------------------------------
* signal handler routines used in PostgresMain()
* --------------------------------
*/
/*
* quickdie() occurs when signaled SIGQUIT by the postmaster.
*
* Either some backend has bought the farm, or we've been told to shut down
* "immediately"; so we need to stop what we're doing and exit.
*/
/*
* Shutdown signal from postmaster: abort transaction and exit
* at soonest convenient time
*/
/*
* Query-cancel signal from postmaster: abort current transaction
* at soonest convenient time
*/
/* signal handler for floating point exception */
/*
* RecoveryConflictInterrupt: out-of-line portion of recovery conflict
* handling following receipt of SIGUSR1. Designed to be similar to die()
* and StatementCancelHandler(). Called only by a normal user backend
* that begins a transaction during recovery.
*/
/*
* 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.
*
* Note: if INTERRUPTS_CAN_BE_PROCESSED() is true, then ProcessInterrupts
* is guaranteed to clear the InterruptPending flag before returning.
* (This is not the same as guaranteeing that it's still clear when we
* return; another interrupt could have arrived. But we promise that
* any pre-existing one will have been serviced.)
*/
void ProcessInterrupts(void) {}
/*
* set_stack_base: set up reference point for stack depth checking
*
* Returns the old reference point, if any.
*/
#ifndef HAVE__BUILTIN_FRAME_ADDRESS
#endif
#ifdef HAVE__BUILTIN_FRAME_ADDRESS
#else
#endif
/*
* restore_stack_base: restore reference point for stack depth checking
*
* This can be used after set_stack_base() to restore the old value. This
* is currently only used in PL/Java. When PL/Java calls a backend function
* from different thread, the thread's stack is at a different location than
* the main thread's stack, so it sets the base pointer before the call, and
* restores it afterwards.
*/
/*
* check_stack_depth/stack_is_too_deep: check for excessively deep recursion
*
* This should be called someplace in any recursive routine that might possibly
* recurse deep enough to overflow the stack. Most Unixen treat stack
* overflow as an unrecoverable SIGSEGV, so we want to error out ourselves
* before hitting the hardware limit.
*
* check_stack_depth() just throws an error summarily. stack_is_too_deep()
* can be used by code that wants to handle the error condition itself.
*/
void
check_stack_depth(void)
{
if (stack_is_too_deep())
{
ereport(ERROR,
(errcode(ERRCODE_STATEMENT_TOO_COMPLEX),
errmsg("stack depth limit exceeded"),
errhint("Increase the configuration parameter \"max_stack_depth\" (currently %dkB), "
"after ensuring the platform's stack depth limit is adequate.",
max_stack_depth)));
}
}
bool
stack_is_too_deep(void)
{
char stack_top_loc;
long stack_depth;
/*
* Compute distance from reference point to my local variables
*/
stack_depth = (long) (stack_base_ptr - &stack_top_loc);
/*
* Take abs value, since stacks grow up on some machines, down on others
*/
if (stack_depth < 0)
stack_depth = -stack_depth;
/*
* Trouble?
*
* The test on stack_base_ptr prevents us from erroring out if called
* during process setup or in a non-backend process. Logically it should
* be done first, but putting it here avoids wasting cycles during normal
* cases.
*/
if (stack_depth > max_stack_depth_bytes &&
stack_base_ptr != NULL)
return true;
return false;
}
/* GUC check hook for max_stack_depth */
/* GUC assign hook for max_stack_depth */
/*
* GUC check_hook for client_connection_check_interval
*/
/*
* GUC check_hook for log_parser_stats, log_planner_stats, log_executor_stats
*
* This function and check_log_stats interact to prevent their variables from
* being set in a disallowed combination. This is a hack that doesn't really
* work right; for example it might fail while applying pg_db_role_setting
* values even though the final state would have been acceptable. However,
* since these variables are legacy settings with little production usage,
* we tolerate that.
*/
/*
* GUC check_hook for log_statement_stats
*/
/*
* set_debug_options --- apply "-d N" command line option
*
* -d is not quite the same as setting log_min_messages because it enables
* other output options.
*/
/* ----------------------------------------------------------------
* process_postgres_switches
* Parse command line arguments for backends
*
* This is called twice, once for the "secure" options coming from the
* postmaster or command line, and once for the "insecure" options coming
* from the client's startup packet. The latter have the same syntax but
* may be restricted in what they can do.
*
* argv[0] is ignored in either case (it's assumed to be the program name).
*
* ctx is PGC_POSTMASTER for secure options, PGC_BACKEND for insecure options
* coming from the client, or PGC_SU_BACKEND for insecure options coming from
* a superuser client.
*
* If a database name is present in the command line arguments, it's
* returned into *dbname (this is allowed only if *dbname is initially NULL).
* ----------------------------------------------------------------
*/
#ifdef HAVE_INT_OPTERR
#endif
#ifdef HAVE_INT_OPTRESET
#endif
/*
* PostgresSingleUserMain
* Entry point for single user mode. argc/argv are the command line
* arguments to be used.
*
* Performs single user specific setup then calls PostgresMain() to actually
* process queries. Single user mode specific setup should go here, rather
* than PostgresMain() or InitPostgres() when reasonably possible.
*/
/* ----------------------------------------------------------------
* PostgresMain
* postgres main loop -- all backends, interactive or otherwise loop here
*
* dbname is the name of the database to connect to, username is the
* PostgreSQL user name to be used for the session.
*
* NB: Single user mode specific setup should go to PostgresSingleUserMain()
* if reasonably possible.
* ----------------------------------------------------------------
*/
#ifdef USE_VALGRIND
#endif
/*
* Throw an error if we're a WAL sender process.
*
* This is used to forbid anything else than simple query protocol messages
* in a WAL sender process. 'firstchar' specifies what kind of a forbidden
* message was received, and is used to construct the error message.
*/
/*
* Obtain platform stack depth limit (in bytes)
*
* Return -1 if unknown
*/
#if defined(HAVE_GETRLIMIT)
#else
#endif
#ifndef WIN32
#if defined(__darwin__)
#else
#endif
#endif /* !WIN32 */
/*
* on_proc_exit handler to log end of session
*/
/*
* Start statement timeout timer, if enabled.
*
* If there's already a timeout running, don't restart the timer. That
* enables compromises between accuracy of timeouts and cost of starting a
* timeout.
*/
/*
* Disable statement timeout, if active.
*/
|