LCOV - code coverage report
Current view: top level - src/backend/tcop - postgres.c (source / functions) Hit Total Coverage
Test: PostgreSQL Lines: 464 1268 36.6 %
Date: 2017-09-29 13:40:31 Functions: 32 53 60.4 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /*-------------------------------------------------------------------------
       2             :  *
       3             :  * postgres.c
       4             :  *    POSTGRES C Backend Interface
       5             :  *
       6             :  * Portions Copyright (c) 1996-2017, PostgreSQL Global Development Group
       7             :  * Portions Copyright (c) 1994, Regents of the University of California
       8             :  *
       9             :  *
      10             :  * IDENTIFICATION
      11             :  *    src/backend/tcop/postgres.c
      12             :  *
      13             :  * NOTES
      14             :  *    this is the "main" module of the postgres backend and
      15             :  *    hence the main module of the "traffic cop".
      16             :  *
      17             :  *-------------------------------------------------------------------------
      18             :  */
      19             : 
      20             : #include "postgres.h"
      21             : 
      22             : #include <fcntl.h>
      23             : #include <limits.h>
      24             : #include <signal.h>
      25             : #include <unistd.h>
      26             : #include <sys/socket.h>
      27             : #ifdef HAVE_SYS_SELECT_H
      28             : #include <sys/select.h>
      29             : #endif
      30             : #ifdef HAVE_SYS_RESOURCE_H
      31             : #include <sys/time.h>
      32             : #include <sys/resource.h>
      33             : #endif
      34             : 
      35             : #ifndef HAVE_GETRUSAGE
      36             : #include "rusagestub.h"
      37             : #endif
      38             : 
      39             : #include "access/parallel.h"
      40             : #include "access/printtup.h"
      41             : #include "access/xact.h"
      42             : #include "catalog/pg_type.h"
      43             : #include "commands/async.h"
      44             : #include "commands/prepare.h"
      45             : #include "libpq/libpq.h"
      46             : #include "libpq/pqformat.h"
      47             : #include "libpq/pqsignal.h"
      48             : #include "miscadmin.h"
      49             : #include "nodes/print.h"
      50             : #include "optimizer/planner.h"
      51             : #include "pgstat.h"
      52             : #include "pg_trace.h"
      53             : #include "parser/analyze.h"
      54             : #include "parser/parser.h"
      55             : #include "pg_getopt.h"
      56             : #include "postmaster/autovacuum.h"
      57             : #include "postmaster/postmaster.h"
      58             : #include "replication/logicallauncher.h"
      59             : #include "replication/logicalworker.h"
      60             : #include "replication/slot.h"
      61             : #include "replication/walsender.h"
      62             : #include "rewrite/rewriteHandler.h"
      63             : #include "storage/bufmgr.h"
      64             : #include "storage/ipc.h"
      65             : #include "storage/proc.h"
      66             : #include "storage/procsignal.h"
      67             : #include "storage/sinval.h"
      68             : #include "tcop/fastpath.h"
      69             : #include "tcop/pquery.h"
      70             : #include "tcop/tcopprot.h"
      71             : #include "tcop/utility.h"
      72             : #include "utils/lsyscache.h"
      73             : #include "utils/memutils.h"
      74             : #include "utils/ps_status.h"
      75             : #include "utils/snapmgr.h"
      76             : #include "utils/timeout.h"
      77             : #include "utils/timestamp.h"
      78             : #include "mb/pg_wchar.h"
      79             : 
      80             : 
      81             : /* ----------------
      82             :  *      global variables
      83             :  * ----------------
      84             :  */
      85             : const char *debug_query_string; /* client-supplied query string */
      86             : 
      87             : /* Note: whereToSendOutput is initialized for the bootstrap/standalone case */
      88             : CommandDest whereToSendOutput = DestDebug;
      89             : 
      90             : /* flag for logging end of session */
      91             : bool        Log_disconnections = false;
      92             : 
      93             : int         log_statement = LOGSTMT_NONE;
      94             : 
      95             : /* GUC variable for maximum stack depth (measured in kilobytes) */
      96             : int         max_stack_depth = 100;
      97             : 
      98             : /* wait N seconds to allow attach from a debugger */
      99             : int         PostAuthDelay = 0;
     100             : 
     101             : 
     102             : 
     103             : /* ----------------
     104             :  *      private variables
     105             :  * ----------------
     106             :  */
     107             : 
     108             : /* max_stack_depth converted to bytes for speed of checking */
     109             : static long max_stack_depth_bytes = 100 * 1024L;
     110             : 
     111             : /*
     112             :  * Stack base pointer -- initialized by PostmasterMain and inherited by
     113             :  * subprocesses. This is not static because old versions of PL/Java modify
     114             :  * it directly. Newer versions use set_stack_base(), but we want to stay
     115             :  * binary-compatible for the time being.
     116             :  */
     117             : char       *stack_base_ptr = NULL;
     118             : 
     119             : /*
     120             :  * On IA64 we also have to remember the register stack base.
     121             :  */
     122             : #if defined(__ia64__) || defined(__ia64)
     123             : char       *register_stack_base_ptr = NULL;
     124             : #endif
     125             : 
     126             : /*
     127             :  * Flag to keep track of whether we have started a transaction.
     128             :  * For extended query protocol this has to be remembered across messages.
     129             :  */
     130             : static bool xact_started = false;
     131             : 
     132             : /*
     133             :  * Flag to indicate that we are doing the outer loop's read-from-client,
     134             :  * as opposed to any random read from client that might happen within
     135             :  * commands like COPY FROM STDIN.
     136             :  */
     137             : static bool DoingCommandRead = false;
     138             : 
     139             : /*
     140             :  * Flags to implement skip-till-Sync-after-error behavior for messages of
     141             :  * the extended query protocol.
     142             :  */
     143             : static bool doing_extended_query_message = false;
     144             : static bool ignore_till_sync = false;
     145             : 
     146             : /*
     147             :  * If an unnamed prepared statement exists, it's stored here.
     148             :  * We keep it separate from the hashtable kept by commands/prepare.c
     149             :  * in order to reduce overhead for short-lived queries.
     150             :  */
     151             : static CachedPlanSource *unnamed_stmt_psrc = NULL;
     152             : 
     153             : /* assorted command-line switches */
     154             : static const char *userDoption = NULL;  /* -D switch */
     155             : static bool EchoQuery = false;  /* -E switch */
     156             : static bool UseSemiNewlineNewline = false;  /* -j switch */
     157             : 
     158             : /* whether or not, and why, we were canceled by conflict with recovery */
     159             : static bool RecoveryConflictPending = false;
     160             : static bool RecoveryConflictRetryable = true;
     161             : static ProcSignalReason RecoveryConflictReason;
     162             : 
     163             : /* ----------------------------------------------------------------
     164             :  *      decls for routines only used in this file
     165             :  * ----------------------------------------------------------------
     166             :  */
     167             : static int  InteractiveBackend(StringInfo inBuf);
     168             : static int  interactive_getc(void);
     169             : static int  SocketBackend(StringInfo inBuf);
     170             : static int  ReadCommand(StringInfo inBuf);
     171             : static void forbidden_in_wal_sender(char firstchar);
     172             : static List *pg_rewrite_query(Query *query);
     173             : static bool check_log_statement(List *stmt_list);
     174             : static int  errdetail_execute(List *raw_parsetree_list);
     175             : static int  errdetail_params(ParamListInfo params);
     176             : static int  errdetail_abort(void);
     177             : static int  errdetail_recovery_conflict(void);
     178             : static void start_xact_command(void);
     179             : static void finish_xact_command(void);
     180             : static bool IsTransactionExitStmt(Node *parsetree);
     181             : static bool IsTransactionExitStmtList(List *pstmts);
     182             : static bool IsTransactionStmtList(List *pstmts);
     183             : static void drop_unnamed_stmt(void);
     184             : static void log_disconnections(int code, Datum arg);
     185             : 
     186             : 
     187             : /* ----------------------------------------------------------------
     188             :  *      routines to obtain user input
     189             :  * ----------------------------------------------------------------
     190             :  */
     191             : 
     192             : /* ----------------
     193             :  *  InteractiveBackend() is called for user interactive connections
     194             :  *
     195             :  *  the string entered by the user is placed in its parameter inBuf,
     196             :  *  and we act like a Q message was received.
     197             :  *
     198             :  *  EOF is returned if end-of-file input is seen; time to shut down.
     199             :  * ----------------
     200             :  */
     201             : 
     202             : static int
     203         524 : InteractiveBackend(StringInfo inBuf)
     204             : {
     205             :     int         c;              /* character read from getc() */
     206             : 
     207             :     /*
     208             :      * display a prompt and obtain input from the user
     209             :      */
     210         524 :     printf("backend> ");
     211         524 :     fflush(stdout);
     212             : 
     213         524 :     resetStringInfo(inBuf);
     214             : 
     215             :     /*
     216             :      * Read characters until EOF or the appropriate delimiter is seen.
     217             :      */
     218      254614 :     while ((c = interactive_getc()) != EOF)
     219             :     {
     220      254089 :         if (c == '\n')
     221             :         {
     222        5678 :             if (UseSemiNewlineNewline)
     223             :             {
     224             :                 /*
     225             :                  * In -j mode, semicolon followed by two newlines ends the
     226             :                  * command; otherwise treat newline as regular character.
     227             :                  */
     228       11283 :                 if (inBuf->len > 1 &&
     229        6471 :                     inBuf->data[inBuf->len - 1] == '\n' &&
     230         866 :                     inBuf->data[inBuf->len - 2] == ';')
     231             :                 {
     232             :                     /* might as well drop the second newline */
     233         523 :                     break;
     234             :                 }
     235             :             }
     236             :             else
     237             :             {
     238             :                 /*
     239             :                  * In plain mode, newline ends the command unless preceded by
     240             :                  * backslash.
     241             :                  */
     242           0 :                 if (inBuf->len > 0 &&
     243           0 :                     inBuf->data[inBuf->len - 1] == '\\')
     244             :                 {
     245             :                     /* discard backslash from inBuf */
     246           0 :                     inBuf->data[--inBuf->len] = '\0';
     247             :                     /* discard newline too */
     248           0 :                     continue;
     249             :                 }
     250             :                 else
     251             :                 {
     252             :                     /* keep the newline character, but end the command */
     253           0 :                     appendStringInfoChar(inBuf, '\n');
     254           0 :                     break;
     255             :                 }
     256             :             }
     257             :         }
     258             : 
     259             :         /* Not newline, or newline treated as regular character */
     260      253566 :         appendStringInfoChar(inBuf, (char) c);
     261             :     }
     262             : 
     263             :     /* No input before EOF signal means time to quit. */
     264         524 :     if (c == EOF && inBuf->len == 0)
     265           1 :         return EOF;
     266             : 
     267             :     /*
     268             :      * otherwise we have a user query so process it.
     269             :      */
     270             : 
     271             :     /* Add '\0' to make it look the same as message case. */
     272         523 :     appendStringInfoChar(inBuf, (char) '\0');
     273             : 
     274             :     /*
     275             :      * if the query echo flag was given, print the query..
     276             :      */
     277         523 :     if (EchoQuery)
     278           0 :         printf("statement: %s\n", inBuf->data);
     279         523 :     fflush(stdout);
     280             : 
     281         523 :     return 'Q';
     282             : }
     283             : 
     284             : /*
     285             :  * interactive_getc -- collect one character from stdin
     286             :  *
     287             :  * Even though we are not reading from a "client" process, we still want to
     288             :  * respond to signals, particularly SIGTERM/SIGQUIT.
     289             :  */
     290             : static int
     291      254090 : interactive_getc(void)
     292             : {
     293             :     int         c;
     294             : 
     295             :     /*
     296             :      * This will not process catchup interrupts or notifications while
     297             :      * reading. But those can't really be relevant for a standalone backend
     298             :      * anyway. To properly handle SIGTERM there's a hack in die() that
     299             :      * directly processes interrupts at this stage...
     300             :      */
     301      254090 :     CHECK_FOR_INTERRUPTS();
     302             : 
     303      254090 :     c = getc(stdin);
     304             : 
     305      254090 :     ProcessClientReadInterrupt(true);
     306             : 
     307      254090 :     return c;
     308             : }
     309             : 
     310             : /* ----------------
     311             :  *  SocketBackend()     Is called for frontend-backend connections
     312             :  *
     313             :  *  Returns the message type code, and loads message body data into inBuf.
     314             :  *
     315             :  *  EOF is returned if the connection is lost.
     316             :  * ----------------
     317             :  */
     318             : static int
     319       26970 : SocketBackend(StringInfo inBuf)
     320             : {
     321             :     int         qtype;
     322             : 
     323             :     /*
     324             :      * Get message type code from the frontend.
     325             :      */
     326       26970 :     HOLD_CANCEL_INTERRUPTS();
     327       26970 :     pq_startmsgread();
     328       26970 :     qtype = pq_getbyte();
     329             : 
     330       26970 :     if (qtype == EOF)           /* frontend disconnected */
     331             :     {
     332           0 :         if (IsTransactionState())
     333           0 :             ereport(COMMERROR,
     334             :                     (errcode(ERRCODE_CONNECTION_FAILURE),
     335             :                      errmsg("unexpected EOF on client connection with an open transaction")));
     336             :         else
     337             :         {
     338             :             /*
     339             :              * Can't send DEBUG log messages to client at this point. Since
     340             :              * we're disconnecting right away, we don't need to restore
     341             :              * whereToSendOutput.
     342             :              */
     343           0 :             whereToSendOutput = DestNone;
     344           0 :             ereport(DEBUG1,
     345             :                     (errcode(ERRCODE_CONNECTION_DOES_NOT_EXIST),
     346             :                      errmsg("unexpected EOF on client connection")));
     347             :         }
     348           0 :         return qtype;
     349             :     }
     350             : 
     351             :     /*
     352             :      * Validate message type code before trying to read body; if we have lost
     353             :      * sync, better to say "command unknown" than to run out of memory because
     354             :      * we used garbage as a length word.
     355             :      *
     356             :      * This also gives us a place to set the doing_extended_query_message flag
     357             :      * as soon as possible.
     358             :      */
     359       26970 :     switch (qtype)
     360             :     {
     361             :         case 'Q':               /* simple query */
     362       26474 :             doing_extended_query_message = false;
     363       26474 :             if (PG_PROTOCOL_MAJOR(FrontendProtocol) < 3)
     364             :             {
     365             :                 /* old style without length word; convert */
     366           0 :                 if (pq_getstring(inBuf))
     367             :                 {
     368           0 :                     if (IsTransactionState())
     369           0 :                         ereport(COMMERROR,
     370             :                                 (errcode(ERRCODE_CONNECTION_FAILURE),
     371             :                                  errmsg("unexpected EOF on client connection with an open transaction")));
     372             :                     else
     373             :                     {
     374             :                         /*
     375             :                          * Can't send DEBUG log messages to client at this
     376             :                          * point. Since we're disconnecting right away, we
     377             :                          * don't need to restore whereToSendOutput.
     378             :                          */
     379           0 :                         whereToSendOutput = DestNone;
     380           0 :                         ereport(DEBUG1,
     381             :                                 (errcode(ERRCODE_CONNECTION_DOES_NOT_EXIST),
     382             :                                  errmsg("unexpected EOF on client connection")));
     383             :                     }
     384           0 :                     return EOF;
     385             :                 }
     386             :             }
     387       26474 :             break;
     388             : 
     389             :         case 'F':               /* fastpath function call */
     390         258 :             doing_extended_query_message = false;
     391         258 :             if (PG_PROTOCOL_MAJOR(FrontendProtocol) < 3)
     392             :             {
     393           0 :                 if (GetOldFunctionMessage(inBuf))
     394             :                 {
     395           0 :                     if (IsTransactionState())
     396           0 :                         ereport(COMMERROR,
     397             :                                 (errcode(ERRCODE_CONNECTION_FAILURE),
     398             :                                  errmsg("unexpected EOF on client connection with an open transaction")));
     399             :                     else
     400             :                     {
     401             :                         /*
     402             :                          * Can't send DEBUG log messages to client at this
     403             :                          * point. Since we're disconnecting right away, we
     404             :                          * don't need to restore whereToSendOutput.
     405             :                          */
     406           0 :                         whereToSendOutput = DestNone;
     407           0 :                         ereport(DEBUG1,
     408             :                                 (errcode(ERRCODE_CONNECTION_DOES_NOT_EXIST),
     409             :                                  errmsg("unexpected EOF on client connection")));
     410             :                     }
     411           0 :                     return EOF;
     412             :                 }
     413             :             }
     414         258 :             break;
     415             : 
     416             :         case 'X':               /* terminate */
     417         215 :             doing_extended_query_message = false;
     418         215 :             ignore_till_sync = false;
     419         215 :             break;
     420             : 
     421             :         case 'B':               /* bind */
     422             :         case 'C':               /* close */
     423             :         case 'D':               /* describe */
     424             :         case 'E':               /* execute */
     425             :         case 'H':               /* flush */
     426             :         case 'P':               /* parse */
     427           0 :             doing_extended_query_message = true;
     428             :             /* these are only legal in protocol 3 */
     429           0 :             if (PG_PROTOCOL_MAJOR(FrontendProtocol) < 3)
     430           0 :                 ereport(FATAL,
     431             :                         (errcode(ERRCODE_PROTOCOL_VIOLATION),
     432             :                          errmsg("invalid frontend message type %d", qtype)));
     433           0 :             break;
     434             : 
     435             :         case 'S':               /* sync */
     436             :             /* stop any active skip-till-Sync */
     437           0 :             ignore_till_sync = false;
     438             :             /* mark not-extended, so that a new error doesn't begin skip */
     439           0 :             doing_extended_query_message = false;
     440             :             /* only legal in protocol 3 */
     441           0 :             if (PG_PROTOCOL_MAJOR(FrontendProtocol) < 3)
     442           0 :                 ereport(FATAL,
     443             :                         (errcode(ERRCODE_PROTOCOL_VIOLATION),
     444             :                          errmsg("invalid frontend message type %d", qtype)));
     445           0 :             break;
     446             : 
     447             :         case 'd':               /* copy data */
     448             :         case 'c':               /* copy done */
     449             :         case 'f':               /* copy fail */
     450          23 :             doing_extended_query_message = false;
     451             :             /* these are only legal in protocol 3 */
     452          23 :             if (PG_PROTOCOL_MAJOR(FrontendProtocol) < 3)
     453           0 :                 ereport(FATAL,
     454             :                         (errcode(ERRCODE_PROTOCOL_VIOLATION),
     455             :                          errmsg("invalid frontend message type %d", qtype)));
     456          23 :             break;
     457             : 
     458             :         default:
     459             : 
     460             :             /*
     461             :              * Otherwise we got garbage from the frontend.  We treat this as
     462             :              * fatal because we have probably lost message boundary sync, and
     463             :              * there's no good way to recover.
     464             :              */
     465           0 :             ereport(FATAL,
     466             :                     (errcode(ERRCODE_PROTOCOL_VIOLATION),
     467             :                      errmsg("invalid frontend message type %d", qtype)));
     468             :             break;
     469             :     }
     470             : 
     471             :     /*
     472             :      * In protocol version 3, all frontend messages have a length word next
     473             :      * after the type code; we can read the message contents independently of
     474             :      * the type.
     475             :      */
     476       26970 :     if (PG_PROTOCOL_MAJOR(FrontendProtocol) >= 3)
     477             :     {
     478       26970 :         if (pq_getmessage(inBuf, 0))
     479           0 :             return EOF;         /* suitable message already logged */
     480             :     }
     481             :     else
     482           0 :         pq_endmsgread();
     483       26970 :     RESUME_CANCEL_INTERRUPTS();
     484             : 
     485       26970 :     return qtype;
     486             : }
     487             : 
     488             : /* ----------------
     489             :  *      ReadCommand reads a command from either the frontend or
     490             :  *      standard input, places it in inBuf, and returns the
     491             :  *      message type code (first byte of the message).
     492             :  *      EOF is returned if end of file.
     493             :  * ----------------
     494             :  */
     495             : static int
     496       27494 : ReadCommand(StringInfo inBuf)
     497             : {
     498             :     int         result;
     499             : 
     500       27494 :     if (whereToSendOutput == DestRemote)
     501       26970 :         result = SocketBackend(inBuf);
     502             :     else
     503         524 :         result = InteractiveBackend(inBuf);
     504       27494 :     return result;
     505             : }
     506             : 
     507             : /*
     508             :  * ProcessClientReadInterrupt() - Process interrupts specific to client reads
     509             :  *
     510             :  * This is called just after low-level reads. That might be after the read
     511             :  * finished successfully, or it was interrupted via interrupt.
     512             :  *
     513             :  * Must preserve errno!
     514             :  */
     515             : void
     516      281769 : ProcessClientReadInterrupt(bool blocked)
     517             : {
     518      281769 :     int         save_errno = errno;
     519             : 
     520      281769 :     if (DoingCommandRead)
     521             :     {
     522             :         /* Check for general interrupts that arrived while reading */
     523      281481 :         CHECK_FOR_INTERRUPTS();
     524             : 
     525             :         /* Process sinval catchup interrupts that happened while reading */
     526      281481 :         if (catchupInterruptPending)
     527          56 :             ProcessCatchupInterrupt();
     528             : 
     529             :         /* Process sinval catchup interrupts that happened while reading */
     530      281481 :         if (notifyInterruptPending)
     531           0 :             ProcessNotifyInterrupt();
     532             :     }
     533         288 :     else if (ProcDiePending && blocked)
     534             :     {
     535             :         /*
     536             :          * We're dying. It's safe (and sane) to handle that now.
     537             :          */
     538           0 :         CHECK_FOR_INTERRUPTS();
     539             :     }
     540             : 
     541      281769 :     errno = save_errno;
     542      281769 : }
     543             : 
     544             : /*
     545             :  * ProcessClientWriteInterrupt() - Process interrupts specific to client writes
     546             :  *
     547             :  * This is called just after low-level writes. That might be after the read
     548             :  * finished successfully, or it was interrupted via interrupt. 'blocked' tells
     549             :  * us whether the
     550             :  *
     551             :  * Must preserve errno!
     552             :  */
     553             : void
     554       32117 : ProcessClientWriteInterrupt(bool blocked)
     555             : {
     556       32117 :     int         save_errno = errno;
     557             : 
     558             :     /*
     559             :      * We only want to process the interrupt here if socket writes are
     560             :      * blocking to increase the chance to get an error message to the client.
     561             :      * If we're not blocked there'll soon be a CHECK_FOR_INTERRUPTS(). But if
     562             :      * we're blocked we'll never get out of that situation if the client has
     563             :      * died.
     564             :      */
     565       32117 :     if (ProcDiePending && blocked)
     566             :     {
     567             :         /*
     568             :          * We're dying. It's safe (and sane) to handle that now. But we don't
     569             :          * want to send the client the error message as that a) would possibly
     570             :          * block again b) would possibly lead to sending an error message to
     571             :          * the client, while we already started to send something else.
     572             :          */
     573           0 :         if (whereToSendOutput == DestRemote)
     574           0 :             whereToSendOutput = DestNone;
     575             : 
     576           0 :         CHECK_FOR_INTERRUPTS();
     577             :     }
     578             : 
     579       32117 :     errno = save_errno;
     580       32117 : }
     581             : 
     582             : /*
     583             :  * Do raw parsing (only).
     584             :  *
     585             :  * A list of parsetrees (RawStmt nodes) is returned, since there might be
     586             :  * multiple commands in the given string.
     587             :  *
     588             :  * NOTE: for interactive queries, it is important to keep this routine
     589             :  * separate from the analysis & rewrite stages.  Analysis and rewriting
     590             :  * cannot be done in an aborted transaction, since they require access to
     591             :  * database tables.  So, we rely on the raw parser to determine whether
     592             :  * we've seen a COMMIT or ABORT command; when we are in abort state, other
     593             :  * commands are not processed any further than the raw parse stage.
     594             :  */
     595             : List *
     596       35710 : pg_parse_query(const char *query_string)
     597             : {
     598             :     List       *raw_parsetree_list;
     599             : 
     600             :     TRACE_POSTGRESQL_QUERY_PARSE_START(query_string);
     601             : 
     602       35710 :     if (log_parser_stats)
     603           0 :         ResetUsage();
     604             : 
     605       35710 :     raw_parsetree_list = raw_parser(query_string);
     606             : 
     607       35579 :     if (log_parser_stats)
     608           0 :         ShowUsage("PARSER STATISTICS");
     609             : 
     610             : #ifdef COPY_PARSE_PLAN_TREES
     611             :     /* Optional debugging check: pass raw parsetrees through copyObject() */
     612             :     {
     613             :         List       *new_list = copyObject(raw_parsetree_list);
     614             : 
     615             :         /* This checks both copyObject() and the equal() routines... */
     616             :         if (!equal(new_list, raw_parsetree_list))
     617             :             elog(WARNING, "copyObject() failed to produce an equal raw parse tree");
     618             :         else
     619             :             raw_parsetree_list = new_list;
     620             :     }
     621             : #endif
     622             : 
     623             :     TRACE_POSTGRESQL_QUERY_PARSE_DONE(query_string);
     624             : 
     625       35579 :     return raw_parsetree_list;
     626             : }
     627             : 
     628             : /*
     629             :  * Given a raw parsetree (gram.y output), and optionally information about
     630             :  * types of parameter symbols ($n), perform parse analysis and rule rewriting.
     631             :  *
     632             :  * A list of Query nodes is returned, since either the analyzer or the
     633             :  * rewriter might expand one query to several.
     634             :  *
     635             :  * NOTE: for reasons mentioned above, this must be separate from raw parsing.
     636             :  */
     637             : List *
     638       28797 : pg_analyze_and_rewrite(RawStmt *parsetree, const char *query_string,
     639             :                        Oid *paramTypes, int numParams,
     640             :                        QueryEnvironment *queryEnv)
     641             : {
     642             :     Query      *query;
     643             :     List       *querytree_list;
     644             : 
     645             :     TRACE_POSTGRESQL_QUERY_REWRITE_START(query_string);
     646             : 
     647             :     /*
     648             :      * (1) Perform parse analysis.
     649             :      */
     650       28797 :     if (log_parser_stats)
     651           0 :         ResetUsage();
     652             : 
     653       28797 :     query = parse_analyze(parsetree, query_string, paramTypes, numParams,
     654             :                           queryEnv);
     655             : 
     656       28080 :     if (log_parser_stats)
     657           0 :         ShowUsage("PARSE ANALYSIS STATISTICS");
     658             : 
     659             :     /*
     660             :      * (2) Rewrite the queries, as necessary
     661             :      */
     662       28080 :     querytree_list = pg_rewrite_query(query);
     663             : 
     664             :     TRACE_POSTGRESQL_QUERY_REWRITE_DONE(query_string);
     665             : 
     666       28020 :     return querytree_list;
     667             : }
     668             : 
     669             : /*
     670             :  * Do parse analysis and rewriting.  This is the same as pg_analyze_and_rewrite
     671             :  * except that external-parameter resolution is determined by parser callback
     672             :  * hooks instead of a fixed list of parameter datatypes.
     673             :  */
     674             : List *
     675        5138 : pg_analyze_and_rewrite_params(RawStmt *parsetree,
     676             :                               const char *query_string,
     677             :                               ParserSetupHook parserSetup,
     678             :                               void *parserSetupArg,
     679             :                               QueryEnvironment *queryEnv)
     680             : {
     681             :     ParseState *pstate;
     682             :     Query      *query;
     683             :     List       *querytree_list;
     684             : 
     685        5138 :     Assert(query_string != NULL);   /* required as of 8.4 */
     686             : 
     687             :     TRACE_POSTGRESQL_QUERY_REWRITE_START(query_string);
     688             : 
     689             :     /*
     690             :      * (1) Perform parse analysis.
     691             :      */
     692        5138 :     if (log_parser_stats)
     693           0 :         ResetUsage();
     694             : 
     695        5138 :     pstate = make_parsestate(NULL);
     696        5138 :     pstate->p_sourcetext = query_string;
     697        5138 :     pstate->p_queryEnv = queryEnv;
     698        5138 :     (*parserSetup) (pstate, parserSetupArg);
     699             : 
     700        5138 :     query = transformTopLevelStmt(pstate, parsetree);
     701             : 
     702        5130 :     if (post_parse_analyze_hook)
     703           0 :         (*post_parse_analyze_hook) (pstate, query);
     704             : 
     705        5130 :     free_parsestate(pstate);
     706             : 
     707        5130 :     if (log_parser_stats)
     708           0 :         ShowUsage("PARSE ANALYSIS STATISTICS");
     709             : 
     710             :     /*
     711             :      * (2) Rewrite the queries, as necessary
     712             :      */
     713        5130 :     querytree_list = pg_rewrite_query(query);
     714             : 
     715             :     TRACE_POSTGRESQL_QUERY_REWRITE_DONE(query_string);
     716             : 
     717        5130 :     return querytree_list;
     718             : }
     719             : 
     720             : /*
     721             :  * Perform rewriting of a query produced by parse analysis.
     722             :  *
     723             :  * Note: query must just have come from the parser, because we do not do
     724             :  * AcquireRewriteLocks() on it.
     725             :  */
     726             : static List *
     727       33210 : pg_rewrite_query(Query *query)
     728             : {
     729             :     List       *querytree_list;
     730             : 
     731       33210 :     if (Debug_print_parse)
     732           0 :         elog_node_display(LOG, "parse tree", query,
     733             :                           Debug_pretty_print);
     734             : 
     735       33210 :     if (log_parser_stats)
     736           0 :         ResetUsage();
     737             : 
     738       33210 :     if (query->commandType == CMD_UTILITY)
     739             :     {
     740             :         /* don't rewrite utilities, just dump 'em into result list */
     741       12517 :         querytree_list = list_make1(query);
     742             :     }
     743             :     else
     744             :     {
     745             :         /* rewrite regular queries */
     746       20693 :         querytree_list = QueryRewrite(query);
     747             :     }
     748             : 
     749       33150 :     if (log_parser_stats)
     750           0 :         ShowUsage("REWRITER STATISTICS");
     751             : 
     752             : #ifdef COPY_PARSE_PLAN_TREES
     753             :     /* Optional debugging check: pass querytree output through copyObject() */
     754             :     {
     755             :         List       *new_list;
     756             : 
     757             :         new_list = copyObject(querytree_list);
     758             :         /* This checks both copyObject() and the equal() routines... */
     759             :         if (!equal(new_list, querytree_list))
     760             :             elog(WARNING, "copyObject() failed to produce equal parse tree");
     761             :         else
     762             :             querytree_list = new_list;
     763             :     }
     764             : #endif
     765             : 
     766       33150 :     if (Debug_print_rewritten)
     767           0 :         elog_node_display(LOG, "rewritten parse tree", querytree_list,
     768             :                           Debug_pretty_print);
     769             : 
     770       33150 :     return querytree_list;
     771             : }
     772             : 
     773             : 
     774             : /*
     775             :  * Generate a plan for a single already-rewritten query.
     776             :  * This is a thin wrapper around planner() and takes the same parameters.
     777             :  */
     778             : PlannedStmt *
     779       22405 : pg_plan_query(Query *querytree, int cursorOptions, ParamListInfo boundParams)
     780             : {
     781             :     PlannedStmt *plan;
     782             : 
     783             :     /* Utility commands have no plans. */
     784       22405 :     if (querytree->commandType == CMD_UTILITY)
     785           0 :         return NULL;
     786             : 
     787             :     /* Planner must have a snapshot in case it calls user-defined functions. */
     788       22405 :     Assert(ActiveSnapshotSet());
     789             : 
     790             :     TRACE_POSTGRESQL_QUERY_PLAN_START();
     791             : 
     792       22405 :     if (log_planner_stats)
     793           0 :         ResetUsage();
     794             : 
     795             :     /* call the optimizer */
     796       22405 :     plan = planner(querytree, cursorOptions, boundParams);
     797             : 
     798       22126 :     if (log_planner_stats)
     799           0 :         ShowUsage("PLANNER STATISTICS");
     800             : 
     801             : #ifdef COPY_PARSE_PLAN_TREES
     802             :     /* Optional debugging check: pass plan output through copyObject() */
     803             :     {
     804             :         PlannedStmt *new_plan = copyObject(plan);
     805             : 
     806             :         /*
     807             :          * equal() currently does not have routines to compare Plan nodes, so
     808             :          * don't try to test equality here.  Perhaps fix someday?
     809             :          */
     810             : #ifdef NOT_USED
     811             :         /* This checks both copyObject() and the equal() routines... */
     812             :         if (!equal(new_plan, plan))
     813             :             elog(WARNING, "copyObject() failed to produce an equal plan tree");
     814             :         else
     815             : #endif
     816             :             plan = new_plan;
     817             :     }
     818             : #endif
     819             : 
     820             :     /*
     821             :      * Print plan if debugging.
     822             :      */
     823       22126 :     if (Debug_print_plan)
     824           0 :         elog_node_display(LOG, "plan", plan, Debug_pretty_print);
     825             : 
     826             :     TRACE_POSTGRESQL_QUERY_PLAN_DONE();
     827             : 
     828       22126 :     return plan;
     829             : }
     830             : 
     831             : /*
     832             :  * Generate plans for a list of already-rewritten queries.
     833             :  *
     834             :  * For normal optimizable statements, invoke the planner.  For utility
     835             :  * statements, just make a wrapper PlannedStmt node.
     836             :  *
     837             :  * The result is a list of PlannedStmt nodes.
     838             :  */
     839             : List *
     840       30586 : pg_plan_queries(List *querytrees, int cursorOptions, ParamListInfo boundParams)
     841             : {
     842       30586 :     List       *stmt_list = NIL;
     843             :     ListCell   *query_list;
     844             : 
     845       60988 :     foreach(query_list, querytrees)
     846             :     {
     847       30674 :         Query      *query = lfirst_node(Query, query_list);
     848             :         PlannedStmt *stmt;
     849             : 
     850       30674 :         if (query->commandType == CMD_UTILITY)
     851             :         {
     852             :             /* Utility commands require no planning. */
     853       12502 :             stmt = makeNode(PlannedStmt);
     854       12502 :             stmt->commandType = CMD_UTILITY;
     855       12502 :             stmt->canSetTag = query->canSetTag;
     856       12502 :             stmt->utilityStmt = query->utilityStmt;
     857       12502 :             stmt->stmt_location = query->stmt_location;
     858       12502 :             stmt->stmt_len = query->stmt_len;
     859             :         }
     860             :         else
     861             :         {
     862       18172 :             stmt = pg_plan_query(query, cursorOptions, boundParams);
     863             :         }
     864             : 
     865       30402 :         stmt_list = lappend(stmt_list, stmt);
     866             :     }
     867             : 
     868       30314 :     return stmt_list;
     869             : }
     870             : 
     871             : 
     872             : /*
     873             :  * exec_simple_query
     874             :  *
     875             :  * Execute a "simple Query" protocol message.
     876             :  */
     877             : static void
     878       26997 : exec_simple_query(const char *query_string)
     879             : {
     880       26997 :     CommandDest dest = whereToSendOutput;
     881             :     MemoryContext oldcontext;
     882             :     List       *parsetree_list;
     883             :     ListCell   *parsetree_item;
     884       26997 :     bool        save_log_statement_stats = log_statement_stats;
     885       26997 :     bool        was_logged = false;
     886             :     bool        isTopLevel;
     887             :     char        msec_str[32];
     888             : 
     889             : 
     890             :     /*
     891             :      * Report query to various monitoring facilities.
     892             :      */
     893       26997 :     debug_query_string = query_string;
     894             : 
     895       26997 :     pgstat_report_activity(STATE_RUNNING, query_string);
     896             : 
     897             :     TRACE_POSTGRESQL_QUERY_START(query_string);
     898             : 
     899             :     /*
     900             :      * We use save_log_statement_stats so ShowUsage doesn't report incorrect
     901             :      * results because ResetUsage wasn't called.
     902             :      */
     903       26997 :     if (save_log_statement_stats)
     904           0 :         ResetUsage();
     905             : 
     906             :     /*
     907             :      * Start up a transaction command.  All queries generated by the
     908             :      * query_string will be in this same command block, *unless* we find a
     909             :      * BEGIN/COMMIT/ABORT statement; we have to force a new xact command after
     910             :      * one of those, else bad things will happen in xact.c. (Note that this
     911             :      * will normally change current memory context.)
     912             :      */
     913       26997 :     start_xact_command();
     914             : 
     915             :     /*
     916             :      * Zap any pre-existing unnamed statement.  (While not strictly necessary,
     917             :      * it seems best to define simple-Query mode as if it used the unnamed
     918             :      * statement and portal; this ensures we recover any storage used by prior
     919             :      * unnamed operations.)
     920             :      */
     921       26997 :     drop_unnamed_stmt();
     922             : 
     923             :     /*
     924             :      * Switch to appropriate context for constructing parsetrees.
     925             :      */
     926       26997 :     oldcontext = MemoryContextSwitchTo(MessageContext);
     927             : 
     928             :     /*
     929             :      * Do basic parsing of the query or queries (this should be safe even if
     930             :      * we are in aborted transaction state!)
     931             :      */
     932       26997 :     parsetree_list = pg_parse_query(query_string);
     933             : 
     934             :     /* Log immediately if dictated by log_statement */
     935       26867 :     if (check_log_statement(parsetree_list))
     936             :     {
     937           0 :         ereport(LOG,
     938             :                 (errmsg("statement: %s", query_string),
     939             :                  errhidestmt(true),
     940             :                  errdetail_execute(parsetree_list)));
     941           0 :         was_logged = true;
     942             :     }
     943             : 
     944             :     /*
     945             :      * Switch back to transaction context to enter the loop.
     946             :      */
     947       26867 :     MemoryContextSwitchTo(oldcontext);
     948             : 
     949             :     /*
     950             :      * We'll tell PortalRun it's a top-level command iff there's exactly one
     951             :      * raw parsetree.  If more than one, it's effectively a transaction block
     952             :      * and we want PreventTransactionChain to reject unsafe commands. (Note:
     953             :      * we're assuming that query rewrite cannot add commands that are
     954             :      * significant to PreventTransactionChain.)
     955             :      */
     956       26867 :     isTopLevel = (list_length(parsetree_list) == 1);
     957             : 
     958             :     /*
     959             :      * Run through the raw parsetree(s) and process each one.
     960             :      */
     961       51151 :     foreach(parsetree_item, parsetree_list)
     962             :     {
     963       27374 :         RawStmt    *parsetree = lfirst_node(RawStmt, parsetree_item);
     964       27374 :         bool        snapshot_set = false;
     965             :         const char *commandTag;
     966             :         char        completionTag[COMPLETION_TAG_BUFSIZE];
     967             :         List       *querytree_list,
     968             :                    *plantree_list;
     969             :         Portal      portal;
     970             :         DestReceiver *receiver;
     971             :         int16       format;
     972             : 
     973             :         /*
     974             :          * Get the command name for use in status display (it also becomes the
     975             :          * default completion tag, down inside PortalRun).  Set ps_status and
     976             :          * do any special start-of-SQL-command processing needed by the
     977             :          * destination.
     978             :          */
     979       27374 :         commandTag = CreateCommandTag(parsetree->stmt);
     980             : 
     981       27374 :         set_ps_display(commandTag, false);
     982             : 
     983       27374 :         BeginCommand(commandTag, dest);
     984             : 
     985             :         /*
     986             :          * If we are in an aborted transaction, reject all commands except
     987             :          * COMMIT/ABORT.  It is important that this test occur before we try
     988             :          * to do parse analysis, rewrite, or planning, since all those phases
     989             :          * try to do database accesses, which may fail in abort state. (It
     990             :          * might be safe to allow some additional utility commands in this
     991             :          * state, but not many...)
     992             :          */
     993       27486 :         if (IsAbortedTransactionBlockState() &&
     994         112 :             !IsTransactionExitStmt(parsetree->stmt))
     995           9 :             ereport(ERROR,
     996             :                     (errcode(ERRCODE_IN_FAILED_SQL_TRANSACTION),
     997             :                      errmsg("current transaction is aborted, "
     998             :                             "commands ignored until end of transaction block"),
     999             :                      errdetail_abort()));
    1000             : 
    1001             :         /* Make sure we are in a transaction command */
    1002       27365 :         start_xact_command();
    1003             : 
    1004             :         /* If we got a cancel signal in parsing or prior command, quit */
    1005       27365 :         CHECK_FOR_INTERRUPTS();
    1006             : 
    1007             :         /*
    1008             :          * Set up a snapshot if parse analysis/planning will need one.
    1009             :          */
    1010       27365 :         if (analyze_requires_snapshot(parsetree))
    1011             :         {
    1012       16262 :             PushActiveSnapshot(GetTransactionSnapshot());
    1013       16262 :             snapshot_set = true;
    1014             :         }
    1015             : 
    1016             :         /*
    1017             :          * OK to analyze, rewrite, and plan this query.
    1018             :          *
    1019             :          * Switch to appropriate context for constructing querytrees (again,
    1020             :          * these must outlive the execution context).
    1021             :          */
    1022       27365 :         oldcontext = MemoryContextSwitchTo(MessageContext);
    1023             : 
    1024       27365 :         querytree_list = pg_analyze_and_rewrite(parsetree, query_string,
    1025             :                                                 NULL, 0, NULL);
    1026             : 
    1027       26593 :         plantree_list = pg_plan_queries(querytree_list,
    1028             :                                         CURSOR_OPT_PARALLEL_OK, NULL);
    1029             : 
    1030             :         /* Done with the snapshot used for parsing/planning */
    1031       26331 :         if (snapshot_set)
    1032       15228 :             PopActiveSnapshot();
    1033             : 
    1034             :         /* If we got a cancel signal in analysis or planning, quit */
    1035       26331 :         CHECK_FOR_INTERRUPTS();
    1036             : 
    1037             :         /*
    1038             :          * Create unnamed portal to run the query or queries in. If there
    1039             :          * already is one, silently drop it.
    1040             :          */
    1041       26331 :         portal = CreatePortal("", true, true);
    1042             :         /* Don't display the portal in pg_cursors */
    1043       26331 :         portal->visible = false;
    1044             : 
    1045             :         /*
    1046             :          * We don't have to copy anything into the portal, because everything
    1047             :          * we are passing here is in MessageContext, which will outlive the
    1048             :          * portal anyway.
    1049             :          */
    1050       26331 :         PortalDefineQuery(portal,
    1051             :                           NULL,
    1052             :                           query_string,
    1053             :                           commandTag,
    1054             :                           plantree_list,
    1055             :                           NULL);
    1056             : 
    1057             :         /*
    1058             :          * Start the portal.  No parameters here.
    1059             :          */
    1060       26331 :         PortalStart(portal, NULL, 0, InvalidSnapshot);
    1061             : 
    1062             :         /*
    1063             :          * Select the appropriate output format: text unless we are doing a
    1064             :          * FETCH from a binary cursor.  (Pretty grotty to have to do this here
    1065             :          * --- but it avoids grottiness in other places.  Ah, the joys of
    1066             :          * backward compatibility...)
    1067             :          */
    1068       26292 :         format = 0;             /* TEXT is default */
    1069       26292 :         if (IsA(parsetree->stmt, FetchStmt))
    1070             :         {
    1071         203 :             FetchStmt  *stmt = (FetchStmt *) parsetree->stmt;
    1072             : 
    1073         203 :             if (!stmt->ismove)
    1074             :             {
    1075         197 :                 Portal      fportal = GetPortalByName(stmt->portalname);
    1076             : 
    1077         390 :                 if (PortalIsValid(fportal) &&
    1078         193 :                     (fportal->cursorOptions & CURSOR_OPT_BINARY))
    1079           0 :                     format = 1; /* BINARY */
    1080             :             }
    1081             :         }
    1082       26292 :         PortalSetResultFormat(portal, 1, &format);
    1083             : 
    1084             :         /*
    1085             :          * Now we can create the destination receiver object.
    1086             :          */
    1087       26292 :         receiver = CreateDestReceiver(dest);
    1088       26292 :         if (dest == DestRemote)
    1089       25269 :             SetRemoteDestReceiverParams(receiver, portal);
    1090             : 
    1091             :         /*
    1092             :          * Switch back to transaction context for execution.
    1093             :          */
    1094       26292 :         MemoryContextSwitchTo(oldcontext);
    1095             : 
    1096             :         /*
    1097             :          * Run the portal to completion, and then drop it (and the receiver).
    1098             :          */
    1099       26292 :         (void) PortalRun(portal,
    1100             :                          FETCH_ALL,
    1101             :                          isTopLevel,
    1102             :                          true,
    1103             :                          receiver,
    1104             :                          receiver,
    1105             :                          completionTag);
    1106             : 
    1107       24298 :         (*receiver->rDestroy) (receiver);
    1108             : 
    1109       24298 :         PortalDrop(portal, false);
    1110             : 
    1111       24298 :         if (IsA(parsetree->stmt, TransactionStmt))
    1112             :         {
    1113             :             /*
    1114             :              * If this was a transaction control statement, commit it. We will
    1115             :              * start a new xact command for the next command (if any).
    1116             :              */
    1117         760 :             finish_xact_command();
    1118             :         }
    1119       23538 :         else if (lnext(parsetree_item) == NULL)
    1120             :         {
    1121             :             /*
    1122             :              * If this is the last parsetree of the query string, close down
    1123             :              * transaction statement before reporting command-complete.  This
    1124             :              * is so that any end-of-transaction errors are reported before
    1125             :              * the command-complete message is issued, to avoid confusing
    1126             :              * clients who will expect either a command-complete message or an
    1127             :              * error, not one and then the other.  But for compatibility with
    1128             :              * historical Postgres behavior, we do not force a transaction
    1129             :              * boundary between queries appearing in a single query string.
    1130             :              */
    1131       23026 :             finish_xact_command();
    1132             :         }
    1133             :         else
    1134             :         {
    1135             :             /*
    1136             :              * We need a CommandCounterIncrement after every query, except
    1137             :              * those that start or end a transaction block.
    1138             :              */
    1139         512 :             CommandCounterIncrement();
    1140             :         }
    1141             : 
    1142             :         /*
    1143             :          * Tell client that we're done with this query.  Note we emit exactly
    1144             :          * one EndCommand report for each raw parsetree, thus one for each SQL
    1145             :          * command the client sent, regardless of rewriting. (But a command
    1146             :          * aborted by error will not send an EndCommand report at all.)
    1147             :          */
    1148       24284 :         EndCommand(completionTag, dest);
    1149             :     }                           /* end loop over parsetrees */
    1150             : 
    1151             :     /*
    1152             :      * Close down transaction statement, if one is open.
    1153             :      */
    1154       23777 :     finish_xact_command();
    1155             : 
    1156             :     /*
    1157             :      * If there were no parsetrees, return EmptyQueryResponse message.
    1158             :      */
    1159       23777 :     if (!parsetree_list)
    1160           5 :         NullCommand(dest);
    1161             : 
    1162             :     /*
    1163             :      * Emit duration logging if appropriate.
    1164             :      */
    1165       23777 :     switch (check_log_duration(msec_str, was_logged))
    1166             :     {
    1167             :         case 1:
    1168           0 :             ereport(LOG,
    1169             :                     (errmsg("duration: %s ms", msec_str),
    1170             :                      errhidestmt(true)));
    1171           0 :             break;
    1172             :         case 2:
    1173           0 :             ereport(LOG,
    1174             :                     (errmsg("duration: %s ms  statement: %s",
    1175             :                             msec_str, query_string),
    1176             :                      errhidestmt(true),
    1177             :                      errdetail_execute(parsetree_list)));
    1178           0 :             break;
    1179             :     }
    1180             : 
    1181       23777 :     if (save_log_statement_stats)
    1182           0 :         ShowUsage("QUERY STATISTICS");
    1183             : 
    1184             :     TRACE_POSTGRESQL_QUERY_DONE(query_string);
    1185             : 
    1186       23777 :     debug_query_string = NULL;
    1187       23777 : }
    1188             : 
    1189             : /*
    1190             :  * exec_parse_message
    1191             :  *
    1192             :  * Execute a "Parse" protocol message.
    1193             :  */
    1194             : static void
    1195           0 : exec_parse_message(const char *query_string,    /* string to execute */
    1196             :                    const char *stmt_name,   /* name for prepared stmt */
    1197             :                    Oid *paramTypes, /* parameter types */
    1198             :                    int numParams)   /* number of parameters */
    1199             : {
    1200           0 :     MemoryContext unnamed_stmt_context = NULL;
    1201             :     MemoryContext oldcontext;
    1202             :     List       *parsetree_list;
    1203             :     RawStmt    *raw_parse_tree;
    1204             :     const char *commandTag;
    1205             :     List       *querytree_list;
    1206             :     CachedPlanSource *psrc;
    1207             :     bool        is_named;
    1208           0 :     bool        save_log_statement_stats = log_statement_stats;
    1209             :     char        msec_str[32];
    1210             : 
    1211             :     /*
    1212             :      * Report query to various monitoring facilities.
    1213             :      */
    1214           0 :     debug_query_string = query_string;
    1215             : 
    1216           0 :     pgstat_report_activity(STATE_RUNNING, query_string);
    1217             : 
    1218           0 :     set_ps_display("PARSE", false);
    1219             : 
    1220           0 :     if (save_log_statement_stats)
    1221           0 :         ResetUsage();
    1222             : 
    1223           0 :     ereport(DEBUG2,
    1224             :             (errmsg("parse %s: %s",
    1225             :                     *stmt_name ? stmt_name : "<unnamed>",
    1226             :                     query_string)));
    1227             : 
    1228             :     /*
    1229             :      * Start up a transaction command so we can run parse analysis etc. (Note
    1230             :      * that this will normally change current memory context.) Nothing happens
    1231             :      * if we are already in one.
    1232             :      */
    1233           0 :     start_xact_command();
    1234             : 
    1235             :     /*
    1236             :      * Switch to appropriate context for constructing parsetrees.
    1237             :      *
    1238             :      * We have two strategies depending on whether the prepared statement is
    1239             :      * named or not.  For a named prepared statement, we do parsing in
    1240             :      * MessageContext and copy the finished trees into the prepared
    1241             :      * statement's plancache entry; then the reset of MessageContext releases
    1242             :      * temporary space used by parsing and rewriting. For an unnamed prepared
    1243             :      * statement, we assume the statement isn't going to hang around long, so
    1244             :      * getting rid of temp space quickly is probably not worth the costs of
    1245             :      * copying parse trees.  So in this case, we create the plancache entry's
    1246             :      * query_context here, and do all the parsing work therein.
    1247             :      */
    1248           0 :     is_named = (stmt_name[0] != '\0');
    1249           0 :     if (is_named)
    1250             :     {
    1251             :         /* Named prepared statement --- parse in MessageContext */
    1252           0 :         oldcontext = MemoryContextSwitchTo(MessageContext);
    1253             :     }
    1254             :     else
    1255             :     {
    1256             :         /* Unnamed prepared statement --- release any prior unnamed stmt */
    1257           0 :         drop_unnamed_stmt();
    1258             :         /* Create context for parsing */
    1259           0 :         unnamed_stmt_context =
    1260           0 :             AllocSetContextCreate(MessageContext,
    1261             :                                   "unnamed prepared statement",
    1262             :                                   ALLOCSET_DEFAULT_SIZES);
    1263           0 :         oldcontext = MemoryContextSwitchTo(unnamed_stmt_context);
    1264             :     }
    1265             : 
    1266             :     /*
    1267             :      * Do basic parsing of the query or queries (this should be safe even if
    1268             :      * we are in aborted transaction state!)
    1269             :      */
    1270           0 :     parsetree_list = pg_parse_query(query_string);
    1271             : 
    1272             :     /*
    1273             :      * We only allow a single user statement in a prepared statement. This is
    1274             :      * mainly to keep the protocol simple --- otherwise we'd need to worry
    1275             :      * about multiple result tupdescs and things like that.
    1276             :      */
    1277           0 :     if (list_length(parsetree_list) > 1)
    1278           0 :         ereport(ERROR,
    1279             :                 (errcode(ERRCODE_SYNTAX_ERROR),
    1280             :                  errmsg("cannot insert multiple commands into a prepared statement")));
    1281             : 
    1282           0 :     if (parsetree_list != NIL)
    1283             :     {
    1284             :         Query      *query;
    1285           0 :         bool        snapshot_set = false;
    1286             :         int         i;
    1287             : 
    1288           0 :         raw_parse_tree = linitial_node(RawStmt, parsetree_list);
    1289             : 
    1290             :         /*
    1291             :          * Get the command name for possible use in status display.
    1292             :          */
    1293           0 :         commandTag = CreateCommandTag(raw_parse_tree->stmt);
    1294             : 
    1295             :         /*
    1296             :          * If we are in an aborted transaction, reject all commands except
    1297             :          * COMMIT/ROLLBACK.  It is important that this test occur before we
    1298             :          * try to do parse analysis, rewrite, or planning, since all those
    1299             :          * phases try to do database accesses, which may fail in abort state.
    1300             :          * (It might be safe to allow some additional utility commands in this
    1301             :          * state, but not many...)
    1302             :          */
    1303           0 :         if (IsAbortedTransactionBlockState() &&
    1304           0 :             !IsTransactionExitStmt(raw_parse_tree->stmt))
    1305           0 :             ereport(ERROR,
    1306             :                     (errcode(ERRCODE_IN_FAILED_SQL_TRANSACTION),
    1307             :                      errmsg("current transaction is aborted, "
    1308             :                             "commands ignored until end of transaction block"),
    1309             :                      errdetail_abort()));
    1310             : 
    1311             :         /*
    1312             :          * Create the CachedPlanSource before we do parse analysis, since it
    1313             :          * needs to see the unmodified raw parse tree.
    1314             :          */
    1315           0 :         psrc = CreateCachedPlan(raw_parse_tree, query_string, commandTag);
    1316             : 
    1317             :         /*
    1318             :          * Set up a snapshot if parse analysis will need one.
    1319             :          */
    1320           0 :         if (analyze_requires_snapshot(raw_parse_tree))
    1321             :         {
    1322           0 :             PushActiveSnapshot(GetTransactionSnapshot());
    1323           0 :             snapshot_set = true;
    1324             :         }
    1325             : 
    1326             :         /*
    1327             :          * Analyze and rewrite the query.  Note that the originally specified
    1328             :          * parameter set is not required to be complete, so we have to use
    1329             :          * parse_analyze_varparams().
    1330             :          */
    1331           0 :         if (log_parser_stats)
    1332           0 :             ResetUsage();
    1333             : 
    1334           0 :         query = parse_analyze_varparams(raw_parse_tree,
    1335             :                                         query_string,
    1336             :                                         &paramTypes,
    1337             :                                         &numParams);
    1338             : 
    1339             :         /*
    1340             :          * Check all parameter types got determined.
    1341             :          */
    1342           0 :         for (i = 0; i < numParams; i++)
    1343             :         {
    1344           0 :             Oid         ptype = paramTypes[i];
    1345             : 
    1346           0 :             if (ptype == InvalidOid || ptype == UNKNOWNOID)
    1347           0 :                 ereport(ERROR,
    1348             :                         (errcode(ERRCODE_INDETERMINATE_DATATYPE),
    1349             :                          errmsg("could not determine data type of parameter $%d",
    1350             :                                 i + 1)));
    1351             :         }
    1352             : 
    1353           0 :         if (log_parser_stats)
    1354           0 :             ShowUsage("PARSE ANALYSIS STATISTICS");
    1355             : 
    1356           0 :         querytree_list = pg_rewrite_query(query);
    1357             : 
    1358             :         /* Done with the snapshot used for parsing */
    1359           0 :         if (snapshot_set)
    1360           0 :             PopActiveSnapshot();
    1361             :     }
    1362             :     else
    1363             :     {
    1364             :         /* Empty input string.  This is legal. */
    1365           0 :         raw_parse_tree = NULL;
    1366           0 :         commandTag = NULL;
    1367           0 :         psrc = CreateCachedPlan(raw_parse_tree, query_string, commandTag);
    1368           0 :         querytree_list = NIL;
    1369             :     }
    1370             : 
    1371             :     /*
    1372             :      * CachedPlanSource must be a direct child of MessageContext before we
    1373             :      * reparent unnamed_stmt_context under it, else we have a disconnected
    1374             :      * circular subgraph.  Klugy, but less so than flipping contexts even more
    1375             :      * above.
    1376             :      */
    1377           0 :     if (unnamed_stmt_context)
    1378           0 :         MemoryContextSetParent(psrc->context, MessageContext);
    1379             : 
    1380             :     /* Finish filling in the CachedPlanSource */
    1381           0 :     CompleteCachedPlan(psrc,
    1382             :                        querytree_list,
    1383             :                        unnamed_stmt_context,
    1384             :                        paramTypes,
    1385             :                        numParams,
    1386             :                        NULL,
    1387             :                        NULL,
    1388             :                        CURSOR_OPT_PARALLEL_OK,  /* allow parallel mode */
    1389             :                        true);   /* fixed result */
    1390             : 
    1391             :     /* If we got a cancel signal during analysis, quit */
    1392           0 :     CHECK_FOR_INTERRUPTS();
    1393             : 
    1394           0 :     if (is_named)
    1395             :     {
    1396             :         /*
    1397             :          * Store the query as a prepared statement.
    1398             :          */
    1399           0 :         StorePreparedStatement(stmt_name, psrc, false);
    1400             :     }
    1401             :     else
    1402             :     {
    1403             :         /*
    1404             :          * We just save the CachedPlanSource into unnamed_stmt_psrc.
    1405             :          */
    1406           0 :         SaveCachedPlan(psrc);
    1407           0 :         unnamed_stmt_psrc = psrc;
    1408             :     }
    1409             : 
    1410           0 :     MemoryContextSwitchTo(oldcontext);
    1411             : 
    1412             :     /*
    1413             :      * We do NOT close the open transaction command here; that only happens
    1414             :      * when the client sends Sync.  Instead, do CommandCounterIncrement just
    1415             :      * in case something happened during parse/plan.
    1416             :      */
    1417           0 :     CommandCounterIncrement();
    1418             : 
    1419             :     /*
    1420             :      * Send ParseComplete.
    1421             :      */
    1422           0 :     if (whereToSendOutput == DestRemote)
    1423           0 :         pq_putemptymessage('1');
    1424             : 
    1425             :     /*
    1426             :      * Emit duration logging if appropriate.
    1427             :      */
    1428           0 :     switch (check_log_duration(msec_str, false))
    1429             :     {
    1430             :         case 1:
    1431           0 :             ereport(LOG,
    1432             :                     (errmsg("duration: %s ms", msec_str),
    1433             :                      errhidestmt(true)));
    1434           0 :             break;
    1435             :         case 2:
    1436           0 :             ereport(LOG,
    1437             :                     (errmsg("duration: %s ms  parse %s: %s",
    1438             :                             msec_str,
    1439             :                             *stmt_name ? stmt_name : "<unnamed>",
    1440             :                             query_string),
    1441             :                      errhidestmt(true)));
    1442           0 :             break;
    1443             :     }
    1444             : 
    1445           0 :     if (save_log_statement_stats)
    1446           0 :         ShowUsage("PARSE MESSAGE STATISTICS");
    1447             : 
    1448           0 :     debug_query_string = NULL;
    1449           0 : }
    1450             : 
    1451             : /*
    1452             :  * exec_bind_message
    1453             :  *
    1454             :  * Process a "Bind" message to create a portal from a prepared statement
    1455             :  */
    1456             : static void
    1457           0 : exec_bind_message(StringInfo input_message)
    1458             : {
    1459             :     const char *portal_name;
    1460             :     const char *stmt_name;
    1461             :     int         numPFormats;
    1462           0 :     int16      *pformats = NULL;
    1463             :     int         numParams;
    1464             :     int         numRFormats;
    1465           0 :     int16      *rformats = NULL;
    1466             :     CachedPlanSource *psrc;
    1467             :     CachedPlan *cplan;
    1468             :     Portal      portal;
    1469             :     char       *query_string;
    1470             :     char       *saved_stmt_name;
    1471             :     ParamListInfo params;
    1472             :     MemoryContext oldContext;
    1473           0 :     bool        save_log_statement_stats = log_statement_stats;
    1474           0 :     bool        snapshot_set = false;
    1475             :     char        msec_str[32];
    1476             : 
    1477             :     /* Get the fixed part of the message */
    1478           0 :     portal_name = pq_getmsgstring(input_message);
    1479           0 :     stmt_name = pq_getmsgstring(input_message);
    1480             : 
    1481           0 :     ereport(DEBUG2,
    1482             :             (errmsg("bind %s to %s",
    1483             :                     *portal_name ? portal_name : "<unnamed>",
    1484             :                     *stmt_name ? stmt_name : "<unnamed>")));
    1485             : 
    1486             :     /* Find prepared statement */
    1487           0 :     if (stmt_name[0] != '\0')
    1488             :     {
    1489             :         PreparedStatement *pstmt;
    1490             : 
    1491           0 :         pstmt = FetchPreparedStatement(stmt_name, true);
    1492           0 :         psrc = pstmt->plansource;
    1493             :     }
    1494             :     else
    1495             :     {
    1496             :         /* special-case the unnamed statement */
    1497           0 :         psrc = unnamed_stmt_psrc;
    1498           0 :         if (!psrc)
    1499           0 :             ereport(ERROR,
    1500             :                     (errcode(ERRCODE_UNDEFINED_PSTATEMENT),
    1501             :                      errmsg("unnamed prepared statement does not exist")));
    1502             :     }
    1503             : 
    1504             :     /*
    1505             :      * Report query to various monitoring facilities.
    1506             :      */
    1507           0 :     debug_query_string = psrc->query_string;
    1508             : 
    1509           0 :     pgstat_report_activity(STATE_RUNNING, psrc->query_string);
    1510             : 
    1511           0 :     set_ps_display("BIND", false);
    1512             : 
    1513           0 :     if (save_log_statement_stats)
    1514           0 :         ResetUsage();
    1515             : 
    1516             :     /*
    1517             :      * Start up a transaction command so we can call functions etc. (Note that
    1518             :      * this will normally change current memory context.) Nothing happens if
    1519             :      * we are already in one.
    1520             :      */
    1521           0 :     start_xact_command();
    1522             : 
    1523             :     /* Switch back to message context */
    1524           0 :     MemoryContextSwitchTo(MessageContext);
    1525             : 
    1526             :     /* Get the parameter format codes */
    1527           0 :     numPFormats = pq_getmsgint(input_message, 2);
    1528           0 :     if (numPFormats > 0)
    1529             :     {
    1530             :         int         i;
    1531             : 
    1532           0 :         pformats = (int16 *) palloc(numPFormats * sizeof(int16));
    1533           0 :         for (i = 0; i < numPFormats; i++)
    1534           0 :             pformats[i] = pq_getmsgint(input_message, 2);
    1535             :     }
    1536             : 
    1537             :     /* Get the parameter value count */
    1538           0 :     numParams = pq_getmsgint(input_message, 2);
    1539             : 
    1540           0 :     if (numPFormats > 1 && numPFormats != numParams)
    1541           0 :         ereport(ERROR,
    1542             :                 (errcode(ERRCODE_PROTOCOL_VIOLATION),
    1543             :                  errmsg("bind message has %d parameter formats but %d parameters",
    1544             :                         numPFormats, numParams)));
    1545             : 
    1546           0 :     if (numParams != psrc->num_params)
    1547           0 :         ereport(ERROR,
    1548             :                 (errcode(ERRCODE_PROTOCOL_VIOLATION),
    1549             :                  errmsg("bind message supplies %d parameters, but prepared statement \"%s\" requires %d",
    1550             :                         numParams, stmt_name, psrc->num_params)));
    1551             : 
    1552             :     /*
    1553             :      * If we are in aborted transaction state, the only portals we can
    1554             :      * actually run are those containing COMMIT or ROLLBACK commands. We
    1555             :      * disallow binding anything else to avoid problems with infrastructure
    1556             :      * that expects to run inside a valid transaction.  We also disallow
    1557             :      * binding any parameters, since we can't risk calling user-defined I/O
    1558             :      * functions.
    1559             :      */
    1560           0 :     if (IsAbortedTransactionBlockState() &&
    1561           0 :         (!(psrc->raw_parse_tree &&
    1562           0 :            IsTransactionExitStmt(psrc->raw_parse_tree->stmt)) ||
    1563             :          numParams != 0))
    1564           0 :         ereport(ERROR,
    1565             :                 (errcode(ERRCODE_IN_FAILED_SQL_TRANSACTION),
    1566             :                  errmsg("current transaction is aborted, "
    1567             :                         "commands ignored until end of transaction block"),
    1568             :                  errdetail_abort()));
    1569             : 
    1570             :     /*
    1571             :      * Create the portal.  Allow silent replacement of an existing portal only
    1572             :      * if the unnamed portal is specified.
    1573             :      */
    1574           0 :     if (portal_name[0] == '\0')
    1575           0 :         portal = CreatePortal(portal_name, true, true);
    1576             :     else
    1577           0 :         portal = CreatePortal(portal_name, false, false);
    1578             : 
    1579             :     /*
    1580             :      * Prepare to copy stuff into the portal's memory context.  We do all this
    1581             :      * copying first, because it could possibly fail (out-of-memory) and we
    1582             :      * don't want a failure to occur between GetCachedPlan and
    1583             :      * PortalDefineQuery; that would result in leaking our plancache refcount.
    1584             :      */
    1585           0 :     oldContext = MemoryContextSwitchTo(PortalGetHeapMemory(portal));
    1586             : 
    1587             :     /* Copy the plan's query string into the portal */
    1588           0 :     query_string = pstrdup(psrc->query_string);
    1589             : 
    1590             :     /* Likewise make a copy of the statement name, unless it's unnamed */
    1591           0 :     if (stmt_name[0])
    1592           0 :         saved_stmt_name = pstrdup(stmt_name);
    1593             :     else
    1594           0 :         saved_stmt_name = NULL;
    1595             : 
    1596             :     /*
    1597             :      * Set a snapshot if we have parameters to fetch (since the input
    1598             :      * functions might need it) or the query isn't a utility command (and
    1599             :      * hence could require redoing parse analysis and planning).  We keep the
    1600             :      * snapshot active till we're done, so that plancache.c doesn't have to
    1601             :      * take new ones.
    1602             :      */
    1603           0 :     if (numParams > 0 ||
    1604           0 :         (psrc->raw_parse_tree &&
    1605           0 :          analyze_requires_snapshot(psrc->raw_parse_tree)))
    1606             :     {
    1607           0 :         PushActiveSnapshot(GetTransactionSnapshot());
    1608           0 :         snapshot_set = true;
    1609             :     }
    1610             : 
    1611             :     /*
    1612             :      * Fetch parameters, if any, and store in the portal's memory context.
    1613             :      */
    1614           0 :     if (numParams > 0)
    1615             :     {
    1616             :         int         paramno;
    1617             : 
    1618           0 :         params = (ParamListInfo) palloc(offsetof(ParamListInfoData, params) +
    1619           0 :                                         numParams * sizeof(ParamExternData));
    1620             :         /* we have static list of params, so no hooks needed */
    1621           0 :         params->paramFetch = NULL;
    1622           0 :         params->paramFetchArg = NULL;
    1623           0 :         params->parserSetup = NULL;
    1624           0 :         params->parserSetupArg = NULL;
    1625           0 :         params->numParams = numParams;
    1626           0 :         params->paramMask = NULL;
    1627             : 
    1628           0 :         for (paramno = 0; paramno < numParams; paramno++)
    1629             :         {
    1630           0 :             Oid         ptype = psrc->param_types[paramno];
    1631             :             int32       plength;
    1632             :             Datum       pval;
    1633             :             bool        isNull;
    1634             :             StringInfoData pbuf;
    1635             :             char        csave;
    1636             :             int16       pformat;
    1637             : 
    1638           0 :             plength = pq_getmsgint(input_message, 4);
    1639           0 :             isNull = (plength == -1);
    1640             : 
    1641           0 :             if (!isNull)
    1642             :             {
    1643           0 :                 const char *pvalue = pq_getmsgbytes(input_message, plength);
    1644             : 
    1645             :                 /*
    1646             :                  * Rather than copying data around, we just set up a phony
    1647             :                  * StringInfo pointing to the correct portion of the message
    1648             :                  * buffer.  We assume we can scribble on the message buffer so
    1649             :                  * as to maintain the convention that StringInfos have a
    1650             :                  * trailing null.  This is grotty but is a big win when
    1651             :                  * dealing with very large parameter strings.
    1652             :                  */
    1653           0 :                 pbuf.data = (char *) pvalue;
    1654           0 :                 pbuf.maxlen = plength + 1;
    1655           0 :                 pbuf.len = plength;
    1656           0 :                 pbuf.cursor = 0;
    1657             : 
    1658           0 :                 csave = pbuf.data[plength];
    1659           0 :                 pbuf.data[plength] = '\0';
    1660             :             }
    1661             :             else
    1662             :             {
    1663           0 :                 pbuf.data = NULL;   /* keep compiler quiet */
    1664           0 :                 csave = 0;
    1665             :             }
    1666             : 
    1667           0 :             if (numPFormats > 1)
    1668           0 :                 pformat = pformats[paramno];
    1669           0 :             else if (numPFormats > 0)
    1670           0 :                 pformat = pformats[0];
    1671             :             else
    1672           0 :                 pformat = 0;    /* default = text */
    1673             : 
    1674           0 :             if (pformat == 0)   /* text mode */
    1675             :             {
    1676             :                 Oid         typinput;
    1677             :                 Oid         typioparam;
    1678             :                 char       *pstring;
    1679             : 
    1680           0 :                 getTypeInputInfo(ptype, &typinput, &typioparam);
    1681             : 
    1682             :                 /*
    1683             :                  * We have to do encoding conversion before calling the
    1684             :                  * typinput routine.
    1685             :                  */
    1686           0 :                 if (isNull)
    1687           0 :                     pstring = NULL;
    1688             :                 else
    1689           0 :                     pstring = pg_client_to_server(pbuf.data, plength);
    1690             : 
    1691           0 :                 pval = OidInputFunctionCall(typinput, pstring, typioparam, -1);
    1692             : 
    1693             :                 /* Free result of encoding conversion, if any */
    1694           0 :                 if (pstring && pstring != pbuf.data)
    1695           0 :                     pfree(pstring);
    1696             :             }
    1697           0 :             else if (pformat == 1)  /* binary mode */
    1698             :             {
    1699             :                 Oid         typreceive;
    1700             :                 Oid         typioparam;
    1701             :                 StringInfo  bufptr;
    1702             : 
    1703             :                 /*
    1704             :                  * Call the parameter type's binary input converter
    1705             :                  */
    1706           0 :                 getTypeBinaryInputInfo(ptype, &typreceive, &typioparam);
    1707             : 
    1708           0 :                 if (isNull)
    1709           0 :                     bufptr = NULL;
    1710             :                 else
    1711           0 :                     bufptr = &pbuf;
    1712             : 
    1713           0 :                 pval = OidReceiveFunctionCall(typreceive, bufptr, typioparam, -1);
    1714             : 
    1715             :                 /* Trouble if it didn't eat the whole buffer */
    1716           0 :                 if (!isNull && pbuf.cursor != pbuf.len)
    1717           0 :                     ereport(ERROR,
    1718             :                             (errcode(ERRCODE_INVALID_BINARY_REPRESENTATION),
    1719             :                              errmsg("incorrect binary data format in bind parameter %d",
    1720             :                                     paramno + 1)));
    1721             :             }
    1722             :             else
    1723             :             {
    1724           0 :                 ereport(ERROR,
    1725             :                         (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
    1726             :                          errmsg("unsupported format code: %d",
    1727             :                                 pformat)));
    1728             :                 pval = 0;       /* keep compiler quiet */
    1729             :             }
    1730             : 
    1731             :             /* Restore message buffer contents */
    1732           0 :             if (!isNull)
    1733           0 :                 pbuf.data[plength] = csave;
    1734             : 
    1735           0 :             params->params[paramno].value = pval;
    1736           0 :             params->params[paramno].isnull = isNull;
    1737             : 
    1738             :             /*
    1739             :              * We mark the params as CONST.  This ensures that any custom plan
    1740             :              * makes full use of the parameter values.
    1741             :              */
    1742           0 :             params->params[paramno].pflags = PARAM_FLAG_CONST;
    1743           0 :             params->params[paramno].ptype = ptype;
    1744             :         }
    1745             :     }
    1746             :     else
    1747           0 :         params = NULL;
    1748             : 
    1749             :     /* Done storing stuff in portal's context */
    1750           0 :     MemoryContextSwitchTo(oldContext);
    1751             : 
    1752             :     /* Get the result format codes */
    1753           0 :     numRFormats = pq_getmsgint(input_message, 2);
    1754           0 :     if (numRFormats > 0)
    1755             :     {
    1756             :         int         i;
    1757             : 
    1758           0 :         rformats = (int16 *) palloc(numRFormats * sizeof(int16));
    1759           0 :         for (i = 0; i < numRFormats; i++)
    1760           0 :             rformats[i] = pq_getmsgint(input_message, 2);
    1761             :     }
    1762             : 
    1763           0 :     pq_getmsgend(input_message);
    1764             : 
    1765             :     /*
    1766             :      * Obtain a plan from the CachedPlanSource.  Any cruft from (re)planning
    1767             :      * will be generated in MessageContext.  The plan refcount will be
    1768             :      * assigned to the Portal, so it will be released at portal destruction.
    1769             :      */
    1770           0 :     cplan = GetCachedPlan(psrc, params, false, NULL);
    1771             : 
    1772             :     /*
    1773             :      * Now we can define the portal.
    1774             :      *
    1775             :      * DO NOT put any code that could possibly throw an error between the
    1776             :      * above GetCachedPlan call and here.
    1777             :      */
    1778           0 :     PortalDefineQuery(portal,
    1779             :                       saved_stmt_name,
    1780             :                       query_string,
    1781             :                       psrc->commandTag,
    1782             :                       cplan->stmt_list,
    1783             :                       cplan);
    1784             : 
    1785             :     /* Done with the snapshot used for parameter I/O and parsing/planning */
    1786           0 :     if (snapshot_set)
    1787           0 :         PopActiveSnapshot();
    1788             : 
    1789             :     /*
    1790             :      * And we're ready to start portal execution.
    1791             :      */
    1792           0 :     PortalStart(portal, params, 0, InvalidSnapshot);
    1793             : 
    1794             :     /*
    1795             :      * Apply the result format requests to the portal.
    1796             :      */
    1797           0 :     PortalSetResultFormat(portal, numRFormats, rformats);
    1798             : 
    1799             :     /*
    1800             :      * Send BindComplete.
    1801             :      */
    1802           0 :     if (whereToSendOutput == DestRemote)
    1803           0 :         pq_putemptymessage('2');
    1804             : 
    1805             :     /*
    1806             :      * Emit duration logging if appropriate.
    1807             :      */
    1808           0 :     switch (check_log_duration(msec_str, false))
    1809             :     {
    1810             :         case 1:
    1811           0 :             ereport(LOG,
    1812             :                     (errmsg("duration: %s ms", msec_str),
    1813             :                      errhidestmt(true)));
    1814           0 :             break;
    1815             :         case 2:
    1816           0 :             ereport(LOG,
    1817             :                     (errmsg("duration: %s ms  bind %s%s%s: %s",
    1818             :                             msec_str,
    1819             :                             *stmt_name ? stmt_name : "<unnamed>",
    1820             :                             *portal_name ? "/" : "",
    1821             :                             *portal_name ? portal_name : "",
    1822             :                             psrc->query_string),
    1823             :                      errhidestmt(true),
    1824             :                      errdetail_params(params)));
    1825           0 :             break;
    1826             :     }
    1827             : 
    1828           0 :     if (save_log_statement_stats)
    1829           0 :         ShowUsage("BIND MESSAGE STATISTICS");
    1830             : 
    1831           0 :     debug_query_string = NULL;
    1832           0 : }
    1833             : 
    1834             : /*
    1835             :  * exec_execute_message
    1836             :  *
    1837             :  * Process an "Execute" message for a portal
    1838             :  */
    1839             : static void
    1840           0 : exec_execute_message(const char *portal_name, long max_rows)
    1841             : {
    1842             :     CommandDest dest;
    1843             :     DestReceiver *receiver;
    1844             :     Portal      portal;
    1845             :     bool        completed;
    1846             :     char        completionTag[COMPLETION_TAG_BUFSIZE];
    1847             :     const char *sourceText;
    1848             :     const char *prepStmtName;
    1849             :     ParamListInfo portalParams;
    1850           0 :     bool        save_log_statement_stats = log_statement_stats;
    1851             :     bool        is_xact_command;
    1852             :     bool        execute_is_fetch;
    1853           0 :     bool        was_logged = false;
    1854             :     char        msec_str[32];
    1855             : 
    1856             :     /* Adjust destination to tell printtup.c what to do */
    1857           0 :     dest = whereToSendOutput;
    1858           0 :     if (dest == DestRemote)
    1859           0 :         dest = DestRemoteExecute;
    1860             : 
    1861           0 :     portal = GetPortalByName(portal_name);
    1862           0 :     if (!PortalIsValid(portal))
    1863           0 :         ereport(ERROR,
    1864             :                 (errcode(ERRCODE_UNDEFINED_CURSOR),
    1865             :                  errmsg("portal \"%s\" does not exist", portal_name)));
    1866             : 
    1867             :     /*
    1868             :      * If the original query was a null string, just return
    1869             :      * EmptyQueryResponse.
    1870             :      */
    1871           0 :     if (portal->commandTag == NULL)
    1872             :     {
    1873           0 :         Assert(portal->stmts == NIL);
    1874           0 :         NullCommand(dest);
    1875           0 :         return;
    1876             :     }
    1877             : 
    1878             :     /* Does the portal contain a transaction command? */
    1879           0 :     is_xact_command = IsTransactionStmtList(portal->stmts);
    1880             : 
    1881             :     /*
    1882             :      * We must copy the sourceText and prepStmtName into MessageContext in
    1883             :      * case the portal is destroyed during finish_xact_command. Can avoid the
    1884             :      * copy if it's not an xact command, though.
    1885             :      */
    1886           0 :     if (is_xact_command)
    1887             :     {
    1888           0 :         sourceText = pstrdup(portal->sourceText);
    1889           0 :         if (portal->prepStmtName)
    1890           0 :             prepStmtName = pstrdup(portal->prepStmtName);
    1891             :         else
    1892           0 :             prepStmtName = "<unnamed>";
    1893             : 
    1894             :         /*
    1895             :          * An xact command shouldn't have any parameters, which is a good
    1896             :          * thing because they wouldn't be around after finish_xact_command.
    1897             :          */
    1898           0 :         portalParams = NULL;
    1899             :     }
    1900             :     else
    1901             :     {
    1902           0 :         sourceText = portal->sourceText;
    1903           0 :         if (portal->prepStmtName)
    1904           0 :             prepStmtName = portal->prepStmtName;
    1905             :         else
    1906           0 :             prepStmtName = "<unnamed>";
    1907           0 :         portalParams = portal->portalParams;
    1908             :     }
    1909             : 
    1910             :     /*
    1911             :      * Report query to various monitoring facilities.
    1912             :      */
    1913           0 :     debug_query_string = sourceText;
    1914             : 
    1915           0 :     pgstat_report_activity(STATE_RUNNING, sourceText);
    1916             : 
    1917           0 :     set_ps_display(portal->commandTag, false);
    1918             : 
    1919           0 :     if (save_log_statement_stats)
    1920           0 :         ResetUsage();
    1921             : 
    1922           0 :     BeginCommand(portal->commandTag, dest);
    1923             : 
    1924             :     /*
    1925             :      * Create dest receiver in MessageContext (we don't want it in transaction
    1926             :      * context, because that may get deleted if portal contains VACUUM).
    1927             :      */
    1928           0 :     receiver = CreateDestReceiver(dest);
    1929           0 :     if (dest == DestRemoteExecute)
    1930           0 :         SetRemoteDestReceiverParams(receiver, portal);
    1931             : 
    1932             :     /*
    1933             :      * Ensure we are in a transaction command (this should normally be the
    1934             :      * case already due to prior BIND).
    1935             :      */
    1936           0 :     start_xact_command();
    1937             : 
    1938             :     /*
    1939             :      * If we re-issue an Execute protocol request against an existing portal,
    1940             :      * then we are only fetching more rows rather than completely re-executing
    1941             :      * the query from the start. atStart is never reset for a v3 portal, so we
    1942             :      * are safe to use this check.
    1943             :      */
    1944           0 :     execute_is_fetch = !portal->atStart;
    1945             : 
    1946             :     /* Log immediately if dictated by log_statement */
    1947           0 :     if (check_log_statement(portal->stmts))
    1948             :     {
    1949           0 :         ereport(LOG,
    1950             :                 (errmsg("%s %s%s%s: %s",
    1951             :                         execute_is_fetch ?
    1952             :                         _("execute fetch from") :
    1953             :                         _("execute"),
    1954             :                         prepStmtName,
    1955             :                         *portal_name ? "/" : "",
    1956             :                         *portal_name ? portal_name : "",
    1957             :                         sourceText),
    1958             :                  errhidestmt(true),
    1959             :                  errdetail_params(portalParams)));
    1960           0 :         was_logged = true;
    1961             :     }
    1962             : 
    1963             :     /*
    1964             :      * If we are in aborted transaction state, the only portals we can
    1965             :      * actually run are those containing COMMIT or ROLLBACK commands.
    1966             :      */
    1967           0 :     if (IsAbortedTransactionBlockState() &&
    1968           0 :         !IsTransactionExitStmtList(portal->stmts))
    1969           0 :         ereport(ERROR,
    1970             :                 (errcode(ERRCODE_IN_FAILED_SQL_TRANSACTION),
    1971             :                  errmsg("current transaction is aborted, "
    1972             :                         "commands ignored until end of transaction block"),
    1973             :                  errdetail_abort()));
    1974             : 
    1975             :     /* Check for cancel signal before we start execution */
    1976           0 :     CHECK_FOR_INTERRUPTS();
    1977             : 
    1978             :     /*
    1979             :      * Okay to run the portal.
    1980             :      */
    1981           0 :     if (max_rows <= 0)
    1982           0 :         max_rows = FETCH_ALL;
    1983             : 
    1984           0 :     completed = PortalRun(portal,
    1985             :                           max_rows,
    1986             :                           true, /* always top level */
    1987           0 :                           !execute_is_fetch && max_rows == FETCH_ALL,
    1988             :                           receiver,
    1989             :                           receiver,
    1990             :                           completionTag);
    1991             : 
    1992           0 :     (*receiver->rDestroy) (receiver);
    1993             : 
    1994           0 :     if (completed)
    1995             :     {
    1996           0 :         if (is_xact_command)
    1997             :         {
    1998             :             /*
    1999             :              * If this was a transaction control statement, commit it.  We
    2000             :              * will start a new xact command for the next command (if any).
    2001             :              */
    2002           0 :             finish_xact_command();
    2003             :         }
    2004             :         else
    2005             :         {
    2006             :             /*
    2007             :              * We need a CommandCounterIncrement after every query, except
    2008             :              * those that start or end a transaction block.
    2009             :              */
    2010           0 :             CommandCounterIncrement();
    2011             :         }
    2012             : 
    2013             :         /* Send appropriate CommandComplete to client */
    2014           0 :         EndCommand(completionTag, dest);
    2015             :     }
    2016             :     else
    2017             :     {
    2018             :         /* Portal run not complete, so send PortalSuspended */
    2019           0 :         if (whereToSendOutput == DestRemote)
    2020           0 :             pq_putemptymessage('s');
    2021             :     }
    2022             : 
    2023             :     /*
    2024             :      * Emit duration logging if appropriate.
    2025             :      */
    2026           0 :     switch (check_log_duration(msec_str, was_logged))
    2027             :     {
    2028             :         case 1:
    2029           0 :             ereport(LOG,
    2030             :                     (errmsg("duration: %s ms", msec_str),
    2031             :                      errhidestmt(true)));
    2032           0 :             break;
    2033             :         case 2:
    2034           0 :             ereport(LOG,
    2035             :                     (errmsg("duration: %s ms  %s %s%s%s: %s",
    2036             :                             msec_str,
    2037             :                             execute_is_fetch ?
    2038             :                             _("execute fetch from") :
    2039             :                             _("execute"),
    2040             :                             prepStmtName,
    2041             :                             *portal_name ? "/" : "",
    2042             :                             *portal_name ? portal_name : "",
    2043             :                             sourceText),
    2044             :                      errhidestmt(true),
    2045             :                      errdetail_params(portalParams)));
    2046           0 :             break;
    2047             :     }
    2048             : 
    2049           0 :     if (save_log_statement_stats)
    2050           0 :         ShowUsage("EXECUTE MESSAGE STATISTICS");
    2051             : 
    2052           0 :     debug_query_string = NULL;
    2053             : }
    2054             : 
    2055             : /*
    2056             :  * check_log_statement
    2057             :  *      Determine whether command should be logged because of log_statement
    2058             :  *
    2059             :  * stmt_list can be either raw grammar output or a list of planned
    2060             :  * statements
    2061             :  */
    2062             : static bool
    2063       26867 : check_log_statement(List *stmt_list)
    2064             : {
    2065             :     ListCell   *stmt_item;
    2066             : 
    2067       26867 :     if (log_statement == LOGSTMT_NONE)
    2068       26867 :         return false;
    2069           0 :     if (log_statement == LOGSTMT_ALL)
    2070           0 :         return true;
    2071             : 
    2072             :     /* Else we have to inspect the statement(s) to see whether to log */
    2073           0 :     foreach(stmt_item, stmt_list)
    2074             :     {
    2075           0 :         Node       *stmt = (Node *) lfirst(stmt_item);
    2076             : 
    2077           0 :         if (GetCommandLogLevel(stmt) <= log_statement)
    2078           0 :             return true;
    2079             :     }
    2080             : 
    2081           0 :     return false;
    2082             : }
    2083             : 
    2084             : /*
    2085             :  * check_log_duration
    2086             :  *      Determine whether current command's duration should be logged
    2087             :  *
    2088             :  * Returns:
    2089             :  *      0 if no logging is needed
    2090             :  *      1 if just the duration should be logged
    2091             :  *      2 if duration and query details should be logged
    2092             :  *
    2093             :  * If logging is needed, the duration in msec is formatted into msec_str[],
    2094             :  * which must be a 32-byte buffer.
    2095             :  *
    2096             :  * was_logged should be TRUE if caller already logged query details (this
    2097             :  * essentially prevents 2 from being returned).
    2098             :  */
    2099             : int
    2100       24035 : check_log_duration(char *msec_str, bool was_logged)
    2101             : {
    2102       24035 :     if (log_duration || log_min_duration_statement >= 0)
    2103             :     {
    2104             :         long        secs;
    2105             :         int         usecs;
    2106             :         int         msecs;
    2107             :         bool        exceeded;
    2108             : 
    2109           0 :         TimestampDifference(GetCurrentStatementStartTimestamp(),
    2110             :                             GetCurrentTimestamp(),
    2111             :                             &secs, &usecs);
    2112           0 :         msecs = usecs / 1000;
    2113             : 
    2114             :         /*
    2115             :          * This odd-looking test for log_min_duration_statement being exceeded
    2116             :          * is designed to avoid integer overflow with very long durations:
    2117             :          * don't compute secs * 1000 until we've verified it will fit in int.
    2118             :          */
    2119           0 :         exceeded = (log_min_duration_statement == 0 ||
    2120           0 :                     (log_min_duration_statement > 0 &&
    2121           0 :                      (secs > log_min_duration_statement / 1000 ||
    2122           0 :                       secs * 1000 + msecs >= log_min_duration_statement)));
    2123             : 
    2124           0 :         if (exceeded || log_duration)
    2125             :         {
    2126           0 :             snprintf(msec_str, 32, "%ld.%03d",
    2127           0 :                      secs * 1000 + msecs, usecs % 1000);
    2128           0 :             if (exceeded && !was_logged)
    2129           0 :                 return 2;
    2130             :             else
    2131           0 :                 return 1;
    2132             :         }
    2133             :     }
    2134             : 
    2135       24035 :     return 0;
    2136             : }
    2137             : 
    2138             : /*
    2139             :  * errdetail_execute
    2140             :  *
    2141             :  * Add an errdetail() line showing the query referenced by an EXECUTE, if any.
    2142             :  * The argument is the raw parsetree list.
    2143             :  */
    2144             : static int
    2145           0 : errdetail_execute(List *raw_parsetree_list)
    2146             : {
    2147             :     ListCell   *parsetree_item;
    2148             : 
    2149           0 :     foreach(parsetree_item, raw_parsetree_list)
    2150             :     {
    2151           0 :         RawStmt    *parsetree = lfirst_node(RawStmt, parsetree_item);
    2152             : 
    2153           0 :         if (IsA(parsetree->stmt, ExecuteStmt))
    2154             :         {
    2155           0 :             ExecuteStmt *stmt = (ExecuteStmt *) parsetree->stmt;
    2156             :             PreparedStatement *pstmt;
    2157             : 
    2158           0 :             pstmt = FetchPreparedStatement(stmt->name, false);
    2159           0 :             if (pstmt)
    2160             :             {
    2161           0 :                 errdetail("prepare: %s", pstmt->plansource->query_string);
    2162           0 :                 return 0;
    2163             :             }
    2164             :         }
    2165             :     }
    2166             : 
    2167           0 :     return 0;
    2168             : }
    2169             : 
    2170             : /*
    2171             :  * errdetail_params
    2172             :  *
    2173             :  * Add an errdetail() line showing bind-parameter data, if available.
    2174             :  */
    2175             : static int
    2176           0 : errdetail_params(ParamListInfo params)
    2177             : {
    2178             :     /* We mustn't call user-defined I/O functions when in an aborted xact */
    2179           0 :     if (params && params->numParams > 0 && !IsAbortedTransactionBlockState())
    2180             :     {
    2181             :         StringInfoData param_str;
    2182             :         MemoryContext oldcontext;
    2183             :         int         paramno;
    2184             : 
    2185             :         /* Make sure any trash is generated in MessageContext */
    2186           0 :         oldcontext = MemoryContextSwitchTo(MessageContext);
    2187             : 
    2188           0 :         initStringInfo(&param_str);
    2189             : 
    2190           0 :         for (paramno = 0; paramno < params->numParams; paramno++)
    2191             :         {
    2192           0 :             ParamExternData *prm = &params->params[paramno];
    2193             :             Oid         typoutput;
    2194             :             bool        typisvarlena;
    2195             :             char       *pstring;
    2196             :             char       *p;
    2197             : 
    2198           0 :             appendStringInfo(&param_str, "%s$%d = ",
    2199             :                              paramno > 0 ? ", " : "",
    2200             :                              paramno + 1);
    2201             : 
    2202           0 :             if (prm->isnull || !OidIsValid(prm->ptype))
    2203             :             {
    2204           0 :                 appendStringInfoString(&param_str, "NULL");
    2205           0 :                 continue;
    2206             :             }
    2207             : 
    2208           0 :             getTypeOutputInfo(prm->ptype, &typoutput, &typisvarlena);
    2209             : 
    2210           0 :             pstring = OidOutputFunctionCall(typoutput, prm->value);
    2211             : 
    2212           0 :             appendStringInfoCharMacro(&param_str, '\'');
    2213           0 :             for (p = pstring; *p; p++)
    2214             :             {
    2215           0 :                 if (*p == '\'') /* double single quotes */
    2216           0 :                     appendStringInfoCharMacro(&param_str, *p);
    2217           0 :                 appendStringInfoCharMacro(&param_str, *p);
    2218             :             }
    2219           0 :             appendStringInfoCharMacro(&param_str, '\'');
    2220             : 
    2221           0 :             pfree(pstring);
    2222             :         }
    2223             : 
    2224           0 :         errdetail("parameters: %s", param_str.data);
    2225             : 
    2226           0 :         pfree(param_str.data);
    2227             : 
    2228           0 :         MemoryContextSwitchTo(oldcontext);
    2229             :     }
    2230             : 
    2231           0 :     return 0;
    2232             : }
    2233             : 
    2234             : /*
    2235             :  * errdetail_abort
    2236             :  *
    2237             :  * Add an errdetail() line showing abort reason, if any.
    2238             :  */
    2239             : static int
    2240           9 : errdetail_abort(void)
    2241             : {
    2242           9 :     if (MyProc->recoveryConflictPending)
    2243           0 :         errdetail("abort reason: recovery conflict");
    2244             : 
    2245           9 :     return 0;
    2246             : }
    2247             : 
    2248             : /*
    2249             :  * errdetail_recovery_conflict
    2250             :  *
    2251             :  * Add an errdetail() line showing conflict source.
    2252             :  */
    2253             : static int
    2254           0 : errdetail_recovery_conflict(void)
    2255             : {
    2256           0 :     switch (RecoveryConflictReason)
    2257             :     {
    2258             :         case PROCSIG_RECOVERY_CONFLICT_BUFFERPIN:
    2259           0 :             errdetail("User was holding shared buffer pin for too long.");
    2260           0 :             break;
    2261             :         case PROCSIG_RECOVERY_CONFLICT_LOCK:
    2262           0 :             errdetail("User was holding a relation lock for too long.");
    2263           0 :             break;
    2264             :         case PROCSIG_RECOVERY_CONFLICT_TABLESPACE:
    2265           0 :             errdetail("User was or might have been using tablespace that must be dropped.");
    2266           0 :             break;
    2267             :         case PROCSIG_RECOVERY_CONFLICT_SNAPSHOT:
    2268           0 :             errdetail("User query might have needed to see row versions that must be removed.");
    2269           0 :             break;
    2270             :         case PROCSIG_RECOVERY_CONFLICT_STARTUP_DEADLOCK:
    2271           0 :             errdetail("User transaction caused buffer deadlock with recovery.");
    2272           0 :             break;
    2273             :         case PROCSIG_RECOVERY_CONFLICT_DATABASE:
    2274           0 :             errdetail("User was connected to a database that must be dropped.");
    2275           0 :             break;
    2276             :         default:
    2277           0 :             break;
    2278             :             /* no errdetail */
    2279             :     }
    2280             : 
    2281           0 :     return 0;
    2282             : }
    2283             : 
    2284             : /*
    2285             :  * exec_describe_statement_message
    2286             :  *
    2287             :  * Process a "Describe" message for a prepared statement
    2288             :  */
    2289             : static void
    2290           0 : exec_describe_statement_message(const char *stmt_name)
    2291             : {
    2292             :     CachedPlanSource *psrc;
    2293             :     StringInfoData buf;
    2294             :     int         i;
    2295             : 
    2296             :     /*
    2297             :      * Start up a transaction command. (Note that this will normally change
    2298             :      * current memory context.) Nothing happens if we are already in one.
    2299             :      */
    2300           0 :     start_xact_command();
    2301             : 
    2302             :     /* Switch back to message context */
    2303           0 :     MemoryContextSwitchTo(MessageContext);
    2304             : 
    2305             :     /* Find prepared statement */
    2306           0 :     if (stmt_name[0] != '\0')
    2307             :     {
    2308             :         PreparedStatement *pstmt;
    2309             : 
    2310           0 :         pstmt = FetchPreparedStatement(stmt_name, true);
    2311           0 :         psrc = pstmt->plansource;
    2312             :     }
    2313             :     else
    2314             :     {
    2315             :         /* special-case the unnamed statement */
    2316           0 :         psrc = unnamed_stmt_psrc;
    2317           0 :         if (!psrc)
    2318           0 :             ereport(ERROR,
    2319             :                     (errcode(ERRCODE_UNDEFINED_PSTATEMENT),
    2320             :                      errmsg("unnamed prepared statement does not exist")));
    2321             :     }
    2322             : 
    2323             :     /* Prepared statements shouldn't have changeable result descs */
    2324           0 :     Assert(psrc->fixed_result);
    2325             : 
    2326             :     /*
    2327             :      * If we are in aborted transaction state, we can't run
    2328             :      * SendRowDescriptionMessage(), because that needs catalog accesses.
    2329             :      * Hence, refuse to Describe statements that return data.  (We shouldn't
    2330             :      * just refuse all Describes, since that might break the ability of some
    2331             :      * clients to issue COMMIT or ROLLBACK commands, if they use code that
    2332             :      * blindly Describes whatever it does.)  We can Describe parameters
    2333             :      * without doing anything dangerous, so we don't restrict that.
    2334             :      */
    2335           0 :     if (IsAbortedTransactionBlockState() &&
    2336           0 :         psrc->resultDesc)
    2337           0 :         ereport(ERROR,
    2338             :                 (errcode(ERRCODE_IN_FAILED_SQL_TRANSACTION),
    2339             :                  errmsg("current transaction is aborted, "
    2340             :                         "commands ignored until end of transaction block"),
    2341             :                  errdetail_abort()));
    2342             : 
    2343           0 :     if (whereToSendOutput != DestRemote)
    2344           0 :         return;                 /* can't actually do anything... */
    2345             : 
    2346             :     /*
    2347             :      * First describe the parameters...
    2348             :      */
    2349           0 :     pq_beginmessage(&buf, 't'); /* parameter description message type */
    2350           0 :     pq_sendint(&buf, psrc->num_params, 2);
    2351             : 
    2352           0 :     for (i = 0; i < psrc->num_params; i++)
    2353             :     {
    2354           0 :         Oid         ptype = psrc->param_types[i];
    2355             : 
    2356           0 :         pq_sendint(&buf, (int) ptype, 4);
    2357             :     }
    2358           0 :     pq_endmessage(&buf);
    2359             : 
    2360             :     /*
    2361             :      * Next send RowDescription or NoData to describe the result...
    2362             :      */
    2363           0 :     if (psrc->resultDesc)
    2364             :     {
    2365             :         List       *tlist;
    2366             : 
    2367             :         /* Get the plan's primary targetlist */
    2368           0 :         tlist = CachedPlanGetTargetList(psrc, NULL);
    2369             : 
    2370           0 :         SendRowDescriptionMessage(psrc->resultDesc, tlist, NULL);
    2371             :     }
    2372             :     else
    2373           0 :         pq_putemptymessage('n');    /* NoData */
    2374             : 
    2375             : }
    2376             : 
    2377             : /*
    2378             :  * exec_describe_portal_message
    2379             :  *
    2380             :  * Process a "Describe" message for a portal
    2381             :  */
    2382             : static void
    2383           0 : exec_describe_portal_message(const char *portal_name)
    2384             : {
    2385             :     Portal      portal;
    2386             : 
    2387             :     /*
    2388             :      * Start up a transaction command. (Note that this will normally change
    2389             :      * current memory context.) Nothing happens if we are already in one.
    2390             :      */
    2391           0 :     start_xact_command();
    2392             : 
    2393             :     /* Switch back to message context */
    2394           0 :     MemoryContextSwitchTo(MessageContext);
    2395             : 
    2396           0 :     portal = GetPortalByName(portal_name);
    2397           0 :     if (!PortalIsValid(portal))
    2398           0 :         ereport(ERROR,
    2399             :                 (errcode(ERRCODE_UNDEFINED_CURSOR),
    2400             :                  errmsg("portal \"%s\" does not exist", portal_name)));
    2401             : 
    2402             :     /*
    2403             :      * If we are in aborted transaction state, we can't run
    2404             :      * SendRowDescriptionMessage(), because that needs catalog accesses.
    2405             :      * Hence, refuse to Describe portals that return data.  (We shouldn't just
    2406             :      * refuse all Describes, since that might break the ability of some
    2407             :      * clients to issue COMMIT or ROLLBACK commands, if they use code that
    2408             :      * blindly Describes whatever it does.)
    2409             :      */
    2410           0 :     if (IsAbortedTransactionBlockState() &&
    2411           0 :         portal->tupDesc)
    2412           0 :         ereport(ERROR,
    2413             :                 (errcode(ERRCODE_IN_FAILED_SQL_TRANSACTION),
    2414             :                  errmsg("current transaction is aborted, "
    2415             :                         "commands ignored until end of transaction block"),
    2416             :                  errdetail_abort()));
    2417             : 
    2418           0 :     if (whereToSendOutput != DestRemote)
    2419           0 :         return;                 /* can't actually do anything... */
    2420             : 
    2421           0 :     if (portal->tupDesc)
    2422           0 :         SendRowDescriptionMessage(portal->tupDesc,
    2423             :                                   FetchPortalTargetList(portal),
    2424             :                                   portal->formats);
    2425             :     else
    2426           0 :         pq_putemptymessage('n');    /* NoData */
    2427             : }
    2428             : 
    2429             : 
    2430             : /*
    2431             :  * Convenience routines for starting/committing a single command.
    2432             :  */
    2433             : static void
    2434       54620 : start_xact_command(void)
    2435             : {
    2436       54620 :     if (!xact_started)
    2437             :     {
    2438       27255 :         StartTransactionCommand();
    2439             : 
    2440             :         /* Set statement timeout running, if any */
    2441             :         /* NB: this mustn't be enabled until we are within an xact */
    2442       27255 :         if (StatementTimeout > 0)
    2443           1 :             enable_timeout_after(STATEMENT_TIMEOUT, StatementTimeout);
    2444             :         else
    2445       27254 :             disable_timeout(STATEMENT_TIMEOUT, false);
    2446             : 
    2447       27255 :         xact_started = true;
    2448             :     }
    2449       54620 : }
    2450             : 
    2451             : static void
    2452       47821 : finish_xact_command(void)
    2453             : {
    2454       47821 :     if (xact_started)
    2455             :     {
    2456             :         /* Cancel any active statement timeout before committing */
    2457       24049 :         disable_timeout(STATEMENT_TIMEOUT, false);
    2458             : 
    2459       24049 :         CommitTransactionCommand();
    2460             : 
    2461             : #ifdef MEMORY_CONTEXT_CHECKING
    2462             :         /* Check all memory contexts that weren't freed during commit */
    2463             :         /* (those that were, were checked before being deleted) */
    2464       24035 :         MemoryContextCheck(TopMemoryContext);
    2465             : #endif
    2466             : 
    2467             : #ifdef SHOW_MEMORY_STATS
    2468             :         /* Print mem stats after each commit for leak tracking */
    2469             :         MemoryContextStats(TopMemoryContext);
    2470             : #endif
    2471             : 
    2472       24035 :         xact_started = false;
    2473             :     }
    2474       47807 : }
    2475             : 
    2476             : 
    2477             : /*
    2478             :  * Convenience routines for checking whether a statement is one of the
    2479             :  * ones that we allow in transaction-aborted state.
    2480             :  */
    2481             : 
    2482             : /* Test a bare parsetree */
    2483             : static bool
    2484         112 : IsTransactionExitStmt(Node *parsetree)
    2485             : {
    2486         112 :     if (parsetree && IsA(parsetree, TransactionStmt))
    2487             :     {
    2488         105 :         TransactionStmt *stmt = (TransactionStmt *) parsetree;
    2489             : 
    2490         184 :         if (stmt->kind == TRANS_STMT_COMMIT ||
    2491         157 :             stmt->kind == TRANS_STMT_PREPARE ||
    2492         101 :             stmt->kind == TRANS_STMT_ROLLBACK ||
    2493          23 :             stmt->kind == TRANS_STMT_ROLLBACK_TO)
    2494         103 :             return true;
    2495             :     }
    2496           9 :     return false;
    2497             : }
    2498             : 
    2499             : /* Test a list that contains PlannedStmt nodes */
    2500             : static bool
    2501           0 : IsTransactionExitStmtList(List *pstmts)
    2502             : {
    2503           0 :     if (list_length(pstmts) == 1)
    2504             :     {
    2505           0 :         PlannedStmt *pstmt = linitial_node(PlannedStmt, pstmts);
    2506             : 
    2507           0 :         if (pstmt->commandType == CMD_UTILITY &&
    2508           0 :             IsTransactionExitStmt(pstmt->utilityStmt))
    2509           0 :             return true;
    2510             :     }
    2511           0 :     return false;
    2512             : }
    2513             : 
    2514             : /* Test a list that contains PlannedStmt nodes */
    2515             : static bool
    2516           0 : IsTransactionStmtList(List *pstmts)
    2517             : {
    2518           0 :     if (list_length(pstmts) == 1)
    2519             :     {
    2520           0 :         PlannedStmt *pstmt = linitial_node(PlannedStmt, pstmts);
    2521             : 
    2522           0 :         if (pstmt->commandType == CMD_UTILITY &&
    2523           0 :             IsA(pstmt->utilityStmt, TransactionStmt))
    2524           0 :             return true;
    2525             :     }
    2526           0 :     return false;
    2527             : }
    2528             : 
    2529             : /* Release any existing unnamed prepared statement */
    2530             : static void
    2531       26997 : drop_unnamed_stmt(void)
    2532             : {
    2533             :     /* paranoia to avoid a dangling pointer in case of error */
    2534       26997 :     if (unnamed_stmt_psrc)
    2535             :     {
    2536           0 :         CachedPlanSource *psrc = unnamed_stmt_psrc;
    2537             : 
    2538           0 :         unnamed_stmt_psrc = NULL;
    2539           0 :         DropCachedPlan(psrc);
    2540             :     }
    2541       26997 : }
    2542             : 
    2543             : 
    2544             : /* --------------------------------
    2545             :  *      signal handler routines used in PostgresMain()
    2546             :  * --------------------------------
    2547             :  */
    2548             : 
    2549             : /*
    2550             :  * quickdie() occurs when signalled SIGQUIT by the postmaster.
    2551             :  *
    2552             :  * Some backend has bought the farm,
    2553             :  * so we need to stop what we're doing and exit.
    2554             :  */
    2555             : void
    2556           0 : quickdie(SIGNAL_ARGS)
    2557             : {
    2558           0 :     sigaddset(&BlockSig, SIGQUIT);  /* prevent nested calls */
    2559           0 :     PG_SETMASK(&BlockSig);
    2560             : 
    2561             :     /*
    2562             :      * Prevent interrupts while exiting; though we just blocked signals that
    2563             :      * would queue new interrupts, one may have been pending.  We don't want a
    2564             :      * quickdie() downgraded to a mere query cancel.
    2565             :      */
    2566           0 :     HOLD_INTERRUPTS();
    2567             : 
    2568             :     /*
    2569             :      * If we're aborting out of client auth, don't risk trying to send
    2570             :      * anything to the client; we will likely violate the protocol, not to
    2571             :      * mention that we may have interrupted the guts of OpenSSL or some
    2572             :      * authentication library.
    2573             :      */
    2574           0 :     if (ClientAuthInProgress && whereToSendOutput == DestRemote)
    2575           0 :         whereToSendOutput = DestNone;
    2576             : 
    2577             :     /*
    2578             :      * Ideally this should be ereport(FATAL), but then we'd not get control
    2579             :      * back...
    2580             :      */
    2581           0 :     ereport(WARNING,
    2582             :             (errcode(ERRCODE_CRASH_SHUTDOWN),
    2583             :              errmsg("terminating connection because of crash of another server process"),
    2584             :              errdetail("The postmaster has commanded this server process to roll back"
    2585             :                        " the current transaction and exit, because another"
    2586             :                        " server process exited abnormally and possibly corrupted"
    2587             :                        " shared memory."),
    2588             :              errhint("In a moment you should be able to reconnect to the"
    2589             :                      " database and repeat your command.")));
    2590             : 
    2591             :     /*
    2592             :      * We DO NOT want to run proc_exit() callbacks -- we're here because
    2593             :      * shared memory may be corrupted, so we don't want to try to clean up our
    2594             :      * transaction.  Just nail the windows shut and get out of town.  Now that
    2595             :      * there's an atexit callback to prevent third-party code from breaking
    2596             :      * things by calling exit() directly, we have to reset the callbacks
    2597             :      * explicitly to make this work as intended.
    2598             :      */
    2599           0 :     on_exit_reset();
    2600             : 
    2601             :     /*
    2602             :      * Note we do exit(2) not exit(0).  This is to force the postmaster into a
    2603             :      * system reset cycle if some idiot DBA sends a manual SIGQUIT to a random
    2604             :      * backend.  This is necessary precisely because we don't clean up our
    2605             :      * shared memory state.  (The "dead man switch" mechanism in pmsignal.c
    2606             :      * should ensure the postmaster sees this as a crash, too, but no harm in
    2607             :      * being doubly sure.)
    2608             :      */
    2609           0 :     exit(2);
    2610             : }
    2611             : 
    2612             : /*
    2613             :  * Shutdown signal from postmaster: abort transaction and exit
    2614             :  * at soonest convenient time
    2615             :  */
    2616             : void
    2617           3 : die(SIGNAL_ARGS)
    2618             : {
    2619           3 :     int         save_errno = errno;
    2620             : 
    2621             :     /* Don't joggle the elbow of proc_exit */
    2622           3 :     if (!proc_exit_inprogress)
    2623             :     {
    2624           2 :         InterruptPending = true;
    2625           2 :         ProcDiePending = true;
    2626             :     }
    2627             : 
    2628             :     /* If we're still here, waken anything waiting on the process latch */
    2629           3 :     SetLatch(MyLatch);
    2630             : 
    2631             :     /*
    2632             :      * If we're in single user mode, we want to quit immediately - we can't
    2633             :      * rely on latches as they wouldn't work when stdin/stdout is a file.
    2634             :      * Rather ugly, but it's unlikely to be worthwhile to invest much more
    2635             :      * effort just for the benefit of single user mode.
    2636             :      */
    2637           3 :     if (DoingCommandRead && whereToSendOutput != DestRemote)
    2638           0 :         ProcessInterrupts();
    2639             : 
    2640           3 :     errno = save_errno;
    2641           3 : }
    2642             : 
    2643             : /*
    2644             :  * Query-cancel signal from postmaster: abort current transaction
    2645             :  * at soonest convenient time
    2646             :  */
    2647             : void
    2648           2 : StatementCancelHandler(SIGNAL_ARGS)
    2649             : {
    2650           2 :     int         save_errno = errno;
    2651             : 
    2652             :     /*
    2653             :      * Don't joggle the elbow of proc_exit
    2654             :      */
    2655           2 :     if (!proc_exit_inprogress)
    2656             :     {
    2657           2 :         InterruptPending = true;
    2658           2 :         QueryCancelPending = true;
    2659             :     }
    2660             : 
    2661             :     /* If we're still here, waken anything waiting on the process latch */
    2662           2 :     SetLatch(MyLatch);
    2663             : 
    2664           2 :     errno = save_errno;
    2665           2 : }
    2666             : 
    2667             : /* signal handler for floating point exception */
    2668             : void
    2669           0 : FloatExceptionHandler(SIGNAL_ARGS)
    2670             : {
    2671             :     /* We're not returning, so no need to save errno */
    2672           0 :     ereport(ERROR,
    2673             :             (errcode(ERRCODE_FLOATING_POINT_EXCEPTION),
    2674             :              errmsg("floating-point exception"),
    2675             :              errdetail("An invalid floating-point operation was signaled. "
    2676             :                        "This probably means an out-of-range result or an "
    2677             :                        "invalid operation, such as division by zero.")));
    2678             : }
    2679             : 
    2680             : /*
    2681             :  * SIGHUP: set flag to re-read config file at next convenient time.
    2682             :  *
    2683             :  * Sets the ConfigReloadPending flag, which should be checked at convenient
    2684             :  * places inside main loops. (Better than doing the reading in the signal
    2685             :  * handler, ey?)
    2686             :  */
    2687             : void
    2688           0 : PostgresSigHupHandler(SIGNAL_ARGS)
    2689             : {
    2690           0 :     int         save_errno = errno;
    2691             : 
    2692           0 :     ConfigReloadPending = true;
    2693           0 :     SetLatch(MyLatch);
    2694             : 
    2695           0 :     errno = save_errno;
    2696           0 : }
    2697             : 
    2698             : /*
    2699             :  * RecoveryConflictInterrupt: out-of-line portion of recovery conflict
    2700             :  * handling following receipt of SIGUSR1. Designed to be similar to die()
    2701             :  * and StatementCancelHandler(). Called only by a normal user backend
    2702             :  * that begins a transaction during recovery.
    2703             :  */
    2704             : void
    2705           0 : RecoveryConflictInterrupt(ProcSignalReason reason)
    2706             : {
    2707           0 :     int         save_errno = errno;
    2708             : 
    2709             :     /*
    2710             :      * Don't joggle the elbow of proc_exit
    2711             :      */
    2712           0 :     if (!proc_exit_inprogress)
    2713             :     {
    2714           0 :         RecoveryConflictReason = reason;
    2715           0 :         switch (reason)
    2716             :         {
    2717             :             case PROCSIG_RECOVERY_CONFLICT_STARTUP_DEADLOCK:
    2718             : 
    2719             :                 /*
    2720             :                  * If we aren't waiting for a lock we can never deadlock.
    2721             :                  */
    2722           0 :                 if (!IsWaitingForLock())
    2723           0 :                     return;
    2724             : 
    2725             :                 /* Intentional drop through to check wait for pin */
    2726             : 
    2727             :             case PROCSIG_RECOVERY_CONFLICT_BUFFERPIN:
    2728             : 
    2729             :                 /*
    2730             :                  * If we aren't blocking the Startup process there is nothing
    2731             :                  * more to do.
    2732             :                  */
    2733           0 :                 if (!HoldingBufferPinThatDelaysRecovery())
    2734           0 :                     return;
    2735             : 
    2736           0 :                 MyProc->recoveryConflictPending = true;
    2737             : 
    2738             :                 /* Intentional drop through to error handling */
    2739             : 
    2740             :             case PROCSIG_RECOVERY_CONFLICT_LOCK:
    2741             :             case PROCSIG_RECOVERY_CONFLICT_TABLESPACE:
    2742             :             case PROCSIG_RECOVERY_CONFLICT_SNAPSHOT:
    2743             : 
    2744             :                 /*
    2745             :                  * If we aren't in a transaction any longer then ignore.
    2746             :                  */
    2747           0 :                 if (!IsTransactionOrTransactionBlock())
    2748           0 :                     return;
    2749             : 
    2750             :                 /*
    2751             :                  * If we can abort just the current subtransaction then we are
    2752             :                  * OK to throw an ERROR to resolve the conflict. Otherwise
    2753             :                  * drop through to the FATAL case.
    2754             :                  *
    2755             :                  * XXX other times that we can throw just an ERROR *may* be
    2756             :                  * PROCSIG_RECOVERY_CONFLICT_LOCK if no locks are held in
    2757             :                  * parent transactions
    2758             :                  *
    2759             :                  * PROCSIG_RECOVERY_CONFLICT_SNAPSHOT if no snapshots are held
    2760             :                  * by parent transactions and the transaction is not
    2761             :                  * transaction-snapshot mode
    2762             :                  *
    2763             :                  * PROCSIG_RECOVERY_CONFLICT_TABLESPACE if no temp files or
    2764             :                  * cursors open in parent transactions
    2765             :                  */
    2766           0 :                 if (!IsSubTransaction())
    2767             :                 {
    2768             :                     /*
    2769             :                      * If we already aborted then we no longer need to cancel.
    2770             :                      * We do this here since we do not wish to ignore aborted
    2771             :                      * subtransactions, which must cause FATAL, currently.
    2772             :                      */
    2773           0 :                     if (IsAbortedTransactionBlockState())
    2774           0 :                         return;
    2775             : 
    2776           0 :                     RecoveryConflictPending = true;
    2777           0 :                     QueryCancelPending = true;
    2778           0 :                     InterruptPending = true;
    2779           0 :                     break;
    2780             :                 }
    2781             : 
    2782             :                 /* Intentional drop through to session cancel */
    2783             : 
    2784             :             case PROCSIG_RECOVERY_CONFLICT_DATABASE:
    2785           0 :                 RecoveryConflictPending = true;
    2786           0 :                 ProcDiePending = true;
    2787           0 :                 InterruptPending = true;
    2788           0 :                 break;
    2789             : 
    2790             :             default:
    2791           0 :                 elog(FATAL, "unrecognized conflict mode: %d",
    2792             :                      (int) reason);
    2793             :         }
    2794             : 
    2795           0 :         Assert(RecoveryConflictPending && (QueryCancelPending || ProcDiePending));
    2796             : 
    2797             :         /*
    2798             :          * All conflicts apart from database cause dynamic errors where the
    2799             :          * command or transaction can be retried at a later point with some
    2800             :          * potential for success. No need to reset this, since non-retryable
    2801             :          * conflict errors are currently FATAL.
    2802             :          */
    2803           0 :         if (reason == PROCSIG_RECOVERY_CONFLICT_DATABASE)
    2804           0 :             RecoveryConflictRetryable = false;
    2805             :     }
    2806             : 
    2807             :     /*
    2808             :      * Set the process latch. This function essentially emulates signal
    2809             :      * handlers like die() and StatementCancelHandler() and it seems prudent
    2810             :      * to behave similarly as they do.
    2811             :      */
    2812           0 :     SetLatch(MyLatch);
    2813             : 
    2814           0 :     errno = save_errno;
    2815             : }
    2816             : 
    2817             : /*
    2818             :  * ProcessInterrupts: out-of-line portion of CHECK_FOR_INTERRUPTS() macro
    2819             :  *
    2820             :  * If an interrupt condition is pending, and it's safe to service it,
    2821             :  * then clear the flag and accept the interrupt.  Called only when
    2822             :  * InterruptPending is true.
    2823             :  */
    2824             : void
    2825         233 : ProcessInterrupts(void)
    2826             : {
    2827             :     /* OK to accept any interrupts now? */
    2828         233 :     if (InterruptHoldoffCount != 0 || CritSectionCount != 0)
    2829           0 :         return;
    2830         233 :     InterruptPending = false;
    2831             : 
    2832         233 :     if (ProcDiePending)
    2833             :     {
    2834           2 :         ProcDiePending = false;
    2835           2 :         QueryCancelPending = false; /* ProcDie trumps QueryCancel */
    2836           2 :         LockErrorCleanup();
    2837             :         /* As in quickdie, don't risk sending to client during auth */
    2838           2 :         if (ClientAuthInProgress && whereToSendOutput == DestRemote)
    2839           0 :             whereToSendOutput = DestNone;
    2840           2 :         if (ClientAuthInProgress)
    2841           0 :             ereport(FATAL,
    2842             :                     (errcode(ERRCODE_QUERY_CANCELED),
    2843             :                      errmsg("canceling authentication due to timeout")));
    2844           2 :         else if (IsAutoVacuumWorkerProcess())
    2845           1 :             ereport(FATAL,
    2846             :                     (errcode(ERRCODE_ADMIN_SHUTDOWN),
    2847             :                      errmsg("terminating autovacuum process due to administrator command")));
    2848           1 :         else if (IsLogicalWorker())
    2849           0 :             ereport(FATAL,
    2850             :                     (errcode(ERRCODE_ADMIN_SHUTDOWN),
    2851             :                      errmsg("terminating logical replication worker due to administrator command")));
    2852           1 :         else if (IsLogicalLauncher())
    2853             :         {
    2854           1 :             ereport(DEBUG1,
    2855             :                     (errmsg("logical replication launcher shutting down")));
    2856             : 
    2857             :             /*
    2858             :              * The logical replication launcher can be stopped at any time.
    2859             :              * Use exit status 1 so the background worker is restarted.
    2860             :              */
    2861           1 :             proc_exit(1);
    2862             :         }
    2863           0 :         else if (RecoveryConflictPending && RecoveryConflictRetryable)
    2864             :         {
    2865           0 :             pgstat_report_recovery_conflict(RecoveryConflictReason);
    2866           0 :             ereport(FATAL,
    2867             :                     (errcode(ERRCODE_T_R_SERIALIZATION_FAILURE),
    2868             :                      errmsg("terminating connection due to conflict with recovery"),
    2869             :                      errdetail_recovery_conflict()));
    2870             :         }
    2871           0 :         else if (RecoveryConflictPending)
    2872             :         {
    2873             :             /* Currently there is only one non-retryable recovery conflict */
    2874           0 :             Assert(RecoveryConflictReason == PROCSIG_RECOVERY_CONFLICT_DATABASE);
    2875           0 :             pgstat_report_recovery_conflict(RecoveryConflictReason);
    2876           0 :             ereport(FATAL,
    2877             :                     (errcode(ERRCODE_DATABASE_DROPPED),
    2878             :                      errmsg("terminating connection due to conflict with recovery"),
    2879             :                      errdetail_recovery_conflict()));
    2880             :         }
    2881             :         else
    2882           0 :             ereport(FATAL,
    2883             :                     (errcode(ERRCODE_ADMIN_SHUTDOWN),
    2884             :                      errmsg("terminating connection due to administrator command")));
    2885             :     }
    2886         231 :     if (ClientConnectionLost)
    2887             :     {
    2888           0 :         QueryCancelPending = false; /* lost connection trumps QueryCancel */
    2889           0 :         LockErrorCleanup();
    2890             :         /* don't send to client, we already know the connection to be dead. */
    2891           0 :         whereToSendOutput = DestNone;
    2892           0 :         ereport(FATAL,
    2893             :                 (errcode(ERRCODE_CONNECTION_FAILURE),
    2894             :                  errmsg("connection to client lost")));
    2895             :     }
    2896             : 
    2897             :     /*
    2898             :      * If a recovery conflict happens while we are waiting for input from the
    2899             :      * client, the client is presumably just sitting idle in a transaction,
    2900             :      * preventing recovery from making progress.  Terminate the connection to
    2901             :      * dislodge it.
    2902             :      */
    2903         231 :     if (RecoveryConflictPending && DoingCommandRead)
    2904             :     {
    2905           0 :         QueryCancelPending = false; /* this trumps QueryCancel */
    2906           0 :         RecoveryConflictPending = false;
    2907           0 :         LockErrorCleanup();
    2908           0 :         pgstat_report_recovery_conflict(RecoveryConflictReason);
    2909           0 :         ereport(FATAL,
    2910             :                 (errcode(ERRCODE_T_R_SERIALIZATION_FAILURE),
    2911             :                  errmsg("terminating connection due to conflict with recovery"),
    2912             :                  errdetail_recovery_conflict(),
    2913             :                  errhint("In a moment you should be able to reconnect to the"
    2914             :                          " database and repeat your command.")));
    2915             :     }
    2916             : 
    2917         231 :     if (QueryCancelPending)
    2918             :     {
    2919             :         bool        lock_timeout_occurred;
    2920             :         bool        stmt_timeout_occurred;
    2921             : 
    2922             :         /*
    2923             :          * Don't allow query cancel interrupts while reading input from the
    2924             :          * client, because we might lose sync in the FE/BE protocol.  (Die
    2925             :          * interrupts are OK, because we won't read any further messages from
    2926             :          * the client in that case.)
    2927             :          */
    2928           1 :         if (QueryCancelHoldoffCount != 0)
    2929             :         {
    2930             :             /*
    2931             :              * Re-arm InterruptPending so that we process the cancel request
    2932             :              * as soon as we're done reading the message.
    2933             :              */
    2934           0 :             InterruptPending = true;
    2935           0 :             return;
    2936             :         }
    2937             : 
    2938           1 :         QueryCancelPending = false;
    2939             : 
    2940             :         /*
    2941             :          * If LOCK_TIMEOUT and STATEMENT_TIMEOUT indicators are both set, we
    2942             :          * need to clear both, so always fetch both.
    2943             :          */
    2944           1 :         lock_timeout_occurred = get_timeout_indicator(LOCK_TIMEOUT, true);
    2945           1 :         stmt_timeout_occurred = get_timeout_indicator(STATEMENT_TIMEOUT, true);
    2946             : 
    2947             :         /*
    2948             :          * If both were set, we want to report whichever timeout completed
    2949             :          * earlier; this ensures consistent behavior if the machine is slow
    2950             :          * enough that the second timeout triggers before we get here.  A tie
    2951             :          * is arbitrarily broken in favor of reporting a lock timeout.
    2952             :          */
    2953           1 :         if (lock_timeout_occurred && stmt_timeout_occurred &&
    2954           0 :             get_timeout_finish_time(STATEMENT_TIMEOUT) < get_timeout_finish_time(LOCK_TIMEOUT))
    2955           0 :             lock_timeout_occurred = false;  /* report stmt timeout */
    2956             : 
    2957           1 :         if (lock_timeout_occurred)
    2958             :         {
    2959           0 :             LockErrorCleanup();
    2960           0 :             ereport(ERROR,
    2961             :                     (errcode(ERRCODE_LOCK_NOT_AVAILABLE),
    2962             :                      errmsg("canceling statement due to lock timeout")));
    2963             :         }
    2964           1 :         if (stmt_timeout_occurred)
    2965             :         {
    2966           1 :             LockErrorCleanup();
    2967           1 :             ereport(ERROR,
    2968             :                     (errcode(ERRCODE_QUERY_CANCELED),
    2969             :                      errmsg("canceling statement due to statement timeout")));
    2970             :         }
    2971           0 :         if (IsAutoVacuumWorkerProcess())
    2972             :         {
    2973           0 :             LockErrorCleanup();
    2974           0 :             ereport(ERROR,
    2975             :                     (errcode(ERRCODE_QUERY_CANCELED),
    2976             :                      errmsg("canceling autovacuum task")));
    2977             :         }
    2978           0 :         if (RecoveryConflictPending)
    2979             :         {
    2980           0 :             RecoveryConflictPending = false;
    2981           0 :             LockErrorCleanup();
    2982           0 :             pgstat_report_recovery_conflict(RecoveryConflictReason);
    2983           0 :             ereport(ERROR,
    2984             :                     (errcode(ERRCODE_T_R_SERIALIZATION_FAILURE),
    2985             :                      errmsg("canceling statement due to conflict with recovery"),
    2986             :                      errdetail_recovery_conflict()));
    2987             :         }
    2988             : 
    2989             :         /*
    2990             :          * If we are reading a command from the client, just ignore the cancel
    2991             :          * request --- sending an extra error message won't accomplish
    2992             :          * anything.  Otherwise, go ahead and throw the error.
    2993             :          */
    2994           0 :         if (!DoingCommandRead)
    2995             :         {
    2996           0 :             LockErrorCleanup();
    2997           0 :             ereport(ERROR,
    2998             :                     (errcode(ERRCODE_QUERY_CANCELED),
    2999             :                      errmsg("canceling statement due to user request")));
    3000             :         }
    3001             :     }
    3002             : 
    3003         230 :     if (IdleInTransactionSessionTimeoutPending)
    3004             :     {
    3005             :         /* Has the timeout setting changed since last we looked? */
    3006           0 :         if (IdleInTransactionSessionTimeout > 0)
    3007           0 :             ereport(FATAL,
    3008             :                     (errcode(ERRCODE_IDLE_IN_TRANSACTION_SESSION_TIMEOUT),
    3009             :                      errmsg("terminating connection due to idle-in-transaction timeout")));
    3010             :         else
    3011           0 :             IdleInTransactionSessionTimeoutPending = false;
    3012             : 
    3013             :     }
    3014             : 
    3015         230 :     if (ParallelMessagePending)
    3016         230 :         HandleParallelMessages();
    3017             : }
    3018             : 
    3019             : 
    3020             : /*
    3021             :  * IA64-specific code to fetch the AR.BSP register for stack depth checks.
    3022             :  *
    3023             :  * We currently support gcc, icc, and HP-UX's native compiler here.
    3024             :  *
    3025             :  * Note: while icc accepts gcc asm blocks on x86[_64], this is not true on
    3026             :  * ia64 (at least not in icc versions before 12.x).  So we have to carry a
    3027             :  * separate implementation for it.
    3028             :  */
    3029             : #if defined(__ia64__) || defined(__ia64)
    3030             : 
    3031             : #if defined(__hpux) && !defined(__GNUC__) && !defined(__INTEL_COMPILER)
    3032             : /* Assume it's HP-UX native compiler */
    3033             : #include <ia64/sys/inline.h>
    3034             : #define ia64_get_bsp() ((char *) (_Asm_mov_from_ar(_AREG_BSP, _NO_FENCE)))
    3035             : #elif defined(__INTEL_COMPILER)
    3036             : /* icc */
    3037             : #include <asm/ia64regs.h>
    3038             : #define ia64_get_bsp() ((char *) __getReg(_IA64_REG_AR_BSP))
    3039             : #else
    3040             : /* gcc */
    3041             : static __inline__ char *
    3042             : ia64_get_bsp(void)
    3043             : {
    3044             :     char       *ret;
    3045             : 
    3046             :     /* the ;; is a "stop", seems to be required before fetching BSP */
    3047             :     __asm__ __volatile__(
    3048             :                          ";;\n"
    3049             :                          " mov %0=ar.bsp   \n"
    3050             : :                        "=r"(ret));
    3051             : 
    3052             :     return ret;
    3053             : }
    3054             : #endif
    3055             : #endif                          /* IA64 */
    3056             : 
    3057             : 
    3058             : /*
    3059             :  * set_stack_base: set up reference point for stack depth checking
    3060             :  *
    3061             :  * Returns the old reference point, if any.
    3062             :  */
    3063             : pg_stack_base_t
    3064           1 : set_stack_base(void)
    3065             : {
    3066             :     char        stack_base;
    3067             :     pg_stack_base_t old;
    3068             : 
    3069             : #if defined(__ia64__) || defined(__ia64)
    3070             :     old.stack_base_ptr = stack_base_ptr;
    3071             :     old.register_stack_base_ptr = register_stack_base_ptr;
    3072             : #else
    3073           1 :     old = stack_base_ptr;
    3074             : #endif
    3075             : 
    3076             :     /* Set up reference point for stack depth checking */
    3077           1 :     stack_base_ptr = &stack_base;
    3078             : #if defined(__ia64__) || defined(__ia64)
    3079             :     register_stack_base_ptr = ia64_get_bsp();
    3080             : #endif
    3081             : 
    3082           1 :     return old;
    3083             : }
    3084             : 
    3085             : /*
    3086             :  * restore_stack_base: restore reference point for stack depth checking
    3087             :  *
    3088             :  * This can be used after set_stack_base() to restore the old value. This
    3089             :  * is currently only used in PL/Java. When PL/Java calls a backend function
    3090             :  * from different thread, the thread's stack is at a different location than
    3091             :  * the main thread's stack, so it sets the base pointer before the call, and
    3092             :  * restores it afterwards.
    3093             :  */
    3094             : void
    3095           0 : restore_stack_base(pg_stack_base_t base)
    3096             : {
    3097             : #if defined(__ia64__) || defined(__ia64)
    3098             :     stack_base_ptr = base.stack_base_ptr;
    3099             :     register_stack_base_ptr = base.register_stack_base_ptr;
    3100             : #else
    3101           0 :     stack_base_ptr = base;
    3102             : #endif
    3103           0 : }
    3104             : 
    3105             : /*
    3106             :  * check_stack_depth/stack_is_too_deep: check for excessively deep recursion
    3107             :  *
    3108             :  * This should be called someplace in any recursive routine that might possibly
    3109             :  * recurse deep enough to overflow the stack.  Most Unixen treat stack
    3110             :  * overflow as an unrecoverable SIGSEGV, so we want to error out ourselves
    3111             :  * before hitting the hardware limit.
    3112             :  *
    3113             :  * check_stack_depth() just throws an error summarily.  stack_is_too_deep()
    3114             :  * can be used by code that wants to handle the error condition itself.
    3115             :  */
    3116             : void
    3117     5785509 : check_stack_depth(void)
    3118             : {
    3119     5785509 :     if (stack_is_too_deep())
    3120             :     {
    3121           5 :         ereport(ERROR,
    3122             :                 (errcode(ERRCODE_STATEMENT_TOO_COMPLEX),
    3123             :                  errmsg("stack depth limit exceeded"),
    3124             :                  errhint("Increase the configuration parameter \"max_stack_depth\" (currently %dkB), "
    3125             :                          "after ensuring the platform's stack depth limit is adequate.",
    3126             :                          max_stack_depth)));
    3127             :     }
    3128     5785504 : }
    3129             : 
    3130             : bool
    3131     8447838 : stack_is_too_deep(void)
    3132             : {
    3133             :     char        stack_top_loc;
    3134             :     long        stack_depth;
    3135             : 
    3136             :     /*
    3137             :      * Compute distance from reference point to my local variables
    3138             :      */
    3139     8447838 :     stack_depth = (long) (stack_base_ptr - &stack_top_loc);
    3140             : 
    3141             :     /*
    3142             :      * Take abs value, since stacks grow up on some machines, down on others
    3143             :      */
    3144     8447838 :     if (stack_depth < 0)
    3145           0 :         stack_depth = -stack_depth;
    3146             : 
    3147             :     /*
    3148             :      * Trouble?
    3149             :      *
    3150             :      * The test on stack_base_ptr prevents us from erroring out if called
    3151             :      * during process setup or in a non-backend process.  Logically it should
    3152             :      * be done first, but putting it here avoids wasting cycles during normal
    3153             :      * cases.
    3154             :      */
    3155     8616167 :     if (stack_depth > max_stack_depth_bytes &&
    3156      168329 :         stack_base_ptr != NULL)
    3157           5 :         return true;
    3158             : 
    3159             :     /*
    3160             :      * On IA64 there is a separate "register" stack that requires its own
    3161             :      * independent check.  For this, we have to measure the change in the
    3162             :      * "BSP" pointer from PostgresMain to here.  Logic is just as above,
    3163             :      * except that we know IA64's register stack grows up.
    3164             :      *
    3165             :      * Note we assume that the same max_stack_depth applies to both stacks.
    3166             :      */
    3167             : #if defined(__ia64__) || defined(__ia64)
    3168             :     stack_depth = (long) (ia64_get_bsp() - register_stack_base_ptr);
    3169             : 
    3170             :     if (stack_depth > max_stack_depth_bytes &&
    3171             :         register_stack_base_ptr != NULL)
    3172             :         return true;
    3173             : #endif                          /* IA64 */
    3174             : 
    3175     8447833 :     return false;
    3176             : }
    3177             : 
    3178             : /* GUC check hook for max_stack_depth */
    3179             : bool
    3180         242 : check_max_stack_depth(int *newval, void **extra, GucSource source)
    3181             : {
    3182         242 :     long        newval_bytes = *newval * 1024L;
    3183         242 :     long        stack_rlimit = get_stack_depth_rlimit();
    3184             : 
    3185         242 :     if (stack_rlimit > 0 && newval_bytes > stack_rlimit - STACK_DEPTH_SLOP)
    3186             :     {
    3187           0 :         GUC_check_errdetail("\"max_stack_depth\" must not exceed %ldkB.",
    3188           0 :                             (stack_rlimit - STACK_DEPTH_SLOP) / 1024L);
    3189           0 :         GUC_check_errhint("Increase the platform's stack depth limit via \"ulimit -s\" or local equivalent.");
    3190           0 :         return false;
    3191             :     }
    3192         242 :     return true;
    3193             : }
    3194             : 
    3195             : /* GUC assign hook for max_stack_depth */
    3196             : void
    3197         244 : assign_max_stack_depth(int newval, void *extra)
    3198             : {
    3199         244 :     long        newval_bytes = newval * 1024L;
    3200             : 
    3201         244 :     max_stack_depth_bytes = newval_bytes;
    3202         244 : }
    3203             : 
    3204             : 
    3205             : /*
    3206             :  * set_debug_options --- apply "-d N" command line option
    3207             :  *
    3208             :  * -d is not quite the same as setting log_min_messages because it enables
    3209             :  * other output options.
    3210             :  */
    3211             : void
    3212           0 : set_debug_options(int debug_flag, GucContext context, GucSource source)
    3213             : {
    3214           0 :     if (debug_flag > 0)
    3215             :     {
    3216             :         char        debugstr[64];
    3217             : 
    3218           0 :         sprintf(debugstr, "debug%d", debug_flag);
    3219           0 :         SetConfigOption("log_min_messages", debugstr, context, source);
    3220             :     }
    3221             :     else
    3222           0 :         SetConfigOption("log_min_messages", "notice", context, source);
    3223             : 
    3224           0 :     if (debug_flag >= 1 && context == PGC_POSTMASTER)
    3225             :     {
    3226           0 :         SetConfigOption("log_connections", "true", context, source);
    3227           0 :         SetConfigOption("log_disconnections", "true", context, source);
    3228             :     }
    3229           0 :     if (debug_flag >= 2)
    3230           0 :         SetConfigOption("log_statement", "all", context, source);
    3231           0 :     if (debug_flag >= 3)
    3232           0 :         SetConfigOption("debug_print_parse", "true", context, source);
    3233           0 :     if (debug_flag >= 4)
    3234           0 :         SetConfigOption("debug_print_plan", "true", context, source);
    3235           0 :     if (debug_flag >= 5)
    3236           0 :         SetConfigOption("debug_print_rewritten", "true", context, source);
    3237           0 : }
    3238             : 
    3239             : 
    3240             : bool
    3241           0 : set_plan_disabling_options(const char *arg, GucContext context, GucSource source)
    3242             : {
    3243           0 :     const char *tmp = NULL;
    3244             : 
    3245           0 :     switch (arg[0])
    3246             :     {
    3247             :         case 's':               /* seqscan */
    3248           0 :             tmp = "enable_seqscan";
    3249           0 :             break;
    3250             :         case 'i':               /* indexscan */
    3251           0 :             tmp = "enable_indexscan";
    3252           0 :             break;
    3253             :         case 'o':               /* indexonlyscan */
    3254           0 :             tmp = "enable_indexonlyscan";
    3255           0 :             break;
    3256             :         case 'b':               /* bitmapscan */
    3257           0 :             tmp = "enable_bitmapscan";
    3258           0 :             break;
    3259             :         case 't':               /* tidscan */
    3260           0 :             tmp = "enable_tidscan";
    3261           0 :             break;
    3262             :         case 'n':               /* nestloop */
    3263           0 :             tmp = "enable_nestloop";
    3264           0 :             break;
    3265             :         case 'm':               /* mergejoin */
    3266           0 :             tmp = "enable_mergejoin";
    3267           0 :             break;
    3268             :         case 'h':               /* hashjoin */
    3269           0 :             tmp = "enable_hashjoin";
    3270           0 :             break;
    3271             :     }
    3272           0 :     if (tmp)
    3273             :     {
    3274           0 :         SetConfigOption(tmp, "false", context, source);
    3275           0 :         return true;
    3276             :     }
    3277             :     else
    3278           0 :         return false;
    3279             : }
    3280             : 
    3281             : 
    3282             : const char *
    3283           0 : get_stats_option_name(const char *arg)
    3284             : {
    3285           0 :     switch (arg[0])
    3286             :     {
    3287             :         case 'p':
    3288           0 :             if (optarg[1] == 'a')   /* "parser" */
    3289           0 :                 return "log_parser_stats";
    3290           0 :             else if (optarg[1] == 'l')  /* "planner" */
    3291           0 :                 return "log_planner_stats";
    3292           0 :             break;
    3293             : 
    3294             :         case 'e':               /* "executor" */
    3295           0 :             return "log_executor_stats";
    3296             :             break;
    3297             :     }
    3298             : 
    3299           0 :     return NULL;
    3300             : }
    3301             : 
    3302             : 
    3303             : /* ----------------------------------------------------------------
    3304             :  * process_postgres_switches
    3305             :  *     Parse command line arguments for PostgresMain
    3306             :  *
    3307             :  * This is called twice, once for the "secure" options coming from the
    3308             :  * postmaster or command line, and once for the "insecure" options coming
    3309             :  * from the client's startup packet.  The latter have the same syntax but
    3310             :  * may be restricted in what they can do.
    3311             :  *
    3312             :  * argv[0] is ignored in either case (it's assumed to be the program name).
    3313             :  *
    3314             :  * ctx is PGC_POSTMASTER for secure options, PGC_BACKEND for insecure options
    3315             :  * coming from the client, or PGC_SU_BACKEND for insecure options coming from
    3316             :  * a superuser client.
    3317             :  *
    3318             :  * If a database name is present in the command line arguments, it's
    3319             :  * returned into *dbname (this is allowed only if *dbname is initially NULL).
    3320             :  * ----------------------------------------------------------------
    3321             :  */
    3322             : void
    3323         431 : process_postgres_switches(int argc, char *argv[], GucContext ctx,
    3324             :                           const char **dbname)
    3325             : {
    3326         431 :     bool        secure = (ctx == PGC_POSTMASTER);
    3327         431 :     int         errs = 0;
    3328             :     GucSource   gucsource;
    3329             :     int         flag;
    3330             : 
    3331         431 :     if (secure)
    3332             :     {
    3333         216 :         gucsource = PGC_S_ARGV; /* switches came from command line */
    3334             : 
    3335             :         /* Ignore the initial --single argument, if present */
    3336         216 :         if (argc > 1 && strcmp(argv[1], "--single") == 0)
    3337             :         {
    3338           1 :             argv++;
    3339           1 :             argc--;
    3340             :         }
    3341             :     }
    3342             :     else
    3343             :     {
    3344         215 :         gucsource = PGC_S_CLIENT;   /* switches came from client */
    3345             :     }
    3346             : 
    3347             : #ifdef HAVE_INT_OPTERR
    3348             : 
    3349             :     /*
    3350             :      * Turn this off because it's either printed to stderr and not the log
    3351             :      * where we'd want it, or argv[0] is now "--single", which would make for
    3352             :      * a weird error message.  We print our own error message below.
    3353             :      */
    3354         431 :     opterr = 0;
    3355             : #endif
    3356             : 
    3357             :     /*
    3358             :      * Parse command-line options.  CAUTION: keep this in sync with
    3359             :      * postmaster/postmaster.c (the option sets should not conflict) and with
    3360             :      * the common help() function in main/main.c.
    3361             :      */
    3362        1082 :     while ((flag = getopt(argc, argv, "B:bc:C:D:d:EeFf:h:ijk:lN:nOo:Pp:r:S:sTt:v:W:-:")) != -1)
    3363             :     {
    3364         220 :         switch (flag)
    3365             :         {
    3366             :             case 'B':
    3367           0 :                 SetConfigOption("shared_buffers", optarg, ctx, gucsource);
    3368           0 :                 break;
    3369             : 
    3370             :             case 'b':
    3371             :                 /* Undocumented flag used for binary upgrades */
    3372           0 :                 if (secure)
    3373           0 :                     IsBinaryUpgrade = true;
    3374           0 :                 break;
    3375             : 
    3376             :             case 'C':
    3377             :                 /* ignored for consistency with the postmaster */
    3378           0 :                 break;
    3379             : 
    3380             :             case 'D':
    3381           0 :                 if (secure)
    3382           0 :                     userDoption = strdup(optarg);
    3383           0 :                 break;
    3384             : 
    3385             :             case 'd':
    3386           0 :                 set_debug_options(atoi(optarg), ctx, gucsource);
    3387           0 :                 break;
    3388             : 
    3389             :             case 'E':
    3390           0 :                 if (secure)
    3391           0 :                     EchoQuery = true;
    3392           0 :                 break;
    3393             : 
    3394             :             case 'e':
    3395           0 :                 SetConfigOption("datestyle", "euro", ctx, gucsource);
    3396           0 :                 break;
    3397             : 
    3398             :             case 'F':
    3399           1 :                 SetConfigOption("fsync", "false", ctx, gucsource);
    3400           1 :                 break;
    3401             : 
    3402             :             case 'f':
    3403           0 :                 if (!set_plan_disabling_options(optarg, ctx, gucsource))
    3404           0 :                     errs++;
    3405           0 :                 break;
    3406             : 
    3407             :             case 'h':
    3408           0 :                 SetConfigOption("listen_addresses", optarg, ctx, gucsource);
    3409           0 :                 break;
    3410             : 
    3411             :             case 'i':
    3412           0 :                 SetConfigOption("listen_addresses", "*", ctx, gucsource);
    3413           0 :                 break;
    3414             : 
    3415             :             case 'j':
    3416           1 :                 if (secure)
    3417           1 :                     UseSemiNewlineNewline = true;
    3418           1 :                 break;
    3419             : 
    3420             :             case 'k':
    3421           0 :                 SetConfigOption("unix_socket_directories", optarg, ctx, gucsource);
    3422           0 :                 break;
    3423             : 
    3424             :             case 'l':
    3425           0 :                 SetConfigOption("ssl", "true", ctx, gucsource);
    3426           0 :                 break;
    3427             : 
    3428             :             case 'N':
    3429           0 :                 SetConfigOption("max_connections", optarg, ctx, gucsource);
    3430           0 :                 break;
    3431             : 
    3432             :             case 'n':
    3433             :                 /* ignored for consistency with postmaster */
    3434           0 :                 break;
    3435             : 
    3436             :             case 'O':
    3437           1 :                 SetConfigOption("allow_system_table_mods", "true", ctx, gucsource);
    3438           1 :                 break;
    3439             : 
    3440             :             case 'o':
    3441           0 :                 errs++;
    3442           0 :                 break;
    3443             : 
    3444             :             case 'P':
    3445           0 :                 SetConfigOption("ignore_system_indexes", "true", ctx, gucsource);
    3446           0 :                 break;
    3447             : 
    3448             :             case 'p':
    3449           0 :                 SetConfigOption("port", optarg, ctx, gucsource);
    3450           0 :                 break;
    3451             : 
    3452             :             case 'r':
    3453             :                 /* send output (stdout and stderr) to the given file */
    3454           0 :                 if (secure)
    3455           0 :                     strlcpy(OutputFileName, optarg, MAXPGPATH);
    3456           0 :                 break;
    3457             : 
    3458             :             case 'S':
    3459           0 :                 SetConfigOption("work_mem", optarg, ctx, gucsource);
    3460           0 :                 break;
    3461             : 
    3462             :             case 's':
    3463           0 :                 SetConfigOption("log_statement_stats", "true", ctx, gucsource);
    3464           0 :                 break;
    3465             : 
    3466             :             case 'T':
    3467             :                 /* ignored for consistency with the postmaster */
    3468           0 :                 break;
    3469             : 
    3470             :             case 't':
    3471             :                 {
    3472           0 :                     const char *tmp = get_stats_option_name(optarg);
    3473             : 
    3474           0 :                     if (tmp)
    3475           0 :                         SetConfigOption(tmp, "true", ctx, gucsource);
    3476             :                     else
    3477           0 :                         errs++;
    3478           0 :                     break;
    3479             :                 }
    3480             : 
    3481             :             case 'v':
    3482             : 
    3483             :                 /*
    3484             :                  * -v is no longer used in normal operation, since
    3485             :                  * FrontendProtocol is already set before we get here. We keep
    3486             :                  * the switch only for possible use in standalone operation,
    3487             :                  * in case we ever support using normal FE/BE protocol with a
    3488             :                  * standalone backend.
    3489             :                  */
    3490           0 :                 if (secure)
    3491           0 :                     FrontendProtocol = (ProtocolVersion) atoi(optarg);
    3492           0 :                 break;
    3493             : 
    3494             :             case 'W':
    3495           0 :                 SetConfigOption("post_auth_delay", optarg, ctx, gucsource);
    3496           0 :                 break;
    3497             : 
    3498             :             case 'c':
    3499             :             case '-':
    3500             :                 {
    3501             :                     char       *name,
    3502             :                                *value;
    3503             : 
    3504         217 :                     ParseLongOption(optarg, &name, &value);
    3505         217 :                     if (!value)
    3506             :                     {
    3507           0 :                         if (flag == '-')
    3508           0 :                             ereport(ERROR,
    3509             :                                     (errcode(ERRCODE_SYNTAX_ERROR),
    3510             :                                      errmsg("--%s requires a value",
    3511             :                                             optarg)));
    3512             :                         else
    3513           0 :                             ereport(ERROR,
    3514             :                                     (errcode(ERRCODE_SYNTAX_ERROR),
    3515             :                                      errmsg("-c %s requires a value",
    3516             :                                             optarg)));
    3517             :                     }
    3518         217 :                     SetConfigOption(name, value, ctx, gucsource);
    3519         217 :                     free(name);
    3520         217 :                     if (value)
    3521         217 :                         free(value);
    3522         217 :                     break;
    3523             :                 }
    3524             : 
    3525             :             default:
    3526           0 :                 errs++;
    3527           0 :                 break;
    3528             :         }
    3529             : 
    3530         220 :         if (errs)
    3531           0 :             break;
    3532             :     }
    3533             : 
    3534             :     /*
    3535             :      * Optional database name should be there only if *dbname is NULL.
    3536             :      */
    3537         431 :     if (!errs && dbname && *dbname == NULL && argc - optind >= 1)
    3538           1 :         *dbname = strdup(argv[optind++]);
    3539             : 
    3540         431 :     if (errs || argc != optind)
    3541             :     {
    3542           0 :         if (errs)
    3543           0 :             optind--;           /* complain about the previous argument */
    3544             : 
    3545             :         /* spell the error message a bit differently depending on context */
    3546           0 :         if (IsUnderPostmaster)
    3547           0 :             ereport(FATAL,
    3548             :                     (errcode(ERRCODE_SYNTAX_ERROR),
    3549             :                      errmsg("invalid command-line argument for server process: %s", argv[optind]),
    3550             :                      errhint("Try \"%s --help\" for more information.", progname)));
    3551             :         else
    3552           0 :             ereport(FATAL,
    3553             :                     (errcode(ERRCODE_SYNTAX_ERROR),
    3554             :                      errmsg("%s: invalid command-line argument: %s",
    3555             :                             progname, argv[optind]),
    3556             :                      errhint("Try \"%s --help\" for more information.", progname)));
    3557             :     }
    3558             : 
    3559             :     /*
    3560             :      * Reset getopt(3) library so that it will work correctly in subprocesses
    3561             :      * or when this function is called a second time with another array.
    3562             :      */
    3563         431 :     optind = 1;
    3564             : #ifdef HAVE_INT_OPTRESET
    3565             :     optreset = 1;               /* some systems need this too */
    3566             : #endif
    3567         431 : }
    3568             : 
    3569             : 
    3570             : /* ----------------------------------------------------------------
    3571             :  * PostgresMain
    3572             :  *     postgres main loop -- all backends, interactive or otherwise start here
    3573             :  *
    3574             :  * argc/argv are the command line arguments to be used.  (When being forked
    3575             :  * by the postmaster, these are not the original argv array of the process.)
    3576             :  * dbname is the name of the database to connect to, or NULL if the database
    3577             :  * name should be extracted from the command line arguments or defaulted.
    3578             :  * username is the PostgreSQL user name to be used for the session.
    3579             :  * ----------------------------------------------------------------
    3580             :  */
    3581             : void
    3582         216 : PostgresMain(int argc, char *argv[],
    3583             :              const char *dbname,
    3584             :              const char *username)
    3585             : {
    3586             :     int         firstchar;
    3587             :     StringInfoData input_message;
    3588             :     sigjmp_buf  local_sigjmp_buf;
    3589         216 :     volatile bool send_ready_for_query = true;
    3590         216 :     bool        disable_idle_in_transaction_timeout = false;
    3591             : 
    3592             :     /* Initialize startup process environment if necessary. */
    3593         216 :     if (!IsUnderPostmaster)
    3594           1 :         InitStandaloneProcess(argv[0]);
    3595             : 
    3596         216 :     SetProcessingMode(InitProcessing);
    3597             : 
    3598             :     /*
    3599             :      * Set default values for command-line options.
    3600             :      */
    3601         216 :     if (!IsUnderPostmaster)
    3602           1 :         InitializeGUCOptions();
    3603             : 
    3604             :     /*
    3605             :      * Parse command-line options.
    3606             :      */
    3607         216 :     process_postgres_switches(argc, argv, PGC_POSTMASTER, &dbname);
    3608             : 
    3609             :     /* Must have gotten a database name, or have a default (the username) */
    3610         216 :     if (dbname == NULL)
    3611             :     {
    3612           0 :         dbname = username;
    3613           0 :         if (dbname == NULL)
    3614           0 :             ereport(FATAL,
    3615             :                     (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
    3616             :                      errmsg("%s: no database nor user name specified",
    3617             :                             progname)));
    3618             :     }
    3619             : 
    3620             :     /* Acquire configuration parameters, unless inherited from postmaster */
    3621         216 :     if (!IsUnderPostmaster)
    3622             :     {
    3623           1 :         if (!SelectConfigFiles(userDoption, progname))
    3624           0 :             proc_exit(1);
    3625             :     }
    3626             : 
    3627             :     /*
    3628             :      * Set up signal handlers and masks.
    3629             :      *
    3630             :      * Note that postmaster blocked all signals before forking child process,
    3631             :      * so there is no race condition whereby we might receive a signal before
    3632             :      * we have set up the handler.
    3633             :      *
    3634             :      * Also note: it's best not to use any signals that are SIG_IGNored in the
    3635             :      * postmaster.  If such a signal arrives before we are able to change the
    3636             :      * handler to non-SIG_IGN, it'll get dropped.  Instead, make a dummy
    3637             :      * handler in the postmaster to reserve the signal. (Of course, this isn't
    3638             :      * an issue for signals that are locally generated, such as SIGALRM and
    3639             :      * SIGPIPE.)
    3640             :      */
    3641         216 :     if (am_walsender)
    3642           0 :         WalSndSignals();
    3643             :     else
    3644             :     {
    3645         216 :         pqsignal(SIGHUP, PostgresSigHupHandler);    /* set flag to read config
    3646             :                                                      * file */
    3647         216 :         pqsignal(SIGINT, StatementCancelHandler);   /* cancel current query */
    3648         216 :         pqsignal(SIGTERM, die); /* cancel current query and exit */
    3649             : 
    3650             :         /*
    3651             :          * In a standalone backend, SIGQUIT can be generated from the keyboard
    3652             :          * easily, while SIGTERM cannot, so we make both signals do die()
    3653             :          * rather than quickdie().
    3654             :          */
    3655         216 :         if (IsUnderPostmaster)
    3656         215 :             pqsignal(SIGQUIT, quickdie);    /* hard crash time */
    3657             :         else
    3658           1 :             pqsignal(SIGQUIT, die); /* cancel current query and exit */
    3659         216 :         InitializeTimeouts();   /* establishes SIGALRM handler */
    3660             : 
    3661             :         /*
    3662             :          * Ignore failure to write to frontend. Note: if frontend closes
    3663             :          * connection, we will notice it and exit cleanly when control next
    3664             :          * returns to outer loop.  This seems safer than forcing exit in the
    3665             :          * midst of output during who-knows-what operation...
    3666             :          */
    3667         216 :         pqsignal(SIGPIPE, SIG_IGN);
    3668         216 :         pqsignal(SIGUSR1, procsignal_sigusr1_handler);
    3669         216 :         pqsignal(SIGUSR2, SIG_IGN);
    3670         216 :         pqsignal(SIGFPE, FloatExceptionHandler);
    3671             : 
    3672             :         /*
    3673             :          * Reset some signals that are accepted by postmaster but not by
    3674             :          * backend
    3675             :          */
    3676         216 :         pqsignal(SIGCHLD, SIG_DFL); /* system() requires this on some
    3677             :                                      * platforms */
    3678             :     }
    3679             : 
    3680         216 :     pqinitmask();
    3681             : 
    3682         216 :     if (IsUnderPostmaster)
    3683             :     {
    3684             :         /* We allow SIGQUIT (quickdie) at all times */
    3685         215 :         sigdelset(&BlockSig, SIGQUIT);
    3686             :     }
    3687             : 
    3688         216 :     PG_SETMASK(&BlockSig);      /* block everything except SIGQUIT */
    3689             : 
    3690         216 :     if (!IsUnderPostmaster)
    3691             :     {
    3692             :         /*
    3693             :          * Validate we have been given a reasonable-looking DataDir (if under
    3694             :          * postmaster, assume postmaster did this already).
    3695             :          */
    3696           1 :         Assert(DataDir);
    3697           1 :         ValidatePgVersion(DataDir);
    3698             : 
    3699             :         /* Change into DataDir (if under postmaster, was done already) */
    3700           1 :         ChangeToDataDir();
    3701             : 
    3702             :         /*
    3703             :          * Create lockfile for data directory.
    3704             :          */
    3705           1 :         CreateDataDirLockFile(false);
    3706             : 
    3707             :         /* Initialize MaxBackends (if under postmaster, was done already) */
    3708           1 :         InitializeMaxBackends();
    3709             :     }
    3710             : 
    3711             :     /* Early initialization */
    3712         216 :     BaseInit();
    3713             : 
    3714             :     /*
    3715             :      * Create a per-backend PGPROC struct in shared memory, except in the
    3716             :      * EXEC_BACKEND case where this was done in SubPostmasterMain. We must do
    3717             :      * this before we can use LWLocks (and in the EXEC_BACKEND case we already
    3718             :      * had to do some stuff with LWLocks).
    3719             :      */
    3720             : #ifdef EXEC_BACKEND
    3721             :     if (!IsUnderPostmaster)
    3722             :         InitProcess();
    3723             : #else
    3724         216 :     InitProcess();
    3725             : #endif
    3726             : 
    3727             :     /* We need to allow SIGINT, etc during the initial transaction */
    3728         216 :     PG_SETMASK(&UnBlockSig);
    3729             : 
    3730             :     /*
    3731             :      * General initialization.
    3732             :      *
    3733             :      * NOTE: if you are tempted to add code in this vicinity, consider putting
    3734             :      * it inside InitPostgres() instead.  In particular, anything that
    3735             :      * involves database access should be there, not here.
    3736             :      */
    3737         216 :     InitPostgres(dbname, InvalidOid, username, InvalidOid, NULL);
    3738             : 
    3739             :     /*
    3740             :      * If the PostmasterContext is still around, recycle the space; we don't
    3741             :      * need it anymore after InitPostgres completes.  Note this does not trash
    3742             :      * *MyProcPort, because ConnCreate() allocated that space with malloc()
    3743             :      * ... else we'd need to copy the Port data first.  Also, subsidiary data
    3744             :      * such as the username isn't lost either; see ProcessStartupPacket().
    3745             :      */
    3746         216 :     if (PostmasterContext)
    3747             :     {
    3748         215 :         MemoryContextDelete(PostmasterContext);
    3749         215 :         PostmasterContext = NULL;
    3750             :     }
    3751             : 
    3752         216 :     SetProcessingMode(NormalProcessing);
    3753             : 
    3754             :     /*
    3755             :      * Now all GUC states are fully set up.  Report them to client if
    3756             :      * appropriate.
    3757             :      */
    3758         216 :     BeginReportingGUCOptions();
    3759             : 
    3760             :     /*
    3761             :      * Also set up handler to log session end; we have to wait till now to be
    3762             :      * sure Log_disconnections has its final value.
    3763             :      */
    3764         216 :     if (IsUnderPostmaster && Log_disconnections)
    3765           0 :         on_proc_exit(log_disconnections, 0);
    3766             : 
    3767             :     /* Perform initialization specific to a WAL sender process. */
    3768         216 :     if (am_walsender)
    3769           0 :         InitWalSender();
    3770             : 
    3771             :     /*
    3772             :      * process any libraries that should be preloaded at backend start (this
    3773             :      * likewise can't be done until GUC settings are complete)
    3774             :      */
    3775         216 :     process_session_preload_libraries();
    3776             : 
    3777             :     /*
    3778             :      * Send this backend's cancellation info to the frontend.
    3779             :      */
    3780         216 :     if (whereToSendOutput == DestRemote)
    3781             :     {
    3782             :         StringInfoData buf;
    3783             : 
    3784         215 :         pq_beginmessage(&buf, 'K');
    3785         215 :         pq_sendint(&buf, (int32) MyProcPid, sizeof(int32));
    3786         215 :         pq_sendint(&buf, (int32) MyCancelKey, sizeof(int32));
    3787         215 :         pq_endmessage(&buf);
    3788             :         /* Need not flush since ReadyForQuery will do it. */
    3789             :     }
    3790             : 
    3791             :     /* Welcome banner for standalone case */
    3792         216 :     if (whereToSendOutput == DestDebug)
    3793           1 :         printf("\nPostgreSQL stand-alone backend %s\n", PG_VERSION);
    3794             : 
    3795             :     /*
    3796             :      * Create the memory context we will use in the main loop.
    3797             :      *
    3798             :      * MessageContext is reset once per iteration of the main loop, ie, upon
    3799             :      * completion of processing of each command message from the client.
    3800             :      */
    3801         216 :     MessageContext = AllocSetContextCreate(TopMemoryContext,
    3802             :                                            "MessageContext",
    3803             :                                            ALLOCSET_DEFAULT_SIZES);
    3804             : 
    3805             :     /*
    3806             :      * Remember stand-alone backend startup time
    3807             :      */
    3808         216 :     if (!IsUnderPostmaster)
    3809           1 :         PgStartTime = GetCurrentTimestamp();
    3810             : 
    3811             :     /*
    3812             :      * POSTGRES main processing loop begins here
    3813             :      *
    3814             :      * If an exception is encountered, processing resumes here so we abort the
    3815             :      * current transaction and start a new one.
    3816             :      *
    3817             :      * You might wonder why this isn't coded as an infinite loop around a
    3818             :      * PG_TRY construct.  The reason is that this is the bottom of the
    3819             :      * exception stack, and so with PG_TRY there would be no exception handler
    3820             :      * in force at all during the CATCH part.  By leaving the outermost setjmp
    3821             :      * always active, we have at least some chance of recovering from an error
    3822             :      * during error recovery.  (If we get into an infinite loop thereby, it
    3823             :      * will soon be stopped by overflow of elog.c's internal state stack.)
    3824             :      *
    3825             :      * Note that we use sigsetjmp(..., 1), so that this function's signal mask
    3826             :      * (to wit, UnBlockSig) will be restored when longjmp'ing to here.  This
    3827             :      * is essential in case we longjmp'd out of a signal handler on a platform
    3828             :      * where that leaves the signal blocked.  It's not redundant with the
    3829             :      * unblock in AbortTransaction() because the latter is only called if we
    3830             :      * were inside a transaction.
    3831             :      */
    3832             : 
    3833        3436 :     if (sigsetjmp(local_sigjmp_buf, 1) != 0)
    3834             :     {
    3835             :         /*
    3836             :          * NOTE: if you are tempted to add more code in this if-block,
    3837             :          * consider the high probability that it should be in
    3838             :          * AbortTransaction() instead.  The only stuff done directly here
    3839             :          * should be stuff that is guaranteed to apply *only* for outer-level
    3840             :          * error recovery, such as adjusting the FE/BE protocol status.
    3841             :          */
    3842             : 
    3843             :         /* Since not using PG_TRY, must reset error stack by hand */
    3844        3220 :         error_context_stack = NULL;
    3845             : 
    3846             :         /* Prevent interrupts while cleaning up */
    3847        3220 :         HOLD_INTERRUPTS();
    3848             : 
    3849             :         /*
    3850             :          * Forget any pending QueryCancel request, since we're returning to
    3851             :          * the idle loop anyway, and cancel any active timeout requests.  (In
    3852             :          * future we might want to allow some timeout requests to survive, but
    3853             :          * at minimum it'd be necessary to do reschedule_timeouts(), in case
    3854             :          * we got here because of a query cancel interrupting the SIGALRM
    3855             :          * interrupt handler.)  Note in particular that we must clear the
    3856             :          * statement and lock timeout indicators, to prevent any future plain
    3857             :          * query cancels from being misreported as timeouts in case we're
    3858             :          * forgetting a timeout cancel.
    3859             :          */
    3860        3220 :         disable_all_timeouts(false);
    3861        3220 :         QueryCancelPending = false; /* second to avoid race condition */
    3862             : 
    3863             :         /* Not reading from the client anymore. */
    3864        3220 :         DoingCommandRead = false;
    3865             : 
    3866             :         /* Make sure libpq is in a good state */
    3867        3220 :         pq_comm_reset();
    3868             : 
    3869             :         /* Report the error to the client and/or server log */
    3870        3220 :         EmitErrorReport();
    3871             : 
    3872             :         /*
    3873             :          * Make sure debug_query_string gets reset before we possibly clobber
    3874             :          * the storage it points at.
    3875             :          */
    3876        3220 :         debug_query_string = NULL;
    3877             : 
    3878             :         /*
    3879             :          * Abort the current transaction in order to recover.
    3880             :          */
    3881        3220 :         AbortCurrentTransaction();
    3882             : 
    3883        3220 :         if (am_walsender)
    3884           0 :             WalSndErrorCleanup();
    3885             : 
    3886             :         /*
    3887             :          * We can't release replication slots inside AbortTransaction() as we
    3888             :          * need to be able to start and abort transactions while having a slot
    3889             :          * acquired. But we never need to hold them across top level errors,
    3890             :          * so releasing here is fine. There's another cleanup in ProcKill()
    3891             :          * ensuring we'll correctly cleanup on FATAL errors as well.
    3892             :          */
    3893        3220 :         if (MyReplicationSlot != NULL)
    3894           0 :             ReplicationSlotRelease();
    3895             : 
    3896             :         /* We also want to cleanup temporary slots on error. */
    3897        3220 :         ReplicationSlotCleanup();
    3898             : 
    3899             :         /*
    3900             :          * Now return to normal top-level context and clear ErrorContext for
    3901             :          * next time.
    3902             :          */
    3903        3220 :         MemoryContextSwitchTo(TopMemoryContext);
    3904        3220 :         FlushErrorState();
    3905             : 
    3906             :         /*
    3907             :          * If we were handling an extended-query-protocol message, initiate
    3908             :          * skip till next Sync.  This also causes us not to issue
    3909             :          * ReadyForQuery (until we get Sync).
    3910             :          */
    3911        3220 :         if (doing_extended_query_message)
    3912           0 :             ignore_till_sync = true;
    3913             : 
    3914             :         /* We don't have a transaction command open anymore */
    3915        3220 :         xact_started = false;
    3916             : 
    3917             :         /*
    3918             :          * If an error occurred while we were reading a message from the
    3919             :          * client, we have potentially lost track of where the previous
    3920             :          * message ends and the next one begins.  Even though we have
    3921             :          * otherwise recovered from the error, we cannot safely read any more
    3922             :          * messages from the client, so there isn't much we can do with the
    3923             :          * connection anymore.
    3924             :          */
    3925        3220 :         if (pq_is_reading_msg())
    3926           0 :             ereport(FATAL,
    3927             :                     (errcode(ERRCODE_PROTOCOL_VIOLATION),
    3928             :                      errmsg("terminating connection because protocol synchronization was lost")));
    3929             : 
    3930             :         /* Now we can allow interrupts again */
    3931        3220 :         RESUME_INTERRUPTS();
    3932             :     }
    3933             : 
    3934             :     /* We can now handle ereport(ERROR) */
    3935        3436 :     PG_exception_stack = &local_sigjmp_buf;
    3936             : 
    3937        3436 :     if (!ignore_till_sync)
    3938        3436 :         send_ready_for_query = true;    /* initially, or after error */
    3939             : 
    3940             :     /*
    3941             :      * Non-error queries loop here.
    3942             :      */
    3943             : 
    3944             :     for (;;)
    3945             :     {
    3946             :         /*
    3947             :          * At top of loop, reset extended-query-message flag, so that any
    3948             :          * errors encountered in "idle" state don't provoke skip.
    3949             :          */
    3950       27494 :         doing_extended_query_message = false;
    3951             : 
    3952             :         /*
    3953             :          * Release storage left over from prior query cycle, and create a new
    3954             :          * query input buffer in the cleared MessageContext.
    3955             :          */
    3956       27494 :         MemoryContextSwitchTo(MessageContext);
    3957       27494 :         MemoryContextResetAndDeleteChildren(MessageContext);
    3958             : 
    3959       27494 :         initStringInfo(&input_message);
    3960             : 
    3961             :         /*
    3962             :          * Also consider releasing our catalog snapshot if any, so that it's
    3963             :          * not preventing advance of global xmin while we wait for the client.
    3964             :          */
    3965       27494 :         InvalidateCatalogSnapshotConditionally();
    3966             : 
    3967             :         /*
    3968             :          * (1) If we've reached idle state, tell the frontend we're ready for
    3969             :          * a new query.
    3970             :          *
    3971             :          * Note: this includes fflush()'ing the last of the prior output.
    3972             :          *
    3973             :          * This is also a good time to send collected statistics to the
    3974             :          * collector, and to update the PS stats display.  We avoid doing
    3975             :          * those every time through the message loop because it'd slow down
    3976             :          * processing of batched messages, and because we don't want to report
    3977             :          * uncommitted updates (that confuses autovacuum).  The notification
    3978             :          * processor wants a call too, if we are not in a transaction block.
    3979             :          */
    3980       27494 :         if (send_ready_for_query)
    3981             :         {
    3982       27471 :             if (IsAbortedTransactionBlockState())
    3983             :             {
    3984         113 :                 set_ps_display("idle in transaction (aborted)", false);
    3985         113 :                 pgstat_report_activity(STATE_IDLEINTRANSACTION_ABORTED, NULL);
    3986             : 
    3987             :                 /* Start the idle-in-transaction timer */
    3988         113 :                 if (IdleInTransactionSessionTimeout > 0)
    3989             :                 {
    3990           0 :                     disable_idle_in_transaction_timeout = true;
    3991           0 :                     enable_timeout_after(IDLE_IN_TRANSACTION_SESSION_TIMEOUT,
    3992             :                                          IdleInTransactionSessionTimeout);
    3993             :                 }
    3994             :             }
    3995       27358 :             else if (IsTransactionOrTransactionBlock())
    3996             :             {
    3997        2482 :                 set_ps_display("idle in transaction", false);
    3998        2482 :                 pgstat_report_activity(STATE_IDLEINTRANSACTION, NULL);
    3999             : 
    4000             :                 /* Start the idle-in-transaction timer */
    4001        2482 :                 if (IdleInTransactionSessionTimeout > 0)
    4002             :                 {
    4003           0 :                     disable_idle_in_transaction_timeout = true;
    4004           0 :                     enable_timeout_after(IDLE_IN_TRANSACTION_SESSION_TIMEOUT,
    4005             :                                          IdleInTransactionSessionTimeout);
    4006             :                 }
    4007             :             }
    4008             :             else
    4009             :             {
    4010       24876 :                 ProcessCompletedNotifies();
    4011       24876 :                 pgstat_report_stat(false);
    4012             : 
    4013       24876 :                 set_ps_display("idle", false);
    4014       24876 :                 pgstat_report_activity(STATE_IDLE, NULL);
    4015             :             }
    4016             : 
    4017       27471 :             ReadyForQuery(whereToSendOutput);
    4018       27471 :             send_ready_for_query = false;
    4019             :         }
    4020             : 
    4021             :         /*
    4022             :          * (2) Allow asynchronous signals to be executed immediately if they
    4023             :          * come in while we are waiting for client input. (This must be
    4024             :          * conditional since we don't want, say, reads on behalf of COPY FROM
    4025             :          * STDIN doing the same thing.)
    4026             :          */
    4027       27494 :         DoingCommandRead = true;
    4028             : 
    4029             :         /*
    4030             :          * (3) read a command (loop blocks here)
    4031             :          */
    4032       27494 :         firstchar = ReadCommand(&input_message);
    4033             : 
    4034             :         /*
    4035             :          * (4) disable async signal conditions again.
    4036             :          *
    4037             :          * Query cancel is supposed to be a no-op when there is no query in
    4038             :          * progress, so if a query cancel arrived while we were idle, just
    4039             :          * reset QueryCancelPending. ProcessInterrupts() has that effect when
    4040             :          * it's called when DoingCommandRead is set, so check for interrupts
    4041             :          * before resetting DoingCommandRead.
    4042             :          */
    4043       27494 :         CHECK_FOR_INTERRUPTS();
    4044       27494 :         DoingCommandRead = false;
    4045             : 
    4046             :         /*
    4047             :          * (5) turn off the idle-in-transaction timeout
    4048             :          */
    4049       27494 :         if (disable_idle_in_transaction_timeout)
    4050             :         {
    4051           0 :             disable_timeout(IDLE_IN_TRANSACTION_SESSION_TIMEOUT, false);
    4052           0 :             disable_idle_in_transaction_timeout = false;
    4053             :         }
    4054             : 
    4055             :         /*
    4056             :          * (6) check for any other interesting events that happened while we
    4057             :          * slept.
    4058             :          */
    4059       27494 :         if (ConfigReloadPending)
    4060             :         {
    4061           0 :             ConfigReloadPending = false;
    4062           0 :             ProcessConfigFile(PGC_SIGHUP);
    4063             :         }
    4064             : 
    4065             :         /*
    4066             :          * (7) process the command.  But ignore it if we're skipping till
    4067             :          * Sync.
    4068             :          */
    4069       27494 :         if (ignore_till_sync && firstchar != EOF)
    4070           0 :             continue;
    4071             : 
    4072       27494 :         switch (firstchar)
    4073             :         {
    4074             :             case 'Q':           /* simple query */
    4075             :                 {
    4076             :                     const char *query_string;
    4077             : 
    4078             :                     /* Set statement_timestamp() */
    4079       26997 :                     SetCurrentStatementStartTimestamp();
    4080             : 
    4081       26997 :                     query_string = pq_getmsgstring(&input_message);
    4082       26997 :                     pq_getmsgend(&input_message);
    4083             : 
    4084       26997 :                     if (am_walsender)
    4085             :                     {
    4086           0 :                         if (!exec_replication_command(query_string))
    4087           0 :                             exec_simple_query(query_string);
    4088             :                     }
    4089             :                     else
    4090       26997 :                         exec_simple_query(query_string);
    4091             : 
    4092       23777 :                     send_ready_for_query = true;
    4093             :                 }
    4094       23777 :                 break;
    4095             : 
    4096             :             case 'P':           /* parse */
    4097             :                 {
    4098             :                     const char *stmt_name;
    4099             :                     const char *query_string;
    4100             :                     int         numParams;
    4101           0 :                     Oid        *paramTypes = NULL;
    4102             : 
    4103           0 :                     forbidden_in_wal_sender(firstchar);
    4104             : 
    4105             :                     /* Set statement_timestamp() */
    4106           0 :                     SetCurrentStatementStartTimestamp();
    4107             : 
    4108           0 :                     stmt_name = pq_getmsgstring(&input_message);
    4109           0 :                     query_string = pq_getmsgstring(&input_message);
    4110           0 :                     numParams = pq_getmsgint(&input_message, 2);
    4111           0 :                     if (numParams > 0)
    4112             :                     {
    4113             :                         int         i;
    4114             : 
    4115           0 :                         paramTypes = (Oid *) palloc(numParams * sizeof(Oid));
    4116           0 :                         for (i = 0; i < numParams; i++)
    4117           0 :                             paramTypes[i] = pq_getmsgint(&input_message, 4);
    4118             :                     }
    4119           0 :                     pq_getmsgend(&input_message);
    4120             : 
    4121           0 :                     exec_parse_message(query_string, stmt_name,
    4122             :                                        paramTypes, numParams);
    4123             :                 }
    4124           0 :                 break;
    4125             : 
    4126             :             case 'B':           /* bind */
    4127           0 :                 forbidden_in_wal_sender(firstchar);
    4128             : 
    4129             :                 /* Set statement_timestamp() */
    4130           0 :                 SetCurrentStatementStartTimestamp();
    4131             : 
    4132             :                 /*
    4133             :                  * this message is complex enough that it seems best to put
    4134             :                  * the field extraction out-of-line
    4135             :                  */
    4136           0 :                 exec_bind_message(&input_message);
    4137           0 :                 break;
    4138             : 
    4139             :             case 'E':           /* execute */
    4140             :                 {
    4141             :                     const char *portal_name;
    4142             :                     int         max_rows;
    4143             : 
    4144           0 :                     forbidden_in_wal_sender(firstchar);
    4145             : 
    4146             :                     /* Set statement_timestamp() */
    4147           0 :                     SetCurrentStatementStartTimestamp();
    4148             : 
    4149           0 :                     portal_name = pq_getmsgstring(&input_message);
    4150           0 :                     max_rows = pq_getmsgint(&input_message, 4);
    4151           0 :                     pq_getmsgend(&input_message);
    4152             : 
    4153           0 :                     exec_execute_message(portal_name, max_rows);
    4154             :                 }
    4155           0 :                 break;
    4156             : 
    4157             :             case 'F':           /* fastpath function call */
    4158         258 :                 forbidden_in_wal_sender(firstchar);
    4159             : 
    4160             :                 /* Set statement_timestamp() */
    4161         258 :                 SetCurrentStatementStartTimestamp();
    4162             : 
    4163             :                 /* Report query to various monitoring facilities. */
    4164         258 :                 pgstat_report_activity(STATE_FASTPATH, NULL);
    4165         258 :                 set_ps_display("<FASTPATH>", false);
    4166             : 
    4167             :                 /* start an xact for this function invocation */
    4168         258 :                 start_xact_command();
    4169             : 
    4170             :                 /*
    4171             :                  * Note: we may at this point be inside an aborted
    4172             :                  * transaction.  We can't throw error for that until we've
    4173             :                  * finished reading the function-call message, so
    4174             :                  * HandleFunctionRequest() must check for it after doing so.
    4175             :                  * Be careful not to do anything that assumes we're inside a
    4176             :                  * valid transaction here.
    4177             :                  */
    4178             : 
    4179             :                 /* switch back to message context */
    4180         258 :                 MemoryContextSwitchTo(MessageContext);
    4181             : 
    4182         258 :                 HandleFunctionRequest(&input_message);
    4183             : 
    4184             :                 /* commit the function-invocation transaction */
    4185         258 :                 finish_xact_command();
    4186             : 
    4187         258 :                 send_ready_for_query = true;
    4188         258 :                 break;
    4189             : 
    4190             :             case 'C':           /* close */
    4191             :                 {
    4192             :                     int         close_type;
    4193             :                     const char *close_target;
    4194             : 
    4195           0 :                     forbidden_in_wal_sender(firstchar);
    4196             : 
    4197           0 :                     close_type = pq_getmsgbyte(&input_message);
    4198           0 :                     close_target = pq_getmsgstring(&input_message);
    4199           0 :                     pq_getmsgend(&input_message);
    4200             : 
    4201           0 :                     switch (close_type)
    4202             :                     {
    4203             :                         case 'S':
    4204           0 :                             if (close_target[0] != '\0')
    4205           0 :                                 DropPreparedStatement(close_target, false);
    4206             :                             else
    4207             :                             {
    4208             :                                 /* special-case the unnamed statement */
    4209           0 :                                 drop_unnamed_stmt();
    4210             :                             }
    4211           0 :                             break;
    4212             :                         case 'P':
    4213             :                             {
    4214             :                                 Portal      portal;
    4215             : 
    4216           0 :                                 portal = GetPortalByName(close_target);
    4217           0 :                                 if (PortalIsValid(portal))
    4218           0 :                                     PortalDrop(portal, false);
    4219             :                             }
    4220           0 :                             break;
    4221             :                         default:
    4222           0 :                             ereport(ERROR,
    4223             :                                     (errcode(ERRCODE_PROTOCOL_VIOLATION),
    4224             :                                      errmsg("invalid CLOSE message subtype %d",
    4225             :                                             close_type)));
    4226             :                             break;
    4227             :                     }
    4228             : 
    4229           0 :                     if (whereToSendOutput == DestRemote)
    4230           0 :                         pq_putemptymessage('3');    /* CloseComplete */
    4231             :                 }
    4232           0 :                 break;
    4233             : 
    4234             :             case 'D':           /* describe */
    4235             :                 {
    4236             :                     int         describe_type;
    4237             :                     const char *describe_target;
    4238             : 
    4239           0 :                     forbidden_in_wal_sender(firstchar);
    4240             : 
    4241             :                     /* Set statement_timestamp() (needed for xact) */
    4242           0 :                     SetCurrentStatementStartTimestamp();
    4243             : 
    4244           0 :                     describe_type = pq_getmsgbyte(&input_message);
    4245           0 :                     describe_target = pq_getmsgstring(&input_message);
    4246           0 :                     pq_getmsgend(&input_message);
    4247             : 
    4248           0 :                     switch (describe_type)
    4249             :                     {
    4250             :                         case 'S':
    4251           0 :                             exec_describe_statement_message(describe_target);
    4252           0 :                             break;
    4253             :                         case 'P':
    4254           0 :                             exec_describe_portal_message(describe_target);
    4255           0 :                             break;
    4256             :                         default:
    4257           0 :                             ereport(ERROR,
    4258             :                                     (errcode(ERRCODE_PROTOCOL_VIOLATION),
    4259             :                                      errmsg("invalid DESCRIBE message subtype %d",
    4260             :                                             describe_type)));
    4261             :                             break;
    4262             :                     }
    4263             :                 }
    4264           0 :                 break;
    4265             : 
    4266             :             case 'H':           /* flush */
    4267           0 :                 pq_getmsgend(&input_message);
    4268           0 :                 if (whereToSendOutput == DestRemote)
    4269           0 :                     pq_flush();
    4270           0 :                 break;
    4271             : 
    4272             :             case 'S':           /* sync */
    4273           0 :                 pq_getmsgend(&input_message);
    4274           0 :                 finish_xact_command();
    4275           0 :                 send_ready_for_query = true;
    4276           0 :                 break;
    4277             : 
    4278             :                 /*
    4279             :                  * 'X' means that the frontend is closing down the socket. EOF
    4280             :                  * means unexpected loss of frontend connection. Either way,
    4281             :                  * perform normal shutdown.
    4282             :                  */
    4283             :             case 'X':
    4284             :             case EOF:
    4285             : 
    4286             :                 /*
    4287             :                  * Reset whereToSendOutput to prevent ereport from attempting
    4288             :                  * to send any more messages to client.
    4289             :                  */
    4290         216 :                 if (whereToSendOutput == DestRemote)
    4291         215 :                     whereToSendOutput = DestNone;
    4292             : 
    4293             :                 /*
    4294             :                  * NOTE: if you are tempted to add more code here, DON'T!
    4295             :                  * Whatever you had in mind to do should be set up as an
    4296             :                  * on_proc_exit or on_shmem_exit callback, instead. Otherwise
    4297             :                  * it will fail to be called during other backend-shutdown
    4298             :                  * scenarios.
    4299             :                  */
    4300         216 :                 proc_exit(0);
    4301             : 
    4302             :             case 'd':           /* copy data */
    4303             :             case 'c':           /* copy done */
    4304             :             case 'f':           /* copy fail */
    4305             : 
    4306             :                 /*
    4307             :                  * Accept but ignore these messages, per protocol spec; we
    4308             :                  * probably got here because a COPY failed, and the frontend
    4309             :                  * is still sending data.
    4310             :                  */
    4311          23 :                 break;
    4312             : 
    4313             :             default:
    4314           0 :                 ereport(FATAL,
    4315             :                         (errcode(ERRCODE_PROTOCOL_VIOLATION),
    4316             :                          errmsg("invalid frontend message type %d",
    4317             :                                 firstchar)));
    4318             :         }
    4319       24058 :     }                           /* end of input-reading loop */
    4320             : }
    4321             : 
    4322             : /*
    4323             :  * Throw an error if we're a WAL sender process.
    4324             :  *
    4325             :  * This is used to forbid anything else than simple query protocol messages
    4326             :  * in a WAL sender process.  'firstchar' specifies what kind of a forbidden
    4327             :  * message was received, and is used to construct the error message.
    4328             :  */
    4329             : static void
    4330         258 : forbidden_in_wal_sender(char firstchar)
    4331             : {
    4332         258 :     if (am_walsender)
    4333             :     {
    4334           0 :         if (firstchar == 'F')
    4335           0 :             ereport(ERROR,
    4336             :                     (errcode(ERRCODE_PROTOCOL_VIOLATION),
    4337             :                      errmsg("fastpath function calls not supported in a replication connection")));
    4338             :         else
    4339           0 :             ereport(ERROR,
    4340             :                     (errcode(ERRCODE_PROTOCOL_VIOLATION),
    4341             :                      errmsg("extended query protocol not supported in a replication connection")));
    4342             :     }
    4343         258 : }
    4344             : 
    4345             : 
    4346             : /*
    4347             :  * Obtain platform stack depth limit (in bytes)
    4348             :  *
    4349             :  * Return -1 if unknown
    4350             :  */
    4351             : long
    4352         247 : get_stack_depth_rlimit(void)
    4353             : {
    4354             : #if defined(HAVE_GETRLIMIT) && defined(RLIMIT_STACK)
    4355             :     static long val = 0;
    4356             : 
    4357             :     /* This won't change after process launch, so check just once */
    4358         247 :     if (val == 0)
    4359             :     {
    4360             :         struct rlimit rlim;
    4361             : 
    4362           5 :         if (getrlimit(RLIMIT_STACK, &rlim) < 0)
    4363           0 :             val = -1;
    4364           5 :         else if (rlim.rlim_cur == RLIM_INFINITY)
    4365           0 :             val = LONG_MAX;
    4366             :         /* rlim_cur is probably of an unsigned type, so check for overflow */
    4367           5 :         else if (rlim.rlim_cur >= LONG_MAX)
    4368           0 :             val = LONG_MAX;
    4369             :         else
    4370           5 :             val = rlim.rlim_cur;
    4371             :     }
    4372         247 :     return val;
    4373             : #else                           /* no getrlimit */
    4374             : #if defined(WIN32) || defined(__CYGWIN__)
    4375             :     /* On Windows we set the backend stack size in src/backend/Makefile */
    4376             :     return WIN32_STACK_RLIMIT;
    4377             : #else                           /* not windows ... give up */
    4378             :     return -1;
    4379             : #endif
    4380             : #endif
    4381             : }
    4382             : 
    4383             : 
    4384             : static struct rusage Save_r;
    4385             : static struct timeval Save_t;
    4386             : 
    4387             : void
    4388           0 : ResetUsage(void)
    4389             : {
    4390           0 :     getrusage(RUSAGE_SELF, &Save_r);
    4391           0 :     gettimeofday(&Save_t, NULL);
    4392           0 : }
    4393             : 
    4394             : void
    4395           0 : ShowUsage(const char *title)
    4396             : {
    4397             :     StringInfoData str;
    4398             :     struct timeval user,
    4399             :                 sys;
    4400             :     struct timeval elapse_t;
    4401             :     struct rusage r;
    4402             : 
    4403           0 :     getrusage(RUSAGE_SELF, &r);
    4404           0 :     gettimeofday(&elapse_t, NULL);
    4405           0 :     memcpy((char *) &user, (char *) &r.ru_utime, sizeof(user));
    4406           0 :     memcpy((char *) &sys, (char *) &r.ru_stime, sizeof(sys));
    4407           0 :     if (elapse_t.tv_usec < Save_t.tv_usec)
    4408             :     {
    4409           0 :         elapse_t.tv_sec--;
    4410           0 :         elapse_t.tv_usec += 1000000;
    4411             :     }
    4412           0 :     if (r.ru_utime.tv_usec < Save_r.ru_utime.tv_usec)
    4413             :     {
    4414           0 :         r.ru_utime.tv_sec--;
    4415           0 :         r.ru_utime.tv_usec += 1000000;
    4416             :     }
    4417           0 :     if (r.ru_stime.tv_usec < Save_r.ru_stime.tv_usec)
    4418             :     {
    4419           0 :         r.ru_stime.tv_sec--;
    4420           0 :         r.ru_stime.tv_usec += 1000000;
    4421             :     }
    4422             : 
    4423             :     /*
    4424             :      * The only stats we don't show here are ixrss, idrss, isrss.  It takes
    4425             :      * some work to interpret them, and most platforms don't fill them in.
    4426             :      */
    4427           0 :     initStringInfo(&str);
    4428             : 
    4429           0 :     appendStringInfoString(&str, "! system usage stats:\n");
    4430           0 :     appendStringInfo(&str,
    4431             :                      "!\t%ld.%06ld s user, %ld.%06ld s system, %ld.%06ld s elapsed\n",
    4432           0 :                      (long) (r.ru_utime.tv_sec - Save_r.ru_utime.tv_sec),
    4433           0 :                      (long) (r.ru_utime.tv_usec - Save_r.ru_utime.tv_usec),
    4434           0 :                      (long) (r.ru_stime.tv_sec - Save_r.ru_stime.tv_sec),
    4435           0 :                      (long) (r.ru_stime.tv_usec - Save_r.ru_stime.tv_usec),
    4436           0 :                      (long) (elapse_t.tv_sec - Save_t.tv_sec),
    4437           0 :                      (long) (elapse_t.tv_usec - Save_t.tv_usec));
    4438           0 :     appendStringInfo(&str,
    4439             :                      "!\t[%ld.%06ld s user, %ld.%06ld s system total]\n",
    4440             :                      (long) user.tv_sec,
    4441             :                      (long) user.tv_usec,
    4442             :                      (long) sys.tv_sec,
    4443             :                      (long) sys.tv_usec);
    4444             : #if defined(HAVE_GETRUSAGE)
    4445           0 :     appendStringInfo(&str,
    4446             :                      "!\t%ld kB max resident size\n",
    4447             : #if defined(__darwin__)
    4448             :                      /* in bytes on macOS */
    4449             :                      r.ru_maxrss/1024
    4450             : #else
    4451             :                      /* in kilobytes on most other platforms */
    4452             :                      r.ru_maxrss
    4453             : #endif
    4454             :         );
    4455           0 :     appendStringInfo(&str,
    4456             :                      "!\t%ld/%ld [%ld/%ld] filesystem blocks in/out\n",
    4457           0 :                      r.ru_inblock - Save_r.ru_inblock,
    4458             :     /* they only drink coffee at dec */
    4459           0 :                      r.ru_oublock - Save_r.ru_oublock,
    4460             :                      r.ru_inblock, r.ru_oublock);
    4461           0 :     appendStringInfo(&str,
    4462             :                      "!\t%ld/%ld [%ld/%ld] page faults/reclaims, %ld [%ld] swaps\n",
    4463           0 :                      r.ru_majflt - Save_r.ru_majflt,
    4464           0 :                      r.ru_minflt - Save_r.ru_minflt,
    4465             :                      r.ru_majflt, r.ru_minflt,
    4466           0 :                      r.ru_nswap - Save_r.ru_nswap,
    4467             :                      r.ru_nswap);
    4468           0 :     appendStringInfo(&str,
    4469             :                      "!\t%ld [%ld] signals rcvd, %ld/%ld [%ld/%ld] messages rcvd/sent\n",
    4470           0 :                      r.ru_nsignals - Save_r.ru_nsignals,
    4471             :                      r.ru_nsignals,
    4472           0 :                      r.ru_msgrcv - Save_r.ru_msgrcv,
    4473           0 :                      r.ru_msgsnd - Save_r.ru_msgsnd,
    4474             :                      r.ru_msgrcv, r.ru_msgsnd);
    4475           0 :     appendStringInfo(&str,
    4476             :                      "!\t%ld/%ld [%ld/%ld] voluntary/involuntary context switches\n",
    4477           0 :                      r.ru_nvcsw - Save_r.ru_nvcsw,
    4478           0 :                      r.ru_nivcsw - Save_r.ru_nivcsw,
    4479             :                      r.ru_nvcsw, r.ru_nivcsw);
    4480             : #endif                          /* HAVE_GETRUSAGE */
    4481             : 
    4482             :     /* remove trailing newline */
    4483           0 :     if (str.data[str.len - 1] == '\n')
    4484           0 :         str.data[--str.len] = '\0';
    4485             : 
    4486           0 :     ereport(LOG,
    4487             :             (errmsg_internal("%s", title),
    4488             :              errdetail_internal("%s", str.data)));
    4489             : 
    4490           0 :     pfree(str.data);
    4491           0 : }
    4492             : 
    4493             : /*
    4494             :  * on_proc_exit handler to log end of session
    4495             :  */
    4496             : static void
    4497           0 : log_disconnections(int code, Datum arg)
    4498             : {
    4499           0 :     Port       *port = MyProcPort;
    4500             :     long        secs;
    4501             :     int         usecs;
    4502             :     int         msecs;
    4503             :     int         hours,
    4504             :                 minutes,
    4505             :                 seconds;
    4506             : 
    4507           0 :     TimestampDifference(port->SessionStartTime,
    4508             :                         GetCurrentTimestamp(),
    4509             :                         &secs, &usecs);
    4510           0 :     msecs = usecs / 1000;
    4511             : 
    4512           0 :     hours = secs / SECS_PER_HOUR;
    4513           0 :     secs %= SECS_PER_HOUR;
    4514           0 :     minutes = secs / SECS_PER_MINUTE;
    4515           0 :     seconds = secs % SECS_PER_MINUTE;
    4516             : 
    4517           0 :     ereport(LOG,
    4518             :             (errmsg("disconnection: session time: %d:%02d:%02d.%03d "
    4519             :                     "user=%s database=%s host=%s%s%s",
    4520             :                     hours, minutes, seconds, msecs,
    4521             :                     port->user_name, port->database_name, port->remote_host,
    4522             :                     port->remote_port[0] ? " port=" : "", port->remote_port)));
    4523           0 : }

Generated by: LCOV version 1.11