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

Generated by: LCOV version 2.0-1