LCOV - code coverage report
Current view: top level - src/backend/utils/error - elog.c (source / functions) Coverage Total Hit
Test: PostgreSQL 19devel Lines: 69.8 % 1361 950
Test Date: 2026-03-02 19:14:38 Functions: 91.7 % 84 77
Legend: Lines:     hit not hit

            Line data    Source code
       1              : /*-------------------------------------------------------------------------
       2              :  *
       3              :  * elog.c
       4              :  *    error logging and reporting
       5              :  *
       6              :  * Because of the extremely high rate at which log messages can be generated,
       7              :  * we need to be mindful of the performance cost of obtaining any information
       8              :  * that may be logged.  Also, it's important to keep in mind that this code may
       9              :  * get called from within an aborted transaction, in which case operations
      10              :  * such as syscache lookups are unsafe.
      11              :  *
      12              :  * Some notes about recursion and errors during error processing:
      13              :  *
      14              :  * We need to be robust about recursive-error scenarios --- for example,
      15              :  * if we run out of memory, it's important to be able to report that fact.
      16              :  * There are a number of considerations that go into this.
      17              :  *
      18              :  * First, distinguish between re-entrant use and actual recursion.  It
      19              :  * is possible for an error or warning message to be emitted while the
      20              :  * parameters for an error message are being computed.  In this case
      21              :  * errstart has been called for the outer message, and some field values
      22              :  * may have already been saved, but we are not actually recursing.  We handle
      23              :  * this by providing a (small) stack of ErrorData records.  The inner message
      24              :  * can be computed and sent without disturbing the state of the outer message.
      25              :  * (If the inner message is actually an error, this isn't very interesting
      26              :  * because control won't come back to the outer message generator ... but
      27              :  * if the inner message is only debug or log data, this is critical.)
      28              :  *
      29              :  * Second, actual recursion will occur if an error is reported by one of
      30              :  * the elog.c routines or something they call.  By far the most probable
      31              :  * scenario of this sort is "out of memory"; and it's also the nastiest
      32              :  * to handle because we'd likely also run out of memory while trying to
      33              :  * report this error!  Our escape hatch for this case is to reset the
      34              :  * ErrorContext to empty before trying to process the inner error.  Since
      35              :  * ErrorContext is guaranteed to have at least 8K of space in it (see mcxt.c),
      36              :  * we should be able to process an "out of memory" message successfully.
      37              :  * Since we lose the prior error state due to the reset, we won't be able
      38              :  * to return to processing the original error, but we wouldn't have anyway.
      39              :  * (NOTE: the escape hatch is not used for recursive situations where the
      40              :  * inner message is of less than ERROR severity; in that case we just
      41              :  * try to process it and return normally.  Usually this will work, but if
      42              :  * it ends up in infinite recursion, we will PANIC due to error stack
      43              :  * overflow.)
      44              :  *
      45              :  *
      46              :  * Portions Copyright (c) 1996-2026, PostgreSQL Global Development Group
      47              :  * Portions Copyright (c) 1994, Regents of the University of California
      48              :  *
      49              :  *
      50              :  * IDENTIFICATION
      51              :  *    src/backend/utils/error/elog.c
      52              :  *
      53              :  *-------------------------------------------------------------------------
      54              :  */
      55              : #include "postgres.h"
      56              : 
      57              : #include <fcntl.h>
      58              : #include <time.h>
      59              : #include <unistd.h>
      60              : #include <signal.h>
      61              : #include <ctype.h>
      62              : #ifdef HAVE_SYSLOG
      63              : #include <syslog.h>
      64              : #endif
      65              : #ifdef HAVE_EXECINFO_H
      66              : #include <execinfo.h>
      67              : #endif
      68              : 
      69              : #ifdef _MSC_VER
      70              : #include <dbghelp.h>
      71              : #endif
      72              : 
      73              : #include "access/xact.h"
      74              : #include "common/ip.h"
      75              : #include "libpq/libpq.h"
      76              : #include "libpq/pqformat.h"
      77              : #include "mb/pg_wchar.h"
      78              : #include "miscadmin.h"
      79              : #include "nodes/miscnodes.h"
      80              : #include "pgstat.h"
      81              : #include "postmaster/bgworker.h"
      82              : #include "postmaster/postmaster.h"
      83              : #include "postmaster/syslogger.h"
      84              : #include "storage/ipc.h"
      85              : #include "storage/proc.h"
      86              : #include "tcop/tcopprot.h"
      87              : #include "utils/guc_hooks.h"
      88              : #include "utils/memutils.h"
      89              : #include "utils/ps_status.h"
      90              : #include "utils/varlena.h"
      91              : 
      92              : 
      93              : /* In this module, access gettext() via err_gettext() */
      94              : #undef _
      95              : #define _(x) err_gettext(x)
      96              : 
      97              : 
      98              : /* Global variables */
      99              : ErrorContextCallback *error_context_stack = NULL;
     100              : 
     101              : sigjmp_buf *PG_exception_stack = NULL;
     102              : 
     103              : /*
     104              :  * Hook for intercepting messages before they are sent to the server log.
     105              :  * Note that the hook will not get called for messages that are suppressed
     106              :  * by log_min_messages.  Also note that logging hooks implemented in preload
     107              :  * libraries will miss any log messages that are generated before the
     108              :  * library is loaded.
     109              :  */
     110              : emit_log_hook_type emit_log_hook = NULL;
     111              : 
     112              : /* GUC parameters */
     113              : int         Log_error_verbosity = PGERROR_DEFAULT;
     114              : char       *Log_line_prefix = NULL; /* format for extra log line info */
     115              : int         Log_destination = LOG_DESTINATION_STDERR;
     116              : char       *Log_destination_string = NULL;
     117              : bool        syslog_sequence_numbers = true;
     118              : bool        syslog_split_messages = true;
     119              : 
     120              : /* Processed form of backtrace_functions GUC */
     121              : static char *backtrace_function_list;
     122              : 
     123              : #ifdef HAVE_SYSLOG
     124              : 
     125              : /*
     126              :  * Max string length to send to syslog().  Note that this doesn't count the
     127              :  * sequence-number prefix we add, and of course it doesn't count the prefix
     128              :  * added by syslog itself.  Solaris and sysklogd truncate the final message
     129              :  * at 1024 bytes, so this value leaves 124 bytes for those prefixes.  (Most
     130              :  * other syslog implementations seem to have limits of 2KB or so.)
     131              :  */
     132              : #ifndef PG_SYSLOG_LIMIT
     133              : #define PG_SYSLOG_LIMIT 900
     134              : #endif
     135              : 
     136              : static bool openlog_done = false;
     137              : static char *syslog_ident = NULL;
     138              : static int  syslog_facility = LOG_LOCAL0;
     139              : 
     140              : static void write_syslog(int level, const char *line);
     141              : #endif
     142              : 
     143              : #ifdef WIN32
     144              : static void write_eventlog(int level, const char *line, int len);
     145              : #endif
     146              : 
     147              : #ifdef _MSC_VER
     148              : static bool backtrace_symbols_initialized = false;
     149              : static HANDLE backtrace_process = NULL;
     150              : #endif
     151              : 
     152              : /* We provide a small stack of ErrorData records for re-entrant cases */
     153              : #define ERRORDATA_STACK_SIZE  5
     154              : 
     155              : static ErrorData errordata[ERRORDATA_STACK_SIZE];
     156              : 
     157              : static int  errordata_stack_depth = -1; /* index of topmost active frame */
     158              : 
     159              : static int  recursion_depth = 0;    /* to detect actual recursion */
     160              : 
     161              : /*
     162              :  * Saved timeval and buffers for formatted timestamps that might be used by
     163              :  * log_line_prefix, csv logs and JSON logs.
     164              :  */
     165              : static struct timeval saved_timeval;
     166              : static bool saved_timeval_set = false;
     167              : 
     168              : #define FORMATTED_TS_LEN 128
     169              : static char formatted_start_time[FORMATTED_TS_LEN];
     170              : static char formatted_log_time[FORMATTED_TS_LEN];
     171              : 
     172              : 
     173              : /* Macro for checking errordata_stack_depth is reasonable */
     174              : #define CHECK_STACK_DEPTH() \
     175              :     do { \
     176              :         if (errordata_stack_depth < 0) \
     177              :         { \
     178              :             errordata_stack_depth = -1; \
     179              :             ereport(ERROR, (errmsg_internal("errstart was not called"))); \
     180              :         } \
     181              :     } while (0)
     182              : 
     183              : 
     184              : static const char *err_gettext(const char *str) pg_attribute_format_arg(1);
     185              : static ErrorData *get_error_stack_entry(void);
     186              : static void set_stack_entry_domain(ErrorData *edata, const char *domain);
     187              : static void set_stack_entry_location(ErrorData *edata,
     188              :                                      const char *filename, int lineno,
     189              :                                      const char *funcname);
     190              : static bool matches_backtrace_functions(const char *funcname);
     191              : static pg_noinline void set_backtrace(ErrorData *edata, int num_skip);
     192              : static void backtrace_cleanup(int code, Datum arg);
     193              : static void set_errdata_field(MemoryContextData *cxt, char **ptr, const char *str);
     194              : static void FreeErrorDataContents(ErrorData *edata);
     195              : static int  log_min_messages_cmp(const ListCell *a, const ListCell *b);
     196              : static void write_console(const char *line, int len);
     197              : static const char *process_log_prefix_padding(const char *p, int *ppadding);
     198              : static void log_line_prefix(StringInfo buf, ErrorData *edata);
     199              : static void send_message_to_server_log(ErrorData *edata);
     200              : static void send_message_to_frontend(ErrorData *edata);
     201              : static void append_with_tabs(StringInfo buf, const char *str);
     202              : 
     203              : 
     204              : /*
     205              :  * is_log_level_output -- is elevel logically >= log_min_level?
     206              :  *
     207              :  * We use this for tests that should consider LOG to sort out-of-order,
     208              :  * between ERROR and FATAL.  Generally this is the right thing for testing
     209              :  * whether a message should go to the postmaster log, whereas a simple >=
     210              :  * test is correct for testing whether the message should go to the client.
     211              :  */
     212              : static inline bool
     213     49315924 : is_log_level_output(int elevel, int log_min_level)
     214              : {
     215     49315924 :     if (elevel == LOG || elevel == LOG_SERVER_ONLY)
     216              :     {
     217       541436 :         if (log_min_level == LOG || log_min_level <= ERROR)
     218       541426 :             return true;
     219              :     }
     220     48774488 :     else if (elevel == WARNING_CLIENT_ONLY)
     221              :     {
     222              :         /* never sent to log, regardless of log_min_level */
     223            0 :         return false;
     224              :     }
     225     48774488 :     else if (log_min_level == LOG)
     226              :     {
     227              :         /* elevel != LOG */
     228            0 :         if (elevel >= FATAL)
     229            0 :             return true;
     230              :     }
     231              :     /* Neither is LOG */
     232     48774488 :     else if (elevel >= log_min_level)
     233       252603 :         return true;
     234              : 
     235     48521895 :     return false;
     236              : }
     237              : 
     238              : /*
     239              :  * Policy-setting subroutines.  These are fairly simple, but it seems wise
     240              :  * to have the code in just one place.
     241              :  */
     242              : 
     243              : /*
     244              :  * should_output_to_server --- should message of given elevel go to the log?
     245              :  */
     246              : static inline bool
     247     48820483 : should_output_to_server(int elevel)
     248              : {
     249     48820483 :     return is_log_level_output(elevel, log_min_messages[MyBackendType]);
     250              : }
     251              : 
     252              : /*
     253              :  * should_output_to_client --- should message of given elevel go to the client?
     254              :  */
     255              : static inline bool
     256     48819439 : should_output_to_client(int elevel)
     257              : {
     258     48819439 :     if (whereToSendOutput == DestRemote && elevel != LOG_SERVER_ONLY)
     259              :     {
     260              :         /*
     261              :          * client_min_messages is honored only after we complete the
     262              :          * authentication handshake.  This is required both for security
     263              :          * reasons and because many clients can't handle NOTICE messages
     264              :          * during authentication.
     265              :          */
     266     22238683 :         if (ClientAuthInProgress)
     267       117958 :             return (elevel >= ERROR);
     268              :         else
     269     22120725 :             return (elevel >= client_min_messages || elevel == INFO);
     270              :     }
     271     26580756 :     return false;
     272              : }
     273              : 
     274              : 
     275              : /*
     276              :  * message_level_is_interesting --- would ereport/elog do anything?
     277              :  *
     278              :  * Returns true if ereport/elog with this elevel will not be a no-op.
     279              :  * This is useful to short-circuit any expensive preparatory work that
     280              :  * might be needed for a logging message.  There is no point in
     281              :  * prepending this to a bare ereport/elog call, however.
     282              :  */
     283              : bool
     284      1523627 : message_level_is_interesting(int elevel)
     285              : {
     286              :     /*
     287              :      * Keep this in sync with the decision-making in errstart().
     288              :      */
     289      3047254 :     if (elevel >= ERROR ||
     290      3046210 :         should_output_to_server(elevel) ||
     291      1522583 :         should_output_to_client(elevel))
     292         2312 :         return true;
     293      1521315 :     return false;
     294              : }
     295              : 
     296              : 
     297              : /*
     298              :  * in_error_recursion_trouble --- are we at risk of infinite error recursion?
     299              :  *
     300              :  * This function exists to provide common control of various fallback steps
     301              :  * that we take if we think we are facing infinite error recursion.  See the
     302              :  * callers for details.
     303              :  */
     304              : bool
     305      2267477 : in_error_recursion_trouble(void)
     306              : {
     307              :     /* Pull the plug if recurse more than once */
     308      2267477 :     return (recursion_depth > 2);
     309              : }
     310              : 
     311              : /*
     312              :  * One of those fallback steps is to stop trying to localize the error
     313              :  * message, since there's a significant probability that that's exactly
     314              :  * what's causing the recursion.
     315              :  */
     316              : static inline const char *
     317       851319 : err_gettext(const char *str)
     318              : {
     319              : #ifdef ENABLE_NLS
     320       851319 :     if (in_error_recursion_trouble())
     321            2 :         return str;
     322              :     else
     323       851317 :         return gettext(str);
     324              : #else
     325              :     return str;
     326              : #endif
     327              : }
     328              : 
     329              : /*
     330              :  * errstart_cold
     331              :  *      A simple wrapper around errstart, but hinted to be "cold".  Supporting
     332              :  *      compilers are more likely to move code for branches containing this
     333              :  *      function into an area away from the calling function's code.  This can
     334              :  *      result in more commonly executed code being more compact and fitting
     335              :  *      on fewer cache lines.
     336              :  */
     337              : pg_attribute_cold bool
     338        22085 : errstart_cold(int elevel, const char *domain)
     339              : {
     340        22085 :     return errstart(elevel, domain);
     341              : }
     342              : 
     343              : /*
     344              :  * errstart --- begin an error-reporting cycle
     345              :  *
     346              :  * Create and initialize error stack entry.  Subsequently, errmsg() and
     347              :  * perhaps other routines will be called to further populate the stack entry.
     348              :  * Finally, errfinish() will be called to actually process the error report.
     349              :  *
     350              :  * Returns true in normal case.  Returns false to short-circuit the error
     351              :  * report (if it's a warning or lower and not to be reported anywhere).
     352              :  */
     353              : bool
     354     47296856 : errstart(int elevel, const char *domain)
     355              : {
     356              :     ErrorData  *edata;
     357              :     bool        output_to_server;
     358     47296856 :     bool        output_to_client = false;
     359              :     int         i;
     360              : 
     361              :     /*
     362              :      * Check some cases in which we want to promote an error into a more
     363              :      * severe error.  None of this logic applies for non-error messages.
     364              :      */
     365     47296856 :     if (elevel >= ERROR)
     366              :     {
     367              :         /*
     368              :          * If we are inside a critical section, all errors become PANIC
     369              :          * errors.  See miscadmin.h.
     370              :          */
     371        26864 :         if (CritSectionCount > 0)
     372            0 :             elevel = PANIC;
     373              : 
     374              :         /*
     375              :          * Check reasons for treating ERROR as FATAL:
     376              :          *
     377              :          * 1. we have no handler to pass the error to (implies we are in the
     378              :          * postmaster or in backend startup).
     379              :          *
     380              :          * 2. ExitOnAnyError mode switch is set (initdb uses this).
     381              :          *
     382              :          * 3. the error occurred after proc_exit has begun to run.  (It's
     383              :          * proc_exit's responsibility to see that this doesn't turn into
     384              :          * infinite recursion!)
     385              :          */
     386        26864 :         if (elevel == ERROR)
     387              :         {
     388        26319 :             if (PG_exception_stack == NULL ||
     389        26133 :                 ExitOnAnyError ||
     390              :                 proc_exit_inprogress)
     391          186 :                 elevel = FATAL;
     392              :         }
     393              : 
     394              :         /*
     395              :          * If the error level is ERROR or more, errfinish is not going to
     396              :          * return to caller; therefore, if there is any stacked error already
     397              :          * in progress it will be lost.  This is more or less okay, except we
     398              :          * do not want to have a FATAL or PANIC error downgraded because the
     399              :          * reporting process was interrupted by a lower-grade error.  So check
     400              :          * the stack and make sure we panic if panic is warranted.
     401              :          */
     402        26865 :         for (i = 0; i <= errordata_stack_depth; i++)
     403            1 :             elevel = Max(elevel, errordata[i].elevel);
     404              :     }
     405              : 
     406              :     /*
     407              :      * Now decide whether we need to process this report at all; if it's
     408              :      * warning or less and not enabled for logging, just return false without
     409              :      * starting up any error logging machinery.
     410              :      */
     411     47296856 :     output_to_server = should_output_to_server(elevel);
     412     47296856 :     output_to_client = should_output_to_client(elevel);
     413     47296856 :     if (elevel < ERROR && !output_to_server && !output_to_client)
     414     46785894 :         return false;
     415              : 
     416              :     /*
     417              :      * We need to do some actual work.  Make sure that memory context
     418              :      * initialization has finished, else we can't do anything useful.
     419              :      */
     420       510962 :     if (ErrorContext == NULL)
     421              :     {
     422              :         /* Oops, hard crash time; very little we can do safely here */
     423            0 :         write_stderr("error occurred before error message processing is available\n");
     424            0 :         exit(2);
     425              :     }
     426              : 
     427              :     /*
     428              :      * Okay, crank up a stack entry to store the info in.
     429              :      */
     430              : 
     431       510962 :     if (recursion_depth++ > 0 && elevel >= ERROR)
     432              :     {
     433              :         /*
     434              :          * Oops, error during error processing.  Clear ErrorContext as
     435              :          * discussed at top of file.  We will not return to the original
     436              :          * error's reporter or handler, so we don't need it.
     437              :          */
     438            0 :         MemoryContextReset(ErrorContext);
     439              : 
     440              :         /*
     441              :          * Infinite error recursion might be due to something broken in a
     442              :          * context traceback routine.  Abandon them too.  We also abandon
     443              :          * attempting to print the error statement (which, if long, could
     444              :          * itself be the source of the recursive failure).
     445              :          */
     446            0 :         if (in_error_recursion_trouble())
     447              :         {
     448            0 :             error_context_stack = NULL;
     449            0 :             debug_query_string = NULL;
     450              :         }
     451              :     }
     452              : 
     453              :     /* Initialize data for this error frame */
     454       510962 :     edata = get_error_stack_entry();
     455       510962 :     edata->elevel = elevel;
     456       510962 :     edata->output_to_server = output_to_server;
     457       510962 :     edata->output_to_client = output_to_client;
     458       510962 :     set_stack_entry_domain(edata, domain);
     459              :     /* Select default errcode based on elevel */
     460       510962 :     if (elevel >= ERROR)
     461        26864 :         edata->sqlerrcode = ERRCODE_INTERNAL_ERROR;
     462       484098 :     else if (elevel >= WARNING)
     463       174482 :         edata->sqlerrcode = ERRCODE_WARNING;
     464              :     else
     465       309616 :         edata->sqlerrcode = ERRCODE_SUCCESSFUL_COMPLETION;
     466              : 
     467              :     /*
     468              :      * Any allocations for this error state level should go into ErrorContext
     469              :      */
     470       510962 :     edata->assoc_context = ErrorContext;
     471              : 
     472       510962 :     recursion_depth--;
     473       510962 :     return true;
     474              : }
     475              : 
     476              : /*
     477              :  * errfinish --- end an error-reporting cycle
     478              :  *
     479              :  * Produce the appropriate error report(s) and pop the error stack.
     480              :  *
     481              :  * If elevel, as passed to errstart(), is ERROR or worse, control does not
     482              :  * return to the caller.  See elog.h for the error level definitions.
     483              :  */
     484              : void
     485       510962 : errfinish(const char *filename, int lineno, const char *funcname)
     486              : {
     487       510962 :     ErrorData  *edata = &errordata[errordata_stack_depth];
     488              :     int         elevel;
     489              :     MemoryContext oldcontext;
     490              :     ErrorContextCallback *econtext;
     491              : 
     492       510962 :     recursion_depth++;
     493       510962 :     CHECK_STACK_DEPTH();
     494              : 
     495              :     /* Save the last few bits of error state into the stack entry */
     496       510962 :     set_stack_entry_location(edata, filename, lineno, funcname);
     497              : 
     498       510962 :     elevel = edata->elevel;
     499              : 
     500              :     /*
     501              :      * Do processing in ErrorContext, which we hope has enough reserved space
     502              :      * to report an error.
     503              :      */
     504       510962 :     oldcontext = MemoryContextSwitchTo(ErrorContext);
     505              : 
     506              :     /* Collect backtrace, if enabled and we didn't already */
     507       510962 :     if (!edata->backtrace &&
     508       510962 :         edata->funcname &&
     509       510962 :         backtrace_functions &&
     510       510962 :         matches_backtrace_functions(edata->funcname))
     511            0 :         set_backtrace(edata, 2);
     512              : 
     513              :     /*
     514              :      * Call any context callback functions.  Errors occurring in callback
     515              :      * functions will be treated as recursive errors --- this ensures we will
     516              :      * avoid infinite recursion (see errstart).
     517              :      */
     518       510962 :     for (econtext = error_context_stack;
     519       652269 :          econtext != NULL;
     520       141307 :          econtext = econtext->previous)
     521       141307 :         econtext->callback(econtext->arg);
     522              : 
     523              :     /*
     524              :      * If ERROR (not more nor less) we pass it off to the current handler.
     525              :      * Printing it and popping the stack is the responsibility of the handler.
     526              :      */
     527       510962 :     if (elevel == ERROR)
     528              :     {
     529              :         /*
     530              :          * We do some minimal cleanup before longjmp'ing so that handlers can
     531              :          * execute in a reasonably sane state.
     532              :          *
     533              :          * Reset InterruptHoldoffCount in case we ereport'd from inside an
     534              :          * interrupt holdoff section.  (We assume here that no handler will
     535              :          * itself be inside a holdoff section.  If necessary, such a handler
     536              :          * could save and restore InterruptHoldoffCount for itself, but this
     537              :          * should make life easier for most.)
     538              :          */
     539        26133 :         InterruptHoldoffCount = 0;
     540        26133 :         QueryCancelHoldoffCount = 0;
     541              : 
     542        26133 :         CritSectionCount = 0;   /* should be unnecessary, but... */
     543              : 
     544              :         /*
     545              :          * Note that we leave CurrentMemoryContext set to ErrorContext. The
     546              :          * handler should reset it to something else soon.
     547              :          */
     548              : 
     549        26133 :         recursion_depth--;
     550        26133 :         PG_RE_THROW();
     551              :     }
     552              : 
     553              :     /* Emit the message to the right places */
     554       484829 :     EmitErrorReport();
     555              : 
     556              :     /*
     557              :      * If this is the outermost recursion level, we can clean up by resetting
     558              :      * ErrorContext altogether (compare FlushErrorState), which is good
     559              :      * because it cleans up any random leakages that might have occurred in
     560              :      * places such as context callback functions.  If we're nested, we can
     561              :      * only safely remove the subsidiary data of the current stack entry.
     562              :      */
     563       484829 :     if (errordata_stack_depth == 0 && recursion_depth == 1)
     564       484795 :         MemoryContextReset(ErrorContext);
     565              :     else
     566           34 :         FreeErrorDataContents(edata);
     567              : 
     568              :     /* Release stack entry and exit error-handling context */
     569       484829 :     errordata_stack_depth--;
     570       484829 :     MemoryContextSwitchTo(oldcontext);
     571       484829 :     recursion_depth--;
     572              : 
     573              :     /*
     574              :      * Perform error recovery action as specified by elevel.
     575              :      */
     576       484829 :     if (elevel == FATAL)
     577              :     {
     578              :         /*
     579              :          * For a FATAL error, we let proc_exit clean up and exit.
     580              :          *
     581              :          * If we just reported a startup failure, the client will disconnect
     582              :          * on receiving it, so don't send any more to the client.
     583              :          */
     584          731 :         if (PG_exception_stack == NULL && whereToSendOutput == DestRemote)
     585          290 :             whereToSendOutput = DestNone;
     586              : 
     587              :         /*
     588              :          * fflush here is just to improve the odds that we get to see the
     589              :          * error message, in case things are so hosed that proc_exit crashes.
     590              :          * Any other code you might be tempted to add here should probably be
     591              :          * in an on_proc_exit or on_shmem_exit callback instead.
     592              :          */
     593          731 :         fflush(NULL);
     594              : 
     595              :         /*
     596              :          * Let the cumulative stats system know. Only mark the session as
     597              :          * terminated by fatal error if there is no other known cause.
     598              :          */
     599          731 :         if (pgStatSessionEndCause == DISCONNECT_NORMAL)
     600          512 :             pgStatSessionEndCause = DISCONNECT_FATAL;
     601              : 
     602              :         /*
     603              :          * Do normal process-exit cleanup, then return exit code 1 to indicate
     604              :          * FATAL termination.  The postmaster may or may not consider this
     605              :          * worthy of panic, depending on which subprocess returns it.
     606              :          */
     607          731 :         proc_exit(1);
     608              :     }
     609              : 
     610       484098 :     if (elevel >= PANIC)
     611              :     {
     612              :         /*
     613              :          * Serious crash time. Postmaster will observe SIGABRT process exit
     614              :          * status and kill the other backends too.
     615              :          *
     616              :          * XXX: what if we are *in* the postmaster?  abort() won't kill our
     617              :          * children...
     618              :          */
     619            0 :         fflush(NULL);
     620            0 :         abort();
     621              :     }
     622              : 
     623              :     /*
     624              :      * Check for cancel/die interrupt first --- this is so that the user can
     625              :      * stop a query emitting tons of notice or warning messages, even if it's
     626              :      * in a loop that otherwise fails to check for interrupts.
     627              :      */
     628       484098 :     CHECK_FOR_INTERRUPTS();
     629       484098 : }
     630              : 
     631              : 
     632              : /*
     633              :  * errsave_start --- begin a "soft" error-reporting cycle
     634              :  *
     635              :  * If "context" isn't an ErrorSaveContext node, this behaves as
     636              :  * errstart(ERROR, domain), and the errsave() macro ends up acting
     637              :  * exactly like ereport(ERROR, ...).
     638              :  *
     639              :  * If "context" is an ErrorSaveContext node, but the node creator only wants
     640              :  * notification of the fact of a soft error without any details, we just set
     641              :  * the error_occurred flag in the ErrorSaveContext node and return false,
     642              :  * which will cause us to skip the remaining error processing steps.
     643              :  *
     644              :  * Otherwise, create and initialize error stack entry and return true.
     645              :  * Subsequently, errmsg() and perhaps other routines will be called to further
     646              :  * populate the stack entry.  Finally, errsave_finish() will be called to
     647              :  * tidy up.
     648              :  */
     649              : bool
     650        26989 : errsave_start(struct Node *context, const char *domain)
     651              : {
     652              :     ErrorSaveContext *escontext;
     653              :     ErrorData  *edata;
     654              : 
     655              :     /*
     656              :      * Do we have a context for soft error reporting?  If not, just punt to
     657              :      * errstart().
     658              :      */
     659        26989 :     if (context == NULL || !IsA(context, ErrorSaveContext))
     660         3637 :         return errstart(ERROR, domain);
     661              : 
     662              :     /* Report that a soft error was detected */
     663        23352 :     escontext = (ErrorSaveContext *) context;
     664        23352 :     escontext->error_occurred = true;
     665              : 
     666              :     /* Nothing else to do if caller wants no further details */
     667        23352 :     if (!escontext->details_wanted)
     668        22709 :         return false;
     669              : 
     670              :     /*
     671              :      * Okay, crank up a stack entry to store the info in.
     672              :      */
     673              : 
     674          643 :     recursion_depth++;
     675              : 
     676              :     /* Initialize data for this error frame */
     677          643 :     edata = get_error_stack_entry();
     678          643 :     edata->elevel = LOG;     /* signal all is well to errsave_finish */
     679          643 :     set_stack_entry_domain(edata, domain);
     680              :     /* Select default errcode based on the assumed elevel of ERROR */
     681          643 :     edata->sqlerrcode = ERRCODE_INTERNAL_ERROR;
     682              : 
     683              :     /*
     684              :      * Any allocations for this error state level should go into the caller's
     685              :      * context.  We don't need to pollute ErrorContext, or even require it to
     686              :      * exist, in this code path.
     687              :      */
     688          643 :     edata->assoc_context = CurrentMemoryContext;
     689              : 
     690          643 :     recursion_depth--;
     691          643 :     return true;
     692              : }
     693              : 
     694              : /*
     695              :  * errsave_finish --- end a "soft" error-reporting cycle
     696              :  *
     697              :  * If errsave_start() decided this was a regular error, behave as
     698              :  * errfinish().  Otherwise, package up the error details and save
     699              :  * them in the ErrorSaveContext node.
     700              :  */
     701              : void
     702         4280 : errsave_finish(struct Node *context, const char *filename, int lineno,
     703              :                const char *funcname)
     704              : {
     705         4280 :     ErrorSaveContext *escontext = (ErrorSaveContext *) context;
     706         4280 :     ErrorData  *edata = &errordata[errordata_stack_depth];
     707              : 
     708              :     /* verify stack depth before accessing *edata */
     709         4280 :     CHECK_STACK_DEPTH();
     710              : 
     711              :     /*
     712              :      * If errsave_start punted to errstart, then elevel will be ERROR or
     713              :      * perhaps even PANIC.  Punt likewise to errfinish.
     714              :      */
     715         4280 :     if (edata->elevel >= ERROR)
     716              :     {
     717         3637 :         errfinish(filename, lineno, funcname);
     718            0 :         pg_unreachable();
     719              :     }
     720              : 
     721              :     /*
     722              :      * Else, we should package up the stack entry contents and deliver them to
     723              :      * the caller.
     724              :      */
     725          643 :     recursion_depth++;
     726              : 
     727              :     /* Save the last few bits of error state into the stack entry */
     728          643 :     set_stack_entry_location(edata, filename, lineno, funcname);
     729              : 
     730              :     /* Replace the LOG value that errsave_start inserted */
     731          643 :     edata->elevel = ERROR;
     732              : 
     733              :     /*
     734              :      * We skip calling backtrace and context functions, which are more likely
     735              :      * to cause trouble than provide useful context; they might act on the
     736              :      * assumption that a transaction abort is about to occur.
     737              :      */
     738              : 
     739              :     /*
     740              :      * Make a copy of the error info for the caller.  All the subsidiary
     741              :      * strings are already in the caller's context, so it's sufficient to
     742              :      * flat-copy the stack entry.
     743              :      */
     744          643 :     escontext->error_data = palloc_object(ErrorData);
     745          643 :     memcpy(escontext->error_data, edata, sizeof(ErrorData));
     746              : 
     747              :     /* Exit error-handling context */
     748          643 :     errordata_stack_depth--;
     749          643 :     recursion_depth--;
     750          643 : }
     751              : 
     752              : 
     753              : /*
     754              :  * get_error_stack_entry --- allocate and initialize a new stack entry
     755              :  *
     756              :  * The entry should be freed, when we're done with it, by calling
     757              :  * FreeErrorDataContents() and then decrementing errordata_stack_depth.
     758              :  *
     759              :  * Returning the entry's address is just a notational convenience,
     760              :  * since it had better be errordata[errordata_stack_depth].
     761              :  *
     762              :  * Although the error stack is not large, we don't expect to run out of space.
     763              :  * Using more than one entry implies a new error report during error recovery,
     764              :  * which is possible but already suggests we're in trouble.  If we exhaust the
     765              :  * stack, almost certainly we are in an infinite loop of errors during error
     766              :  * recovery, so we give up and PANIC.
     767              :  *
     768              :  * (Note that this is distinct from the recursion_depth checks, which
     769              :  * guard against recursion while handling a single stack entry.)
     770              :  */
     771              : static ErrorData *
     772       511661 : get_error_stack_entry(void)
     773              : {
     774              :     ErrorData  *edata;
     775              : 
     776              :     /* Allocate error frame */
     777       511661 :     errordata_stack_depth++;
     778       511661 :     if (unlikely(errordata_stack_depth >= ERRORDATA_STACK_SIZE))
     779              :     {
     780              :         /* Wups, stack not big enough */
     781            0 :         errordata_stack_depth = -1; /* make room on stack */
     782            0 :         ereport(PANIC, (errmsg_internal("ERRORDATA_STACK_SIZE exceeded")));
     783              :     }
     784              : 
     785              :     /* Initialize error frame to all zeroes/NULLs */
     786       511661 :     edata = &errordata[errordata_stack_depth];
     787       511661 :     memset(edata, 0, sizeof(ErrorData));
     788              : 
     789              :     /* Save errno immediately to ensure error parameter eval can't change it */
     790       511661 :     edata->saved_errno = errno;
     791              : 
     792       511661 :     return edata;
     793              : }
     794              : 
     795              : /*
     796              :  * set_stack_entry_domain --- fill in the internationalization domain
     797              :  */
     798              : static void
     799       511605 : set_stack_entry_domain(ErrorData *edata, const char *domain)
     800              : {
     801              :     /* the default text domain is the backend's */
     802       511605 :     edata->domain = domain ? domain : PG_TEXTDOMAIN("postgres");
     803              :     /* initialize context_domain the same way (see set_errcontext_domain()) */
     804       511605 :     edata->context_domain = edata->domain;
     805       511605 : }
     806              : 
     807              : /*
     808              :  * set_stack_entry_location --- fill in code-location details
     809              :  *
     810              :  * Store the values of __FILE__, __LINE__, and __func__ from the call site.
     811              :  * We make an effort to normalize __FILE__, since compilers are inconsistent
     812              :  * about how much of the path they'll include, and we'd prefer that the
     813              :  * behavior not depend on that (especially, that it not vary with build path).
     814              :  */
     815              : static void
     816       511605 : set_stack_entry_location(ErrorData *edata,
     817              :                          const char *filename, int lineno,
     818              :                          const char *funcname)
     819              : {
     820       511605 :     if (filename)
     821              :     {
     822              :         const char *slash;
     823              : 
     824              :         /* keep only base name, useful especially for vpath builds */
     825       511605 :         slash = strrchr(filename, '/');
     826       511605 :         if (slash)
     827           13 :             filename = slash + 1;
     828              :         /* Some Windows compilers use backslashes in __FILE__ strings */
     829       511605 :         slash = strrchr(filename, '\\');
     830       511605 :         if (slash)
     831            0 :             filename = slash + 1;
     832              :     }
     833              : 
     834       511605 :     edata->filename = filename;
     835       511605 :     edata->lineno = lineno;
     836       511605 :     edata->funcname = funcname;
     837       511605 : }
     838              : 
     839              : /*
     840              :  * matches_backtrace_functions --- checks whether the given funcname matches
     841              :  * backtrace_functions
     842              :  *
     843              :  * See check_backtrace_functions.
     844              :  */
     845              : static bool
     846       510962 : matches_backtrace_functions(const char *funcname)
     847              : {
     848              :     const char *p;
     849              : 
     850       510962 :     if (!backtrace_function_list || funcname == NULL || funcname[0] == '\0')
     851       510962 :         return false;
     852              : 
     853            0 :     p = backtrace_function_list;
     854              :     for (;;)
     855              :     {
     856            0 :         if (*p == '\0')         /* end of backtrace_function_list */
     857            0 :             break;
     858              : 
     859            0 :         if (strcmp(funcname, p) == 0)
     860            0 :             return true;
     861            0 :         p += strlen(p) + 1;
     862              :     }
     863              : 
     864            0 :     return false;
     865              : }
     866              : 
     867              : 
     868              : /*
     869              :  * errcode --- add SQLSTATE error code to the current error
     870              :  *
     871              :  * The code is expected to be represented as per MAKE_SQLSTATE().
     872              :  */
     873              : int
     874        28951 : errcode(int sqlerrcode)
     875              : {
     876        28951 :     ErrorData  *edata = &errordata[errordata_stack_depth];
     877              : 
     878              :     /* we don't bother incrementing recursion_depth */
     879        28951 :     CHECK_STACK_DEPTH();
     880              : 
     881        28951 :     edata->sqlerrcode = sqlerrcode;
     882              : 
     883        28951 :     return 0;                   /* return value does not matter */
     884              : }
     885              : 
     886              : 
     887              : /*
     888              :  * errcode_for_file_access --- add SQLSTATE error code to the current error
     889              :  *
     890              :  * The SQLSTATE code is chosen based on the saved errno value.  We assume
     891              :  * that the failing operation was some type of disk file access.
     892              :  *
     893              :  * NOTE: the primary error message string should generally include %m
     894              :  * when this is used.
     895              :  */
     896              : int
     897           81 : errcode_for_file_access(void)
     898              : {
     899           81 :     ErrorData  *edata = &errordata[errordata_stack_depth];
     900              : 
     901              :     /* we don't bother incrementing recursion_depth */
     902           81 :     CHECK_STACK_DEPTH();
     903              : 
     904           81 :     switch (edata->saved_errno)
     905              :     {
     906              :             /* Permission-denied failures */
     907            4 :         case EPERM:             /* Not super-user */
     908              :         case EACCES:            /* Permission denied */
     909              : #ifdef EROFS
     910              :         case EROFS:             /* Read only file system */
     911              : #endif
     912            4 :             edata->sqlerrcode = ERRCODE_INSUFFICIENT_PRIVILEGE;
     913            4 :             break;
     914              : 
     915              :             /* File not found */
     916           55 :         case ENOENT:            /* No such file or directory */
     917           55 :             edata->sqlerrcode = ERRCODE_UNDEFINED_FILE;
     918           55 :             break;
     919              : 
     920              :             /* Duplicate file */
     921            0 :         case EEXIST:            /* File exists */
     922            0 :             edata->sqlerrcode = ERRCODE_DUPLICATE_FILE;
     923            0 :             break;
     924              : 
     925              :             /* Wrong object type or state */
     926            2 :         case ENOTDIR:           /* Not a directory */
     927              :         case EISDIR:            /* Is a directory */
     928              : #if defined(ENOTEMPTY) && (ENOTEMPTY != EEXIST) /* same code on AIX */
     929              :         case ENOTEMPTY:         /* Directory not empty */
     930              : #endif
     931            2 :             edata->sqlerrcode = ERRCODE_WRONG_OBJECT_TYPE;
     932            2 :             break;
     933              : 
     934              :             /* Insufficient resources */
     935            0 :         case ENOSPC:            /* No space left on device */
     936            0 :             edata->sqlerrcode = ERRCODE_DISK_FULL;
     937            0 :             break;
     938              : 
     939            0 :         case ENOMEM:            /* Out of memory */
     940            0 :             edata->sqlerrcode = ERRCODE_OUT_OF_MEMORY;
     941            0 :             break;
     942              : 
     943            0 :         case ENFILE:            /* File table overflow */
     944              :         case EMFILE:            /* Too many open files */
     945            0 :             edata->sqlerrcode = ERRCODE_INSUFFICIENT_RESOURCES;
     946            0 :             break;
     947              : 
     948              :             /* Hardware failure */
     949            8 :         case EIO:               /* I/O error */
     950            8 :             edata->sqlerrcode = ERRCODE_IO_ERROR;
     951            8 :             break;
     952              : 
     953            0 :         case ENAMETOOLONG:      /* File name too long */
     954            0 :             edata->sqlerrcode = ERRCODE_FILE_NAME_TOO_LONG;
     955            0 :             break;
     956              : 
     957              :             /* All else is classified as internal errors */
     958           12 :         default:
     959           12 :             edata->sqlerrcode = ERRCODE_INTERNAL_ERROR;
     960           12 :             break;
     961              :     }
     962              : 
     963           81 :     return 0;                   /* return value does not matter */
     964              : }
     965              : 
     966              : /*
     967              :  * errcode_for_socket_access --- add SQLSTATE error code to the current error
     968              :  *
     969              :  * The SQLSTATE code is chosen based on the saved errno value.  We assume
     970              :  * that the failing operation was some type of socket access.
     971              :  *
     972              :  * NOTE: the primary error message string should generally include %m
     973              :  * when this is used.
     974              :  */
     975              : int
     976           23 : errcode_for_socket_access(void)
     977              : {
     978           23 :     ErrorData  *edata = &errordata[errordata_stack_depth];
     979              : 
     980              :     /* we don't bother incrementing recursion_depth */
     981           23 :     CHECK_STACK_DEPTH();
     982              : 
     983           23 :     switch (edata->saved_errno)
     984              :     {
     985              :             /* Loss of connection */
     986           23 :         case ALL_CONNECTION_FAILURE_ERRNOS:
     987           23 :             edata->sqlerrcode = ERRCODE_CONNECTION_FAILURE;
     988           23 :             break;
     989              : 
     990              :             /* All else is classified as internal errors */
     991            0 :         default:
     992            0 :             edata->sqlerrcode = ERRCODE_INTERNAL_ERROR;
     993            0 :             break;
     994              :     }
     995              : 
     996           23 :     return 0;                   /* return value does not matter */
     997              : }
     998              : 
     999              : 
    1000              : /*
    1001              :  * This macro handles expansion of a format string and associated parameters;
    1002              :  * it's common code for errmsg(), errdetail(), etc.  Must be called inside
    1003              :  * a routine that is declared like "const char *fmt, ..." and has an edata
    1004              :  * pointer set up.  The message is assigned to edata->targetfield, or
    1005              :  * appended to it if appendval is true.  The message is subject to translation
    1006              :  * if translateit is true.
    1007              :  *
    1008              :  * Note: we pstrdup the buffer rather than just transferring its storage
    1009              :  * to the edata field because the buffer might be considerably larger than
    1010              :  * really necessary.
    1011              :  */
    1012              : #define EVALUATE_MESSAGE(domain, targetfield, appendval, translateit)   \
    1013              :     { \
    1014              :         StringInfoData  buf; \
    1015              :         /* Internationalize the error format string */ \
    1016              :         if ((translateit) && !in_error_recursion_trouble()) \
    1017              :             fmt = dgettext((domain), fmt);                \
    1018              :         initStringInfo(&buf); \
    1019              :         if ((appendval) && edata->targetfield) { \
    1020              :             appendStringInfoString(&buf, edata->targetfield); \
    1021              :             appendStringInfoChar(&buf, '\n'); \
    1022              :         } \
    1023              :         /* Generate actual output --- have to use appendStringInfoVA */ \
    1024              :         for (;;) \
    1025              :         { \
    1026              :             va_list     args; \
    1027              :             int         needed; \
    1028              :             errno = edata->saved_errno; \
    1029              :             va_start(args, fmt); \
    1030              :             needed = appendStringInfoVA(&buf, fmt, args); \
    1031              :             va_end(args); \
    1032              :             if (needed == 0) \
    1033              :                 break; \
    1034              :             enlargeStringInfo(&buf, needed); \
    1035              :         } \
    1036              :         /* Save the completed message into the stack item */ \
    1037              :         if (edata->targetfield) \
    1038              :             pfree(edata->targetfield); \
    1039              :         edata->targetfield = pstrdup(buf.data); \
    1040              :         pfree(buf.data); \
    1041              :     }
    1042              : 
    1043              : /*
    1044              :  * Same as above, except for pluralized error messages.  The calling routine
    1045              :  * must be declared like "const char *fmt_singular, const char *fmt_plural,
    1046              :  * unsigned long n, ...".  Translation is assumed always wanted.
    1047              :  */
    1048              : #define EVALUATE_MESSAGE_PLURAL(domain, targetfield, appendval)  \
    1049              :     { \
    1050              :         const char     *fmt; \
    1051              :         StringInfoData  buf; \
    1052              :         /* Internationalize the error format string */ \
    1053              :         if (!in_error_recursion_trouble()) \
    1054              :             fmt = dngettext((domain), fmt_singular, fmt_plural, n); \
    1055              :         else \
    1056              :             fmt = (n == 1 ? fmt_singular : fmt_plural); \
    1057              :         initStringInfo(&buf); \
    1058              :         if ((appendval) && edata->targetfield) { \
    1059              :             appendStringInfoString(&buf, edata->targetfield); \
    1060              :             appendStringInfoChar(&buf, '\n'); \
    1061              :         } \
    1062              :         /* Generate actual output --- have to use appendStringInfoVA */ \
    1063              :         for (;;) \
    1064              :         { \
    1065              :             va_list     args; \
    1066              :             int         needed; \
    1067              :             errno = edata->saved_errno; \
    1068              :             va_start(args, n); \
    1069              :             needed = appendStringInfoVA(&buf, fmt, args); \
    1070              :             va_end(args); \
    1071              :             if (needed == 0) \
    1072              :                 break; \
    1073              :             enlargeStringInfo(&buf, needed); \
    1074              :         } \
    1075              :         /* Save the completed message into the stack item */ \
    1076              :         if (edata->targetfield) \
    1077              :             pfree(edata->targetfield); \
    1078              :         edata->targetfield = pstrdup(buf.data); \
    1079              :         pfree(buf.data); \
    1080              :     }
    1081              : 
    1082              : 
    1083              : /*
    1084              :  * errmsg --- add a primary error message text to the current error
    1085              :  *
    1086              :  * In addition to the usual %-escapes recognized by printf, "%m" in
    1087              :  * fmt is replaced by the error message for the caller's value of errno.
    1088              :  *
    1089              :  * Note: no newline is needed at the end of the fmt string, since
    1090              :  * ereport will provide one for the output methods that need it.
    1091              :  */
    1092              : int
    1093       370108 : errmsg(const char *fmt,...)
    1094              : {
    1095       370108 :     ErrorData  *edata = &errordata[errordata_stack_depth];
    1096              :     MemoryContext oldcontext;
    1097              : 
    1098       370108 :     recursion_depth++;
    1099       370108 :     CHECK_STACK_DEPTH();
    1100       370108 :     oldcontext = MemoryContextSwitchTo(edata->assoc_context);
    1101              : 
    1102       370108 :     edata->message_id = fmt;
    1103       371313 :     EVALUATE_MESSAGE(edata->domain, message, false, true);
    1104              : 
    1105       370108 :     MemoryContextSwitchTo(oldcontext);
    1106       370108 :     recursion_depth--;
    1107       370108 :     return 0;                   /* return value does not matter */
    1108              : }
    1109              : 
    1110              : /*
    1111              :  * Add a backtrace to the containing ereport() call.  This is intended to be
    1112              :  * added temporarily during debugging.
    1113              :  */
    1114              : int
    1115            0 : errbacktrace(void)
    1116              : {
    1117            0 :     ErrorData  *edata = &errordata[errordata_stack_depth];
    1118              :     MemoryContext oldcontext;
    1119              : 
    1120            0 :     recursion_depth++;
    1121            0 :     CHECK_STACK_DEPTH();
    1122            0 :     oldcontext = MemoryContextSwitchTo(edata->assoc_context);
    1123              : 
    1124            0 :     set_backtrace(edata, 1);
    1125              : 
    1126            0 :     MemoryContextSwitchTo(oldcontext);
    1127            0 :     recursion_depth--;
    1128              : 
    1129            0 :     return 0;
    1130              : }
    1131              : 
    1132              : /*
    1133              :  * Compute backtrace data and add it to the supplied ErrorData.  num_skip
    1134              :  * specifies how many inner frames to skip.  Use this to avoid showing the
    1135              :  * internal backtrace support functions in the backtrace.  This requires that
    1136              :  * this and related functions are not inlined.
    1137              :  *
    1138              :  * The implementation is, unsurprisingly, platform-specific:
    1139              :  * - GNU libc and copycats: Uses backtrace() and backtrace_symbols()
    1140              :  * - Windows: Uses CaptureStackBackTrace() with DbgHelp for symbol resolution
    1141              :  *   (requires PDB files; falls back to exported functions/raw addresses if
    1142              :  *   unavailable)
    1143              :  * - Others (musl libc): unsupported
    1144              :  */
    1145              : static void
    1146            0 : set_backtrace(ErrorData *edata, int num_skip)
    1147              : {
    1148              :     StringInfoData errtrace;
    1149              : 
    1150            0 :     initStringInfo(&errtrace);
    1151              : 
    1152              : #ifdef HAVE_BACKTRACE_SYMBOLS
    1153              :     {
    1154              :         void       *frames[100];
    1155              :         int         nframes;
    1156              :         char      **strfrms;
    1157              : 
    1158            0 :         nframes = backtrace(frames, lengthof(frames));
    1159            0 :         strfrms = backtrace_symbols(frames, nframes);
    1160            0 :         if (strfrms != NULL)
    1161              :         {
    1162            0 :             for (int i = num_skip; i < nframes; i++)
    1163            0 :                 appendStringInfo(&errtrace, "\n%s", strfrms[i]);
    1164            0 :             free(strfrms);
    1165              :         }
    1166              :         else
    1167            0 :             appendStringInfoString(&errtrace,
    1168              :                                    "insufficient memory for backtrace generation");
    1169              :     }
    1170              : #elif defined(_MSC_VER)
    1171              :     {
    1172              :         void       *frames[100];
    1173              :         int         nframes;
    1174              :         char        buffer[sizeof(SYMBOL_INFOW) + MAX_SYM_NAME * sizeof(wchar_t)];
    1175              :         PSYMBOL_INFOW psymbol;
    1176              : 
    1177              :         /*
    1178              :          * This is arranged so that we don't retry if we happen to fail to
    1179              :          * initialize state on the first attempt in any one process.
    1180              :          */
    1181              :         if (!backtrace_symbols_initialized)
    1182              :         {
    1183              :             backtrace_symbols_initialized = true;
    1184              : 
    1185              :             if (DuplicateHandle(GetCurrentProcess(),
    1186              :                                 GetCurrentProcess(),
    1187              :                                 GetCurrentProcess(),
    1188              :                                 &backtrace_process,
    1189              :                                 0,
    1190              :                                 FALSE,
    1191              :                                 DUPLICATE_SAME_ACCESS) == 0)
    1192              :             {
    1193              :                 appendStringInfo(&errtrace,
    1194              :                                  "could not get process handle for backtrace: error code %lu",
    1195              :                                  GetLastError());
    1196              :                 edata->backtrace = errtrace.data;
    1197              :                 return;
    1198              :             }
    1199              : 
    1200              :             SymSetOptions(SYMOPT_DEFERRED_LOADS |
    1201              :                           SYMOPT_FAIL_CRITICAL_ERRORS |
    1202              :                           SYMOPT_LOAD_LINES |
    1203              :                           SYMOPT_UNDNAME);
    1204              : 
    1205              :             if (!SymInitialize(backtrace_process, NULL, TRUE))
    1206              :             {
    1207              :                 CloseHandle(backtrace_process);
    1208              :                 backtrace_process = NULL;
    1209              :                 appendStringInfo(&errtrace,
    1210              :                                  "could not initialize symbol handler: error code %lu",
    1211              :                                  GetLastError());
    1212              :                 edata->backtrace = errtrace.data;
    1213              :                 return;
    1214              :             }
    1215              : 
    1216              :             on_proc_exit(backtrace_cleanup, 0);
    1217              :         }
    1218              : 
    1219              :         if (backtrace_process == NULL)
    1220              :             return;
    1221              : 
    1222              :         nframes = CaptureStackBackTrace(num_skip, lengthof(frames), frames, NULL);
    1223              : 
    1224              :         if (nframes == 0)
    1225              :         {
    1226              :             appendStringInfoString(&errtrace, "zero stack frames captured");
    1227              :             edata->backtrace = errtrace.data;
    1228              :             return;
    1229              :         }
    1230              : 
    1231              :         psymbol = (PSYMBOL_INFOW) buffer;
    1232              :         psymbol->MaxNameLen = MAX_SYM_NAME;
    1233              :         psymbol->SizeOfStruct = sizeof(SYMBOL_INFOW);
    1234              : 
    1235              :         for (int i = 0; i < nframes; i++)
    1236              :         {
    1237              :             DWORD64     address = (DWORD64) frames[i];
    1238              :             DWORD64     displacement = 0;
    1239              :             BOOL        sym_result;
    1240              : 
    1241              :             sym_result = SymFromAddrW(backtrace_process,
    1242              :                                       address,
    1243              :                                       &displacement,
    1244              :                                       psymbol);
    1245              :             if (sym_result == TRUE)
    1246              :             {
    1247              :                 char        symbol_name[MAX_SYM_NAME];
    1248              :                 size_t      result;
    1249              : 
    1250              :                 /*
    1251              :                  * Convert symbol name from UTF-16 to database encoding using
    1252              :                  * wchar2char(), which handles both UTF-8 and non-UTF-8
    1253              :                  * databases correctly on Windows.
    1254              :                  */
    1255              :                 result = wchar2char(symbol_name, (const wchar_t *) psymbol->Name,
    1256              :                                     sizeof(symbol_name), NULL);
    1257              : 
    1258              :                 if (result == (size_t) -1 || result == sizeof(symbol_name))
    1259              :                 {
    1260              :                     /* Conversion failed, use address only */
    1261              :                     appendStringInfo(&errtrace,
    1262              :                                      "\n[0x%llx]",
    1263              :                                      (unsigned long long) address);
    1264              :                 }
    1265              :                 else
    1266              :                 {
    1267              :                     IMAGEHLP_LINEW64 line;
    1268              :                     DWORD       line_displacement = 0;
    1269              :                     char        filename[MAX_PATH];
    1270              : 
    1271              :                     line.SizeOfStruct = sizeof(IMAGEHLP_LINEW64);
    1272              : 
    1273              :                     /* Start with the common part: symbol+offset [address] */
    1274              :                     appendStringInfo(&errtrace,
    1275              :                                      "\n%s+0x%llx [0x%llx]",
    1276              :                                      symbol_name,
    1277              :                                      (unsigned long long) displacement,
    1278              :                                      (unsigned long long) address);
    1279              : 
    1280              :                     /* Try to append line info if available */
    1281              :                     if (SymGetLineFromAddrW64(backtrace_process,
    1282              :                                               address,
    1283              :                                               &line_displacement,
    1284              :                                               &line))
    1285              :                     {
    1286              :                         result = wchar2char(filename, (const wchar_t *) line.FileName,
    1287              :                                             sizeof(filename), NULL);
    1288              : 
    1289              :                         if (result != (size_t) -1 && result != sizeof(filename))
    1290              :                         {
    1291              :                             appendStringInfo(&errtrace,
    1292              :                                              " [%s:%lu]",
    1293              :                                              filename,
    1294              :                                              (unsigned long) line.LineNumber);
    1295              :                         }
    1296              :                     }
    1297              :                 }
    1298              :             }
    1299              :             else
    1300              :             {
    1301              :                 appendStringInfo(&errtrace,
    1302              :                                  "\n[0x%llx] (symbol lookup failed: error code %lu)",
    1303              :                                  (unsigned long long) address,
    1304              :                                  GetLastError());
    1305              :             }
    1306              :         }
    1307              :     }
    1308              : #else
    1309              :     appendStringInfoString(&errtrace,
    1310              :                            "backtrace generation is not supported by this installation");
    1311              : #endif
    1312              : 
    1313            0 :     edata->backtrace = errtrace.data;
    1314            0 : }
    1315              : 
    1316              : /*
    1317              :  * Cleanup function for set_backtrace().
    1318              :  */
    1319              : pg_attribute_unused()
    1320              : static void
    1321            0 : backtrace_cleanup(int code, Datum arg)
    1322              : {
    1323              : #ifdef _MSC_VER
    1324              :     /*
    1325              :      * Currently only used to clean up after SymInitialize.  We shouldn't ever
    1326              :      * be called if backtrace_process is NULL, but better be safe.
    1327              :      */
    1328              :     if (backtrace_process)
    1329              :     {
    1330              :         SymCleanup(backtrace_process);
    1331              :         backtrace_process = NULL;
    1332              :     }
    1333              : #endif
    1334            0 : }
    1335              : 
    1336              : /*
    1337              :  * errmsg_internal --- add a primary error message text to the current error
    1338              :  *
    1339              :  * This is exactly like errmsg() except that strings passed to errmsg_internal
    1340              :  * are not translated, and are customarily left out of the
    1341              :  * internationalization message dictionary.  This should be used for "can't
    1342              :  * happen" cases that are probably not worth spending translation effort on.
    1343              :  * We also use this for certain cases where we *must* not try to translate
    1344              :  * the message because the translation would fail and result in infinite
    1345              :  * error recursion.
    1346              :  */
    1347              : int
    1348       140886 : errmsg_internal(const char *fmt,...)
    1349              : {
    1350       140886 :     ErrorData  *edata = &errordata[errordata_stack_depth];
    1351              :     MemoryContext oldcontext;
    1352              : 
    1353       140886 :     recursion_depth++;
    1354       140886 :     CHECK_STACK_DEPTH();
    1355       140886 :     oldcontext = MemoryContextSwitchTo(edata->assoc_context);
    1356              : 
    1357       140886 :     edata->message_id = fmt;
    1358       140902 :     EVALUATE_MESSAGE(edata->domain, message, false, false);
    1359              : 
    1360       140886 :     MemoryContextSwitchTo(oldcontext);
    1361       140886 :     recursion_depth--;
    1362       140886 :     return 0;                   /* return value does not matter */
    1363              : }
    1364              : 
    1365              : 
    1366              : /*
    1367              :  * errmsg_plural --- add a primary error message text to the current error,
    1368              :  * with support for pluralization of the message text
    1369              :  */
    1370              : int
    1371          605 : errmsg_plural(const char *fmt_singular, const char *fmt_plural,
    1372              :               unsigned long n,...)
    1373              : {
    1374          605 :     ErrorData  *edata = &errordata[errordata_stack_depth];
    1375              :     MemoryContext oldcontext;
    1376              : 
    1377          605 :     recursion_depth++;
    1378          605 :     CHECK_STACK_DEPTH();
    1379          605 :     oldcontext = MemoryContextSwitchTo(edata->assoc_context);
    1380              : 
    1381          605 :     edata->message_id = fmt_singular;
    1382          605 :     EVALUATE_MESSAGE_PLURAL(edata->domain, message, false);
    1383              : 
    1384          605 :     MemoryContextSwitchTo(oldcontext);
    1385          605 :     recursion_depth--;
    1386          605 :     return 0;                   /* return value does not matter */
    1387              : }
    1388              : 
    1389              : 
    1390              : /*
    1391              :  * errdetail --- add a detail error message text to the current error
    1392              :  */
    1393              : int
    1394        36632 : errdetail(const char *fmt,...)
    1395              : {
    1396        36632 :     ErrorData  *edata = &errordata[errordata_stack_depth];
    1397              :     MemoryContext oldcontext;
    1398              : 
    1399        36632 :     recursion_depth++;
    1400        36632 :     CHECK_STACK_DEPTH();
    1401        36632 :     oldcontext = MemoryContextSwitchTo(edata->assoc_context);
    1402              : 
    1403        36638 :     EVALUATE_MESSAGE(edata->domain, detail, false, true);
    1404              : 
    1405        36632 :     MemoryContextSwitchTo(oldcontext);
    1406        36632 :     recursion_depth--;
    1407        36632 :     return 0;                   /* return value does not matter */
    1408              : }
    1409              : 
    1410              : 
    1411              : /*
    1412              :  * errdetail_internal --- add a detail error message text to the current error
    1413              :  *
    1414              :  * This is exactly like errdetail() except that strings passed to
    1415              :  * errdetail_internal are not translated, and are customarily left out of the
    1416              :  * internationalization message dictionary.  This should be used for detail
    1417              :  * messages that seem not worth translating for one reason or another
    1418              :  * (typically, that they don't seem to be useful to average users).
    1419              :  */
    1420              : int
    1421         1660 : errdetail_internal(const char *fmt,...)
    1422              : {
    1423         1660 :     ErrorData  *edata = &errordata[errordata_stack_depth];
    1424              :     MemoryContext oldcontext;
    1425              : 
    1426         1660 :     recursion_depth++;
    1427         1660 :     CHECK_STACK_DEPTH();
    1428         1660 :     oldcontext = MemoryContextSwitchTo(edata->assoc_context);
    1429              : 
    1430         1679 :     EVALUATE_MESSAGE(edata->domain, detail, false, false);
    1431              : 
    1432         1660 :     MemoryContextSwitchTo(oldcontext);
    1433         1660 :     recursion_depth--;
    1434         1660 :     return 0;                   /* return value does not matter */
    1435              : }
    1436              : 
    1437              : 
    1438              : /*
    1439              :  * errdetail_log --- add a detail_log error message text to the current error
    1440              :  */
    1441              : int
    1442          614 : errdetail_log(const char *fmt,...)
    1443              : {
    1444          614 :     ErrorData  *edata = &errordata[errordata_stack_depth];
    1445              :     MemoryContext oldcontext;
    1446              : 
    1447          614 :     recursion_depth++;
    1448          614 :     CHECK_STACK_DEPTH();
    1449          614 :     oldcontext = MemoryContextSwitchTo(edata->assoc_context);
    1450              : 
    1451          634 :     EVALUATE_MESSAGE(edata->domain, detail_log, false, true);
    1452              : 
    1453          614 :     MemoryContextSwitchTo(oldcontext);
    1454          614 :     recursion_depth--;
    1455          614 :     return 0;                   /* return value does not matter */
    1456              : }
    1457              : 
    1458              : /*
    1459              :  * errdetail_log_plural --- add a detail_log error message text to the current error
    1460              :  * with support for pluralization of the message text
    1461              :  */
    1462              : int
    1463          375 : errdetail_log_plural(const char *fmt_singular, const char *fmt_plural,
    1464              :                      unsigned long n,...)
    1465              : {
    1466          375 :     ErrorData  *edata = &errordata[errordata_stack_depth];
    1467              :     MemoryContext oldcontext;
    1468              : 
    1469          375 :     recursion_depth++;
    1470          375 :     CHECK_STACK_DEPTH();
    1471          375 :     oldcontext = MemoryContextSwitchTo(edata->assoc_context);
    1472              : 
    1473          375 :     EVALUATE_MESSAGE_PLURAL(edata->domain, detail_log, false);
    1474              : 
    1475          375 :     MemoryContextSwitchTo(oldcontext);
    1476          375 :     recursion_depth--;
    1477          375 :     return 0;                   /* return value does not matter */
    1478              : }
    1479              : 
    1480              : 
    1481              : /*
    1482              :  * errdetail_plural --- add a detail error message text to the current error,
    1483              :  * with support for pluralization of the message text
    1484              :  */
    1485              : int
    1486           31 : errdetail_plural(const char *fmt_singular, const char *fmt_plural,
    1487              :                  unsigned long n,...)
    1488              : {
    1489           31 :     ErrorData  *edata = &errordata[errordata_stack_depth];
    1490              :     MemoryContext oldcontext;
    1491              : 
    1492           31 :     recursion_depth++;
    1493           31 :     CHECK_STACK_DEPTH();
    1494           31 :     oldcontext = MemoryContextSwitchTo(edata->assoc_context);
    1495              : 
    1496           31 :     EVALUATE_MESSAGE_PLURAL(edata->domain, detail, false);
    1497              : 
    1498           31 :     MemoryContextSwitchTo(oldcontext);
    1499           31 :     recursion_depth--;
    1500           31 :     return 0;                   /* return value does not matter */
    1501              : }
    1502              : 
    1503              : 
    1504              : /*
    1505              :  * errhint --- add a hint error message text to the current error
    1506              :  */
    1507              : int
    1508       174112 : errhint(const char *fmt,...)
    1509              : {
    1510       174112 :     ErrorData  *edata = &errordata[errordata_stack_depth];
    1511              :     MemoryContext oldcontext;
    1512              : 
    1513       174112 :     recursion_depth++;
    1514       174112 :     CHECK_STACK_DEPTH();
    1515       174112 :     oldcontext = MemoryContextSwitchTo(edata->assoc_context);
    1516              : 
    1517       174112 :     EVALUATE_MESSAGE(edata->domain, hint, false, true);
    1518              : 
    1519       174112 :     MemoryContextSwitchTo(oldcontext);
    1520       174112 :     recursion_depth--;
    1521       174112 :     return 0;                   /* return value does not matter */
    1522              : }
    1523              : 
    1524              : /*
    1525              :  * errhint_internal --- add a hint error message text to the current error
    1526              :  *
    1527              :  * Non-translated version of errhint(), see also errmsg_internal().
    1528              :  */
    1529              : int
    1530           36 : errhint_internal(const char *fmt,...)
    1531              : {
    1532           36 :     ErrorData  *edata = &errordata[errordata_stack_depth];
    1533              :     MemoryContext oldcontext;
    1534              : 
    1535           36 :     recursion_depth++;
    1536           36 :     CHECK_STACK_DEPTH();
    1537           36 :     oldcontext = MemoryContextSwitchTo(edata->assoc_context);
    1538              : 
    1539           36 :     EVALUATE_MESSAGE(edata->domain, hint, false, false);
    1540              : 
    1541           36 :     MemoryContextSwitchTo(oldcontext);
    1542           36 :     recursion_depth--;
    1543           36 :     return 0;                   /* return value does not matter */
    1544              : }
    1545              : 
    1546              : /*
    1547              :  * errhint_plural --- add a hint error message text to the current error,
    1548              :  * with support for pluralization of the message text
    1549              :  */
    1550              : int
    1551            4 : errhint_plural(const char *fmt_singular, const char *fmt_plural,
    1552              :                unsigned long n,...)
    1553              : {
    1554            4 :     ErrorData  *edata = &errordata[errordata_stack_depth];
    1555              :     MemoryContext oldcontext;
    1556              : 
    1557            4 :     recursion_depth++;
    1558            4 :     CHECK_STACK_DEPTH();
    1559            4 :     oldcontext = MemoryContextSwitchTo(edata->assoc_context);
    1560              : 
    1561            4 :     EVALUATE_MESSAGE_PLURAL(edata->domain, hint, false);
    1562              : 
    1563            4 :     MemoryContextSwitchTo(oldcontext);
    1564            4 :     recursion_depth--;
    1565            4 :     return 0;                   /* return value does not matter */
    1566              : }
    1567              : 
    1568              : 
    1569              : /*
    1570              :  * errcontext_msg --- add a context error message text to the current error
    1571              :  *
    1572              :  * Unlike other cases, multiple calls are allowed to build up a stack of
    1573              :  * context information.  We assume earlier calls represent more-closely-nested
    1574              :  * states.
    1575              :  */
    1576              : int
    1577        23651 : errcontext_msg(const char *fmt,...)
    1578              : {
    1579        23651 :     ErrorData  *edata = &errordata[errordata_stack_depth];
    1580              :     MemoryContext oldcontext;
    1581              : 
    1582        23651 :     recursion_depth++;
    1583        23651 :     CHECK_STACK_DEPTH();
    1584        23651 :     oldcontext = MemoryContextSwitchTo(edata->assoc_context);
    1585              : 
    1586        47321 :     EVALUATE_MESSAGE(edata->context_domain, context, true, true);
    1587              : 
    1588        23651 :     MemoryContextSwitchTo(oldcontext);
    1589        23651 :     recursion_depth--;
    1590        23651 :     return 0;                   /* return value does not matter */
    1591              : }
    1592              : 
    1593              : /*
    1594              :  * set_errcontext_domain --- set message domain to be used by errcontext()
    1595              :  *
    1596              :  * errcontext_msg() can be called from a different module than the original
    1597              :  * ereport(), so we cannot use the message domain passed in errstart() to
    1598              :  * translate it.  Instead, each errcontext_msg() call should be preceded by
    1599              :  * a set_errcontext_domain() call to specify the domain.  This is usually
    1600              :  * done transparently by the errcontext() macro.
    1601              :  */
    1602              : int
    1603        23651 : set_errcontext_domain(const char *domain)
    1604              : {
    1605        23651 :     ErrorData  *edata = &errordata[errordata_stack_depth];
    1606              : 
    1607              :     /* we don't bother incrementing recursion_depth */
    1608        23651 :     CHECK_STACK_DEPTH();
    1609              : 
    1610              :     /* the default text domain is the backend's */
    1611        23651 :     edata->context_domain = domain ? domain : PG_TEXTDOMAIN("postgres");
    1612              : 
    1613        23651 :     return 0;                   /* return value does not matter */
    1614              : }
    1615              : 
    1616              : 
    1617              : /*
    1618              :  * errhidestmt --- optionally suppress STATEMENT: field of log entry
    1619              :  *
    1620              :  * This should be called if the message text already includes the statement.
    1621              :  */
    1622              : int
    1623       151988 : errhidestmt(bool hide_stmt)
    1624              : {
    1625       151988 :     ErrorData  *edata = &errordata[errordata_stack_depth];
    1626              : 
    1627              :     /* we don't bother incrementing recursion_depth */
    1628       151988 :     CHECK_STACK_DEPTH();
    1629              : 
    1630       151988 :     edata->hide_stmt = hide_stmt;
    1631              : 
    1632       151988 :     return 0;                   /* return value does not matter */
    1633              : }
    1634              : 
    1635              : /*
    1636              :  * errhidecontext --- optionally suppress CONTEXT: field of log entry
    1637              :  *
    1638              :  * This should only be used for verbose debugging messages where the repeated
    1639              :  * inclusion of context would bloat the log volume too much.
    1640              :  */
    1641              : int
    1642         9987 : errhidecontext(bool hide_ctx)
    1643              : {
    1644         9987 :     ErrorData  *edata = &errordata[errordata_stack_depth];
    1645              : 
    1646              :     /* we don't bother incrementing recursion_depth */
    1647         9987 :     CHECK_STACK_DEPTH();
    1648              : 
    1649         9987 :     edata->hide_ctx = hide_ctx;
    1650              : 
    1651         9987 :     return 0;                   /* return value does not matter */
    1652              : }
    1653              : 
    1654              : /*
    1655              :  * errposition --- add cursor position to the current error
    1656              :  */
    1657              : int
    1658         6278 : errposition(int cursorpos)
    1659              : {
    1660         6278 :     ErrorData  *edata = &errordata[errordata_stack_depth];
    1661              : 
    1662              :     /* we don't bother incrementing recursion_depth */
    1663         6278 :     CHECK_STACK_DEPTH();
    1664              : 
    1665         6278 :     edata->cursorpos = cursorpos;
    1666              : 
    1667         6278 :     return 0;                   /* return value does not matter */
    1668              : }
    1669              : 
    1670              : /*
    1671              :  * internalerrposition --- add internal cursor position to the current error
    1672              :  */
    1673              : int
    1674          245 : internalerrposition(int cursorpos)
    1675              : {
    1676          245 :     ErrorData  *edata = &errordata[errordata_stack_depth];
    1677              : 
    1678              :     /* we don't bother incrementing recursion_depth */
    1679          245 :     CHECK_STACK_DEPTH();
    1680              : 
    1681          245 :     edata->internalpos = cursorpos;
    1682              : 
    1683          245 :     return 0;                   /* return value does not matter */
    1684              : }
    1685              : 
    1686              : /*
    1687              :  * internalerrquery --- add internal query text to the current error
    1688              :  *
    1689              :  * Can also pass NULL to drop the internal query text entry.  This case
    1690              :  * is intended for use in error callback subroutines that are editorializing
    1691              :  * on the layout of the error report.
    1692              :  */
    1693              : int
    1694          239 : internalerrquery(const char *query)
    1695              : {
    1696          239 :     ErrorData  *edata = &errordata[errordata_stack_depth];
    1697              : 
    1698              :     /* we don't bother incrementing recursion_depth */
    1699          239 :     CHECK_STACK_DEPTH();
    1700              : 
    1701          239 :     if (edata->internalquery)
    1702              :     {
    1703           83 :         pfree(edata->internalquery);
    1704           83 :         edata->internalquery = NULL;
    1705              :     }
    1706              : 
    1707          239 :     if (query)
    1708          147 :         edata->internalquery = MemoryContextStrdup(edata->assoc_context, query);
    1709              : 
    1710          239 :     return 0;                   /* return value does not matter */
    1711              : }
    1712              : 
    1713              : /*
    1714              :  * err_generic_string -- used to set individual ErrorData string fields
    1715              :  * identified by PG_DIAG_xxx codes.
    1716              :  *
    1717              :  * This intentionally only supports fields that don't use localized strings,
    1718              :  * so that there are no translation considerations.
    1719              :  *
    1720              :  * Most potential callers should not use this directly, but instead prefer
    1721              :  * higher-level abstractions, such as errtablecol() (see relcache.c).
    1722              :  */
    1723              : int
    1724         6414 : err_generic_string(int field, const char *str)
    1725              : {
    1726         6414 :     ErrorData  *edata = &errordata[errordata_stack_depth];
    1727              : 
    1728              :     /* we don't bother incrementing recursion_depth */
    1729         6414 :     CHECK_STACK_DEPTH();
    1730              : 
    1731         6414 :     switch (field)
    1732              :     {
    1733         2247 :         case PG_DIAG_SCHEMA_NAME:
    1734         2247 :             set_errdata_field(edata->assoc_context, &edata->schema_name, str);
    1735         2247 :             break;
    1736         1845 :         case PG_DIAG_TABLE_NAME:
    1737         1845 :             set_errdata_field(edata->assoc_context, &edata->table_name, str);
    1738         1845 :             break;
    1739          285 :         case PG_DIAG_COLUMN_NAME:
    1740          285 :             set_errdata_field(edata->assoc_context, &edata->column_name, str);
    1741          285 :             break;
    1742          419 :         case PG_DIAG_DATATYPE_NAME:
    1743          419 :             set_errdata_field(edata->assoc_context, &edata->datatype_name, str);
    1744          419 :             break;
    1745         1618 :         case PG_DIAG_CONSTRAINT_NAME:
    1746         1618 :             set_errdata_field(edata->assoc_context, &edata->constraint_name, str);
    1747         1618 :             break;
    1748            0 :         default:
    1749            0 :             elog(ERROR, "unsupported ErrorData field id: %d", field);
    1750              :             break;
    1751              :     }
    1752              : 
    1753         6414 :     return 0;                   /* return value does not matter */
    1754              : }
    1755              : 
    1756              : /*
    1757              :  * set_errdata_field --- set an ErrorData string field
    1758              :  */
    1759              : static void
    1760         6414 : set_errdata_field(MemoryContextData *cxt, char **ptr, const char *str)
    1761              : {
    1762              :     Assert(*ptr == NULL);
    1763         6414 :     *ptr = MemoryContextStrdup(cxt, str);
    1764         6414 : }
    1765              : 
    1766              : /*
    1767              :  * geterrcode --- return the currently set SQLSTATE error code
    1768              :  *
    1769              :  * This is only intended for use in error callback subroutines, since there
    1770              :  * is no other place outside elog.c where the concept is meaningful.
    1771              :  */
    1772              : int
    1773         3189 : geterrcode(void)
    1774              : {
    1775         3189 :     ErrorData  *edata = &errordata[errordata_stack_depth];
    1776              : 
    1777              :     /* we don't bother incrementing recursion_depth */
    1778         3189 :     CHECK_STACK_DEPTH();
    1779              : 
    1780         3189 :     return edata->sqlerrcode;
    1781              : }
    1782              : 
    1783              : /*
    1784              :  * geterrposition --- return the currently set error position (0 if none)
    1785              :  *
    1786              :  * This is only intended for use in error callback subroutines, since there
    1787              :  * is no other place outside elog.c where the concept is meaningful.
    1788              :  */
    1789              : int
    1790         7496 : geterrposition(void)
    1791              : {
    1792         7496 :     ErrorData  *edata = &errordata[errordata_stack_depth];
    1793              : 
    1794              :     /* we don't bother incrementing recursion_depth */
    1795         7496 :     CHECK_STACK_DEPTH();
    1796              : 
    1797         7496 :     return edata->cursorpos;
    1798              : }
    1799              : 
    1800              : /*
    1801              :  * getinternalerrposition --- same for internal error position
    1802              :  *
    1803              :  * This is only intended for use in error callback subroutines, since there
    1804              :  * is no other place outside elog.c where the concept is meaningful.
    1805              :  */
    1806              : int
    1807          124 : getinternalerrposition(void)
    1808              : {
    1809          124 :     ErrorData  *edata = &errordata[errordata_stack_depth];
    1810              : 
    1811              :     /* we don't bother incrementing recursion_depth */
    1812          124 :     CHECK_STACK_DEPTH();
    1813              : 
    1814          124 :     return edata->internalpos;
    1815              : }
    1816              : 
    1817              : 
    1818              : /*
    1819              :  * Functions to allow construction of error message strings separately from
    1820              :  * the ereport() call itself.
    1821              :  *
    1822              :  * The expected calling convention is
    1823              :  *
    1824              :  *  pre_format_elog_string(errno, domain), var = format_elog_string(format,...)
    1825              :  *
    1826              :  * which can be hidden behind a macro such as GUC_check_errdetail().  We
    1827              :  * assume that any functions called in the arguments of format_elog_string()
    1828              :  * cannot result in re-entrant use of these functions --- otherwise the wrong
    1829              :  * text domain might be used, or the wrong errno substituted for %m.  This is
    1830              :  * okay for the current usage with GUC check hooks, but might need further
    1831              :  * effort someday.
    1832              :  *
    1833              :  * The result of format_elog_string() is stored in ErrorContext, and will
    1834              :  * therefore survive until FlushErrorState() is called.
    1835              :  */
    1836              : static int  save_format_errnumber;
    1837              : static const char *save_format_domain;
    1838              : 
    1839              : void
    1840           55 : pre_format_elog_string(int errnumber, const char *domain)
    1841              : {
    1842              :     /* Save errno before evaluation of argument functions can change it */
    1843           55 :     save_format_errnumber = errnumber;
    1844              :     /* Save caller's text domain */
    1845           55 :     save_format_domain = domain;
    1846           55 : }
    1847              : 
    1848              : char *
    1849           55 : format_elog_string(const char *fmt,...)
    1850              : {
    1851              :     ErrorData   errdata;
    1852              :     ErrorData  *edata;
    1853              :     MemoryContext oldcontext;
    1854              : 
    1855              :     /* Initialize a mostly-dummy error frame */
    1856           55 :     edata = &errdata;
    1857         1320 :     MemSet(edata, 0, sizeof(ErrorData));
    1858              :     /* the default text domain is the backend's */
    1859           55 :     edata->domain = save_format_domain ? save_format_domain : PG_TEXTDOMAIN("postgres");
    1860              :     /* set the errno to be used to interpret %m */
    1861           55 :     edata->saved_errno = save_format_errnumber;
    1862              : 
    1863           55 :     oldcontext = MemoryContextSwitchTo(ErrorContext);
    1864              : 
    1865           55 :     edata->message_id = fmt;
    1866           55 :     EVALUATE_MESSAGE(edata->domain, message, false, true);
    1867              : 
    1868           55 :     MemoryContextSwitchTo(oldcontext);
    1869              : 
    1870           55 :     return edata->message;
    1871              : }
    1872              : 
    1873              : 
    1874              : /*
    1875              :  * Actual output of the top-of-stack error message
    1876              :  *
    1877              :  * In the ereport(ERROR) case this is called from PostgresMain (or not at all,
    1878              :  * if the error is caught by somebody).  For all other severity levels this
    1879              :  * is called by errfinish.
    1880              :  */
    1881              : void
    1882       507779 : EmitErrorReport(void)
    1883              : {
    1884       507779 :     ErrorData  *edata = &errordata[errordata_stack_depth];
    1885              :     MemoryContext oldcontext;
    1886              : 
    1887       507779 :     recursion_depth++;
    1888       507779 :     CHECK_STACK_DEPTH();
    1889       507779 :     oldcontext = MemoryContextSwitchTo(edata->assoc_context);
    1890              : 
    1891              :     /*
    1892              :      * Reset the formatted timestamp fields before emitting any logs.  This
    1893              :      * includes all the log destinations and emit_log_hook, as the latter
    1894              :      * could use log_line_prefix or the formatted timestamps.
    1895              :      */
    1896       507779 :     saved_timeval_set = false;
    1897       507779 :     formatted_log_time[0] = '\0';
    1898              : 
    1899              :     /*
    1900              :      * Call hook before sending message to log.  The hook function is allowed
    1901              :      * to turn off edata->output_to_server, so we must recheck that afterward.
    1902              :      * Making any other change in the content of edata is not considered
    1903              :      * supported.
    1904              :      *
    1905              :      * Note: the reason why the hook can only turn off output_to_server, and
    1906              :      * not turn it on, is that it'd be unreliable: we will never get here at
    1907              :      * all if errstart() deems the message uninteresting.  A hook that could
    1908              :      * make decisions in that direction would have to hook into errstart(),
    1909              :      * where it would have much less information available.  emit_log_hook is
    1910              :      * intended for custom log filtering and custom log message transmission
    1911              :      * mechanisms.
    1912              :      *
    1913              :      * The log hook has access to both the translated and original English
    1914              :      * error message text, which is passed through to allow it to be used as a
    1915              :      * message identifier. Note that the original text is not available for
    1916              :      * detail, detail_log, hint and context text elements.
    1917              :      */
    1918       507779 :     if (edata->output_to_server && emit_log_hook)
    1919            0 :         (*emit_log_hook) (edata);
    1920              : 
    1921              :     /* Send to server log, if enabled */
    1922       507779 :     if (edata->output_to_server)
    1923       495401 :         send_message_to_server_log(edata);
    1924              : 
    1925              :     /* Send to client, if enabled */
    1926       507779 :     if (edata->output_to_client)
    1927       102142 :         send_message_to_frontend(edata);
    1928              : 
    1929       507779 :     MemoryContextSwitchTo(oldcontext);
    1930       507779 :     recursion_depth--;
    1931       507779 : }
    1932              : 
    1933              : /*
    1934              :  * CopyErrorData --- obtain a copy of the topmost error stack entry
    1935              :  *
    1936              :  * This is only for use in error handler code.  The data is copied into the
    1937              :  * current memory context, so callers should always switch away from
    1938              :  * ErrorContext first; otherwise it will be lost when FlushErrorState is done.
    1939              :  */
    1940              : ErrorData *
    1941         3217 : CopyErrorData(void)
    1942              : {
    1943         3217 :     ErrorData  *edata = &errordata[errordata_stack_depth];
    1944              :     ErrorData  *newedata;
    1945              : 
    1946              :     /*
    1947              :      * we don't increment recursion_depth because out-of-memory here does not
    1948              :      * indicate a problem within the error subsystem.
    1949              :      */
    1950         3217 :     CHECK_STACK_DEPTH();
    1951              : 
    1952              :     Assert(CurrentMemoryContext != ErrorContext);
    1953              : 
    1954              :     /* Copy the struct itself */
    1955         3217 :     newedata = palloc_object(ErrorData);
    1956         3217 :     memcpy(newedata, edata, sizeof(ErrorData));
    1957              : 
    1958              :     /*
    1959              :      * Make copies of separately-allocated strings.  Note that we copy even
    1960              :      * theoretically-constant strings such as filename.  This is because those
    1961              :      * could point into JIT-created code segments that might get unloaded at
    1962              :      * transaction cleanup.  In some cases we need the copied ErrorData to
    1963              :      * survive transaction boundaries, so we'd better copy those strings too.
    1964              :      */
    1965         3217 :     if (newedata->filename)
    1966         3217 :         newedata->filename = pstrdup(newedata->filename);
    1967         3217 :     if (newedata->funcname)
    1968         3217 :         newedata->funcname = pstrdup(newedata->funcname);
    1969         3217 :     if (newedata->domain)
    1970         3217 :         newedata->domain = pstrdup(newedata->domain);
    1971         3217 :     if (newedata->context_domain)
    1972         3217 :         newedata->context_domain = pstrdup(newedata->context_domain);
    1973         3217 :     if (newedata->message)
    1974         3217 :         newedata->message = pstrdup(newedata->message);
    1975         3217 :     if (newedata->detail)
    1976           88 :         newedata->detail = pstrdup(newedata->detail);
    1977         3217 :     if (newedata->detail_log)
    1978            0 :         newedata->detail_log = pstrdup(newedata->detail_log);
    1979         3217 :     if (newedata->hint)
    1980           22 :         newedata->hint = pstrdup(newedata->hint);
    1981         3217 :     if (newedata->context)
    1982         3198 :         newedata->context = pstrdup(newedata->context);
    1983         3217 :     if (newedata->backtrace)
    1984            0 :         newedata->backtrace = pstrdup(newedata->backtrace);
    1985         3217 :     if (newedata->message_id)
    1986         3217 :         newedata->message_id = pstrdup(newedata->message_id);
    1987         3217 :     if (newedata->schema_name)
    1988           28 :         newedata->schema_name = pstrdup(newedata->schema_name);
    1989         3217 :     if (newedata->table_name)
    1990           30 :         newedata->table_name = pstrdup(newedata->table_name);
    1991         3217 :     if (newedata->column_name)
    1992            9 :         newedata->column_name = pstrdup(newedata->column_name);
    1993         3217 :     if (newedata->datatype_name)
    1994           10 :         newedata->datatype_name = pstrdup(newedata->datatype_name);
    1995         3217 :     if (newedata->constraint_name)
    1996           27 :         newedata->constraint_name = pstrdup(newedata->constraint_name);
    1997         3217 :     if (newedata->internalquery)
    1998           17 :         newedata->internalquery = pstrdup(newedata->internalquery);
    1999              : 
    2000              :     /* Use the calling context for string allocation */
    2001         3217 :     newedata->assoc_context = CurrentMemoryContext;
    2002              : 
    2003         3217 :     return newedata;
    2004              : }
    2005              : 
    2006              : /*
    2007              :  * FreeErrorData --- free the structure returned by CopyErrorData.
    2008              :  *
    2009              :  * Error handlers should use this in preference to assuming they know all
    2010              :  * the separately-allocated fields.
    2011              :  */
    2012              : void
    2013           71 : FreeErrorData(ErrorData *edata)
    2014              : {
    2015           71 :     FreeErrorDataContents(edata);
    2016           71 :     pfree(edata);
    2017           71 : }
    2018              : 
    2019              : /*
    2020              :  * FreeErrorDataContents --- free the subsidiary data of an ErrorData.
    2021              :  *
    2022              :  * This can be used on either an error stack entry or a copied ErrorData.
    2023              :  */
    2024              : static void
    2025          105 : FreeErrorDataContents(ErrorData *edata)
    2026              : {
    2027          105 :     if (edata->message)
    2028          105 :         pfree(edata->message);
    2029          105 :     if (edata->detail)
    2030           19 :         pfree(edata->detail);
    2031          105 :     if (edata->detail_log)
    2032            0 :         pfree(edata->detail_log);
    2033          105 :     if (edata->hint)
    2034            8 :         pfree(edata->hint);
    2035          105 :     if (edata->context)
    2036           54 :         pfree(edata->context);
    2037          105 :     if (edata->backtrace)
    2038            0 :         pfree(edata->backtrace);
    2039          105 :     if (edata->schema_name)
    2040           12 :         pfree(edata->schema_name);
    2041          105 :     if (edata->table_name)
    2042           14 :         pfree(edata->table_name);
    2043          105 :     if (edata->column_name)
    2044            5 :         pfree(edata->column_name);
    2045          105 :     if (edata->datatype_name)
    2046            6 :         pfree(edata->datatype_name);
    2047          105 :     if (edata->constraint_name)
    2048           11 :         pfree(edata->constraint_name);
    2049          105 :     if (edata->internalquery)
    2050           14 :         pfree(edata->internalquery);
    2051          105 : }
    2052              : 
    2053              : /*
    2054              :  * FlushErrorState --- flush the error state after error recovery
    2055              :  *
    2056              :  * This should be called by an error handler after it's done processing
    2057              :  * the error; or as soon as it's done CopyErrorData, if it intends to
    2058              :  * do stuff that is likely to provoke another error.  You are not "out" of
    2059              :  * the error subsystem until you have done this.
    2060              :  */
    2061              : void
    2062        26007 : FlushErrorState(void)
    2063              : {
    2064              :     /*
    2065              :      * Reset stack to empty.  The only case where it would be more than one
    2066              :      * deep is if we serviced an error that interrupted construction of
    2067              :      * another message.  We assume control escaped out of that message
    2068              :      * construction and won't ever go back.
    2069              :      */
    2070        26007 :     errordata_stack_depth = -1;
    2071        26007 :     recursion_depth = 0;
    2072              :     /* Delete all data in ErrorContext */
    2073        26007 :     MemoryContextReset(ErrorContext);
    2074        26007 : }
    2075              : 
    2076              : /*
    2077              :  * ThrowErrorData --- report an error described by an ErrorData structure
    2078              :  *
    2079              :  * This function should be called on an ErrorData structure that isn't stored
    2080              :  * on the errordata stack and hasn't been processed yet. It will call
    2081              :  * errstart() and errfinish() as needed, so those should not have already been
    2082              :  * called.
    2083              :  *
    2084              :  * ThrowErrorData() is useful for handling soft errors. It's also useful for
    2085              :  * re-reporting errors originally reported by background worker processes and
    2086              :  * then propagated (with or without modification) to the backend responsible
    2087              :  * for them.
    2088              :  */
    2089              : void
    2090            9 : ThrowErrorData(ErrorData *edata)
    2091              : {
    2092              :     ErrorData  *newedata;
    2093              :     MemoryContext oldcontext;
    2094              : 
    2095            9 :     if (!errstart(edata->elevel, edata->domain))
    2096            0 :         return;                 /* error is not to be reported at all */
    2097              : 
    2098            9 :     newedata = &errordata[errordata_stack_depth];
    2099            9 :     recursion_depth++;
    2100            9 :     oldcontext = MemoryContextSwitchTo(newedata->assoc_context);
    2101              : 
    2102              :     /* Copy the supplied fields to the error stack entry. */
    2103            9 :     if (edata->sqlerrcode != 0)
    2104            9 :         newedata->sqlerrcode = edata->sqlerrcode;
    2105            9 :     if (edata->message)
    2106            9 :         newedata->message = pstrdup(edata->message);
    2107            9 :     if (edata->detail)
    2108            0 :         newedata->detail = pstrdup(edata->detail);
    2109            9 :     if (edata->detail_log)
    2110            0 :         newedata->detail_log = pstrdup(edata->detail_log);
    2111            9 :     if (edata->hint)
    2112            0 :         newedata->hint = pstrdup(edata->hint);
    2113            9 :     if (edata->context)
    2114            6 :         newedata->context = pstrdup(edata->context);
    2115            9 :     if (edata->backtrace)
    2116            0 :         newedata->backtrace = pstrdup(edata->backtrace);
    2117              :     /* assume message_id is not available */
    2118            9 :     if (edata->schema_name)
    2119            0 :         newedata->schema_name = pstrdup(edata->schema_name);
    2120            9 :     if (edata->table_name)
    2121            0 :         newedata->table_name = pstrdup(edata->table_name);
    2122            9 :     if (edata->column_name)
    2123            0 :         newedata->column_name = pstrdup(edata->column_name);
    2124            9 :     if (edata->datatype_name)
    2125            0 :         newedata->datatype_name = pstrdup(edata->datatype_name);
    2126            9 :     if (edata->constraint_name)
    2127            0 :         newedata->constraint_name = pstrdup(edata->constraint_name);
    2128            9 :     newedata->cursorpos = edata->cursorpos;
    2129            9 :     newedata->internalpos = edata->internalpos;
    2130            9 :     if (edata->internalquery)
    2131            0 :         newedata->internalquery = pstrdup(edata->internalquery);
    2132              : 
    2133            9 :     MemoryContextSwitchTo(oldcontext);
    2134            9 :     recursion_depth--;
    2135              : 
    2136              :     /* Process the error. */
    2137            9 :     errfinish(edata->filename, edata->lineno, edata->funcname);
    2138              : }
    2139              : 
    2140              : /*
    2141              :  * ReThrowError --- re-throw a previously copied error
    2142              :  *
    2143              :  * A handler can do CopyErrorData/FlushErrorState to get out of the error
    2144              :  * subsystem, then do some processing, and finally ReThrowError to re-throw
    2145              :  * the original error.  This is slower than just PG_RE_THROW() but should
    2146              :  * be used if the "some processing" is likely to incur another error.
    2147              :  */
    2148              : void
    2149           32 : ReThrowError(ErrorData *edata)
    2150              : {
    2151              :     ErrorData  *newedata;
    2152              : 
    2153              :     Assert(edata->elevel == ERROR);
    2154              : 
    2155              :     /* Push the data back into the error context */
    2156           32 :     recursion_depth++;
    2157           32 :     MemoryContextSwitchTo(ErrorContext);
    2158              : 
    2159           32 :     newedata = get_error_stack_entry();
    2160           32 :     memcpy(newedata, edata, sizeof(ErrorData));
    2161              : 
    2162              :     /* Make copies of separately-allocated fields */
    2163           32 :     if (newedata->message)
    2164           32 :         newedata->message = pstrdup(newedata->message);
    2165           32 :     if (newedata->detail)
    2166           19 :         newedata->detail = pstrdup(newedata->detail);
    2167           32 :     if (newedata->detail_log)
    2168            0 :         newedata->detail_log = pstrdup(newedata->detail_log);
    2169           32 :     if (newedata->hint)
    2170            0 :         newedata->hint = pstrdup(newedata->hint);
    2171           32 :     if (newedata->context)
    2172           30 :         newedata->context = pstrdup(newedata->context);
    2173           32 :     if (newedata->backtrace)
    2174            0 :         newedata->backtrace = pstrdup(newedata->backtrace);
    2175           32 :     if (newedata->schema_name)
    2176            7 :         newedata->schema_name = pstrdup(newedata->schema_name);
    2177           32 :     if (newedata->table_name)
    2178            7 :         newedata->table_name = pstrdup(newedata->table_name);
    2179           32 :     if (newedata->column_name)
    2180            0 :         newedata->column_name = pstrdup(newedata->column_name);
    2181           32 :     if (newedata->datatype_name)
    2182            0 :         newedata->datatype_name = pstrdup(newedata->datatype_name);
    2183           32 :     if (newedata->constraint_name)
    2184            7 :         newedata->constraint_name = pstrdup(newedata->constraint_name);
    2185           32 :     if (newedata->internalquery)
    2186            0 :         newedata->internalquery = pstrdup(newedata->internalquery);
    2187              : 
    2188              :     /* Reset the assoc_context to be ErrorContext */
    2189           32 :     newedata->assoc_context = ErrorContext;
    2190              : 
    2191           32 :     recursion_depth--;
    2192           32 :     PG_RE_THROW();
    2193              : }
    2194              : 
    2195              : /*
    2196              :  * pg_re_throw --- out-of-line implementation of PG_RE_THROW() macro
    2197              :  */
    2198              : void
    2199        57228 : pg_re_throw(void)
    2200              : {
    2201              :     /* If possible, throw the error to the next outer setjmp handler */
    2202        57228 :     if (PG_exception_stack != NULL)
    2203        57228 :         siglongjmp(*PG_exception_stack, 1);
    2204              :     else
    2205              :     {
    2206              :         /*
    2207              :          * If we get here, elog(ERROR) was thrown inside a PG_TRY block, which
    2208              :          * we have now exited only to discover that there is no outer setjmp
    2209              :          * handler to pass the error to.  Had the error been thrown outside
    2210              :          * the block to begin with, we'd have promoted the error to FATAL, so
    2211              :          * the correct behavior is to make it FATAL now; that is, emit it and
    2212              :          * then call proc_exit.
    2213              :          */
    2214            0 :         ErrorData  *edata = &errordata[errordata_stack_depth];
    2215              : 
    2216              :         Assert(errordata_stack_depth >= 0);
    2217              :         Assert(edata->elevel == ERROR);
    2218            0 :         edata->elevel = FATAL;
    2219              : 
    2220              :         /*
    2221              :          * At least in principle, the increase in severity could have changed
    2222              :          * where-to-output decisions, so recalculate.
    2223              :          */
    2224            0 :         edata->output_to_server = should_output_to_server(FATAL);
    2225            0 :         edata->output_to_client = should_output_to_client(FATAL);
    2226              : 
    2227              :         /*
    2228              :          * We can use errfinish() for the rest, but we don't want it to call
    2229              :          * any error context routines a second time.  Since we know we are
    2230              :          * about to exit, it should be OK to just clear the context stack.
    2231              :          */
    2232            0 :         error_context_stack = NULL;
    2233              : 
    2234            0 :         errfinish(edata->filename, edata->lineno, edata->funcname);
    2235              :     }
    2236              : 
    2237              :     /* Doesn't return ... */
    2238            0 :     ExceptionalCondition("pg_re_throw tried to return", __FILE__, __LINE__);
    2239              : }
    2240              : 
    2241              : 
    2242              : /*
    2243              :  * GetErrorContextStack - Return the context stack, for display/diags
    2244              :  *
    2245              :  * Returns a pstrdup'd string in the caller's context which includes the PG
    2246              :  * error call stack.  It is the caller's responsibility to ensure this string
    2247              :  * is pfree'd (or its context cleaned up) when done.
    2248              :  *
    2249              :  * This information is collected by traversing the error contexts and calling
    2250              :  * each context's callback function, each of which is expected to call
    2251              :  * errcontext() to return a string which can be presented to the user.
    2252              :  */
    2253              : char *
    2254           24 : GetErrorContextStack(void)
    2255              : {
    2256              :     ErrorData  *edata;
    2257              :     ErrorContextCallback *econtext;
    2258              : 
    2259              :     /*
    2260              :      * Crank up a stack entry to store the info in.
    2261              :      */
    2262           24 :     recursion_depth++;
    2263              : 
    2264           24 :     edata = get_error_stack_entry();
    2265              : 
    2266              :     /*
    2267              :      * Set up assoc_context to be the caller's context, so any allocations
    2268              :      * done (which will include edata->context) will use their context.
    2269              :      */
    2270           24 :     edata->assoc_context = CurrentMemoryContext;
    2271              : 
    2272              :     /*
    2273              :      * Call any context callback functions to collect the context information
    2274              :      * into edata->context.
    2275              :      *
    2276              :      * Errors occurring in callback functions should go through the regular
    2277              :      * error handling code which should handle any recursive errors, though we
    2278              :      * double-check above, just in case.
    2279              :      */
    2280           24 :     for (econtext = error_context_stack;
    2281           96 :          econtext != NULL;
    2282           72 :          econtext = econtext->previous)
    2283           72 :         econtext->callback(econtext->arg);
    2284              : 
    2285              :     /*
    2286              :      * Clean ourselves off the stack, any allocations done should have been
    2287              :      * using edata->assoc_context, which we set up earlier to be the caller's
    2288              :      * context, so we're free to just remove our entry off the stack and
    2289              :      * decrement recursion depth and exit.
    2290              :      */
    2291           24 :     errordata_stack_depth--;
    2292           24 :     recursion_depth--;
    2293              : 
    2294              :     /*
    2295              :      * Return a pointer to the string the caller asked for, which should have
    2296              :      * been allocated in their context.
    2297              :      */
    2298           24 :     return edata->context;
    2299              : }
    2300              : 
    2301              : 
    2302              : /*
    2303              :  * Initialization of error output file
    2304              :  */
    2305              : void
    2306        23238 : DebugFileOpen(void)
    2307              : {
    2308              :     int         fd,
    2309              :                 istty;
    2310              : 
    2311        23238 :     if (OutputFileName[0])
    2312              :     {
    2313              :         /*
    2314              :          * A debug-output file name was given.
    2315              :          *
    2316              :          * Make sure we can write the file, and find out if it's a tty.
    2317              :          */
    2318            0 :         if ((fd = open(OutputFileName, O_CREAT | O_APPEND | O_WRONLY,
    2319              :                        0666)) < 0)
    2320            0 :             ereport(FATAL,
    2321              :                     (errcode_for_file_access(),
    2322              :                      errmsg("could not open file \"%s\": %m", OutputFileName)));
    2323            0 :         istty = isatty(fd);
    2324            0 :         close(fd);
    2325              : 
    2326              :         /*
    2327              :          * Redirect our stderr to the debug output file.
    2328              :          */
    2329            0 :         if (!freopen(OutputFileName, "a", stderr))
    2330            0 :             ereport(FATAL,
    2331              :                     (errcode_for_file_access(),
    2332              :                      errmsg("could not reopen file \"%s\" as stderr: %m",
    2333              :                             OutputFileName)));
    2334              : 
    2335              :         /*
    2336              :          * If the file is a tty and we're running under the postmaster, try to
    2337              :          * send stdout there as well (if it isn't a tty then stderr will block
    2338              :          * out stdout, so we may as well let stdout go wherever it was going
    2339              :          * before).
    2340              :          */
    2341            0 :         if (istty && IsUnderPostmaster)
    2342            0 :             if (!freopen(OutputFileName, "a", stdout))
    2343            0 :                 ereport(FATAL,
    2344              :                         (errcode_for_file_access(),
    2345              :                          errmsg("could not reopen file \"%s\" as stdout: %m",
    2346              :                                 OutputFileName)));
    2347              :     }
    2348        23238 : }
    2349              : 
    2350              : 
    2351              : /*
    2352              :  * GUC check_hook for log_min_messages
    2353              :  *
    2354              :  * This value is parsed as a comma-separated list of zero or more TYPE:LEVEL
    2355              :  * elements.  For each element, TYPE corresponds to a bk_category value (see
    2356              :  * postmaster/proctypelist.h); LEVEL is one of server_message_level_options.
    2357              :  *
    2358              :  * In addition, there must be a single LEVEL element (with no TYPE part)
    2359              :  * which sets the default level for process types that aren't specified.
    2360              :  */
    2361              : bool
    2362         1610 : check_log_min_messages(char **newval, void **extra, GucSource source)
    2363              : {
    2364              :     char       *rawstring;
    2365              :     List       *elemlist;
    2366              :     StringInfoData buf;
    2367              :     char       *result;
    2368              :     int         newlevel[BACKEND_NUM_TYPES];
    2369         1610 :     bool        assigned[BACKEND_NUM_TYPES] = {0};
    2370         1610 :     int         defaultlevel = -1;  /* -1 means not assigned */
    2371              : 
    2372         1610 :     const char *const process_types[] = {
    2373              : #define PG_PROCTYPE(bktype, bkcategory, description, main_func, shmem_attach) \
    2374              :         [bktype] = bkcategory,
    2375              : #include "postmaster/proctypelist.h"
    2376              : #undef PG_PROCTYPE
    2377              :     };
    2378              : 
    2379              :     /* Need a modifiable copy of string. */
    2380         1610 :     rawstring = guc_strdup(LOG, *newval);
    2381         1610 :     if (rawstring == NULL)
    2382            0 :         return false;
    2383              : 
    2384              :     /* Parse the string into a list. */
    2385         1610 :     if (!SplitGUCList(rawstring, ',', &elemlist))
    2386              :     {
    2387              :         /* syntax error in list */
    2388            0 :         GUC_check_errdetail("List syntax is invalid.");
    2389            0 :         list_free(elemlist);
    2390            0 :         guc_free(rawstring);
    2391            0 :         return false;
    2392              :     }
    2393              : 
    2394              :     /* Validate and assign log level and process type. */
    2395         4842 :     foreach_ptr(char, elem, elemlist)
    2396         1637 :     {
    2397         1652 :         char       *sep = strchr(elem, ':');
    2398              : 
    2399              :         /*
    2400              :          * If there's no ':' separator in the entry, this is the default log
    2401              :          * level.  Otherwise it's a process type-specific entry.
    2402              :          */
    2403         1652 :         if (sep == NULL)
    2404              :         {
    2405              :             const struct config_enum_entry *entry;
    2406              :             bool        found;
    2407              : 
    2408              :             /* Reject duplicates for default log level. */
    2409         1604 :             if (defaultlevel != -1)
    2410              :             {
    2411            3 :                 GUC_check_errdetail("Redundant specification of default log level.");
    2412            3 :                 goto lmm_fail;
    2413              :             }
    2414              : 
    2415              :             /* Validate the log level */
    2416         1601 :             found = false;
    2417        13389 :             for (entry = server_message_level_options; entry && entry->name; entry++)
    2418              :             {
    2419        13386 :                 if (pg_strcasecmp(entry->name, elem) == 0)
    2420              :                 {
    2421         1598 :                     defaultlevel = entry->val;
    2422         1598 :                     found = true;
    2423         1598 :                     break;
    2424              :                 }
    2425              :             }
    2426              : 
    2427         1601 :             if (!found)
    2428              :             {
    2429            3 :                 GUC_check_errdetail("Unrecognized log level: \"%s\".", elem);
    2430            3 :                 goto lmm_fail;
    2431              :             }
    2432              :         }
    2433              :         else
    2434              :         {
    2435           48 :             char       *loglevel = sep + 1;
    2436           48 :             char       *ptype = elem;
    2437              :             bool        found;
    2438              :             int         level;
    2439              :             const struct config_enum_entry *entry;
    2440              : 
    2441              :             /*
    2442              :              * Temporarily clobber the ':' with a string terminator, so that
    2443              :              * we can validate it.  We restore this at the bottom.
    2444              :              */
    2445           48 :             *sep = '\0';
    2446              : 
    2447              :             /* Validate the log level */
    2448           48 :             found = false;
    2449          357 :             for (entry = server_message_level_options; entry && entry->name; entry++)
    2450              :             {
    2451          354 :                 if (pg_strcasecmp(entry->name, loglevel) == 0)
    2452              :                 {
    2453           45 :                     level = entry->val;
    2454           45 :                     found = true;
    2455           45 :                     break;
    2456              :                 }
    2457              :             }
    2458              : 
    2459           48 :             if (!found)
    2460              :             {
    2461            3 :                 GUC_check_errdetail("Unrecognized log level for process type \"%s\": \"%s\".",
    2462              :                                     ptype, loglevel);
    2463            3 :                 goto lmm_fail;
    2464              :             }
    2465              : 
    2466              :             /* Is the process type name valid and unique? */
    2467           45 :             found = false;
    2468          804 :             for (int i = 0; i < BACKEND_NUM_TYPES; i++)
    2469              :             {
    2470          762 :                 if (pg_strcasecmp(process_types[i], ptype) == 0)
    2471              :                 {
    2472              :                     /* Reject duplicates for a process type. */
    2473           84 :                     if (assigned[i])
    2474              :                     {
    2475            3 :                         GUC_check_errdetail("Redundant log level specification for process type \"%s\".",
    2476              :                                             ptype);
    2477            3 :                         goto lmm_fail;
    2478              :                     }
    2479              : 
    2480           81 :                     newlevel[i] = level;
    2481           81 :                     assigned[i] = true;
    2482           81 :                     found = true;
    2483              : 
    2484              :                     /*
    2485              :                      * note: we must keep looking! some process types appear
    2486              :                      * multiple times in proctypelist.h.
    2487              :                      */
    2488              :                 }
    2489              :             }
    2490              : 
    2491           42 :             if (!found)
    2492              :             {
    2493            3 :                 GUC_check_errdetail("Unrecognized process type \"%s\".", ptype);
    2494            3 :                 goto lmm_fail;
    2495              :             }
    2496              : 
    2497              :             /* Put the separator back in place */
    2498           39 :             *sep = ':';
    2499              :         }
    2500              : 
    2501              :         /* all good */
    2502         1637 :         continue;
    2503              : 
    2504           15 : lmm_fail:
    2505           15 :         guc_free(rawstring);
    2506           15 :         list_free(elemlist);
    2507           15 :         return false;
    2508              :     }
    2509              : 
    2510              :     /*
    2511              :      * The default log level must be specified. It is the fallback value.
    2512              :      */
    2513         1595 :     if (defaultlevel == -1)
    2514              :     {
    2515            3 :         GUC_check_errdetail("Default log level was not defined.");
    2516            3 :         guc_free(rawstring);
    2517            3 :         list_free(elemlist);
    2518            3 :         return false;
    2519              :     }
    2520              : 
    2521              :     /* Apply the default log level to all processes not listed. */
    2522        30248 :     for (int i = 0; i < BACKEND_NUM_TYPES; i++)
    2523              :     {
    2524        28656 :         if (!assigned[i])
    2525        28620 :             newlevel[i] = defaultlevel;
    2526              :     }
    2527              : 
    2528              :     /*
    2529              :      * Save an ordered representation of the user-specified string, for the
    2530              :      * show_hook.
    2531              :      */
    2532         1592 :     list_sort(elemlist, log_min_messages_cmp);
    2533              : 
    2534         1592 :     initStringInfoExt(&buf, strlen(rawstring) + 1);
    2535         4797 :     foreach_ptr(char, elem, elemlist)
    2536              :     {
    2537         1613 :         if (foreach_current_index(elem) == 0)
    2538         1592 :             appendStringInfoString(&buf, elem);
    2539              :         else
    2540           21 :             appendStringInfo(&buf, ", %s", elem);
    2541              :     }
    2542              : 
    2543         1592 :     result = guc_strdup(LOG, buf.data);
    2544         1592 :     if (!result)
    2545              :     {
    2546            0 :         pfree(buf.data);
    2547            0 :         return false;
    2548              :     }
    2549              : 
    2550         1592 :     guc_free(*newval);
    2551         1592 :     *newval = result;
    2552              : 
    2553         1592 :     guc_free(rawstring);
    2554         1592 :     list_free(elemlist);
    2555         1592 :     pfree(buf.data);
    2556              : 
    2557              :     /*
    2558              :      * Pass back data for assign_log_min_messages to use.
    2559              :      */
    2560         1592 :     *extra = guc_malloc(LOG, BACKEND_NUM_TYPES * sizeof(int));
    2561         1592 :     if (!*extra)
    2562            0 :         return false;
    2563         1592 :     memcpy(*extra, newlevel, BACKEND_NUM_TYPES * sizeof(int));
    2564              : 
    2565         1592 :     return true;
    2566              : }
    2567              : 
    2568              : /*
    2569              :  * list_sort() callback for check_log_min_messages.  The default element
    2570              :  * goes first; the rest are ordered by strcmp() of the process type.
    2571              :  */
    2572              : static int
    2573           36 : log_min_messages_cmp(const ListCell *a, const ListCell *b)
    2574              : {
    2575           36 :     const char *s = lfirst(a);
    2576           36 :     const char *t = lfirst(b);
    2577              : 
    2578           36 :     if (strchr(s, ':') == NULL)
    2579            6 :         return -1;
    2580           30 :     else if (strchr(t, ':') == NULL)
    2581            9 :         return 1;
    2582              :     else
    2583           21 :         return strcmp(s, t);
    2584              : }
    2585              : 
    2586              : /*
    2587              :  * GUC assign_hook for log_min_messages
    2588              :  */
    2589              : void
    2590         1600 : assign_log_min_messages(const char *newval, void *extra)
    2591              : {
    2592        30400 :     for (int i = 0; i < BACKEND_NUM_TYPES; i++)
    2593        28800 :         log_min_messages[i] = ((int *) extra)[i];
    2594         1600 : }
    2595              : 
    2596              : /*
    2597              :  * GUC check_hook for backtrace_functions
    2598              :  *
    2599              :  * We split the input string, where commas separate function names
    2600              :  * and certain whitespace chars are ignored, into a \0-separated (and
    2601              :  * \0\0-terminated) list of function names.  This formulation allows
    2602              :  * easy scanning when an error is thrown while avoiding the use of
    2603              :  * non-reentrant strtok(), as well as keeping the output data in a
    2604              :  * single palloc() chunk.
    2605              :  */
    2606              : bool
    2607         1188 : check_backtrace_functions(char **newval, void **extra, GucSource source)
    2608              : {
    2609         1188 :     int         newvallen = strlen(*newval);
    2610              :     char       *someval;
    2611              :     int         validlen;
    2612              :     int         i;
    2613              :     int         j;
    2614              : 
    2615              :     /*
    2616              :      * Allow characters that can be C identifiers and commas as separators, as
    2617              :      * well as some whitespace for readability.
    2618              :      */
    2619         1188 :     validlen = strspn(*newval,
    2620              :                       "0123456789_"
    2621              :                       "abcdefghijklmnopqrstuvwxyz"
    2622              :                       "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
    2623              :                       ", \n\t");
    2624         1188 :     if (validlen != newvallen)
    2625              :     {
    2626            0 :         GUC_check_errdetail("Invalid character.");
    2627            0 :         return false;
    2628              :     }
    2629              : 
    2630         1188 :     if (*newval[0] == '\0')
    2631              :     {
    2632         1188 :         *extra = NULL;
    2633         1188 :         return true;
    2634              :     }
    2635              : 
    2636              :     /*
    2637              :      * Allocate space for the output and create the copy.  We could discount
    2638              :      * whitespace chars to save some memory, but it doesn't seem worth the
    2639              :      * trouble.
    2640              :      */
    2641            0 :     someval = guc_malloc(LOG, newvallen + 1 + 1);
    2642            0 :     if (!someval)
    2643            0 :         return false;
    2644            0 :     for (i = 0, j = 0; i < newvallen; i++)
    2645              :     {
    2646            0 :         if ((*newval)[i] == ',')
    2647            0 :             someval[j++] = '\0';    /* next item */
    2648            0 :         else if ((*newval)[i] == ' ' ||
    2649            0 :                  (*newval)[i] == '\n' ||
    2650            0 :                  (*newval)[i] == '\t')
    2651              :             ;                   /* ignore these */
    2652              :         else
    2653            0 :             someval[j++] = (*newval)[i];    /* copy anything else */
    2654              :     }
    2655              : 
    2656              :     /* two \0s end the setting */
    2657            0 :     someval[j] = '\0';
    2658            0 :     someval[j + 1] = '\0';
    2659              : 
    2660            0 :     *extra = someval;
    2661            0 :     return true;
    2662              : }
    2663              : 
    2664              : /*
    2665              :  * GUC assign_hook for backtrace_functions
    2666              :  */
    2667              : void
    2668         1188 : assign_backtrace_functions(const char *newval, void *extra)
    2669              : {
    2670         1188 :     backtrace_function_list = (char *) extra;
    2671         1188 : }
    2672              : 
    2673              : /*
    2674              :  * GUC check_hook for log_destination
    2675              :  */
    2676              : bool
    2677         1189 : check_log_destination(char **newval, void **extra, GucSource source)
    2678              : {
    2679              :     char       *rawstring;
    2680              :     List       *elemlist;
    2681              :     ListCell   *l;
    2682         1189 :     int         newlogdest = 0;
    2683              :     int        *myextra;
    2684              : 
    2685              :     /* Need a modifiable copy of string */
    2686         1189 :     rawstring = pstrdup(*newval);
    2687              : 
    2688              :     /* Parse string into list of identifiers */
    2689         1189 :     if (!SplitIdentifierString(rawstring, ',', &elemlist))
    2690              :     {
    2691              :         /* syntax error in list */
    2692            0 :         GUC_check_errdetail("List syntax is invalid.");
    2693            0 :         pfree(rawstring);
    2694            0 :         list_free(elemlist);
    2695            0 :         return false;
    2696              :     }
    2697              : 
    2698         2380 :     foreach(l, elemlist)
    2699              :     {
    2700         1191 :         char       *tok = (char *) lfirst(l);
    2701              : 
    2702         1191 :         if (pg_strcasecmp(tok, "stderr") == 0)
    2703         1189 :             newlogdest |= LOG_DESTINATION_STDERR;
    2704            2 :         else if (pg_strcasecmp(tok, "csvlog") == 0)
    2705            1 :             newlogdest |= LOG_DESTINATION_CSVLOG;
    2706            1 :         else if (pg_strcasecmp(tok, "jsonlog") == 0)
    2707            1 :             newlogdest |= LOG_DESTINATION_JSONLOG;
    2708              : #ifdef HAVE_SYSLOG
    2709            0 :         else if (pg_strcasecmp(tok, "syslog") == 0)
    2710            0 :             newlogdest |= LOG_DESTINATION_SYSLOG;
    2711              : #endif
    2712              : #ifdef WIN32
    2713              :         else if (pg_strcasecmp(tok, "eventlog") == 0)
    2714              :             newlogdest |= LOG_DESTINATION_EVENTLOG;
    2715              : #endif
    2716              :         else
    2717              :         {
    2718            0 :             GUC_check_errdetail("Unrecognized key word: \"%s\".", tok);
    2719            0 :             pfree(rawstring);
    2720            0 :             list_free(elemlist);
    2721            0 :             return false;
    2722              :         }
    2723              :     }
    2724              : 
    2725         1189 :     pfree(rawstring);
    2726         1189 :     list_free(elemlist);
    2727              : 
    2728         1189 :     myextra = (int *) guc_malloc(LOG, sizeof(int));
    2729         1189 :     if (!myextra)
    2730            0 :         return false;
    2731         1189 :     *myextra = newlogdest;
    2732         1189 :     *extra = myextra;
    2733              : 
    2734         1189 :     return true;
    2735              : }
    2736              : 
    2737              : /*
    2738              :  * GUC assign_hook for log_destination
    2739              :  */
    2740              : void
    2741         1189 : assign_log_destination(const char *newval, void *extra)
    2742              : {
    2743         1189 :     Log_destination = *((int *) extra);
    2744         1189 : }
    2745              : 
    2746              : /*
    2747              :  * GUC assign_hook for syslog_ident
    2748              :  */
    2749              : void
    2750         1188 : assign_syslog_ident(const char *newval, void *extra)
    2751              : {
    2752              : #ifdef HAVE_SYSLOG
    2753              :     /*
    2754              :      * guc.c is likely to call us repeatedly with same parameters, so don't
    2755              :      * thrash the syslog connection unnecessarily.  Also, we do not re-open
    2756              :      * the connection until needed, since this routine will get called whether
    2757              :      * or not Log_destination actually mentions syslog.
    2758              :      *
    2759              :      * Note that we make our own copy of the ident string rather than relying
    2760              :      * on guc.c's.  This may be overly paranoid, but it ensures that we cannot
    2761              :      * accidentally free a string that syslog is still using.
    2762              :      */
    2763         1188 :     if (syslog_ident == NULL || strcmp(syslog_ident, newval) != 0)
    2764              :     {
    2765         1188 :         if (openlog_done)
    2766              :         {
    2767            0 :             closelog();
    2768            0 :             openlog_done = false;
    2769              :         }
    2770         1188 :         free(syslog_ident);
    2771         1188 :         syslog_ident = strdup(newval);
    2772              :         /* if the strdup fails, we will cope in write_syslog() */
    2773              :     }
    2774              : #endif
    2775              :     /* Without syslog support, just ignore it */
    2776         1188 : }
    2777              : 
    2778              : /*
    2779              :  * GUC assign_hook for syslog_facility
    2780              :  */
    2781              : void
    2782         1188 : assign_syslog_facility(int newval, void *extra)
    2783              : {
    2784              : #ifdef HAVE_SYSLOG
    2785              :     /*
    2786              :      * As above, don't thrash the syslog connection unnecessarily.
    2787              :      */
    2788         1188 :     if (syslog_facility != newval)
    2789              :     {
    2790            0 :         if (openlog_done)
    2791              :         {
    2792            0 :             closelog();
    2793            0 :             openlog_done = false;
    2794              :         }
    2795            0 :         syslog_facility = newval;
    2796              :     }
    2797              : #endif
    2798              :     /* Without syslog support, just ignore it */
    2799         1188 : }
    2800              : 
    2801              : #ifdef HAVE_SYSLOG
    2802              : 
    2803              : /*
    2804              :  * Write a message line to syslog
    2805              :  */
    2806              : static void
    2807            0 : write_syslog(int level, const char *line)
    2808              : {
    2809              :     static unsigned long seq = 0;
    2810              : 
    2811              :     int         len;
    2812              :     const char *nlpos;
    2813              : 
    2814              :     /* Open syslog connection if not done yet */
    2815            0 :     if (!openlog_done)
    2816              :     {
    2817            0 :         openlog(syslog_ident ? syslog_ident : "postgres",
    2818              :                 LOG_PID | LOG_NDELAY | LOG_NOWAIT,
    2819              :                 syslog_facility);
    2820            0 :         openlog_done = true;
    2821              :     }
    2822              : 
    2823              :     /*
    2824              :      * We add a sequence number to each log message to suppress "same"
    2825              :      * messages.
    2826              :      */
    2827            0 :     seq++;
    2828              : 
    2829              :     /*
    2830              :      * Our problem here is that many syslog implementations don't handle long
    2831              :      * messages in an acceptable manner. While this function doesn't help that
    2832              :      * fact, it does work around by splitting up messages into smaller pieces.
    2833              :      *
    2834              :      * We divide into multiple syslog() calls if message is too long or if the
    2835              :      * message contains embedded newline(s).
    2836              :      */
    2837            0 :     len = strlen(line);
    2838            0 :     nlpos = strchr(line, '\n');
    2839            0 :     if (syslog_split_messages && (len > PG_SYSLOG_LIMIT || nlpos != NULL))
    2840            0 :     {
    2841            0 :         int         chunk_nr = 0;
    2842              : 
    2843            0 :         while (len > 0)
    2844              :         {
    2845              :             char        buf[PG_SYSLOG_LIMIT + 1];
    2846              :             int         buflen;
    2847              :             int         i;
    2848              : 
    2849              :             /* if we start at a newline, move ahead one char */
    2850            0 :             if (line[0] == '\n')
    2851              :             {
    2852            0 :                 line++;
    2853            0 :                 len--;
    2854              :                 /* we need to recompute the next newline's position, too */
    2855            0 :                 nlpos = strchr(line, '\n');
    2856            0 :                 continue;
    2857              :             }
    2858              : 
    2859              :             /* copy one line, or as much as will fit, to buf */
    2860            0 :             if (nlpos != NULL)
    2861            0 :                 buflen = nlpos - line;
    2862              :             else
    2863            0 :                 buflen = len;
    2864            0 :             buflen = Min(buflen, PG_SYSLOG_LIMIT);
    2865            0 :             memcpy(buf, line, buflen);
    2866            0 :             buf[buflen] = '\0';
    2867              : 
    2868              :             /* trim to multibyte letter boundary */
    2869            0 :             buflen = pg_mbcliplen(buf, buflen, buflen);
    2870            0 :             if (buflen <= 0)
    2871            0 :                 return;
    2872            0 :             buf[buflen] = '\0';
    2873              : 
    2874              :             /* already word boundary? */
    2875            0 :             if (line[buflen] != '\0' &&
    2876            0 :                 !isspace((unsigned char) line[buflen]))
    2877              :             {
    2878              :                 /* try to divide at word boundary */
    2879            0 :                 i = buflen - 1;
    2880            0 :                 while (i > 0 && !isspace((unsigned char) buf[i]))
    2881            0 :                     i--;
    2882              : 
    2883            0 :                 if (i > 0)       /* else couldn't divide word boundary */
    2884              :                 {
    2885            0 :                     buflen = i;
    2886            0 :                     buf[i] = '\0';
    2887              :                 }
    2888              :             }
    2889              : 
    2890            0 :             chunk_nr++;
    2891              : 
    2892            0 :             if (syslog_sequence_numbers)
    2893            0 :                 syslog(level, "[%lu-%d] %s", seq, chunk_nr, buf);
    2894              :             else
    2895            0 :                 syslog(level, "[%d] %s", chunk_nr, buf);
    2896              : 
    2897            0 :             line += buflen;
    2898            0 :             len -= buflen;
    2899              :         }
    2900              :     }
    2901              :     else
    2902              :     {
    2903              :         /* message short enough */
    2904            0 :         if (syslog_sequence_numbers)
    2905            0 :             syslog(level, "[%lu] %s", seq, line);
    2906              :         else
    2907            0 :             syslog(level, "%s", line);
    2908              :     }
    2909              : }
    2910              : #endif                          /* HAVE_SYSLOG */
    2911              : 
    2912              : #ifdef WIN32
    2913              : /*
    2914              :  * Get the PostgreSQL equivalent of the Windows ANSI code page.  "ANSI" system
    2915              :  * interfaces (e.g. CreateFileA()) expect string arguments in this encoding.
    2916              :  * Every process in a given system will find the same value at all times.
    2917              :  */
    2918              : static int
    2919              : GetACPEncoding(void)
    2920              : {
    2921              :     static int  encoding = -2;
    2922              : 
    2923              :     if (encoding == -2)
    2924              :         encoding = pg_codepage_to_encoding(GetACP());
    2925              : 
    2926              :     return encoding;
    2927              : }
    2928              : 
    2929              : /*
    2930              :  * Write a message line to the windows event log
    2931              :  */
    2932              : static void
    2933              : write_eventlog(int level, const char *line, int len)
    2934              : {
    2935              :     int         eventlevel = EVENTLOG_ERROR_TYPE;
    2936              :     static HANDLE evtHandle = INVALID_HANDLE_VALUE;
    2937              : 
    2938              :     if (evtHandle == INVALID_HANDLE_VALUE)
    2939              :     {
    2940              :         evtHandle = RegisterEventSource(NULL,
    2941              :                                         event_source ? event_source : DEFAULT_EVENT_SOURCE);
    2942              :         if (evtHandle == NULL)
    2943              :         {
    2944              :             evtHandle = INVALID_HANDLE_VALUE;
    2945              :             return;
    2946              :         }
    2947              :     }
    2948              : 
    2949              :     switch (level)
    2950              :     {
    2951              :         case DEBUG5:
    2952              :         case DEBUG4:
    2953              :         case DEBUG3:
    2954              :         case DEBUG2:
    2955              :         case DEBUG1:
    2956              :         case LOG:
    2957              :         case LOG_SERVER_ONLY:
    2958              :         case INFO:
    2959              :         case NOTICE:
    2960              :             eventlevel = EVENTLOG_INFORMATION_TYPE;
    2961              :             break;
    2962              :         case WARNING:
    2963              :         case WARNING_CLIENT_ONLY:
    2964              :             eventlevel = EVENTLOG_WARNING_TYPE;
    2965              :             break;
    2966              :         case ERROR:
    2967              :         case FATAL:
    2968              :         case PANIC:
    2969              :         default:
    2970              :             eventlevel = EVENTLOG_ERROR_TYPE;
    2971              :             break;
    2972              :     }
    2973              : 
    2974              :     /*
    2975              :      * If message character encoding matches the encoding expected by
    2976              :      * ReportEventA(), call it to avoid the hazards of conversion.  Otherwise,
    2977              :      * try to convert the message to UTF16 and write it with ReportEventW().
    2978              :      * Fall back on ReportEventA() if conversion failed.
    2979              :      *
    2980              :      * Since we palloc the structure required for conversion, also fall
    2981              :      * through to writing unconverted if we have not yet set up
    2982              :      * CurrentMemoryContext.
    2983              :      *
    2984              :      * Also verify that we are not on our way into error recursion trouble due
    2985              :      * to error messages thrown deep inside pgwin32_message_to_UTF16().
    2986              :      */
    2987              :     if (!in_error_recursion_trouble() &&
    2988              :         CurrentMemoryContext != NULL &&
    2989              :         GetMessageEncoding() != GetACPEncoding())
    2990              :     {
    2991              :         WCHAR      *utf16;
    2992              : 
    2993              :         utf16 = pgwin32_message_to_UTF16(line, len, NULL);
    2994              :         if (utf16)
    2995              :         {
    2996              :             const WCHAR *utf16_const = utf16;
    2997              : 
    2998              :             ReportEventW(evtHandle,
    2999              :                          eventlevel,
    3000              :                          0,
    3001              :                          0,     /* All events are Id 0 */
    3002              :                          NULL,
    3003              :                          1,
    3004              :                          0,
    3005              :                          &utf16_const,
    3006              :                          NULL);
    3007              :             /* XXX Try ReportEventA() when ReportEventW() fails? */
    3008              : 
    3009              :             pfree(utf16);
    3010              :             return;
    3011              :         }
    3012              :     }
    3013              :     ReportEventA(evtHandle,
    3014              :                  eventlevel,
    3015              :                  0,
    3016              :                  0,             /* All events are Id 0 */
    3017              :                  NULL,
    3018              :                  1,
    3019              :                  0,
    3020              :                  &line,
    3021              :                  NULL);
    3022              : }
    3023              : #endif                          /* WIN32 */
    3024              : 
    3025              : static void
    3026       495381 : write_console(const char *line, int len)
    3027              : {
    3028              :     int         rc;
    3029              : 
    3030              : #ifdef WIN32
    3031              : 
    3032              :     /*
    3033              :      * Try to convert the message to UTF16 and write it with WriteConsoleW().
    3034              :      * Fall back on write() if anything fails.
    3035              :      *
    3036              :      * In contrast to write_eventlog(), don't skip straight to write() based
    3037              :      * on the applicable encodings.  Unlike WriteConsoleW(), write() depends
    3038              :      * on the suitability of the console output code page.  Since we put
    3039              :      * stderr into binary mode in SubPostmasterMain(), write() skips the
    3040              :      * necessary translation anyway.
    3041              :      *
    3042              :      * WriteConsoleW() will fail if stderr is redirected, so just fall through
    3043              :      * to writing unconverted to the logfile in this case.
    3044              :      *
    3045              :      * Since we palloc the structure required for conversion, also fall
    3046              :      * through to writing unconverted if we have not yet set up
    3047              :      * CurrentMemoryContext.
    3048              :      */
    3049              :     if (!in_error_recursion_trouble() &&
    3050              :         !redirection_done &&
    3051              :         CurrentMemoryContext != NULL)
    3052              :     {
    3053              :         WCHAR      *utf16;
    3054              :         int         utf16len;
    3055              : 
    3056              :         utf16 = pgwin32_message_to_UTF16(line, len, &utf16len);
    3057              :         if (utf16 != NULL)
    3058              :         {
    3059              :             HANDLE      stdHandle;
    3060              :             DWORD       written;
    3061              : 
    3062              :             stdHandle = GetStdHandle(STD_ERROR_HANDLE);
    3063              :             if (WriteConsoleW(stdHandle, utf16, utf16len, &written, NULL))
    3064              :             {
    3065              :                 pfree(utf16);
    3066              :                 return;
    3067              :             }
    3068              : 
    3069              :             /*
    3070              :              * In case WriteConsoleW() failed, fall back to writing the
    3071              :              * message unconverted.
    3072              :              */
    3073              :             pfree(utf16);
    3074              :         }
    3075              :     }
    3076              : #else
    3077              : 
    3078              :     /*
    3079              :      * Conversion on non-win32 platforms is not implemented yet. It requires
    3080              :      * non-throw version of pg_do_encoding_conversion(), that converts
    3081              :      * unconvertible characters to '?' without errors.
    3082              :      *
    3083              :      * XXX: We have a no-throw version now. It doesn't convert to '?' though.
    3084              :      */
    3085              : #endif
    3086              : 
    3087              :     /*
    3088              :      * We ignore any error from write() here.  We have no useful way to report
    3089              :      * it ... certainly whining on stderr isn't likely to be productive.
    3090              :      */
    3091       495381 :     rc = write(fileno(stderr), line, len);
    3092              :     (void) rc;
    3093       495381 : }
    3094              : 
    3095              : /*
    3096              :  * get_formatted_log_time -- compute and get the log timestamp.
    3097              :  *
    3098              :  * The timestamp is computed if not set yet, so as it is kept consistent
    3099              :  * among all the log destinations that require it to be consistent.  Note
    3100              :  * that the computed timestamp is returned in a static buffer, not
    3101              :  * palloc()'d.
    3102              :  */
    3103              : char *
    3104       741048 : get_formatted_log_time(void)
    3105              : {
    3106              :     pg_time_t   stamp_time;
    3107              :     char        msbuf[13];
    3108              : 
    3109              :     /* leave if already computed */
    3110       741048 :     if (formatted_log_time[0] != '\0')
    3111           40 :         return formatted_log_time;
    3112              : 
    3113       741008 :     if (!saved_timeval_set)
    3114              :     {
    3115       495401 :         gettimeofday(&saved_timeval, NULL);
    3116       495401 :         saved_timeval_set = true;
    3117              :     }
    3118              : 
    3119       741008 :     stamp_time = (pg_time_t) saved_timeval.tv_sec;
    3120              : 
    3121              :     /*
    3122              :      * Note: we expect that guc.c will ensure that log_timezone is set up (at
    3123              :      * least with a minimal GMT value) before Log_line_prefix can become
    3124              :      * nonempty or CSV/JSON mode can be selected.
    3125              :      */
    3126       741008 :     pg_strftime(formatted_log_time, FORMATTED_TS_LEN,
    3127              :     /* leave room for milliseconds... */
    3128              :                 "%Y-%m-%d %H:%M:%S     %Z",
    3129       741008 :                 pg_localtime(&stamp_time, log_timezone));
    3130              : 
    3131              :     /* 'paste' milliseconds into place... */
    3132       741008 :     sprintf(msbuf, ".%03d", (int) (saved_timeval.tv_usec / 1000));
    3133       741008 :     memcpy(formatted_log_time + 19, msbuf, 4);
    3134              : 
    3135       741008 :     return formatted_log_time;
    3136              : }
    3137              : 
    3138              : /*
    3139              :  * reset_formatted_start_time -- reset the start timestamp
    3140              :  */
    3141              : void
    3142        16982 : reset_formatted_start_time(void)
    3143              : {
    3144        16982 :     formatted_start_time[0] = '\0';
    3145        16982 : }
    3146              : 
    3147              : /*
    3148              :  * get_formatted_start_time -- compute and get the start timestamp.
    3149              :  *
    3150              :  * The timestamp is computed if not set yet.  Note that the computed
    3151              :  * timestamp is returned in a static buffer, not palloc()'d.
    3152              :  */
    3153              : char *
    3154           40 : get_formatted_start_time(void)
    3155              : {
    3156           40 :     pg_time_t   stamp_time = (pg_time_t) MyStartTime;
    3157              : 
    3158              :     /* leave if already computed */
    3159           40 :     if (formatted_start_time[0] != '\0')
    3160           18 :         return formatted_start_time;
    3161              : 
    3162              :     /*
    3163              :      * Note: we expect that guc.c will ensure that log_timezone is set up (at
    3164              :      * least with a minimal GMT value) before Log_line_prefix can become
    3165              :      * nonempty or CSV/JSON mode can be selected.
    3166              :      */
    3167           22 :     pg_strftime(formatted_start_time, FORMATTED_TS_LEN,
    3168              :                 "%Y-%m-%d %H:%M:%S %Z",
    3169           22 :                 pg_localtime(&stamp_time, log_timezone));
    3170              : 
    3171           22 :     return formatted_start_time;
    3172              : }
    3173              : 
    3174              : /*
    3175              :  * check_log_of_query -- check if a query can be logged
    3176              :  */
    3177              : bool
    3178       495441 : check_log_of_query(ErrorData *edata)
    3179              : {
    3180              :     /* log required? */
    3181       495441 :     if (!is_log_level_output(edata->elevel, log_min_error_statement))
    3182       201040 :         return false;
    3183              : 
    3184              :     /* query log wanted? */
    3185       294401 :     if (edata->hide_stmt)
    3186       144545 :         return false;
    3187              : 
    3188              :     /* query string available? */
    3189       149856 :     if (debug_query_string == NULL)
    3190       119975 :         return false;
    3191              : 
    3192        29881 :     return true;
    3193              : }
    3194              : 
    3195              : /*
    3196              :  * get_backend_type_for_log -- backend type for log entries
    3197              :  *
    3198              :  * Returns a pointer to a static buffer, not palloc()'d.
    3199              :  */
    3200              : const char *
    3201       740867 : get_backend_type_for_log(void)
    3202              : {
    3203              :     const char *backend_type_str;
    3204              : 
    3205       740867 :     if (MyProcPid == PostmasterPid)
    3206        11034 :         backend_type_str = "postmaster";
    3207       729833 :     else if (MyBackendType == B_BG_WORKER)
    3208              :     {
    3209        11062 :         if (MyBgworkerEntry)
    3210        11062 :             backend_type_str = MyBgworkerEntry->bgw_type;
    3211              :         else
    3212            0 :             backend_type_str = "early bgworker";
    3213              :     }
    3214              :     else
    3215       718771 :         backend_type_str = GetBackendTypeDesc(MyBackendType);
    3216              : 
    3217       740867 :     return backend_type_str;
    3218              : }
    3219              : 
    3220              : /*
    3221              :  * process_log_prefix_padding --- helper function for processing the format
    3222              :  * string in log_line_prefix
    3223              :  *
    3224              :  * Note: This function returns NULL if it finds something which
    3225              :  * it deems invalid in the format string.
    3226              :  */
    3227              : static const char *
    3228            0 : process_log_prefix_padding(const char *p, int *ppadding)
    3229              : {
    3230            0 :     int         paddingsign = 1;
    3231            0 :     int         padding = 0;
    3232              : 
    3233            0 :     if (*p == '-')
    3234              :     {
    3235            0 :         p++;
    3236              : 
    3237            0 :         if (*p == '\0')         /* Did the buf end in %- ? */
    3238            0 :             return NULL;
    3239            0 :         paddingsign = -1;
    3240              :     }
    3241              : 
    3242              :     /* generate an int version of the numerical string */
    3243            0 :     while (*p >= '0' && *p <= '9')
    3244            0 :         padding = padding * 10 + (*p++ - '0');
    3245              : 
    3246              :     /* format is invalid if it ends with the padding number */
    3247            0 :     if (*p == '\0')
    3248            0 :         return NULL;
    3249              : 
    3250            0 :     padding *= paddingsign;
    3251            0 :     *ppadding = padding;
    3252            0 :     return p;
    3253              : }
    3254              : 
    3255              : /*
    3256              :  * Format log status information using Log_line_prefix.
    3257              :  */
    3258              : static void
    3259       741008 : log_line_prefix(StringInfo buf, ErrorData *edata)
    3260              : {
    3261       741008 :     log_status_format(buf, Log_line_prefix, edata);
    3262       741008 : }
    3263              : 
    3264              : /*
    3265              :  * Format log status info; append to the provided buffer.
    3266              :  */
    3267              : void
    3268       741008 : log_status_format(StringInfo buf, const char *format, ErrorData *edata)
    3269              : {
    3270              :     /* static counter for line numbers */
    3271              :     static long log_line_number = 0;
    3272              : 
    3273              :     /* has counter been reset in current process? */
    3274              :     static int  log_my_pid = 0;
    3275              :     int         padding;
    3276              :     const char *p;
    3277              : 
    3278              :     /*
    3279              :      * This is one of the few places where we'd rather not inherit a static
    3280              :      * variable's value from the postmaster.  But since we will, reset it when
    3281              :      * MyProcPid changes. MyStartTime also changes when MyProcPid does, so
    3282              :      * reset the formatted start timestamp too.
    3283              :      */
    3284       741008 :     if (log_my_pid != MyProcPid)
    3285              :     {
    3286        16960 :         log_line_number = 0;
    3287        16960 :         log_my_pid = MyProcPid;
    3288        16960 :         reset_formatted_start_time();
    3289              :     }
    3290       741008 :     log_line_number++;
    3291              : 
    3292       741008 :     if (format == NULL)
    3293       370630 :         return;                 /* in case guc hasn't run yet */
    3294              : 
    3295      7038474 :     for (p = format; *p != '\0'; p++)
    3296              :     {
    3297      6668096 :         if (*p != '%')
    3298              :         {
    3299              :             /* literal char, just copy */
    3300      3334229 :             appendStringInfoChar(buf, *p);
    3301      3334229 :             continue;
    3302              :         }
    3303              : 
    3304              :         /* must be a '%', so skip to the next char */
    3305      3333867 :         p++;
    3306      3333867 :         if (*p == '\0')
    3307            0 :             break;              /* format error - ignore it */
    3308      3333867 :         else if (*p == '%')
    3309              :         {
    3310              :             /* string contains %% */
    3311            0 :             appendStringInfoChar(buf, '%');
    3312            0 :             continue;
    3313              :         }
    3314              : 
    3315              : 
    3316              :         /*
    3317              :          * Process any formatting which may exist after the '%'.  Note that
    3318              :          * process_log_prefix_padding moves p past the padding number if it
    3319              :          * exists.
    3320              :          *
    3321              :          * Note: Since only '-', '0' to '9' are valid formatting characters we
    3322              :          * can do a quick check here to pre-check for formatting. If the char
    3323              :          * is not formatting then we can skip a useless function call.
    3324              :          *
    3325              :          * Further note: At least on some platforms, passing %*s rather than
    3326              :          * %s to appendStringInfo() is substantially slower, so many of the
    3327              :          * cases below avoid doing that unless non-zero padding is in fact
    3328              :          * specified.
    3329              :          */
    3330      3333867 :         if (*p > '9')
    3331      3333867 :             padding = 0;
    3332            0 :         else if ((p = process_log_prefix_padding(p, &padding)) == NULL)
    3333            0 :             break;
    3334              : 
    3335              :         /* process the option */
    3336      3333867 :         switch (*p)
    3337              :         {
    3338       370197 :             case 'a':
    3339       370197 :                 if (MyProcPort)
    3340              :                 {
    3341       370197 :                     const char *appname = application_name;
    3342              : 
    3343       370197 :                     if (appname == NULL || *appname == '\0')
    3344         2051 :                         appname = _("[unknown]");
    3345       370197 :                     if (padding != 0)
    3346            0 :                         appendStringInfo(buf, "%*s", padding, appname);
    3347              :                     else
    3348       370197 :                         appendStringInfoString(buf, appname);
    3349              :                 }
    3350            0 :                 else if (padding != 0)
    3351            0 :                     appendStringInfoSpaces(buf,
    3352              :                                            padding > 0 ? padding : -padding);
    3353              : 
    3354       370197 :                 break;
    3355       740827 :             case 'b':
    3356              :                 {
    3357       740827 :                     const char *backend_type_str = get_backend_type_for_log();
    3358              : 
    3359       740827 :                     if (padding != 0)
    3360            0 :                         appendStringInfo(buf, "%*s", padding, backend_type_str);
    3361              :                     else
    3362       740827 :                         appendStringInfoString(buf, backend_type_str);
    3363       740827 :                     break;
    3364              :                 }
    3365            0 :             case 'u':
    3366            0 :                 if (MyProcPort)
    3367              :                 {
    3368            0 :                     const char *username = MyProcPort->user_name;
    3369              : 
    3370            0 :                     if (username == NULL || *username == '\0')
    3371            0 :                         username = _("[unknown]");
    3372            0 :                     if (padding != 0)
    3373            0 :                         appendStringInfo(buf, "%*s", padding, username);
    3374              :                     else
    3375            0 :                         appendStringInfoString(buf, username);
    3376              :                 }
    3377            0 :                 else if (padding != 0)
    3378            0 :                     appendStringInfoSpaces(buf,
    3379              :                                            padding > 0 ? padding : -padding);
    3380            0 :                 break;
    3381            0 :             case 'd':
    3382            0 :                 if (MyProcPort)
    3383              :                 {
    3384            0 :                     const char *dbname = MyProcPort->database_name;
    3385              : 
    3386            0 :                     if (dbname == NULL || *dbname == '\0')
    3387            0 :                         dbname = _("[unknown]");
    3388            0 :                     if (padding != 0)
    3389            0 :                         appendStringInfo(buf, "%*s", padding, dbname);
    3390              :                     else
    3391            0 :                         appendStringInfoString(buf, dbname);
    3392              :                 }
    3393            0 :                 else if (padding != 0)
    3394            0 :                     appendStringInfoSpaces(buf,
    3395              :                                            padding > 0 ? padding : -padding);
    3396            0 :                 break;
    3397            0 :             case 'c':
    3398            0 :                 if (padding != 0)
    3399              :                 {
    3400              :                     char        strfbuf[128];
    3401              : 
    3402            0 :                     snprintf(strfbuf, sizeof(strfbuf) - 1, "%" PRIx64 ".%x",
    3403              :                              MyStartTime, MyProcPid);
    3404            0 :                     appendStringInfo(buf, "%*s", padding, strfbuf);
    3405              :                 }
    3406              :                 else
    3407            0 :                     appendStringInfo(buf, "%" PRIx64 ".%x", MyStartTime, MyProcPid);
    3408            0 :                 break;
    3409       741008 :             case 'p':
    3410       741008 :                 if (padding != 0)
    3411            0 :                     appendStringInfo(buf, "%*d", padding, MyProcPid);
    3412              :                 else
    3413       741008 :                     appendStringInfo(buf, "%d", MyProcPid);
    3414       741008 :                 break;
    3415              : 
    3416            0 :             case 'P':
    3417            0 :                 if (MyProc)
    3418              :                 {
    3419            0 :                     PGPROC     *leader = MyProc->lockGroupLeader;
    3420              : 
    3421              :                     /*
    3422              :                      * Show the leader only for active parallel workers. This
    3423              :                      * leaves out the leader of a parallel group.
    3424              :                      */
    3425            0 :                     if (leader == NULL || leader->pid == MyProcPid)
    3426            0 :                         appendStringInfoSpaces(buf,
    3427              :                                                padding > 0 ? padding : -padding);
    3428            0 :                     else if (padding != 0)
    3429            0 :                         appendStringInfo(buf, "%*d", padding, leader->pid);
    3430              :                     else
    3431            0 :                         appendStringInfo(buf, "%d", leader->pid);
    3432              :                 }
    3433            0 :                 else if (padding != 0)
    3434            0 :                     appendStringInfoSpaces(buf,
    3435              :                                            padding > 0 ? padding : -padding);
    3436            0 :                 break;
    3437              : 
    3438            0 :             case 'l':
    3439            0 :                 if (padding != 0)
    3440            0 :                     appendStringInfo(buf, "%*ld", padding, log_line_number);
    3441              :                 else
    3442            0 :                     appendStringInfo(buf, "%ld", log_line_number);
    3443            0 :                 break;
    3444       741008 :             case 'm':
    3445              :                 /* force a log timestamp reset */
    3446       741008 :                 formatted_log_time[0] = '\0';
    3447       741008 :                 (void) get_formatted_log_time();
    3448              : 
    3449       741008 :                 if (padding != 0)
    3450            0 :                     appendStringInfo(buf, "%*s", padding, formatted_log_time);
    3451              :                 else
    3452       741008 :                     appendStringInfoString(buf, formatted_log_time);
    3453       741008 :                 break;
    3454            0 :             case 't':
    3455              :                 {
    3456            0 :                     pg_time_t   stamp_time = (pg_time_t) time(NULL);
    3457              :                     char        strfbuf[128];
    3458              : 
    3459            0 :                     pg_strftime(strfbuf, sizeof(strfbuf),
    3460              :                                 "%Y-%m-%d %H:%M:%S %Z",
    3461            0 :                                 pg_localtime(&stamp_time, log_timezone));
    3462            0 :                     if (padding != 0)
    3463            0 :                         appendStringInfo(buf, "%*s", padding, strfbuf);
    3464              :                     else
    3465            0 :                         appendStringInfoString(buf, strfbuf);
    3466              :                 }
    3467            0 :                 break;
    3468            0 :             case 'n':
    3469              :                 {
    3470              :                     char        strfbuf[128];
    3471              : 
    3472            0 :                     if (!saved_timeval_set)
    3473              :                     {
    3474            0 :                         gettimeofday(&saved_timeval, NULL);
    3475            0 :                         saved_timeval_set = true;
    3476              :                     }
    3477              : 
    3478            0 :                     snprintf(strfbuf, sizeof(strfbuf), "%ld.%03d",
    3479            0 :                              (long) saved_timeval.tv_sec,
    3480            0 :                              (int) (saved_timeval.tv_usec / 1000));
    3481              : 
    3482            0 :                     if (padding != 0)
    3483            0 :                         appendStringInfo(buf, "%*s", padding, strfbuf);
    3484              :                     else
    3485            0 :                         appendStringInfoString(buf, strfbuf);
    3486              :                 }
    3487            0 :                 break;
    3488            0 :             case 's':
    3489              :                 {
    3490            0 :                     char       *start_time = get_formatted_start_time();
    3491              : 
    3492            0 :                     if (padding != 0)
    3493            0 :                         appendStringInfo(buf, "%*s", padding, start_time);
    3494              :                     else
    3495            0 :                         appendStringInfoString(buf, start_time);
    3496              :                 }
    3497            0 :                 break;
    3498            0 :             case 'i':
    3499            0 :                 if (MyProcPort)
    3500              :                 {
    3501              :                     const char *psdisp;
    3502              :                     int         displen;
    3503              : 
    3504            0 :                     psdisp = get_ps_display(&displen);
    3505            0 :                     if (padding != 0)
    3506            0 :                         appendStringInfo(buf, "%*s", padding, psdisp);
    3507              :                     else
    3508            0 :                         appendBinaryStringInfo(buf, psdisp, displen);
    3509              :                 }
    3510            0 :                 else if (padding != 0)
    3511            0 :                     appendStringInfoSpaces(buf,
    3512              :                                            padding > 0 ? padding : -padding);
    3513            0 :                 break;
    3514            0 :             case 'L':
    3515              :                 {
    3516              :                     const char *local_host;
    3517              : 
    3518            0 :                     if (MyProcPort)
    3519              :                     {
    3520            0 :                         if (MyProcPort->local_host[0] == '\0')
    3521              :                         {
    3522              :                             /*
    3523              :                              * First time through: cache the lookup, since it
    3524              :                              * might not have trivial cost.
    3525              :                              */
    3526            0 :                             (void) pg_getnameinfo_all(&MyProcPort->laddr.addr,
    3527            0 :                                                       MyProcPort->laddr.salen,
    3528            0 :                                                       MyProcPort->local_host,
    3529              :                                                       sizeof(MyProcPort->local_host),
    3530              :                                                       NULL, 0,
    3531              :                                                       NI_NUMERICHOST | NI_NUMERICSERV);
    3532              :                         }
    3533            0 :                         local_host = MyProcPort->local_host;
    3534              :                     }
    3535              :                     else
    3536              :                     {
    3537              :                         /* Background process, or connection not yet made */
    3538            0 :                         local_host = "[none]";
    3539              :                     }
    3540            0 :                     if (padding != 0)
    3541            0 :                         appendStringInfo(buf, "%*s", padding, local_host);
    3542              :                     else
    3543            0 :                         appendStringInfoString(buf, local_host);
    3544              :                 }
    3545            0 :                 break;
    3546            0 :             case 'r':
    3547            0 :                 if (MyProcPort && MyProcPort->remote_host)
    3548              :                 {
    3549            0 :                     if (padding != 0)
    3550              :                     {
    3551            0 :                         if (MyProcPort->remote_port && MyProcPort->remote_port[0] != '\0')
    3552            0 :                         {
    3553              :                             /*
    3554              :                              * This option is slightly special as the port
    3555              :                              * number may be appended onto the end. Here we
    3556              :                              * need to build 1 string which contains the
    3557              :                              * remote_host and optionally the remote_port (if
    3558              :                              * set) so we can properly align the string.
    3559              :                              */
    3560              : 
    3561              :                             char       *hostport;
    3562              : 
    3563            0 :                             hostport = psprintf("%s(%s)", MyProcPort->remote_host, MyProcPort->remote_port);
    3564            0 :                             appendStringInfo(buf, "%*s", padding, hostport);
    3565            0 :                             pfree(hostport);
    3566              :                         }
    3567              :                         else
    3568            0 :                             appendStringInfo(buf, "%*s", padding, MyProcPort->remote_host);
    3569              :                     }
    3570              :                     else
    3571              :                     {
    3572              :                         /* padding is 0, so we don't need a temp buffer */
    3573            0 :                         appendStringInfoString(buf, MyProcPort->remote_host);
    3574            0 :                         if (MyProcPort->remote_port &&
    3575            0 :                             MyProcPort->remote_port[0] != '\0')
    3576            0 :                             appendStringInfo(buf, "(%s)",
    3577            0 :                                              MyProcPort->remote_port);
    3578              :                     }
    3579              :                 }
    3580            0 :                 else if (padding != 0)
    3581            0 :                     appendStringInfoSpaces(buf,
    3582              :                                            padding > 0 ? padding : -padding);
    3583            0 :                 break;
    3584            0 :             case 'h':
    3585            0 :                 if (MyProcPort && MyProcPort->remote_host)
    3586              :                 {
    3587            0 :                     if (padding != 0)
    3588            0 :                         appendStringInfo(buf, "%*s", padding, MyProcPort->remote_host);
    3589              :                     else
    3590            0 :                         appendStringInfoString(buf, MyProcPort->remote_host);
    3591              :                 }
    3592            0 :                 else if (padding != 0)
    3593            0 :                     appendStringInfoSpaces(buf,
    3594              :                                            padding > 0 ? padding : -padding);
    3595            0 :                 break;
    3596       740827 :             case 'q':
    3597              :                 /* in postmaster and friends, stop if %q is seen */
    3598              :                 /* in a backend, just ignore */
    3599       740827 :                 if (MyProcPort == NULL)
    3600       370630 :                     return;
    3601       370197 :                 break;
    3602            0 :             case 'v':
    3603              :                 /* keep VXID format in sync with lockfuncs.c */
    3604            0 :                 if (MyProc != NULL && MyProc->vxid.procNumber != INVALID_PROC_NUMBER)
    3605              :                 {
    3606            0 :                     if (padding != 0)
    3607              :                     {
    3608              :                         char        strfbuf[128];
    3609              : 
    3610            0 :                         snprintf(strfbuf, sizeof(strfbuf) - 1, "%d/%u",
    3611            0 :                                  MyProc->vxid.procNumber, MyProc->vxid.lxid);
    3612            0 :                         appendStringInfo(buf, "%*s", padding, strfbuf);
    3613              :                     }
    3614              :                     else
    3615            0 :                         appendStringInfo(buf, "%d/%u", MyProc->vxid.procNumber, MyProc->vxid.lxid);
    3616              :                 }
    3617            0 :                 else if (padding != 0)
    3618            0 :                     appendStringInfoSpaces(buf,
    3619              :                                            padding > 0 ? padding : -padding);
    3620            0 :                 break;
    3621            0 :             case 'x':
    3622            0 :                 if (padding != 0)
    3623            0 :                     appendStringInfo(buf, "%*u", padding, GetTopTransactionIdIfAny());
    3624              :                 else
    3625            0 :                     appendStringInfo(buf, "%u", GetTopTransactionIdIfAny());
    3626            0 :                 break;
    3627            0 :             case 'e':
    3628            0 :                 if (padding != 0)
    3629            0 :                     appendStringInfo(buf, "%*s", padding, unpack_sql_state(edata->sqlerrcode));
    3630              :                 else
    3631            0 :                     appendStringInfoString(buf, unpack_sql_state(edata->sqlerrcode));
    3632            0 :                 break;
    3633            0 :             case 'Q':
    3634            0 :                 if (padding != 0)
    3635            0 :                     appendStringInfo(buf, "%*" PRId64, padding,
    3636              :                                      pgstat_get_my_query_id());
    3637              :                 else
    3638            0 :                     appendStringInfo(buf, "%" PRId64,
    3639              :                                      pgstat_get_my_query_id());
    3640            0 :                 break;
    3641            0 :             default:
    3642              :                 /* format error - ignore it */
    3643            0 :                 break;
    3644              :         }
    3645              :     }
    3646              : }
    3647              : 
    3648              : /*
    3649              :  * Unpack MAKE_SQLSTATE code. Note that this returns a pointer to a
    3650              :  * static buffer.
    3651              :  */
    3652              : char *
    3653       111847 : unpack_sql_state(int sql_state)
    3654              : {
    3655              :     static char buf[12];
    3656              :     int         i;
    3657              : 
    3658       671082 :     for (i = 0; i < 5; i++)
    3659              :     {
    3660       559235 :         buf[i] = PGUNSIXBIT(sql_state);
    3661       559235 :         sql_state >>= 6;
    3662              :     }
    3663              : 
    3664       111847 :     buf[i] = '\0';
    3665       111847 :     return buf;
    3666              : }
    3667              : 
    3668              : 
    3669              : /*
    3670              :  * Write error report to server's log
    3671              :  */
    3672              : static void
    3673       495401 : send_message_to_server_log(ErrorData *edata)
    3674              : {
    3675              :     StringInfoData buf;
    3676       495401 :     bool        fallback_to_stderr = false;
    3677              : 
    3678       495401 :     initStringInfo(&buf);
    3679              : 
    3680       495401 :     log_line_prefix(&buf, edata);
    3681       495401 :     appendStringInfo(&buf, "%s:  ", _(error_severity(edata->elevel)));
    3682              : 
    3683       495401 :     if (Log_error_verbosity >= PGERROR_VERBOSE)
    3684          161 :         appendStringInfo(&buf, "%s: ", unpack_sql_state(edata->sqlerrcode));
    3685              : 
    3686       495401 :     if (edata->message)
    3687       495401 :         append_with_tabs(&buf, edata->message);
    3688              :     else
    3689            0 :         append_with_tabs(&buf, _("missing error text"));
    3690              : 
    3691       495401 :     if (edata->cursorpos > 0)
    3692         6071 :         appendStringInfo(&buf, _(" at character %d"),
    3693              :                          edata->cursorpos);
    3694       489330 :     else if (edata->internalpos > 0)
    3695           47 :         appendStringInfo(&buf, _(" at character %d"),
    3696              :                          edata->internalpos);
    3697              : 
    3698       495401 :     appendStringInfoChar(&buf, '\n');
    3699              : 
    3700       495401 :     if (Log_error_verbosity >= PGERROR_DEFAULT)
    3701              :     {
    3702       495401 :         if (edata->detail_log)
    3703              :         {
    3704          634 :             log_line_prefix(&buf, edata);
    3705          634 :             appendStringInfoString(&buf, _("DETAIL:  "));
    3706          634 :             append_with_tabs(&buf, edata->detail_log);
    3707          634 :             appendStringInfoChar(&buf, '\n');
    3708              :         }
    3709       494767 :         else if (edata->detail)
    3710              :         {
    3711        37252 :             log_line_prefix(&buf, edata);
    3712        37252 :             appendStringInfoString(&buf, _("DETAIL:  "));
    3713        37252 :             append_with_tabs(&buf, edata->detail);
    3714        37252 :             appendStringInfoChar(&buf, '\n');
    3715              :         }
    3716       495401 :         if (edata->hint)
    3717              :         {
    3718       174126 :             log_line_prefix(&buf, edata);
    3719       174126 :             appendStringInfoString(&buf, _("HINT:  "));
    3720       174126 :             append_with_tabs(&buf, edata->hint);
    3721       174126 :             appendStringInfoChar(&buf, '\n');
    3722              :         }
    3723       495401 :         if (edata->internalquery)
    3724              :         {
    3725           47 :             log_line_prefix(&buf, edata);
    3726           47 :             appendStringInfoString(&buf, _("QUERY:  "));
    3727           47 :             append_with_tabs(&buf, edata->internalquery);
    3728           47 :             appendStringInfoChar(&buf, '\n');
    3729              :         }
    3730       495401 :         if (edata->context && !edata->hide_ctx)
    3731              :         {
    3732         3510 :             log_line_prefix(&buf, edata);
    3733         3510 :             appendStringInfoString(&buf, _("CONTEXT:  "));
    3734         3510 :             append_with_tabs(&buf, edata->context);
    3735         3510 :             appendStringInfoChar(&buf, '\n');
    3736              :         }
    3737       495401 :         if (Log_error_verbosity >= PGERROR_VERBOSE)
    3738              :         {
    3739              :             /* assume no newlines in funcname or filename... */
    3740          161 :             if (edata->funcname && edata->filename)
    3741              :             {
    3742          161 :                 log_line_prefix(&buf, edata);
    3743          161 :                 appendStringInfo(&buf, _("LOCATION:  %s, %s:%d\n"),
    3744              :                                  edata->funcname, edata->filename,
    3745              :                                  edata->lineno);
    3746              :             }
    3747            0 :             else if (edata->filename)
    3748              :             {
    3749            0 :                 log_line_prefix(&buf, edata);
    3750            0 :                 appendStringInfo(&buf, _("LOCATION:  %s:%d\n"),
    3751              :                                  edata->filename, edata->lineno);
    3752              :             }
    3753              :         }
    3754       495401 :         if (edata->backtrace)
    3755              :         {
    3756            0 :             log_line_prefix(&buf, edata);
    3757            0 :             appendStringInfoString(&buf, _("BACKTRACE:  "));
    3758            0 :             append_with_tabs(&buf, edata->backtrace);
    3759            0 :             appendStringInfoChar(&buf, '\n');
    3760              :         }
    3761              :     }
    3762              : 
    3763              :     /*
    3764              :      * If the user wants the query that generated this error logged, do it.
    3765              :      */
    3766       495401 :     if (check_log_of_query(edata))
    3767              :     {
    3768        29877 :         log_line_prefix(&buf, edata);
    3769        29877 :         appendStringInfoString(&buf, _("STATEMENT:  "));
    3770        29877 :         append_with_tabs(&buf, debug_query_string);
    3771        29877 :         appendStringInfoChar(&buf, '\n');
    3772              :     }
    3773              : 
    3774              : #ifdef HAVE_SYSLOG
    3775              :     /* Write to syslog, if enabled */
    3776       495401 :     if (Log_destination & LOG_DESTINATION_SYSLOG)
    3777              :     {
    3778              :         int         syslog_level;
    3779              : 
    3780            0 :         switch (edata->elevel)
    3781              :         {
    3782            0 :             case DEBUG5:
    3783              :             case DEBUG4:
    3784              :             case DEBUG3:
    3785              :             case DEBUG2:
    3786              :             case DEBUG1:
    3787            0 :                 syslog_level = LOG_DEBUG;
    3788            0 :                 break;
    3789            0 :             case LOG:
    3790              :             case LOG_SERVER_ONLY:
    3791              :             case INFO:
    3792            0 :                 syslog_level = LOG_INFO;
    3793            0 :                 break;
    3794            0 :             case NOTICE:
    3795              :             case WARNING:
    3796              :             case WARNING_CLIENT_ONLY:
    3797            0 :                 syslog_level = LOG_NOTICE;
    3798            0 :                 break;
    3799            0 :             case ERROR:
    3800            0 :                 syslog_level = LOG_WARNING;
    3801            0 :                 break;
    3802            0 :             case FATAL:
    3803            0 :                 syslog_level = LOG_ERR;
    3804            0 :                 break;
    3805            0 :             case PANIC:
    3806              :             default:
    3807            0 :                 syslog_level = LOG_CRIT;
    3808            0 :                 break;
    3809              :         }
    3810              : 
    3811            0 :         write_syslog(syslog_level, buf.data);
    3812              :     }
    3813              : #endif                          /* HAVE_SYSLOG */
    3814              : 
    3815              : #ifdef WIN32
    3816              :     /* Write to eventlog, if enabled */
    3817              :     if (Log_destination & LOG_DESTINATION_EVENTLOG)
    3818              :     {
    3819              :         write_eventlog(edata->elevel, buf.data, buf.len);
    3820              :     }
    3821              : #endif                          /* WIN32 */
    3822              : 
    3823              :     /* Write to csvlog, if enabled */
    3824       495401 :     if (Log_destination & LOG_DESTINATION_CSVLOG)
    3825              :     {
    3826              :         /*
    3827              :          * Send CSV data if it's safe to do so (syslogger doesn't need the
    3828              :          * pipe).  If this is not possible, fallback to an entry written to
    3829              :          * stderr.
    3830              :          */
    3831           21 :         if (redirection_done || MyBackendType == B_LOGGER)
    3832           20 :             write_csvlog(edata);
    3833              :         else
    3834            1 :             fallback_to_stderr = true;
    3835              :     }
    3836              : 
    3837              :     /* Write to JSON log, if enabled */
    3838       495401 :     if (Log_destination & LOG_DESTINATION_JSONLOG)
    3839              :     {
    3840              :         /*
    3841              :          * Send JSON data if it's safe to do so (syslogger doesn't need the
    3842              :          * pipe).  If this is not possible, fallback to an entry written to
    3843              :          * stderr.
    3844              :          */
    3845           21 :         if (redirection_done || MyBackendType == B_LOGGER)
    3846              :         {
    3847           20 :             write_jsonlog(edata);
    3848              :         }
    3849              :         else
    3850            1 :             fallback_to_stderr = true;
    3851              :     }
    3852              : 
    3853              :     /*
    3854              :      * Write to stderr, if enabled or if required because of a previous
    3855              :      * limitation.
    3856              :      */
    3857       495401 :     if ((Log_destination & LOG_DESTINATION_STDERR) ||
    3858            0 :         whereToSendOutput == DestDebug ||
    3859              :         fallback_to_stderr)
    3860              :     {
    3861              :         /*
    3862              :          * Use the chunking protocol if we know the syslogger should be
    3863              :          * catching stderr output, and we are not ourselves the syslogger.
    3864              :          * Otherwise, just do a vanilla write to stderr.
    3865              :          */
    3866       495401 :         if (redirection_done && MyBackendType != B_LOGGER)
    3867           20 :             write_pipe_chunks(buf.data, buf.len, LOG_DESTINATION_STDERR);
    3868              : #ifdef WIN32
    3869              : 
    3870              :         /*
    3871              :          * In a win32 service environment, there is no usable stderr. Capture
    3872              :          * anything going there and write it to the eventlog instead.
    3873              :          *
    3874              :          * If stderr redirection is active, it was OK to write to stderr above
    3875              :          * because that's really a pipe to the syslogger process.
    3876              :          */
    3877              :         else if (pgwin32_is_service())
    3878              :             write_eventlog(edata->elevel, buf.data, buf.len);
    3879              : #endif
    3880              :         else
    3881       495381 :             write_console(buf.data, buf.len);
    3882              :     }
    3883              : 
    3884              :     /* If in the syslogger process, try to write messages direct to file */
    3885       495401 :     if (MyBackendType == B_LOGGER)
    3886            0 :         write_syslogger_file(buf.data, buf.len, LOG_DESTINATION_STDERR);
    3887              : 
    3888              :     /* No more need of the message formatted for stderr */
    3889       495401 :     pfree(buf.data);
    3890       495401 : }
    3891              : 
    3892              : /*
    3893              :  * Send data to the syslogger using the chunked protocol
    3894              :  *
    3895              :  * Note: when there are multiple backends writing into the syslogger pipe,
    3896              :  * it's critical that each write go into the pipe indivisibly, and not
    3897              :  * get interleaved with data from other processes.  Fortunately, the POSIX
    3898              :  * spec requires that writes to pipes be atomic so long as they are not
    3899              :  * more than PIPE_BUF bytes long.  So we divide long messages into chunks
    3900              :  * that are no more than that length, and send one chunk per write() call.
    3901              :  * The collector process knows how to reassemble the chunks.
    3902              :  *
    3903              :  * Because of the atomic write requirement, there are only two possible
    3904              :  * results from write() here: -1 for failure, or the requested number of
    3905              :  * bytes.  There is not really anything we can do about a failure; retry would
    3906              :  * probably be an infinite loop, and we can't even report the error usefully.
    3907              :  * (There is noplace else we could send it!)  So we might as well just ignore
    3908              :  * the result from write().  However, on some platforms you get a compiler
    3909              :  * warning from ignoring write()'s result, so do a little dance with casting
    3910              :  * rc to void to shut up the compiler.
    3911              :  */
    3912              : void
    3913           60 : write_pipe_chunks(char *data, int len, int dest)
    3914              : {
    3915              :     PipeProtoChunk p;
    3916           60 :     int         fd = fileno(stderr);
    3917              :     int         rc;
    3918              : 
    3919              :     Assert(len > 0);
    3920              : 
    3921           60 :     p.proto.nuls[0] = p.proto.nuls[1] = '\0';
    3922           60 :     p.proto.pid = MyProcPid;
    3923           60 :     p.proto.flags = 0;
    3924           60 :     if (dest == LOG_DESTINATION_STDERR)
    3925           20 :         p.proto.flags |= PIPE_PROTO_DEST_STDERR;
    3926           40 :     else if (dest == LOG_DESTINATION_CSVLOG)
    3927           20 :         p.proto.flags |= PIPE_PROTO_DEST_CSVLOG;
    3928           20 :     else if (dest == LOG_DESTINATION_JSONLOG)
    3929           20 :         p.proto.flags |= PIPE_PROTO_DEST_JSONLOG;
    3930              : 
    3931              :     /* write all but the last chunk */
    3932           60 :     while (len > PIPE_MAX_PAYLOAD)
    3933              :     {
    3934              :         /* no need to set PIPE_PROTO_IS_LAST yet */
    3935            0 :         p.proto.len = PIPE_MAX_PAYLOAD;
    3936            0 :         memcpy(p.proto.data, data, PIPE_MAX_PAYLOAD);
    3937            0 :         rc = write(fd, &p, PIPE_HEADER_SIZE + PIPE_MAX_PAYLOAD);
    3938              :         (void) rc;
    3939            0 :         data += PIPE_MAX_PAYLOAD;
    3940            0 :         len -= PIPE_MAX_PAYLOAD;
    3941              :     }
    3942              : 
    3943              :     /* write the last chunk */
    3944           60 :     p.proto.flags |= PIPE_PROTO_IS_LAST;
    3945           60 :     p.proto.len = len;
    3946           60 :     memcpy(p.proto.data, data, len);
    3947           60 :     rc = write(fd, &p, PIPE_HEADER_SIZE + len);
    3948              :     (void) rc;
    3949           60 : }
    3950              : 
    3951              : 
    3952              : /*
    3953              :  * Append a text string to the error report being built for the client.
    3954              :  *
    3955              :  * This is ordinarily identical to pq_sendstring(), but if we are in
    3956              :  * error recursion trouble we skip encoding conversion, because of the
    3957              :  * possibility that the problem is a failure in the encoding conversion
    3958              :  * subsystem itself.  Code elsewhere should ensure that the passed-in
    3959              :  * strings will be plain 7-bit ASCII, and thus not in need of conversion,
    3960              :  * in such cases.  (In particular, we disable localization of error messages
    3961              :  * to help ensure that's true.)
    3962              :  */
    3963              : static void
    3964       809912 : err_sendstring(StringInfo buf, const char *str)
    3965              : {
    3966       809912 :     if (in_error_recursion_trouble())
    3967            0 :         pq_send_ascii_string(buf, str);
    3968              :     else
    3969       809912 :         pq_sendstring(buf, str);
    3970       809912 : }
    3971              : 
    3972              : /*
    3973              :  * Write error report to client
    3974              :  */
    3975              : static void
    3976       102142 : send_message_to_frontend(ErrorData *edata)
    3977              : {
    3978              :     StringInfoData msgbuf;
    3979              : 
    3980              :     /*
    3981              :      * We no longer support pre-3.0 FE/BE protocol, except here.  If a client
    3982              :      * tries to connect using an older protocol version, it's nice to send the
    3983              :      * "protocol version not supported" error in a format the client
    3984              :      * understands.  If protocol hasn't been set yet, early in backend
    3985              :      * startup, assume modern protocol.
    3986              :      */
    3987       102142 :     if (PG_PROTOCOL_MAJOR(FrontendProtocol) >= 3 || FrontendProtocol == 0)
    3988       102141 :     {
    3989              :         /* New style with separate fields */
    3990              :         const char *sev;
    3991              :         char        tbuf[12];
    3992              : 
    3993              :         /* 'N' (Notice) is for nonfatal conditions, 'E' is for errors */
    3994       102141 :         if (edata->elevel < ERROR)
    3995        79023 :             pq_beginmessage(&msgbuf, PqMsg_NoticeResponse);
    3996              :         else
    3997        23118 :             pq_beginmessage(&msgbuf, PqMsg_ErrorResponse);
    3998              : 
    3999       102141 :         sev = error_severity(edata->elevel);
    4000       102141 :         pq_sendbyte(&msgbuf, PG_DIAG_SEVERITY);
    4001       102141 :         err_sendstring(&msgbuf, _(sev));
    4002       102141 :         pq_sendbyte(&msgbuf, PG_DIAG_SEVERITY_NONLOCALIZED);
    4003       102141 :         err_sendstring(&msgbuf, sev);
    4004              : 
    4005       102141 :         pq_sendbyte(&msgbuf, PG_DIAG_SQLSTATE);
    4006       102141 :         err_sendstring(&msgbuf, unpack_sql_state(edata->sqlerrcode));
    4007              : 
    4008              :         /* M field is required per protocol, so always send something */
    4009       102141 :         pq_sendbyte(&msgbuf, PG_DIAG_MESSAGE_PRIMARY);
    4010       102141 :         if (edata->message)
    4011       102141 :             err_sendstring(&msgbuf, edata->message);
    4012              :         else
    4013            0 :             err_sendstring(&msgbuf, _("missing error text"));
    4014              : 
    4015       102141 :         if (edata->detail)
    4016              :         {
    4017         6194 :             pq_sendbyte(&msgbuf, PG_DIAG_MESSAGE_DETAIL);
    4018         6194 :             err_sendstring(&msgbuf, edata->detail);
    4019              :         }
    4020              : 
    4021              :         /* detail_log is intentionally not used here */
    4022              : 
    4023       102141 :         if (edata->hint)
    4024              :         {
    4025        67427 :             pq_sendbyte(&msgbuf, PG_DIAG_MESSAGE_HINT);
    4026        67427 :             err_sendstring(&msgbuf, edata->hint);
    4027              :         }
    4028              : 
    4029       102141 :         if (edata->context)
    4030              :         {
    4031         9287 :             pq_sendbyte(&msgbuf, PG_DIAG_CONTEXT);
    4032         9287 :             err_sendstring(&msgbuf, edata->context);
    4033              :         }
    4034              : 
    4035       102141 :         if (edata->schema_name)
    4036              :         {
    4037         2190 :             pq_sendbyte(&msgbuf, PG_DIAG_SCHEMA_NAME);
    4038         2190 :             err_sendstring(&msgbuf, edata->schema_name);
    4039              :         }
    4040              : 
    4041       102141 :         if (edata->table_name)
    4042              :         {
    4043         1813 :             pq_sendbyte(&msgbuf, PG_DIAG_TABLE_NAME);
    4044         1813 :             err_sendstring(&msgbuf, edata->table_name);
    4045              :         }
    4046              : 
    4047       102141 :         if (edata->column_name)
    4048              :         {
    4049          276 :             pq_sendbyte(&msgbuf, PG_DIAG_COLUMN_NAME);
    4050          276 :             err_sendstring(&msgbuf, edata->column_name);
    4051              :         }
    4052              : 
    4053       102141 :         if (edata->datatype_name)
    4054              :         {
    4055          382 :             pq_sendbyte(&msgbuf, PG_DIAG_DATATYPE_NAME);
    4056          382 :             err_sendstring(&msgbuf, edata->datatype_name);
    4057              :         }
    4058              : 
    4059       102141 :         if (edata->constraint_name)
    4060              :         {
    4061         1568 :             pq_sendbyte(&msgbuf, PG_DIAG_CONSTRAINT_NAME);
    4062         1568 :             err_sendstring(&msgbuf, edata->constraint_name);
    4063              :         }
    4064              : 
    4065       102141 :         if (edata->cursorpos > 0)
    4066              :         {
    4067         5694 :             snprintf(tbuf, sizeof(tbuf), "%d", edata->cursorpos);
    4068         5694 :             pq_sendbyte(&msgbuf, PG_DIAG_STATEMENT_POSITION);
    4069         5694 :             err_sendstring(&msgbuf, tbuf);
    4070              :         }
    4071              : 
    4072       102141 :         if (edata->internalpos > 0)
    4073              :         {
    4074           47 :             snprintf(tbuf, sizeof(tbuf), "%d", edata->internalpos);
    4075           47 :             pq_sendbyte(&msgbuf, PG_DIAG_INTERNAL_POSITION);
    4076           47 :             err_sendstring(&msgbuf, tbuf);
    4077              :         }
    4078              : 
    4079       102141 :         if (edata->internalquery)
    4080              :         {
    4081           47 :             pq_sendbyte(&msgbuf, PG_DIAG_INTERNAL_QUERY);
    4082           47 :             err_sendstring(&msgbuf, edata->internalquery);
    4083              :         }
    4084              : 
    4085       102141 :         if (edata->filename)
    4086              :         {
    4087       102141 :             pq_sendbyte(&msgbuf, PG_DIAG_SOURCE_FILE);
    4088       102141 :             err_sendstring(&msgbuf, edata->filename);
    4089              :         }
    4090              : 
    4091       102141 :         if (edata->lineno > 0)
    4092              :         {
    4093       102141 :             snprintf(tbuf, sizeof(tbuf), "%d", edata->lineno);
    4094       102141 :             pq_sendbyte(&msgbuf, PG_DIAG_SOURCE_LINE);
    4095       102141 :             err_sendstring(&msgbuf, tbuf);
    4096              :         }
    4097              : 
    4098       102141 :         if (edata->funcname)
    4099              :         {
    4100       102141 :             pq_sendbyte(&msgbuf, PG_DIAG_SOURCE_FUNCTION);
    4101       102141 :             err_sendstring(&msgbuf, edata->funcname);
    4102              :         }
    4103              : 
    4104       102141 :         pq_sendbyte(&msgbuf, '\0'); /* terminator */
    4105              : 
    4106       102141 :         pq_endmessage(&msgbuf);
    4107              :     }
    4108              :     else
    4109              :     {
    4110              :         /* Old style --- gin up a backwards-compatible message */
    4111              :         StringInfoData buf;
    4112              : 
    4113            1 :         initStringInfo(&buf);
    4114              : 
    4115            1 :         appendStringInfo(&buf, "%s:  ", _(error_severity(edata->elevel)));
    4116              : 
    4117            1 :         if (edata->message)
    4118            1 :             appendStringInfoString(&buf, edata->message);
    4119              :         else
    4120            0 :             appendStringInfoString(&buf, _("missing error text"));
    4121              : 
    4122            1 :         appendStringInfoChar(&buf, '\n');
    4123              : 
    4124              :         /* 'N' (Notice) is for nonfatal conditions, 'E' is for errors */
    4125            1 :         pq_putmessage_v2((edata->elevel < ERROR) ? 'N' : 'E', buf.data, buf.len + 1);
    4126              : 
    4127            1 :         pfree(buf.data);
    4128              :     }
    4129              : 
    4130              :     /*
    4131              :      * This flush is normally not necessary, since postgres.c will flush out
    4132              :      * waiting data when control returns to the main loop. But it seems best
    4133              :      * to leave it here, so that the client has some clue what happened if the
    4134              :      * backend dies before getting back to the main loop ... error/notice
    4135              :      * messages should not be a performance-critical path anyway, so an extra
    4136              :      * flush won't hurt much ...
    4137              :      */
    4138       102142 :     pq_flush();
    4139       102142 : }
    4140              : 
    4141              : 
    4142              : /*
    4143              :  * Support routines for formatting error messages.
    4144              :  */
    4145              : 
    4146              : 
    4147              : /*
    4148              :  * error_severity --- get string representing elevel
    4149              :  *
    4150              :  * The string is not localized here, but we mark the strings for translation
    4151              :  * so that callers can invoke _() on the result.
    4152              :  */
    4153              : const char *
    4154       597583 : error_severity(int elevel)
    4155              : {
    4156              :     const char *prefix;
    4157              : 
    4158       597583 :     switch (elevel)
    4159              :     {
    4160        26602 :         case DEBUG1:
    4161              :         case DEBUG2:
    4162              :         case DEBUG3:
    4163              :         case DEBUG4:
    4164              :         case DEBUG5:
    4165        26602 :             prefix = gettext_noop("DEBUG");
    4166        26602 :             break;
    4167       270786 :         case LOG:
    4168              :         case LOG_SERVER_ONLY:
    4169       270786 :             prefix = gettext_noop("LOG");
    4170       270786 :             break;
    4171          350 :         case INFO:
    4172          350 :             prefix = gettext_noop("INFO");
    4173          350 :             break;
    4174        11978 :         case NOTICE:
    4175        11978 :             prefix = gettext_noop("NOTICE");
    4176        11978 :             break;
    4177       241078 :         case WARNING:
    4178              :         case WARNING_CLIENT_ONLY:
    4179       241078 :             prefix = gettext_noop("WARNING");
    4180       241078 :             break;
    4181        45733 :         case ERROR:
    4182        45733 :             prefix = gettext_noop("ERROR");
    4183        45733 :             break;
    4184         1056 :         case FATAL:
    4185         1056 :             prefix = gettext_noop("FATAL");
    4186         1056 :             break;
    4187            0 :         case PANIC:
    4188            0 :             prefix = gettext_noop("PANIC");
    4189            0 :             break;
    4190            0 :         default:
    4191            0 :             prefix = "???";
    4192            0 :             break;
    4193              :     }
    4194              : 
    4195       597583 :     return prefix;
    4196              : }
    4197              : 
    4198              : 
    4199              : /*
    4200              :  *  append_with_tabs
    4201              :  *
    4202              :  *  Append the string to the StringInfo buffer, inserting a tab after any
    4203              :  *  newline.
    4204              :  */
    4205              : static void
    4206       740847 : append_with_tabs(StringInfo buf, const char *str)
    4207              : {
    4208              :     char        ch;
    4209              : 
    4210    170870054 :     while ((ch = *str++) != '\0')
    4211              :     {
    4212    170129207 :         appendStringInfoCharMacro(buf, ch);
    4213    170129207 :         if (ch == '\n')
    4214      1501908 :             appendStringInfoCharMacro(buf, '\t');
    4215              :     }
    4216       740847 : }
    4217              : 
    4218              : 
    4219              : /*
    4220              :  * Write errors to stderr (or by equal means when stderr is
    4221              :  * not available). Used before ereport/elog can be used
    4222              :  * safely (memory context, GUC load etc)
    4223              :  */
    4224              : void
    4225            0 : write_stderr(const char *fmt,...)
    4226              : {
    4227              :     va_list     ap;
    4228              : 
    4229            0 :     va_start(ap, fmt);
    4230            0 :     vwrite_stderr(fmt, ap);
    4231            0 :     va_end(ap);
    4232            0 : }
    4233              : 
    4234              : 
    4235              : /*
    4236              :  * Write errors to stderr (or by equal means when stderr is
    4237              :  * not available) - va_list version
    4238              :  */
    4239              : void
    4240            0 : vwrite_stderr(const char *fmt, va_list ap)
    4241              : {
    4242              : #ifdef WIN32
    4243              :     char        errbuf[2048];   /* Arbitrary size? */
    4244              : #endif
    4245              : 
    4246            0 :     fmt = _(fmt);
    4247              : #ifndef WIN32
    4248              :     /* On Unix, we just fprintf to stderr */
    4249            0 :     vfprintf(stderr, fmt, ap);
    4250            0 :     fflush(stderr);
    4251              : #else
    4252              :     vsnprintf(errbuf, sizeof(errbuf), fmt, ap);
    4253              : 
    4254              :     /*
    4255              :      * On Win32, we print to stderr if running on a console, or write to
    4256              :      * eventlog if running as a service
    4257              :      */
    4258              :     if (pgwin32_is_service())   /* Running as a service */
    4259              :     {
    4260              :         write_eventlog(ERROR, errbuf, strlen(errbuf));
    4261              :     }
    4262              :     else
    4263              :     {
    4264              :         /* Not running as service, write to stderr */
    4265              :         write_console(errbuf, strlen(errbuf));
    4266              :         fflush(stderr);
    4267              :     }
    4268              : #endif
    4269            0 : }
        

Generated by: LCOV version 2.0-1