LCOV - code coverage report
Current view: top level - src/backend/utils/error - elog.c (source / functions) Hit Total Coverage
Test: PostgreSQL 13beta1 Lines: 705 1206 58.5 %
Date: 2020-05-25 06:06:29 Functions: 52 62 83.9 %
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-2020, 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             : #include "access/transam.h"
      70             : #include "access/xact.h"
      71             : #include "libpq/libpq.h"
      72             : #include "libpq/pqformat.h"
      73             : #include "mb/pg_wchar.h"
      74             : #include "miscadmin.h"
      75             : #include "postmaster/bgworker.h"
      76             : #include "postmaster/postmaster.h"
      77             : #include "postmaster/syslogger.h"
      78             : #include "storage/ipc.h"
      79             : #include "storage/proc.h"
      80             : #include "tcop/tcopprot.h"
      81             : #include "utils/guc.h"
      82             : #include "utils/memutils.h"
      83             : #include "utils/ps_status.h"
      84             : 
      85             : 
      86             : /* In this module, access gettext() via err_gettext() */
      87             : #undef _
      88             : #define _(x) err_gettext(x)
      89             : 
      90             : 
      91             : /* Global variables */
      92             : ErrorContextCallback *error_context_stack = NULL;
      93             : 
      94             : sigjmp_buf *PG_exception_stack = NULL;
      95             : 
      96             : extern bool redirection_done;
      97             : 
      98             : /*
      99             :  * Hook for intercepting messages before they are sent to the server log.
     100             :  * Note that the hook will not get called for messages that are suppressed
     101             :  * by log_min_messages.  Also note that logging hooks implemented in preload
     102             :  * libraries will miss any log messages that are generated before the
     103             :  * library is loaded.
     104             :  */
     105             : emit_log_hook_type emit_log_hook = NULL;
     106             : 
     107             : /* GUC parameters */
     108             : int         Log_error_verbosity = PGERROR_VERBOSE;
     109             : char       *Log_line_prefix = NULL; /* format for extra log line info */
     110             : int         Log_destination = LOG_DESTINATION_STDERR;
     111             : char       *Log_destination_string = NULL;
     112             : bool        syslog_sequence_numbers = true;
     113             : bool        syslog_split_messages = true;
     114             : 
     115             : #ifdef HAVE_SYSLOG
     116             : 
     117             : /*
     118             :  * Max string length to send to syslog().  Note that this doesn't count the
     119             :  * sequence-number prefix we add, and of course it doesn't count the prefix
     120             :  * added by syslog itself.  Solaris and sysklogd truncate the final message
     121             :  * at 1024 bytes, so this value leaves 124 bytes for those prefixes.  (Most
     122             :  * other syslog implementations seem to have limits of 2KB or so.)
     123             :  */
     124             : #ifndef PG_SYSLOG_LIMIT
     125             : #define PG_SYSLOG_LIMIT 900
     126             : #endif
     127             : 
     128             : static bool openlog_done = false;
     129             : static char *syslog_ident = NULL;
     130             : static int  syslog_facility = LOG_LOCAL0;
     131             : 
     132             : static void write_syslog(int level, const char *line);
     133             : #endif
     134             : 
     135             : #ifdef WIN32
     136             : extern char *event_source;
     137             : 
     138             : static void write_eventlog(int level, const char *line, int len);
     139             : #endif
     140             : 
     141             : /* We provide a small stack of ErrorData records for re-entrant cases */
     142             : #define ERRORDATA_STACK_SIZE  5
     143             : 
     144             : static ErrorData errordata[ERRORDATA_STACK_SIZE];
     145             : 
     146             : static int  errordata_stack_depth = -1; /* index of topmost active frame */
     147             : 
     148             : static int  recursion_depth = 0;    /* to detect actual recursion */
     149             : 
     150             : /*
     151             :  * Saved timeval and buffers for formatted timestamps that might be used by
     152             :  * both log_line_prefix and csv logs.
     153             :  */
     154             : static struct timeval saved_timeval;
     155             : static bool saved_timeval_set = false;
     156             : 
     157             : #define FORMATTED_TS_LEN 128
     158             : static char formatted_start_time[FORMATTED_TS_LEN];
     159             : static char formatted_log_time[FORMATTED_TS_LEN];
     160             : 
     161             : 
     162             : /* Macro for checking errordata_stack_depth is reasonable */
     163             : #define CHECK_STACK_DEPTH() \
     164             :     do { \
     165             :         if (errordata_stack_depth < 0) \
     166             :         { \
     167             :             errordata_stack_depth = -1; \
     168             :             ereport(ERROR, (errmsg_internal("errstart was not called"))); \
     169             :         } \
     170             :     } while (0)
     171             : 
     172             : 
     173             : static const char *err_gettext(const char *str) pg_attribute_format_arg(1);
     174             : static pg_noinline void set_backtrace(ErrorData *edata, int num_skip);
     175             : static void set_errdata_field(MemoryContextData *cxt, char **ptr, const char *str);
     176             : static void write_console(const char *line, int len);
     177             : static void setup_formatted_log_time(void);
     178             : static void setup_formatted_start_time(void);
     179             : static const char *process_log_prefix_padding(const char *p, int *padding);
     180             : static void log_line_prefix(StringInfo buf, ErrorData *edata);
     181             : static void write_csvlog(ErrorData *edata);
     182             : static void send_message_to_server_log(ErrorData *edata);
     183             : static void write_pipe_chunks(char *data, int len, int dest);
     184             : static void send_message_to_frontend(ErrorData *edata);
     185             : static const char *error_severity(int elevel);
     186             : static void append_with_tabs(StringInfo buf, const char *str);
     187             : static bool is_log_level_output(int elevel, int log_min_level);
     188             : 
     189             : 
     190             : /*
     191             :  * in_error_recursion_trouble --- are we at risk of infinite error recursion?
     192             :  *
     193             :  * This function exists to provide common control of various fallback steps
     194             :  * that we take if we think we are facing infinite error recursion.  See the
     195             :  * callers for details.
     196             :  */
     197             : bool
     198      486268 : in_error_recursion_trouble(void)
     199             : {
     200             :     /* Pull the plug if recurse more than once */
     201      486268 :     return (recursion_depth > 2);
     202             : }
     203             : 
     204             : /*
     205             :  * One of those fallback steps is to stop trying to localize the error
     206             :  * message, since there's a significant probability that that's exactly
     207             :  * what's causing the recursion.
     208             :  */
     209             : static inline const char *
     210      137456 : err_gettext(const char *str)
     211             : {
     212             : #ifdef ENABLE_NLS
     213      137456 :     if (in_error_recursion_trouble())
     214           0 :         return str;
     215             :     else
     216      137456 :         return gettext(str);
     217             : #else
     218             :     return str;
     219             : #endif
     220             : }
     221             : 
     222             : 
     223             : /*
     224             :  * errstart --- begin an error-reporting cycle
     225             :  *
     226             :  * Create and initialize error stack entry.  Subsequently, errmsg() and
     227             :  * perhaps other routines will be called to further populate the stack entry.
     228             :  * Finally, errfinish() will be called to actually process the error report.
     229             :  *
     230             :  * Returns true in normal case.  Returns false to short-circuit the error
     231             :  * report (if it's a warning or lower and not to be reported anywhere).
     232             :  */
     233             : bool
     234   101800722 : errstart(int elevel, const char *domain)
     235             : {
     236             :     ErrorData  *edata;
     237             :     bool        output_to_server;
     238   101800722 :     bool        output_to_client = false;
     239             :     int         i;
     240             : 
     241             :     /*
     242             :      * Check some cases in which we want to promote an error into a more
     243             :      * severe error.  None of this logic applies for non-error messages.
     244             :      */
     245   101800722 :     if (elevel >= ERROR)
     246             :     {
     247             :         /*
     248             :          * If we are inside a critical section, all errors become PANIC
     249             :          * errors.  See miscadmin.h.
     250             :          */
     251       20456 :         if (CritSectionCount > 0)
     252           0 :             elevel = PANIC;
     253             : 
     254             :         /*
     255             :          * Check reasons for treating ERROR as FATAL:
     256             :          *
     257             :          * 1. we have no handler to pass the error to (implies we are in the
     258             :          * postmaster or in backend startup).
     259             :          *
     260             :          * 2. ExitOnAnyError mode switch is set (initdb uses this).
     261             :          *
     262             :          * 3. the error occurred after proc_exit has begun to run.  (It's
     263             :          * proc_exit's responsibility to see that this doesn't turn into
     264             :          * infinite recursion!)
     265             :          */
     266       20456 :         if (elevel == ERROR)
     267             :         {
     268       20220 :             if (PG_exception_stack == NULL ||
     269       20062 :                 ExitOnAnyError ||
     270             :                 proc_exit_inprogress)
     271         158 :                 elevel = FATAL;
     272             :         }
     273             : 
     274             :         /*
     275             :          * If the error level is ERROR or more, errfinish is not going to
     276             :          * return to caller; therefore, if there is any stacked error already
     277             :          * in progress it will be lost.  This is more or less okay, except we
     278             :          * do not want to have a FATAL or PANIC error downgraded because the
     279             :          * reporting process was interrupted by a lower-grade error.  So check
     280             :          * the stack and make sure we panic if panic is warranted.
     281             :          */
     282       20458 :         for (i = 0; i <= errordata_stack_depth; i++)
     283           2 :             elevel = Max(elevel, errordata[i].elevel);
     284             :     }
     285             : 
     286             :     /*
     287             :      * Now decide whether we need to process this report at all; if it's
     288             :      * warning or less and not enabled for logging, just return false without
     289             :      * starting up any error logging machinery.
     290             :      */
     291             : 
     292             :     /* Determine whether message is enabled for server log output */
     293   101800722 :     output_to_server = is_log_level_output(elevel, log_min_messages);
     294             : 
     295             :     /* Determine whether message is enabled for client output */
     296   101800722 :     if (whereToSendOutput == DestRemote && elevel != LOG_SERVER_ONLY)
     297             :     {
     298             :         /*
     299             :          * client_min_messages is honored only after we complete the
     300             :          * authentication handshake.  This is required both for security
     301             :          * reasons and because many clients can't handle NOTICE messages
     302             :          * during authentication.
     303             :          */
     304      386668 :         if (ClientAuthInProgress)
     305       40234 :             output_to_client = (elevel >= ERROR);
     306             :         else
     307      346434 :             output_to_client = (elevel >= client_min_messages ||
     308             :                                 elevel == INFO);
     309             :     }
     310             : 
     311             :     /* Skip processing effort if non-error message will not be output */
     312   101800722 :     if (elevel < ERROR && !output_to_server && !output_to_client)
     313   101720616 :         return false;
     314             : 
     315             :     /*
     316             :      * We need to do some actual work.  Make sure that memory context
     317             :      * initialization has finished, else we can't do anything useful.
     318             :      */
     319       80106 :     if (ErrorContext == NULL)
     320             :     {
     321             :         /* Oops, hard crash time; very little we can do safely here */
     322           0 :         write_stderr("error occurred before error message processing is available\n");
     323           0 :         exit(2);
     324             :     }
     325             : 
     326             :     /*
     327             :      * Okay, crank up a stack entry to store the info in.
     328             :      */
     329             : 
     330       80106 :     if (recursion_depth++ > 0 && elevel >= ERROR)
     331             :     {
     332             :         /*
     333             :          * Oops, error during error processing.  Clear ErrorContext as
     334             :          * discussed at top of file.  We will not return to the original
     335             :          * error's reporter or handler, so we don't need it.
     336             :          */
     337           0 :         MemoryContextReset(ErrorContext);
     338             : 
     339             :         /*
     340             :          * Infinite error recursion might be due to something broken in a
     341             :          * context traceback routine.  Abandon them too.  We also abandon
     342             :          * attempting to print the error statement (which, if long, could
     343             :          * itself be the source of the recursive failure).
     344             :          */
     345           0 :         if (in_error_recursion_trouble())
     346             :         {
     347           0 :             error_context_stack = NULL;
     348           0 :             debug_query_string = NULL;
     349             :         }
     350             :     }
     351       80106 :     if (++errordata_stack_depth >= ERRORDATA_STACK_SIZE)
     352             :     {
     353             :         /*
     354             :          * Wups, stack not big enough.  We treat this as a PANIC condition
     355             :          * because it suggests an infinite loop of errors during error
     356             :          * recovery.
     357             :          */
     358           0 :         errordata_stack_depth = -1; /* make room on stack */
     359           0 :         ereport(PANIC, (errmsg_internal("ERRORDATA_STACK_SIZE exceeded")));
     360             :     }
     361             : 
     362             :     /* Initialize data for this error frame */
     363       80106 :     edata = &errordata[errordata_stack_depth];
     364     2002650 :     MemSet(edata, 0, sizeof(ErrorData));
     365       80106 :     edata->elevel = elevel;
     366       80106 :     edata->output_to_server = output_to_server;
     367       80106 :     edata->output_to_client = output_to_client;
     368             :     /* the default text domain is the backend's */
     369       80106 :     edata->domain = domain ? domain : PG_TEXTDOMAIN("postgres");
     370             :     /* initialize context_domain the same way (see set_errcontext_domain()) */
     371       80106 :     edata->context_domain = edata->domain;
     372             :     /* Select default errcode based on elevel */
     373       80106 :     if (elevel >= ERROR)
     374       20456 :         edata->sqlerrcode = ERRCODE_INTERNAL_ERROR;
     375       59650 :     else if (elevel == WARNING)
     376        1700 :         edata->sqlerrcode = ERRCODE_WARNING;
     377             :     else
     378       57950 :         edata->sqlerrcode = ERRCODE_SUCCESSFUL_COMPLETION;
     379             :     /* errno is saved here so that error parameter eval can't change it */
     380       80106 :     edata->saved_errno = errno;
     381             : 
     382             :     /*
     383             :      * Any allocations for this error state level should go into ErrorContext
     384             :      */
     385       80106 :     edata->assoc_context = ErrorContext;
     386             : 
     387       80106 :     recursion_depth--;
     388       80106 :     return true;
     389             : }
     390             : 
     391             : /*
     392             :  * Checks whether the given funcname matches backtrace_functions; see
     393             :  * check_backtrace_functions.
     394             :  */
     395             : static bool
     396       80106 : matches_backtrace_functions(const char *funcname)
     397             : {
     398             :     char       *p;
     399             : 
     400       80106 :     if (!backtrace_symbol_list || funcname == NULL || funcname[0] == '\0')
     401       80106 :         return false;
     402             : 
     403           0 :     p = backtrace_symbol_list;
     404             :     for (;;)
     405             :     {
     406           0 :         if (*p == '\0')         /* end of backtrace_symbol_list */
     407           0 :             break;
     408             : 
     409           0 :         if (strcmp(funcname, p) == 0)
     410           0 :             return true;
     411           0 :         p += strlen(p) + 1;
     412             :     }
     413             : 
     414           0 :     return false;
     415             : }
     416             : 
     417             : /*
     418             :  * errfinish --- end an error-reporting cycle
     419             :  *
     420             :  * Produce the appropriate error report(s) and pop the error stack.
     421             :  *
     422             :  * If elevel, as passed to errstart(), is ERROR or worse, control does not
     423             :  * return to the caller.  See elog.h for the error level definitions.
     424             :  */
     425             : void
     426       80106 : errfinish(const char *filename, int lineno, const char *funcname)
     427             : {
     428       80106 :     ErrorData  *edata = &errordata[errordata_stack_depth];
     429             :     int         elevel;
     430             :     MemoryContext oldcontext;
     431             :     ErrorContextCallback *econtext;
     432             : 
     433       80106 :     recursion_depth++;
     434       80106 :     CHECK_STACK_DEPTH();
     435             : 
     436             :     /* Save the last few bits of error state into the stack entry */
     437       80106 :     if (filename)
     438             :     {
     439             :         const char *slash;
     440             : 
     441             :         /* keep only base name, useful especially for vpath builds */
     442       80106 :         slash = strrchr(filename, '/');
     443       80106 :         if (slash)
     444           0 :             filename = slash + 1;
     445             :     }
     446             : 
     447       80106 :     edata->filename = filename;
     448       80106 :     edata->lineno = lineno;
     449       80106 :     edata->funcname = funcname;
     450             : 
     451       80106 :     elevel = edata->elevel;
     452             : 
     453             :     /*
     454             :      * Do processing in ErrorContext, which we hope has enough reserved space
     455             :      * to report an error.
     456             :      */
     457       80106 :     oldcontext = MemoryContextSwitchTo(ErrorContext);
     458             : 
     459       80106 :     if (!edata->backtrace &&
     460       80106 :         edata->funcname &&
     461       80106 :         backtrace_functions &&
     462       80106 :         matches_backtrace_functions(edata->funcname))
     463           0 :         set_backtrace(edata, 2);
     464             : 
     465             :     /*
     466             :      * Call any context callback functions.  Errors occurring in callback
     467             :      * functions will be treated as recursive errors --- this ensures we will
     468             :      * avoid infinite recursion (see errstart).
     469             :      */
     470      101344 :     for (econtext = error_context_stack;
     471             :          econtext != NULL;
     472       21238 :          econtext = econtext->previous)
     473       21238 :         econtext->callback(econtext->arg);
     474             : 
     475             :     /*
     476             :      * If ERROR (not more nor less) we pass it off to the current handler.
     477             :      * Printing it and popping the stack is the responsibility of the handler.
     478             :      */
     479       80106 :     if (elevel == ERROR)
     480             :     {
     481             :         /*
     482             :          * We do some minimal cleanup before longjmp'ing so that handlers can
     483             :          * execute in a reasonably sane state.
     484             :          *
     485             :          * Reset InterruptHoldoffCount in case we ereport'd from inside an
     486             :          * interrupt holdoff section.  (We assume here that no handler will
     487             :          * itself be inside a holdoff section.  If necessary, such a handler
     488             :          * could save and restore InterruptHoldoffCount for itself, but this
     489             :          * should make life easier for most.)
     490             :          */
     491       20062 :         InterruptHoldoffCount = 0;
     492       20062 :         QueryCancelHoldoffCount = 0;
     493             : 
     494       20062 :         CritSectionCount = 0;   /* should be unnecessary, but... */
     495             : 
     496             :         /*
     497             :          * Note that we leave CurrentMemoryContext set to ErrorContext. The
     498             :          * handler should reset it to something else soon.
     499             :          */
     500             : 
     501       20062 :         recursion_depth--;
     502       20062 :         PG_RE_THROW();
     503             :     }
     504             : 
     505             :     /*
     506             :      * If we are doing FATAL or PANIC, abort any old-style COPY OUT in
     507             :      * progress, so that we can report the message before dying.  (Without
     508             :      * this, pq_putmessage will refuse to send the message at all, which is
     509             :      * what we want for NOTICE messages, but not for fatal exits.) This hack
     510             :      * is necessary because of poor design of old-style copy protocol.
     511             :      */
     512       60044 :     if (elevel >= FATAL && whereToSendOutput == DestRemote)
     513         120 :         pq_endcopyout(true);
     514             : 
     515             :     /* Emit the message to the right places */
     516       60044 :     EmitErrorReport();
     517             : 
     518             :     /* Now free up subsidiary data attached to stack entry, and release it */
     519       60044 :     if (edata->message)
     520       60044 :         pfree(edata->message);
     521       60044 :     if (edata->detail)
     522        3696 :         pfree(edata->detail);
     523       60044 :     if (edata->detail_log)
     524         446 :         pfree(edata->detail_log);
     525       60044 :     if (edata->hint)
     526         138 :         pfree(edata->hint);
     527       60044 :     if (edata->context)
     528        8618 :         pfree(edata->context);
     529       60044 :     if (edata->backtrace)
     530           0 :         pfree(edata->backtrace);
     531       60044 :     if (edata->schema_name)
     532          10 :         pfree(edata->schema_name);
     533       60044 :     if (edata->table_name)
     534          10 :         pfree(edata->table_name);
     535       60044 :     if (edata->column_name)
     536           2 :         pfree(edata->column_name);
     537       60044 :     if (edata->datatype_name)
     538           2 :         pfree(edata->datatype_name);
     539       60044 :     if (edata->constraint_name)
     540           2 :         pfree(edata->constraint_name);
     541       60044 :     if (edata->internalquery)
     542           4 :         pfree(edata->internalquery);
     543             : 
     544       60044 :     errordata_stack_depth--;
     545             : 
     546             :     /* Exit error-handling context */
     547       60044 :     MemoryContextSwitchTo(oldcontext);
     548       60044 :     recursion_depth--;
     549             : 
     550             :     /*
     551             :      * Perform error recovery action as specified by elevel.
     552             :      */
     553       60044 :     if (elevel == FATAL)
     554             :     {
     555             :         /*
     556             :          * For a FATAL error, we let proc_exit clean up and exit.
     557             :          *
     558             :          * If we just reported a startup failure, the client will disconnect
     559             :          * on receiving it, so don't send any more to the client.
     560             :          */
     561         394 :         if (PG_exception_stack == NULL && whereToSendOutput == DestRemote)
     562         106 :             whereToSendOutput = DestNone;
     563             : 
     564             :         /*
     565             :          * fflush here is just to improve the odds that we get to see the
     566             :          * error message, in case things are so hosed that proc_exit crashes.
     567             :          * Any other code you might be tempted to add here should probably be
     568             :          * in an on_proc_exit or on_shmem_exit callback instead.
     569             :          */
     570         394 :         fflush(stdout);
     571         394 :         fflush(stderr);
     572             : 
     573             :         /*
     574             :          * Do normal process-exit cleanup, then return exit code 1 to indicate
     575             :          * FATAL termination.  The postmaster may or may not consider this
     576             :          * worthy of panic, depending on which subprocess returns it.
     577             :          */
     578         394 :         proc_exit(1);
     579             :     }
     580             : 
     581       59650 :     if (elevel >= PANIC)
     582             :     {
     583             :         /*
     584             :          * Serious crash time. Postmaster will observe SIGABRT process exit
     585             :          * status and kill the other backends too.
     586             :          *
     587             :          * XXX: what if we are *in* the postmaster?  abort() won't kill our
     588             :          * children...
     589             :          */
     590           0 :         fflush(stdout);
     591           0 :         fflush(stderr);
     592           0 :         abort();
     593             :     }
     594             : 
     595             :     /*
     596             :      * Check for cancel/die interrupt first --- this is so that the user can
     597             :      * stop a query emitting tons of notice or warning messages, even if it's
     598             :      * in a loop that otherwise fails to check for interrupts.
     599             :      */
     600       59650 :     CHECK_FOR_INTERRUPTS();
     601       59650 : }
     602             : 
     603             : 
     604             : /*
     605             :  * errcode --- add SQLSTATE error code to the current error
     606             :  *
     607             :  * The code is expected to be represented as per MAKE_SQLSTATE().
     608             :  */
     609             : int
     610       21462 : errcode(int sqlerrcode)
     611             : {
     612       21462 :     ErrorData  *edata = &errordata[errordata_stack_depth];
     613             : 
     614             :     /* we don't bother incrementing recursion_depth */
     615       21462 :     CHECK_STACK_DEPTH();
     616             : 
     617       21462 :     edata->sqlerrcode = sqlerrcode;
     618             : 
     619       21462 :     return 0;                   /* return value does not matter */
     620             : }
     621             : 
     622             : 
     623             : /*
     624             :  * errcode_for_file_access --- add SQLSTATE error code to the current error
     625             :  *
     626             :  * The SQLSTATE code is chosen based on the saved errno value.  We assume
     627             :  * that the failing operation was some type of disk file access.
     628             :  *
     629             :  * NOTE: the primary error message string should generally include %m
     630             :  * when this is used.
     631             :  */
     632             : int
     633          24 : errcode_for_file_access(void)
     634             : {
     635          24 :     ErrorData  *edata = &errordata[errordata_stack_depth];
     636             : 
     637             :     /* we don't bother incrementing recursion_depth */
     638          24 :     CHECK_STACK_DEPTH();
     639             : 
     640          24 :     switch (edata->saved_errno)
     641             :     {
     642             :             /* Permission-denied failures */
     643           0 :         case EPERM:             /* Not super-user */
     644             :         case EACCES:            /* Permission denied */
     645             : #ifdef EROFS
     646             :         case EROFS:             /* Read only file system */
     647             : #endif
     648           0 :             edata->sqlerrcode = ERRCODE_INSUFFICIENT_PRIVILEGE;
     649           0 :             break;
     650             : 
     651             :             /* File not found */
     652          22 :         case ENOENT:            /* No such file or directory */
     653          22 :             edata->sqlerrcode = ERRCODE_UNDEFINED_FILE;
     654          22 :             break;
     655             : 
     656             :             /* Duplicate file */
     657           0 :         case EEXIST:            /* File exists */
     658           0 :             edata->sqlerrcode = ERRCODE_DUPLICATE_FILE;
     659           0 :             break;
     660             : 
     661             :             /* Wrong object type or state */
     662           0 :         case ENOTDIR:           /* Not a directory */
     663             :         case EISDIR:            /* Is a directory */
     664             : #if defined(ENOTEMPTY) && (ENOTEMPTY != EEXIST) /* same code on AIX */
     665             :         case ENOTEMPTY:         /* Directory not empty */
     666             : #endif
     667           0 :             edata->sqlerrcode = ERRCODE_WRONG_OBJECT_TYPE;
     668           0 :             break;
     669             : 
     670             :             /* Insufficient resources */
     671           0 :         case ENOSPC:            /* No space left on device */
     672           0 :             edata->sqlerrcode = ERRCODE_DISK_FULL;
     673           0 :             break;
     674             : 
     675           0 :         case ENFILE:            /* File table overflow */
     676             :         case EMFILE:            /* Too many open files */
     677           0 :             edata->sqlerrcode = ERRCODE_INSUFFICIENT_RESOURCES;
     678           0 :             break;
     679             : 
     680             :             /* Hardware failure */
     681           0 :         case EIO:               /* I/O error */
     682           0 :             edata->sqlerrcode = ERRCODE_IO_ERROR;
     683           0 :             break;
     684             : 
     685             :             /* All else is classified as internal errors */
     686           2 :         default:
     687           2 :             edata->sqlerrcode = ERRCODE_INTERNAL_ERROR;
     688           2 :             break;
     689             :     }
     690             : 
     691          24 :     return 0;                   /* return value does not matter */
     692             : }
     693             : 
     694             : /*
     695             :  * errcode_for_socket_access --- add SQLSTATE error code to the current error
     696             :  *
     697             :  * The SQLSTATE code is chosen based on the saved errno value.  We assume
     698             :  * that the failing operation was some type of socket access.
     699             :  *
     700             :  * NOTE: the primary error message string should generally include %m
     701             :  * when this is used.
     702             :  */
     703             : int
     704          28 : errcode_for_socket_access(void)
     705             : {
     706          28 :     ErrorData  *edata = &errordata[errordata_stack_depth];
     707             : 
     708             :     /* we don't bother incrementing recursion_depth */
     709          28 :     CHECK_STACK_DEPTH();
     710             : 
     711          28 :     switch (edata->saved_errno)
     712             :     {
     713             :             /* Loss of connection */
     714          20 :         case EPIPE:
     715             : #ifdef ECONNRESET
     716             :         case ECONNRESET:
     717             : #endif
     718          20 :             edata->sqlerrcode = ERRCODE_CONNECTION_FAILURE;
     719          20 :             break;
     720             : 
     721             :             /* All else is classified as internal errors */
     722           8 :         default:
     723           8 :             edata->sqlerrcode = ERRCODE_INTERNAL_ERROR;
     724           8 :             break;
     725             :     }
     726             : 
     727          28 :     return 0;                   /* return value does not matter */
     728             : }
     729             : 
     730             : 
     731             : /*
     732             :  * This macro handles expansion of a format string and associated parameters;
     733             :  * it's common code for errmsg(), errdetail(), etc.  Must be called inside
     734             :  * a routine that is declared like "const char *fmt, ..." and has an edata
     735             :  * pointer set up.  The message is assigned to edata->targetfield, or
     736             :  * appended to it if appendval is true.  The message is subject to translation
     737             :  * if translateit is true.
     738             :  *
     739             :  * Note: we pstrdup the buffer rather than just transferring its storage
     740             :  * to the edata field because the buffer might be considerably larger than
     741             :  * really necessary.
     742             :  */
     743             : #define EVALUATE_MESSAGE(domain, targetfield, appendval, translateit)   \
     744             :     { \
     745             :         StringInfoData  buf; \
     746             :         /* Internationalize the error format string */ \
     747             :         if ((translateit) && !in_error_recursion_trouble()) \
     748             :             fmt = dgettext((domain), fmt);                \
     749             :         initStringInfo(&buf); \
     750             :         if ((appendval) && edata->targetfield) { \
     751             :             appendStringInfoString(&buf, edata->targetfield); \
     752             :             appendStringInfoChar(&buf, '\n'); \
     753             :         } \
     754             :         /* Generate actual output --- have to use appendStringInfoVA */ \
     755             :         for (;;) \
     756             :         { \
     757             :             va_list     args; \
     758             :             int         needed; \
     759             :             errno = edata->saved_errno; \
     760             :             va_start(args, fmt); \
     761             :             needed = appendStringInfoVA(&buf, fmt, args); \
     762             :             va_end(args); \
     763             :             if (needed == 0) \
     764             :                 break; \
     765             :             enlargeStringInfo(&buf, needed); \
     766             :         } \
     767             :         /* Save the completed message into the stack item */ \
     768             :         if (edata->targetfield) \
     769             :             pfree(edata->targetfield); \
     770             :         edata->targetfield = pstrdup(buf.data); \
     771             :         pfree(buf.data); \
     772             :     }
     773             : 
     774             : /*
     775             :  * Same as above, except for pluralized error messages.  The calling routine
     776             :  * must be declared like "const char *fmt_singular, const char *fmt_plural,
     777             :  * unsigned long n, ...".  Translation is assumed always wanted.
     778             :  */
     779             : #define EVALUATE_MESSAGE_PLURAL(domain, targetfield, appendval)  \
     780             :     { \
     781             :         const char     *fmt; \
     782             :         StringInfoData  buf; \
     783             :         /* Internationalize the error format string */ \
     784             :         if (!in_error_recursion_trouble()) \
     785             :             fmt = dngettext((domain), fmt_singular, fmt_plural, n); \
     786             :         else \
     787             :             fmt = (n == 1 ? fmt_singular : fmt_plural); \
     788             :         initStringInfo(&buf); \
     789             :         if ((appendval) && edata->targetfield) { \
     790             :             appendStringInfoString(&buf, edata->targetfield); \
     791             :             appendStringInfoChar(&buf, '\n'); \
     792             :         } \
     793             :         /* Generate actual output --- have to use appendStringInfoVA */ \
     794             :         for (;;) \
     795             :         { \
     796             :             va_list     args; \
     797             :             int         needed; \
     798             :             errno = edata->saved_errno; \
     799             :             va_start(args, n); \
     800             :             needed = appendStringInfoVA(&buf, fmt, args); \
     801             :             va_end(args); \
     802             :             if (needed == 0) \
     803             :                 break; \
     804             :             enlargeStringInfo(&buf, needed); \
     805             :         } \
     806             :         /* Save the completed message into the stack item */ \
     807             :         if (edata->targetfield) \
     808             :             pfree(edata->targetfield); \
     809             :         edata->targetfield = pstrdup(buf.data); \
     810             :         pfree(buf.data); \
     811             :     }
     812             : 
     813             : 
     814             : /*
     815             :  * errmsg --- add a primary error message text to the current error
     816             :  *
     817             :  * In addition to the usual %-escapes recognized by printf, "%m" in
     818             :  * fmt is replaced by the error message for the caller's value of errno.
     819             :  *
     820             :  * Note: no newline is needed at the end of the fmt string, since
     821             :  * ereport will provide one for the output methods that need it.
     822             :  */
     823             : int
     824       68506 : errmsg(const char *fmt,...)
     825             : {
     826       68506 :     ErrorData  *edata = &errordata[errordata_stack_depth];
     827             :     MemoryContext oldcontext;
     828             : 
     829       68506 :     recursion_depth++;
     830       68506 :     CHECK_STACK_DEPTH();
     831       68506 :     oldcontext = MemoryContextSwitchTo(edata->assoc_context);
     832             : 
     833       68506 :     edata->message_id = fmt;
     834       70758 :     EVALUATE_MESSAGE(edata->domain, message, false, true);
     835             : 
     836       68506 :     MemoryContextSwitchTo(oldcontext);
     837       68506 :     recursion_depth--;
     838       68506 :     return 0;                   /* return value does not matter */
     839             : }
     840             : 
     841             : /*
     842             :  * Add a backtrace to the containing ereport() call.  This is intended to be
     843             :  * added temporarily during debugging.
     844             :  */
     845             : int
     846           0 : errbacktrace(void)
     847             : {
     848           0 :     ErrorData  *edata = &errordata[errordata_stack_depth];
     849             :     MemoryContext oldcontext;
     850             : 
     851           0 :     recursion_depth++;
     852           0 :     CHECK_STACK_DEPTH();
     853           0 :     oldcontext = MemoryContextSwitchTo(edata->assoc_context);
     854             : 
     855           0 :     set_backtrace(edata, 1);
     856             : 
     857           0 :     MemoryContextSwitchTo(oldcontext);
     858           0 :     recursion_depth--;
     859             : 
     860           0 :     return 0;
     861             : }
     862             : 
     863             : /*
     864             :  * Compute backtrace data and add it to the supplied ErrorData.  num_skip
     865             :  * specifies how many inner frames to skip.  Use this to avoid showing the
     866             :  * internal backtrace support functions in the backtrace.  This requires that
     867             :  * this and related functions are not inlined.
     868             :  */
     869             : static void
     870           0 : set_backtrace(ErrorData *edata, int num_skip)
     871             : {
     872             :     StringInfoData errtrace;
     873             : 
     874           0 :     initStringInfo(&errtrace);
     875             : 
     876             : #ifdef HAVE_BACKTRACE_SYMBOLS
     877             :     {
     878             :         void       *buf[100];
     879             :         int         nframes;
     880             :         char      **strfrms;
     881             : 
     882           0 :         nframes = backtrace(buf, lengthof(buf));
     883           0 :         strfrms = backtrace_symbols(buf, nframes);
     884           0 :         if (strfrms == NULL)
     885           0 :             return;
     886             : 
     887           0 :         for (int i = num_skip; i < nframes; i++)
     888           0 :             appendStringInfo(&errtrace, "\n%s", strfrms[i]);
     889           0 :         free(strfrms);
     890             :     }
     891             : #else
     892             :     appendStringInfoString(&errtrace,
     893             :                            "backtrace generation is not supported by this installation");
     894             : #endif
     895             : 
     896           0 :     edata->backtrace = errtrace.data;
     897             : }
     898             : 
     899             : /*
     900             :  * errmsg_internal --- add a primary error message text to the current error
     901             :  *
     902             :  * This is exactly like errmsg() except that strings passed to errmsg_internal
     903             :  * are not translated, and are customarily left out of the
     904             :  * internationalization message dictionary.  This should be used for "can't
     905             :  * happen" cases that are probably not worth spending translation effort on.
     906             :  * We also use this for certain cases where we *must* not try to translate
     907             :  * the message because the translation would fail and result in infinite
     908             :  * error recursion.
     909             :  */
     910             : int
     911       11182 : errmsg_internal(const char *fmt,...)
     912             : {
     913       11182 :     ErrorData  *edata = &errordata[errordata_stack_depth];
     914             :     MemoryContext oldcontext;
     915             : 
     916       11182 :     recursion_depth++;
     917       11182 :     CHECK_STACK_DEPTH();
     918       11182 :     oldcontext = MemoryContextSwitchTo(edata->assoc_context);
     919             : 
     920       11182 :     edata->message_id = fmt;
     921       11182 :     EVALUATE_MESSAGE(edata->domain, message, false, false);
     922             : 
     923       11182 :     MemoryContextSwitchTo(oldcontext);
     924       11182 :     recursion_depth--;
     925       11182 :     return 0;                   /* return value does not matter */
     926             : }
     927             : 
     928             : 
     929             : /*
     930             :  * errmsg_plural --- add a primary error message text to the current error,
     931             :  * with support for pluralization of the message text
     932             :  */
     933             : int
     934         414 : errmsg_plural(const char *fmt_singular, const char *fmt_plural,
     935             :               unsigned long n,...)
     936             : {
     937         414 :     ErrorData  *edata = &errordata[errordata_stack_depth];
     938             :     MemoryContext oldcontext;
     939             : 
     940         414 :     recursion_depth++;
     941         414 :     CHECK_STACK_DEPTH();
     942         414 :     oldcontext = MemoryContextSwitchTo(edata->assoc_context);
     943             : 
     944         414 :     edata->message_id = fmt_singular;
     945         414 :     EVALUATE_MESSAGE_PLURAL(edata->domain, message, false);
     946             : 
     947         414 :     MemoryContextSwitchTo(oldcontext);
     948         414 :     recursion_depth--;
     949         414 :     return 0;                   /* return value does not matter */
     950             : }
     951             : 
     952             : 
     953             : /*
     954             :  * errdetail --- add a detail error message text to the current error
     955             :  */
     956             : int
     957        7228 : errdetail(const char *fmt,...)
     958             : {
     959        7228 :     ErrorData  *edata = &errordata[errordata_stack_depth];
     960             :     MemoryContext oldcontext;
     961             : 
     962        7228 :     recursion_depth++;
     963        7228 :     CHECK_STACK_DEPTH();
     964        7228 :     oldcontext = MemoryContextSwitchTo(edata->assoc_context);
     965             : 
     966        7236 :     EVALUATE_MESSAGE(edata->domain, detail, false, true);
     967             : 
     968        7228 :     MemoryContextSwitchTo(oldcontext);
     969        7228 :     recursion_depth--;
     970        7228 :     return 0;                   /* return value does not matter */
     971             : }
     972             : 
     973             : 
     974             : /*
     975             :  * errdetail_internal --- add a detail error message text to the current error
     976             :  *
     977             :  * This is exactly like errdetail() except that strings passed to
     978             :  * errdetail_internal are not translated, and are customarily left out of the
     979             :  * internationalization message dictionary.  This should be used for detail
     980             :  * messages that seem not worth translating for one reason or another
     981             :  * (typically, that they don't seem to be useful to average users).
     982             :  */
     983             : int
     984        1068 : errdetail_internal(const char *fmt,...)
     985             : {
     986        1068 :     ErrorData  *edata = &errordata[errordata_stack_depth];
     987             :     MemoryContext oldcontext;
     988             : 
     989        1068 :     recursion_depth++;
     990        1068 :     CHECK_STACK_DEPTH();
     991        1068 :     oldcontext = MemoryContextSwitchTo(edata->assoc_context);
     992             : 
     993        1068 :     EVALUATE_MESSAGE(edata->domain, detail, false, false);
     994             : 
     995        1068 :     MemoryContextSwitchTo(oldcontext);
     996        1068 :     recursion_depth--;
     997        1068 :     return 0;                   /* return value does not matter */
     998             : }
     999             : 
    1000             : 
    1001             : /*
    1002             :  * errdetail_log --- add a detail_log error message text to the current error
    1003             :  */
    1004             : int
    1005         650 : errdetail_log(const char *fmt,...)
    1006             : {
    1007         650 :     ErrorData  *edata = &errordata[errordata_stack_depth];
    1008             :     MemoryContext oldcontext;
    1009             : 
    1010         650 :     recursion_depth++;
    1011         650 :     CHECK_STACK_DEPTH();
    1012         650 :     oldcontext = MemoryContextSwitchTo(edata->assoc_context);
    1013             : 
    1014         660 :     EVALUATE_MESSAGE(edata->domain, detail_log, false, true);
    1015             : 
    1016         650 :     MemoryContextSwitchTo(oldcontext);
    1017         650 :     recursion_depth--;
    1018         650 :     return 0;                   /* return value does not matter */
    1019             : }
    1020             : 
    1021             : /*
    1022             :  * errdetail_log_plural --- add a detail_log error message text to the current error
    1023             :  * with support for pluralization of the message text
    1024             :  */
    1025             : int
    1026          34 : errdetail_log_plural(const char *fmt_singular, const char *fmt_plural,
    1027             :                      unsigned long n,...)
    1028             : {
    1029          34 :     ErrorData  *edata = &errordata[errordata_stack_depth];
    1030             :     MemoryContext oldcontext;
    1031             : 
    1032          34 :     recursion_depth++;
    1033          34 :     CHECK_STACK_DEPTH();
    1034          34 :     oldcontext = MemoryContextSwitchTo(edata->assoc_context);
    1035             : 
    1036          34 :     EVALUATE_MESSAGE_PLURAL(edata->domain, detail_log, false);
    1037             : 
    1038          34 :     MemoryContextSwitchTo(oldcontext);
    1039          34 :     recursion_depth--;
    1040          34 :     return 0;                   /* return value does not matter */
    1041             : }
    1042             : 
    1043             : 
    1044             : /*
    1045             :  * errdetail_plural --- add a detail error message text to the current error,
    1046             :  * with support for pluralization of the message text
    1047             :  */
    1048             : int
    1049          22 : errdetail_plural(const char *fmt_singular, const char *fmt_plural,
    1050             :                  unsigned long n,...)
    1051             : {
    1052          22 :     ErrorData  *edata = &errordata[errordata_stack_depth];
    1053             :     MemoryContext oldcontext;
    1054             : 
    1055          22 :     recursion_depth++;
    1056          22 :     CHECK_STACK_DEPTH();
    1057          22 :     oldcontext = MemoryContextSwitchTo(edata->assoc_context);
    1058             : 
    1059          22 :     EVALUATE_MESSAGE_PLURAL(edata->domain, detail, false);
    1060             : 
    1061          22 :     MemoryContextSwitchTo(oldcontext);
    1062          22 :     recursion_depth--;
    1063          22 :     return 0;                   /* return value does not matter */
    1064             : }
    1065             : 
    1066             : 
    1067             : /*
    1068             :  * errhint --- add a hint error message text to the current error
    1069             :  */
    1070             : int
    1071        2598 : errhint(const char *fmt,...)
    1072             : {
    1073        2598 :     ErrorData  *edata = &errordata[errordata_stack_depth];
    1074             :     MemoryContext oldcontext;
    1075             : 
    1076        2598 :     recursion_depth++;
    1077        2598 :     CHECK_STACK_DEPTH();
    1078        2598 :     oldcontext = MemoryContextSwitchTo(edata->assoc_context);
    1079             : 
    1080        2598 :     EVALUATE_MESSAGE(edata->domain, hint, false, true);
    1081             : 
    1082        2598 :     MemoryContextSwitchTo(oldcontext);
    1083        2598 :     recursion_depth--;
    1084        2598 :     return 0;                   /* return value does not matter */
    1085             : }
    1086             : 
    1087             : 
    1088             : /*
    1089             :  * errcontext_msg --- add a context error message text to the current error
    1090             :  *
    1091             :  * Unlike other cases, multiple calls are allowed to build up a stack of
    1092             :  * context information.  We assume earlier calls represent more-closely-nested
    1093             :  * states.
    1094             :  */
    1095             : int
    1096       19518 : errcontext_msg(const char *fmt,...)
    1097             : {
    1098       19518 :     ErrorData  *edata = &errordata[errordata_stack_depth];
    1099             :     MemoryContext oldcontext;
    1100             : 
    1101       19518 :     recursion_depth++;
    1102       19518 :     CHECK_STACK_DEPTH();
    1103       19518 :     oldcontext = MemoryContextSwitchTo(edata->assoc_context);
    1104             : 
    1105       39064 :     EVALUATE_MESSAGE(edata->context_domain, context, true, true);
    1106             : 
    1107       19518 :     MemoryContextSwitchTo(oldcontext);
    1108       19518 :     recursion_depth--;
    1109       19518 :     return 0;                   /* return value does not matter */
    1110             : }
    1111             : 
    1112             : /*
    1113             :  * set_errcontext_domain --- set message domain to be used by errcontext()
    1114             :  *
    1115             :  * errcontext_msg() can be called from a different module than the original
    1116             :  * ereport(), so we cannot use the message domain passed in errstart() to
    1117             :  * translate it.  Instead, each errcontext_msg() call should be preceded by
    1118             :  * a set_errcontext_domain() call to specify the domain.  This is usually
    1119             :  * done transparently by the errcontext() macro.
    1120             :  */
    1121             : int
    1122       19518 : set_errcontext_domain(const char *domain)
    1123             : {
    1124       19518 :     ErrorData  *edata = &errordata[errordata_stack_depth];
    1125             : 
    1126             :     /* we don't bother incrementing recursion_depth */
    1127       19518 :     CHECK_STACK_DEPTH();
    1128             : 
    1129             :     /* the default text domain is the backend's */
    1130       19518 :     edata->context_domain = domain ? domain : PG_TEXTDOMAIN("postgres");
    1131             : 
    1132       19518 :     return 0;                   /* return value does not matter */
    1133             : }
    1134             : 
    1135             : 
    1136             : /*
    1137             :  * errhidestmt --- optionally suppress STATEMENT: field of log entry
    1138             :  *
    1139             :  * This should be called if the message text already includes the statement.
    1140             :  */
    1141             : int
    1142       33932 : errhidestmt(bool hide_stmt)
    1143             : {
    1144       33932 :     ErrorData  *edata = &errordata[errordata_stack_depth];
    1145             : 
    1146             :     /* we don't bother incrementing recursion_depth */
    1147       33932 :     CHECK_STACK_DEPTH();
    1148             : 
    1149       33932 :     edata->hide_stmt = hide_stmt;
    1150             : 
    1151       33932 :     return 0;                   /* return value does not matter */
    1152             : }
    1153             : 
    1154             : /*
    1155             :  * errhidecontext --- optionally suppress CONTEXT: field of log entry
    1156             :  *
    1157             :  * This should only be used for verbose debugging messages where the repeated
    1158             :  * inclusion of context would bloat the log volume too much.
    1159             :  */
    1160             : int
    1161           0 : errhidecontext(bool hide_ctx)
    1162             : {
    1163           0 :     ErrorData  *edata = &errordata[errordata_stack_depth];
    1164             : 
    1165             :     /* we don't bother incrementing recursion_depth */
    1166           0 :     CHECK_STACK_DEPTH();
    1167             : 
    1168           0 :     edata->hide_ctx = hide_ctx;
    1169             : 
    1170           0 :     return 0;                   /* return value does not matter */
    1171             : }
    1172             : 
    1173             : 
    1174             : /*
    1175             :  * errfunction --- add reporting function name to the current error
    1176             :  *
    1177             :  * This is used when backwards compatibility demands that the function
    1178             :  * name appear in messages sent to old-protocol clients.  Note that the
    1179             :  * passed string is expected to be a non-freeable constant string.
    1180             :  */
    1181             : int
    1182           0 : errfunction(const char *funcname)
    1183             : {
    1184           0 :     ErrorData  *edata = &errordata[errordata_stack_depth];
    1185             : 
    1186             :     /* we don't bother incrementing recursion_depth */
    1187           0 :     CHECK_STACK_DEPTH();
    1188             : 
    1189           0 :     edata->funcname = funcname;
    1190           0 :     edata->show_funcname = true;
    1191             : 
    1192           0 :     return 0;                   /* return value does not matter */
    1193             : }
    1194             : 
    1195             : /*
    1196             :  * errposition --- add cursor position to the current error
    1197             :  */
    1198             : int
    1199        4540 : errposition(int cursorpos)
    1200             : {
    1201        4540 :     ErrorData  *edata = &errordata[errordata_stack_depth];
    1202             : 
    1203             :     /* we don't bother incrementing recursion_depth */
    1204        4540 :     CHECK_STACK_DEPTH();
    1205             : 
    1206        4540 :     edata->cursorpos = cursorpos;
    1207             : 
    1208        4540 :     return 0;                   /* return value does not matter */
    1209             : }
    1210             : 
    1211             : /*
    1212             :  * internalerrposition --- add internal cursor position to the current error
    1213             :  */
    1214             : int
    1215         358 : internalerrposition(int cursorpos)
    1216             : {
    1217         358 :     ErrorData  *edata = &errordata[errordata_stack_depth];
    1218             : 
    1219             :     /* we don't bother incrementing recursion_depth */
    1220         358 :     CHECK_STACK_DEPTH();
    1221             : 
    1222         358 :     edata->internalpos = cursorpos;
    1223             : 
    1224         358 :     return 0;                   /* return value does not matter */
    1225             : }
    1226             : 
    1227             : /*
    1228             :  * internalerrquery --- add internal query text to the current error
    1229             :  *
    1230             :  * Can also pass NULL to drop the internal query text entry.  This case
    1231             :  * is intended for use in error callback subroutines that are editorializing
    1232             :  * on the layout of the error report.
    1233             :  */
    1234             : int
    1235         346 : internalerrquery(const char *query)
    1236             : {
    1237         346 :     ErrorData  *edata = &errordata[errordata_stack_depth];
    1238             : 
    1239             :     /* we don't bother incrementing recursion_depth */
    1240         346 :     CHECK_STACK_DEPTH();
    1241             : 
    1242         346 :     if (edata->internalquery)
    1243             :     {
    1244         124 :         pfree(edata->internalquery);
    1245         124 :         edata->internalquery = NULL;
    1246             :     }
    1247             : 
    1248         346 :     if (query)
    1249         202 :         edata->internalquery = MemoryContextStrdup(edata->assoc_context, query);
    1250             : 
    1251         346 :     return 0;                   /* return value does not matter */
    1252             : }
    1253             : 
    1254             : /*
    1255             :  * err_generic_string -- used to set individual ErrorData string fields
    1256             :  * identified by PG_DIAG_xxx codes.
    1257             :  *
    1258             :  * This intentionally only supports fields that don't use localized strings,
    1259             :  * so that there are no translation considerations.
    1260             :  *
    1261             :  * Most potential callers should not use this directly, but instead prefer
    1262             :  * higher-level abstractions, such as errtablecol() (see relcache.c).
    1263             :  */
    1264             : int
    1265        6602 : err_generic_string(int field, const char *str)
    1266             : {
    1267        6602 :     ErrorData  *edata = &errordata[errordata_stack_depth];
    1268             : 
    1269             :     /* we don't bother incrementing recursion_depth */
    1270        6602 :     CHECK_STACK_DEPTH();
    1271             : 
    1272        6602 :     switch (field)
    1273             :     {
    1274        2324 :         case PG_DIAG_SCHEMA_NAME:
    1275        2324 :             set_errdata_field(edata->assoc_context, &edata->schema_name, str);
    1276        2324 :             break;
    1277        1864 :         case PG_DIAG_TABLE_NAME:
    1278        1864 :             set_errdata_field(edata->assoc_context, &edata->table_name, str);
    1279        1864 :             break;
    1280         242 :         case PG_DIAG_COLUMN_NAME:
    1281         242 :             set_errdata_field(edata->assoc_context, &edata->column_name, str);
    1282         242 :             break;
    1283         492 :         case PG_DIAG_DATATYPE_NAME:
    1284         492 :             set_errdata_field(edata->assoc_context, &edata->datatype_name, str);
    1285         492 :             break;
    1286        1680 :         case PG_DIAG_CONSTRAINT_NAME:
    1287        1680 :             set_errdata_field(edata->assoc_context, &edata->constraint_name, str);
    1288        1680 :             break;
    1289           0 :         default:
    1290           0 :             elog(ERROR, "unsupported ErrorData field id: %d", field);
    1291             :             break;
    1292             :     }
    1293             : 
    1294        6602 :     return 0;                   /* return value does not matter */
    1295             : }
    1296             : 
    1297             : /*
    1298             :  * set_errdata_field --- set an ErrorData string field
    1299             :  */
    1300             : static void
    1301        6602 : set_errdata_field(MemoryContextData *cxt, char **ptr, const char *str)
    1302             : {
    1303             :     Assert(*ptr == NULL);
    1304        6602 :     *ptr = MemoryContextStrdup(cxt, str);
    1305        6602 : }
    1306             : 
    1307             : /*
    1308             :  * geterrcode --- return the currently set SQLSTATE error code
    1309             :  *
    1310             :  * This is only intended for use in error callback subroutines, since there
    1311             :  * is no other place outside elog.c where the concept is meaningful.
    1312             :  */
    1313             : int
    1314        2054 : geterrcode(void)
    1315             : {
    1316        2054 :     ErrorData  *edata = &errordata[errordata_stack_depth];
    1317             : 
    1318             :     /* we don't bother incrementing recursion_depth */
    1319        2054 :     CHECK_STACK_DEPTH();
    1320             : 
    1321        2054 :     return edata->sqlerrcode;
    1322             : }
    1323             : 
    1324             : /*
    1325             :  * geterrposition --- return the currently set error position (0 if none)
    1326             :  *
    1327             :  * This is only intended for use in error callback subroutines, since there
    1328             :  * is no other place outside elog.c where the concept is meaningful.
    1329             :  */
    1330             : int
    1331        7894 : geterrposition(void)
    1332             : {
    1333        7894 :     ErrorData  *edata = &errordata[errordata_stack_depth];
    1334             : 
    1335             :     /* we don't bother incrementing recursion_depth */
    1336        7894 :     CHECK_STACK_DEPTH();
    1337             : 
    1338        7894 :     return edata->cursorpos;
    1339             : }
    1340             : 
    1341             : /*
    1342             :  * getinternalerrposition --- same for internal error position
    1343             :  *
    1344             :  * This is only intended for use in error callback subroutines, since there
    1345             :  * is no other place outside elog.c where the concept is meaningful.
    1346             :  */
    1347             : int
    1348         160 : getinternalerrposition(void)
    1349             : {
    1350         160 :     ErrorData  *edata = &errordata[errordata_stack_depth];
    1351             : 
    1352             :     /* we don't bother incrementing recursion_depth */
    1353         160 :     CHECK_STACK_DEPTH();
    1354             : 
    1355         160 :     return edata->internalpos;
    1356             : }
    1357             : 
    1358             : 
    1359             : /*
    1360             :  * Functions to allow construction of error message strings separately from
    1361             :  * the ereport() call itself.
    1362             :  *
    1363             :  * The expected calling convention is
    1364             :  *
    1365             :  *  pre_format_elog_string(errno, domain), var = format_elog_string(format,...)
    1366             :  *
    1367             :  * which can be hidden behind a macro such as GUC_check_errdetail().  We
    1368             :  * assume that any functions called in the arguments of format_elog_string()
    1369             :  * cannot result in re-entrant use of these functions --- otherwise the wrong
    1370             :  * text domain might be used, or the wrong errno substituted for %m.  This is
    1371             :  * okay for the current usage with GUC check hooks, but might need further
    1372             :  * effort someday.
    1373             :  *
    1374             :  * The result of format_elog_string() is stored in ErrorContext, and will
    1375             :  * therefore survive until FlushErrorState() is called.
    1376             :  */
    1377             : static int  save_format_errnumber;
    1378             : static const char *save_format_domain;
    1379             : 
    1380             : void
    1381          26 : pre_format_elog_string(int errnumber, const char *domain)
    1382             : {
    1383             :     /* Save errno before evaluation of argument functions can change it */
    1384          26 :     save_format_errnumber = errnumber;
    1385             :     /* Save caller's text domain */
    1386          26 :     save_format_domain = domain;
    1387          26 : }
    1388             : 
    1389             : char *
    1390          26 : format_elog_string(const char *fmt,...)
    1391             : {
    1392             :     ErrorData   errdata;
    1393             :     ErrorData  *edata;
    1394             :     MemoryContext oldcontext;
    1395             : 
    1396             :     /* Initialize a mostly-dummy error frame */
    1397          26 :     edata = &errdata;
    1398         650 :     MemSet(edata, 0, sizeof(ErrorData));
    1399             :     /* the default text domain is the backend's */
    1400          26 :     edata->domain = save_format_domain ? save_format_domain : PG_TEXTDOMAIN("postgres");
    1401             :     /* set the errno to be used to interpret %m */
    1402          26 :     edata->saved_errno = save_format_errnumber;
    1403             : 
    1404          26 :     oldcontext = MemoryContextSwitchTo(ErrorContext);
    1405             : 
    1406          26 :     edata->message_id = fmt;
    1407          26 :     EVALUATE_MESSAGE(edata->domain, message, false, true);
    1408             : 
    1409          26 :     MemoryContextSwitchTo(oldcontext);
    1410             : 
    1411          26 :     return edata->message;
    1412             : }
    1413             : 
    1414             : 
    1415             : /*
    1416             :  * Actual output of the top-of-stack error message
    1417             :  *
    1418             :  * In the ereport(ERROR) case this is called from PostgresMain (or not at all,
    1419             :  * if the error is caught by somebody).  For all other severity levels this
    1420             :  * is called by errfinish.
    1421             :  */
    1422             : void
    1423       78968 : EmitErrorReport(void)
    1424             : {
    1425       78968 :     ErrorData  *edata = &errordata[errordata_stack_depth];
    1426             :     MemoryContext oldcontext;
    1427             : 
    1428       78968 :     recursion_depth++;
    1429       78968 :     CHECK_STACK_DEPTH();
    1430       78968 :     oldcontext = MemoryContextSwitchTo(edata->assoc_context);
    1431             : 
    1432             :     /*
    1433             :      * Call hook before sending message to log.  The hook function is allowed
    1434             :      * to turn off edata->output_to_server, so we must recheck that afterward.
    1435             :      * Making any other change in the content of edata is not considered
    1436             :      * supported.
    1437             :      *
    1438             :      * Note: the reason why the hook can only turn off output_to_server, and
    1439             :      * not turn it on, is that it'd be unreliable: we will never get here at
    1440             :      * all if errstart() deems the message uninteresting.  A hook that could
    1441             :      * make decisions in that direction would have to hook into errstart(),
    1442             :      * where it would have much less information available.  emit_log_hook is
    1443             :      * intended for custom log filtering and custom log message transmission
    1444             :      * mechanisms.
    1445             :      *
    1446             :      * The log hook has access to both the translated and original English
    1447             :      * error message text, which is passed through to allow it to be used as a
    1448             :      * message identifier. Note that the original text is not available for
    1449             :      * detail, detail_log, hint and context text elements.
    1450             :      */
    1451       78968 :     if (edata->output_to_server && emit_log_hook)
    1452           0 :         (*emit_log_hook) (edata);
    1453             : 
    1454             :     /* Send to server log, if enabled */
    1455       78968 :     if (edata->output_to_server)
    1456       68108 :         send_message_to_server_log(edata);
    1457             : 
    1458             :     /* Send to client, if enabled */
    1459       78968 :     if (edata->output_to_client)
    1460       31630 :         send_message_to_frontend(edata);
    1461             : 
    1462       78968 :     MemoryContextSwitchTo(oldcontext);
    1463       78968 :     recursion_depth--;
    1464       78968 : }
    1465             : 
    1466             : /*
    1467             :  * CopyErrorData --- obtain a copy of the topmost error stack entry
    1468             :  *
    1469             :  * This is only for use in error handler code.  The data is copied into the
    1470             :  * current memory context, so callers should always switch away from
    1471             :  * ErrorContext first; otherwise it will be lost when FlushErrorState is done.
    1472             :  */
    1473             : ErrorData *
    1474        1132 : CopyErrorData(void)
    1475             : {
    1476        1132 :     ErrorData  *edata = &errordata[errordata_stack_depth];
    1477             :     ErrorData  *newedata;
    1478             : 
    1479             :     /*
    1480             :      * we don't increment recursion_depth because out-of-memory here does not
    1481             :      * indicate a problem within the error subsystem.
    1482             :      */
    1483        1132 :     CHECK_STACK_DEPTH();
    1484             : 
    1485             :     Assert(CurrentMemoryContext != ErrorContext);
    1486             : 
    1487             :     /* Copy the struct itself */
    1488        1132 :     newedata = (ErrorData *) palloc(sizeof(ErrorData));
    1489        1132 :     memcpy(newedata, edata, sizeof(ErrorData));
    1490             : 
    1491             :     /* Make copies of separately-allocated fields */
    1492        1132 :     if (newedata->message)
    1493        1132 :         newedata->message = pstrdup(newedata->message);
    1494        1132 :     if (newedata->detail)
    1495          60 :         newedata->detail = pstrdup(newedata->detail);
    1496        1132 :     if (newedata->detail_log)
    1497           0 :         newedata->detail_log = pstrdup(newedata->detail_log);
    1498        1132 :     if (newedata->hint)
    1499          44 :         newedata->hint = pstrdup(newedata->hint);
    1500        1132 :     if (newedata->context)
    1501        1106 :         newedata->context = pstrdup(newedata->context);
    1502        1132 :     if (newedata->backtrace)
    1503           0 :         newedata->backtrace = pstrdup(newedata->backtrace);
    1504        1132 :     if (newedata->schema_name)
    1505          28 :         newedata->schema_name = pstrdup(newedata->schema_name);
    1506        1132 :     if (newedata->table_name)
    1507          32 :         newedata->table_name = pstrdup(newedata->table_name);
    1508        1132 :     if (newedata->column_name)
    1509          16 :         newedata->column_name = pstrdup(newedata->column_name);
    1510        1132 :     if (newedata->datatype_name)
    1511          18 :         newedata->datatype_name = pstrdup(newedata->datatype_name);
    1512        1132 :     if (newedata->constraint_name)
    1513          26 :         newedata->constraint_name = pstrdup(newedata->constraint_name);
    1514        1132 :     if (newedata->internalquery)
    1515          32 :         newedata->internalquery = pstrdup(newedata->internalquery);
    1516             : 
    1517             :     /* Use the calling context for string allocation */
    1518        1132 :     newedata->assoc_context = CurrentMemoryContext;
    1519             : 
    1520        1132 :     return newedata;
    1521             : }
    1522             : 
    1523             : /*
    1524             :  * FreeErrorData --- free the structure returned by CopyErrorData.
    1525             :  *
    1526             :  * Error handlers should use this in preference to assuming they know all
    1527             :  * the separately-allocated fields.
    1528             :  */
    1529             : void
    1530         106 : FreeErrorData(ErrorData *edata)
    1531             : {
    1532         106 :     if (edata->message)
    1533         106 :         pfree(edata->message);
    1534         106 :     if (edata->detail)
    1535          20 :         pfree(edata->detail);
    1536         106 :     if (edata->detail_log)
    1537           0 :         pfree(edata->detail_log);
    1538         106 :     if (edata->hint)
    1539          24 :         pfree(edata->hint);
    1540         106 :     if (edata->context)
    1541          92 :         pfree(edata->context);
    1542         106 :     if (edata->backtrace)
    1543           0 :         pfree(edata->backtrace);
    1544         106 :     if (edata->schema_name)
    1545          16 :         pfree(edata->schema_name);
    1546         106 :     if (edata->table_name)
    1547          20 :         pfree(edata->table_name);
    1548         106 :     if (edata->column_name)
    1549          10 :         pfree(edata->column_name);
    1550         106 :     if (edata->datatype_name)
    1551          12 :         pfree(edata->datatype_name);
    1552         106 :     if (edata->constraint_name)
    1553          14 :         pfree(edata->constraint_name);
    1554         106 :     if (edata->internalquery)
    1555          28 :         pfree(edata->internalquery);
    1556         106 :     pfree(edata);
    1557         106 : }
    1558             : 
    1559             : /*
    1560             :  * FlushErrorState --- flush the error state after error recovery
    1561             :  *
    1562             :  * This should be called by an error handler after it's done processing
    1563             :  * the error; or as soon as it's done CopyErrorData, if it intends to
    1564             :  * do stuff that is likely to provoke another error.  You are not "out" of
    1565             :  * the error subsystem until you have done this.
    1566             :  */
    1567             : void
    1568       20060 : FlushErrorState(void)
    1569             : {
    1570             :     /*
    1571             :      * Reset stack to empty.  The only case where it would be more than one
    1572             :      * deep is if we serviced an error that interrupted construction of
    1573             :      * another message.  We assume control escaped out of that message
    1574             :      * construction and won't ever go back.
    1575             :      */
    1576       20060 :     errordata_stack_depth = -1;
    1577       20060 :     recursion_depth = 0;
    1578             :     /* Delete all data in ErrorContext */
    1579       20060 :     MemoryContextResetAndDeleteChildren(ErrorContext);
    1580       20060 : }
    1581             : 
    1582             : /*
    1583             :  * ThrowErrorData --- report an error described by an ErrorData structure
    1584             :  *
    1585             :  * This is somewhat like ReThrowError, but it allows elevels besides ERROR,
    1586             :  * and the boolean flags such as output_to_server are computed via the
    1587             :  * default rules rather than being copied from the given ErrorData.
    1588             :  * This is primarily used to re-report errors originally reported by
    1589             :  * background worker processes and then propagated (with or without
    1590             :  * modification) to the backend responsible for them.
    1591             :  */
    1592             : void
    1593           4 : ThrowErrorData(ErrorData *edata)
    1594             : {
    1595             :     ErrorData  *newedata;
    1596             :     MemoryContext oldcontext;
    1597             : 
    1598           4 :     if (!errstart(edata->elevel, edata->domain))
    1599           0 :         return;                 /* error is not to be reported at all */
    1600             : 
    1601           4 :     newedata = &errordata[errordata_stack_depth];
    1602           4 :     recursion_depth++;
    1603           4 :     oldcontext = MemoryContextSwitchTo(newedata->assoc_context);
    1604             : 
    1605             :     /* Copy the supplied fields to the error stack entry. */
    1606           4 :     if (edata->sqlerrcode != 0)
    1607           4 :         newedata->sqlerrcode = edata->sqlerrcode;
    1608           4 :     if (edata->message)
    1609           4 :         newedata->message = pstrdup(edata->message);
    1610           4 :     if (edata->detail)
    1611           0 :         newedata->detail = pstrdup(edata->detail);
    1612           4 :     if (edata->detail_log)
    1613           0 :         newedata->detail_log = pstrdup(edata->detail_log);
    1614           4 :     if (edata->hint)
    1615           0 :         newedata->hint = pstrdup(edata->hint);
    1616           4 :     if (edata->context)
    1617           4 :         newedata->context = pstrdup(edata->context);
    1618           4 :     if (edata->backtrace)
    1619           0 :         newedata->backtrace = pstrdup(edata->backtrace);
    1620             :     /* assume message_id is not available */
    1621           4 :     if (edata->schema_name)
    1622           0 :         newedata->schema_name = pstrdup(edata->schema_name);
    1623           4 :     if (edata->table_name)
    1624           0 :         newedata->table_name = pstrdup(edata->table_name);
    1625           4 :     if (edata->column_name)
    1626           0 :         newedata->column_name = pstrdup(edata->column_name);
    1627           4 :     if (edata->datatype_name)
    1628           0 :         newedata->datatype_name = pstrdup(edata->datatype_name);
    1629           4 :     if (edata->constraint_name)
    1630           0 :         newedata->constraint_name = pstrdup(edata->constraint_name);
    1631           4 :     newedata->cursorpos = edata->cursorpos;
    1632           4 :     newedata->internalpos = edata->internalpos;
    1633           4 :     if (edata->internalquery)
    1634           0 :         newedata->internalquery = pstrdup(edata->internalquery);
    1635             : 
    1636           4 :     MemoryContextSwitchTo(oldcontext);
    1637           4 :     recursion_depth--;
    1638             : 
    1639             :     /* Process the error. */
    1640           4 :     errfinish(edata->filename, edata->lineno, edata->funcname);
    1641             : }
    1642             : 
    1643             : /*
    1644             :  * ReThrowError --- re-throw a previously copied error
    1645             :  *
    1646             :  * A handler can do CopyErrorData/FlushErrorState to get out of the error
    1647             :  * subsystem, then do some processing, and finally ReThrowError to re-throw
    1648             :  * the original error.  This is slower than just PG_RE_THROW() but should
    1649             :  * be used if the "some processing" is likely to incur another error.
    1650             :  */
    1651             : void
    1652          32 : ReThrowError(ErrorData *edata)
    1653             : {
    1654             :     ErrorData  *newedata;
    1655             : 
    1656             :     Assert(edata->elevel == ERROR);
    1657             : 
    1658             :     /* Push the data back into the error context */
    1659          32 :     recursion_depth++;
    1660          32 :     MemoryContextSwitchTo(ErrorContext);
    1661             : 
    1662          32 :     if (++errordata_stack_depth >= ERRORDATA_STACK_SIZE)
    1663             :     {
    1664             :         /*
    1665             :          * Wups, stack not big enough.  We treat this as a PANIC condition
    1666             :          * because it suggests an infinite loop of errors during error
    1667             :          * recovery.
    1668             :          */
    1669           0 :         errordata_stack_depth = -1; /* make room on stack */
    1670           0 :         ereport(PANIC, (errmsg_internal("ERRORDATA_STACK_SIZE exceeded")));
    1671             :     }
    1672             : 
    1673          32 :     newedata = &errordata[errordata_stack_depth];
    1674          32 :     memcpy(newedata, edata, sizeof(ErrorData));
    1675             : 
    1676             :     /* Make copies of separately-allocated fields */
    1677          32 :     if (newedata->message)
    1678          32 :         newedata->message = pstrdup(newedata->message);
    1679          32 :     if (newedata->detail)
    1680          16 :         newedata->detail = pstrdup(newedata->detail);
    1681          32 :     if (newedata->detail_log)
    1682           0 :         newedata->detail_log = pstrdup(newedata->detail_log);
    1683          32 :     if (newedata->hint)
    1684           0 :         newedata->hint = pstrdup(newedata->hint);
    1685          32 :     if (newedata->context)
    1686          32 :         newedata->context = pstrdup(newedata->context);
    1687          32 :     if (newedata->backtrace)
    1688           0 :         newedata->backtrace = pstrdup(newedata->backtrace);
    1689          32 :     if (newedata->schema_name)
    1690           0 :         newedata->schema_name = pstrdup(newedata->schema_name);
    1691          32 :     if (newedata->table_name)
    1692           0 :         newedata->table_name = pstrdup(newedata->table_name);
    1693          32 :     if (newedata->column_name)
    1694           0 :         newedata->column_name = pstrdup(newedata->column_name);
    1695          32 :     if (newedata->datatype_name)
    1696           0 :         newedata->datatype_name = pstrdup(newedata->datatype_name);
    1697          32 :     if (newedata->constraint_name)
    1698           0 :         newedata->constraint_name = pstrdup(newedata->constraint_name);
    1699          32 :     if (newedata->internalquery)
    1700           0 :         newedata->internalquery = pstrdup(newedata->internalquery);
    1701             : 
    1702             :     /* Reset the assoc_context to be ErrorContext */
    1703          32 :     newedata->assoc_context = ErrorContext;
    1704             : 
    1705          32 :     recursion_depth--;
    1706          32 :     PG_RE_THROW();
    1707             : }
    1708             : 
    1709             : /*
    1710             :  * pg_re_throw --- out-of-line implementation of PG_RE_THROW() macro
    1711             :  */
    1712             : void
    1713       41414 : pg_re_throw(void)
    1714             : {
    1715             :     /* If possible, throw the error to the next outer setjmp handler */
    1716       41414 :     if (PG_exception_stack != NULL)
    1717       41414 :         siglongjmp(*PG_exception_stack, 1);
    1718             :     else
    1719             :     {
    1720             :         /*
    1721             :          * If we get here, elog(ERROR) was thrown inside a PG_TRY block, which
    1722             :          * we have now exited only to discover that there is no outer setjmp
    1723             :          * handler to pass the error to.  Had the error been thrown outside
    1724             :          * the block to begin with, we'd have promoted the error to FATAL, so
    1725             :          * the correct behavior is to make it FATAL now; that is, emit it and
    1726             :          * then call proc_exit.
    1727             :          */
    1728           0 :         ErrorData  *edata = &errordata[errordata_stack_depth];
    1729             : 
    1730             :         Assert(errordata_stack_depth >= 0);
    1731             :         Assert(edata->elevel == ERROR);
    1732           0 :         edata->elevel = FATAL;
    1733             : 
    1734             :         /*
    1735             :          * At least in principle, the increase in severity could have changed
    1736             :          * where-to-output decisions, so recalculate.  This should stay in
    1737             :          * sync with errstart(), which see for comments.
    1738             :          */
    1739           0 :         if (IsPostmasterEnvironment)
    1740           0 :             edata->output_to_server = is_log_level_output(FATAL,
    1741             :                                                           log_min_messages);
    1742             :         else
    1743           0 :             edata->output_to_server = (FATAL >= log_min_messages);
    1744           0 :         if (whereToSendOutput == DestRemote)
    1745           0 :             edata->output_to_client = true;
    1746             : 
    1747             :         /*
    1748             :          * We can use errfinish() for the rest, but we don't want it to call
    1749             :          * any error context routines a second time.  Since we know we are
    1750             :          * about to exit, it should be OK to just clear the context stack.
    1751             :          */
    1752           0 :         error_context_stack = NULL;
    1753             : 
    1754           0 :         errfinish(edata->filename, edata->lineno, edata->funcname);
    1755             :     }
    1756             : 
    1757             :     /* Doesn't return ... */
    1758           0 :     ExceptionalCondition("pg_re_throw tried to return", "FailedAssertion",
    1759             :                          __FILE__, __LINE__);
    1760             : }
    1761             : 
    1762             : 
    1763             : /*
    1764             :  * GetErrorContextStack - Return the context stack, for display/diags
    1765             :  *
    1766             :  * Returns a pstrdup'd string in the caller's context which includes the PG
    1767             :  * error call stack.  It is the caller's responsibility to ensure this string
    1768             :  * is pfree'd (or its context cleaned up) when done.
    1769             :  *
    1770             :  * This information is collected by traversing the error contexts and calling
    1771             :  * each context's callback function, each of which is expected to call
    1772             :  * errcontext() to return a string which can be presented to the user.
    1773             :  */
    1774             : char *
    1775          32 : GetErrorContextStack(void)
    1776             : {
    1777             :     ErrorData  *edata;
    1778             :     ErrorContextCallback *econtext;
    1779             : 
    1780             :     /*
    1781             :      * Okay, crank up a stack entry to store the info in.
    1782             :      */
    1783          32 :     recursion_depth++;
    1784             : 
    1785          32 :     if (++errordata_stack_depth >= ERRORDATA_STACK_SIZE)
    1786             :     {
    1787             :         /*
    1788             :          * Wups, stack not big enough.  We treat this as a PANIC condition
    1789             :          * because it suggests an infinite loop of errors during error
    1790             :          * recovery.
    1791             :          */
    1792           0 :         errordata_stack_depth = -1; /* make room on stack */
    1793           0 :         ereport(PANIC, (errmsg_internal("ERRORDATA_STACK_SIZE exceeded")));
    1794             :     }
    1795             : 
    1796             :     /*
    1797             :      * Things look good so far, so initialize our error frame
    1798             :      */
    1799          32 :     edata = &errordata[errordata_stack_depth];
    1800         800 :     MemSet(edata, 0, sizeof(ErrorData));
    1801             : 
    1802             :     /*
    1803             :      * Set up assoc_context to be the caller's context, so any allocations
    1804             :      * done (which will include edata->context) will use their context.
    1805             :      */
    1806          32 :     edata->assoc_context = CurrentMemoryContext;
    1807             : 
    1808             :     /*
    1809             :      * Call any context callback functions to collect the context information
    1810             :      * into edata->context.
    1811             :      *
    1812             :      * Errors occurring in callback functions should go through the regular
    1813             :      * error handling code which should handle any recursive errors, though we
    1814             :      * double-check above, just in case.
    1815             :      */
    1816         128 :     for (econtext = error_context_stack;
    1817             :          econtext != NULL;
    1818          96 :          econtext = econtext->previous)
    1819          96 :         econtext->callback(econtext->arg);
    1820             : 
    1821             :     /*
    1822             :      * Clean ourselves off the stack, any allocations done should have been
    1823             :      * using edata->assoc_context, which we set up earlier to be the caller's
    1824             :      * context, so we're free to just remove our entry off the stack and
    1825             :      * decrement recursion depth and exit.
    1826             :      */
    1827          32 :     errordata_stack_depth--;
    1828          32 :     recursion_depth--;
    1829             : 
    1830             :     /*
    1831             :      * Return a pointer to the string the caller asked for, which should have
    1832             :      * been allocated in their context.
    1833             :      */
    1834          32 :     return edata->context;
    1835             : }
    1836             : 
    1837             : 
    1838             : /*
    1839             :  * Initialization of error output file
    1840             :  */
    1841             : void
    1842       13876 : DebugFileOpen(void)
    1843             : {
    1844             :     int         fd,
    1845             :                 istty;
    1846             : 
    1847       13876 :     if (OutputFileName[0])
    1848             :     {
    1849             :         /*
    1850             :          * A debug-output file name was given.
    1851             :          *
    1852             :          * Make sure we can write the file, and find out if it's a tty.
    1853             :          */
    1854           0 :         if ((fd = open(OutputFileName, O_CREAT | O_APPEND | O_WRONLY,
    1855             :                        0666)) < 0)
    1856           0 :             ereport(FATAL,
    1857             :                     (errcode_for_file_access(),
    1858             :                      errmsg("could not open file \"%s\": %m", OutputFileName)));
    1859           0 :         istty = isatty(fd);
    1860           0 :         close(fd);
    1861             : 
    1862             :         /*
    1863             :          * Redirect our stderr to the debug output file.
    1864             :          */
    1865           0 :         if (!freopen(OutputFileName, "a", stderr))
    1866           0 :             ereport(FATAL,
    1867             :                     (errcode_for_file_access(),
    1868             :                      errmsg("could not reopen file \"%s\" as stderr: %m",
    1869             :                             OutputFileName)));
    1870             : 
    1871             :         /*
    1872             :          * If the file is a tty and we're running under the postmaster, try to
    1873             :          * send stdout there as well (if it isn't a tty then stderr will block
    1874             :          * out stdout, so we may as well let stdout go wherever it was going
    1875             :          * before).
    1876             :          */
    1877           0 :         if (istty && IsUnderPostmaster)
    1878           0 :             if (!freopen(OutputFileName, "a", stdout))
    1879           0 :                 ereport(FATAL,
    1880             :                         (errcode_for_file_access(),
    1881             :                          errmsg("could not reopen file \"%s\" as stdout: %m",
    1882             :                                 OutputFileName)));
    1883             :     }
    1884       13876 : }
    1885             : 
    1886             : 
    1887             : #ifdef HAVE_SYSLOG
    1888             : 
    1889             : /*
    1890             :  * Set or update the parameters for syslog logging
    1891             :  */
    1892             : void
    1893        4368 : set_syslog_parameters(const char *ident, int facility)
    1894             : {
    1895             :     /*
    1896             :      * guc.c is likely to call us repeatedly with same parameters, so don't
    1897             :      * thrash the syslog connection unnecessarily.  Also, we do not re-open
    1898             :      * the connection until needed, since this routine will get called whether
    1899             :      * or not Log_destination actually mentions syslog.
    1900             :      *
    1901             :      * Note that we make our own copy of the ident string rather than relying
    1902             :      * on guc.c's.  This may be overly paranoid, but it ensures that we cannot
    1903             :      * accidentally free a string that syslog is still using.
    1904             :      */
    1905        4368 :     if (syslog_ident == NULL || strcmp(syslog_ident, ident) != 0 ||
    1906        2184 :         syslog_facility != facility)
    1907             :     {
    1908        2184 :         if (openlog_done)
    1909             :         {
    1910           0 :             closelog();
    1911           0 :             openlog_done = false;
    1912             :         }
    1913        2184 :         if (syslog_ident)
    1914           0 :             free(syslog_ident);
    1915        2184 :         syslog_ident = strdup(ident);
    1916             :         /* if the strdup fails, we will cope in write_syslog() */
    1917        2184 :         syslog_facility = facility;
    1918             :     }
    1919        4368 : }
    1920             : 
    1921             : 
    1922             : /*
    1923             :  * Write a message line to syslog
    1924             :  */
    1925             : static void
    1926           0 : write_syslog(int level, const char *line)
    1927             : {
    1928             :     static unsigned long seq = 0;
    1929             : 
    1930             :     int         len;
    1931             :     const char *nlpos;
    1932             : 
    1933             :     /* Open syslog connection if not done yet */
    1934           0 :     if (!openlog_done)
    1935             :     {
    1936           0 :         openlog(syslog_ident ? syslog_ident : "postgres",
    1937             :                 LOG_PID | LOG_NDELAY | LOG_NOWAIT,
    1938             :                 syslog_facility);
    1939           0 :         openlog_done = true;
    1940             :     }
    1941             : 
    1942             :     /*
    1943             :      * We add a sequence number to each log message to suppress "same"
    1944             :      * messages.
    1945             :      */
    1946           0 :     seq++;
    1947             : 
    1948             :     /*
    1949             :      * Our problem here is that many syslog implementations don't handle long
    1950             :      * messages in an acceptable manner. While this function doesn't help that
    1951             :      * fact, it does work around by splitting up messages into smaller pieces.
    1952             :      *
    1953             :      * We divide into multiple syslog() calls if message is too long or if the
    1954             :      * message contains embedded newline(s).
    1955             :      */
    1956           0 :     len = strlen(line);
    1957           0 :     nlpos = strchr(line, '\n');
    1958           0 :     if (syslog_split_messages && (len > PG_SYSLOG_LIMIT || nlpos != NULL))
    1959           0 :     {
    1960           0 :         int         chunk_nr = 0;
    1961             : 
    1962           0 :         while (len > 0)
    1963             :         {
    1964             :             char        buf[PG_SYSLOG_LIMIT + 1];
    1965             :             int         buflen;
    1966             :             int         i;
    1967             : 
    1968             :             /* if we start at a newline, move ahead one char */
    1969           0 :             if (line[0] == '\n')
    1970             :             {
    1971           0 :                 line++;
    1972           0 :                 len--;
    1973             :                 /* we need to recompute the next newline's position, too */
    1974           0 :                 nlpos = strchr(line, '\n');
    1975           0 :                 continue;
    1976             :             }
    1977             : 
    1978             :             /* copy one line, or as much as will fit, to buf */
    1979           0 :             if (nlpos != NULL)
    1980           0 :                 buflen = nlpos - line;
    1981             :             else
    1982           0 :                 buflen = len;
    1983           0 :             buflen = Min(buflen, PG_SYSLOG_LIMIT);
    1984           0 :             memcpy(buf, line, buflen);
    1985           0 :             buf[buflen] = '\0';
    1986             : 
    1987             :             /* trim to multibyte letter boundary */
    1988           0 :             buflen = pg_mbcliplen(buf, buflen, buflen);
    1989           0 :             if (buflen <= 0)
    1990           0 :                 return;
    1991           0 :             buf[buflen] = '\0';
    1992             : 
    1993             :             /* already word boundary? */
    1994           0 :             if (line[buflen] != '\0' &&
    1995           0 :                 !isspace((unsigned char) line[buflen]))
    1996             :             {
    1997             :                 /* try to divide at word boundary */
    1998           0 :                 i = buflen - 1;
    1999           0 :                 while (i > 0 && !isspace((unsigned char) buf[i]))
    2000           0 :                     i--;
    2001             : 
    2002           0 :                 if (i > 0)       /* else couldn't divide word boundary */
    2003             :                 {
    2004           0 :                     buflen = i;
    2005           0 :                     buf[i] = '\0';
    2006             :                 }
    2007             :             }
    2008             : 
    2009           0 :             chunk_nr++;
    2010             : 
    2011           0 :             if (syslog_sequence_numbers)
    2012           0 :                 syslog(level, "[%lu-%d] %s", seq, chunk_nr, buf);
    2013             :             else
    2014           0 :                 syslog(level, "[%d] %s", chunk_nr, buf);
    2015             : 
    2016           0 :             line += buflen;
    2017           0 :             len -= buflen;
    2018             :         }
    2019             :     }
    2020             :     else
    2021             :     {
    2022             :         /* message short enough */
    2023           0 :         if (syslog_sequence_numbers)
    2024           0 :             syslog(level, "[%lu] %s", seq, line);
    2025             :         else
    2026           0 :             syslog(level, "%s", line);
    2027             :     }
    2028             : }
    2029             : #endif                          /* HAVE_SYSLOG */
    2030             : 
    2031             : #ifdef WIN32
    2032             : /*
    2033             :  * Get the PostgreSQL equivalent of the Windows ANSI code page.  "ANSI" system
    2034             :  * interfaces (e.g. CreateFileA()) expect string arguments in this encoding.
    2035             :  * Every process in a given system will find the same value at all times.
    2036             :  */
    2037             : static int
    2038             : GetACPEncoding(void)
    2039             : {
    2040             :     static int  encoding = -2;
    2041             : 
    2042             :     if (encoding == -2)
    2043             :         encoding = pg_codepage_to_encoding(GetACP());
    2044             : 
    2045             :     return encoding;
    2046             : }
    2047             : 
    2048             : /*
    2049             :  * Write a message line to the windows event log
    2050             :  */
    2051             : static void
    2052             : write_eventlog(int level, const char *line, int len)
    2053             : {
    2054             :     WCHAR      *utf16;
    2055             :     int         eventlevel = EVENTLOG_ERROR_TYPE;
    2056             :     static HANDLE evtHandle = INVALID_HANDLE_VALUE;
    2057             : 
    2058             :     if (evtHandle == INVALID_HANDLE_VALUE)
    2059             :     {
    2060             :         evtHandle = RegisterEventSource(NULL,
    2061             :                                         event_source ? event_source : DEFAULT_EVENT_SOURCE);
    2062             :         if (evtHandle == NULL)
    2063             :         {
    2064             :             evtHandle = INVALID_HANDLE_VALUE;
    2065             :             return;
    2066             :         }
    2067             :     }
    2068             : 
    2069             :     switch (level)
    2070             :     {
    2071             :         case DEBUG5:
    2072             :         case DEBUG4:
    2073             :         case DEBUG3:
    2074             :         case DEBUG2:
    2075             :         case DEBUG1:
    2076             :         case LOG:
    2077             :         case LOG_SERVER_ONLY:
    2078             :         case INFO:
    2079             :         case NOTICE:
    2080             :             eventlevel = EVENTLOG_INFORMATION_TYPE;
    2081             :             break;
    2082             :         case WARNING:
    2083             :             eventlevel = EVENTLOG_WARNING_TYPE;
    2084             :             break;
    2085             :         case ERROR:
    2086             :         case FATAL:
    2087             :         case PANIC:
    2088             :         default:
    2089             :             eventlevel = EVENTLOG_ERROR_TYPE;
    2090             :             break;
    2091             :     }
    2092             : 
    2093             :     /*
    2094             :      * If message character encoding matches the encoding expected by
    2095             :      * ReportEventA(), call it to avoid the hazards of conversion.  Otherwise,
    2096             :      * try to convert the message to UTF16 and write it with ReportEventW().
    2097             :      * Fall back on ReportEventA() if conversion failed.
    2098             :      *
    2099             :      * Since we palloc the structure required for conversion, also fall
    2100             :      * through to writing unconverted if we have not yet set up
    2101             :      * CurrentMemoryContext.
    2102             :      *
    2103             :      * Also verify that we are not on our way into error recursion trouble due
    2104             :      * to error messages thrown deep inside pgwin32_message_to_UTF16().
    2105             :      */
    2106             :     if (!in_error_recursion_trouble() &&
    2107             :         CurrentMemoryContext != NULL &&
    2108             :         GetMessageEncoding() != GetACPEncoding())
    2109             :     {
    2110             :         utf16 = pgwin32_message_to_UTF16(line, len, NULL);
    2111             :         if (utf16)
    2112             :         {
    2113             :             ReportEventW(evtHandle,
    2114             :                          eventlevel,
    2115             :                          0,
    2116             :                          0,     /* All events are Id 0 */
    2117             :                          NULL,
    2118             :                          1,
    2119             :                          0,
    2120             :                          (LPCWSTR *) &utf16,
    2121             :                          NULL);
    2122             :             /* XXX Try ReportEventA() when ReportEventW() fails? */
    2123             : 
    2124             :             pfree(utf16);
    2125             :             return;
    2126             :         }
    2127             :     }
    2128             :     ReportEventA(evtHandle,
    2129             :                  eventlevel,
    2130             :                  0,
    2131             :                  0,             /* All events are Id 0 */
    2132             :                  NULL,
    2133             :                  1,
    2134             :                  0,
    2135             :                  &line,
    2136             :                  NULL);
    2137             : }
    2138             : #endif                          /* WIN32 */
    2139             : 
    2140             : static void
    2141       68084 : write_console(const char *line, int len)
    2142             : {
    2143             :     int         rc;
    2144             : 
    2145             : #ifdef WIN32
    2146             : 
    2147             :     /*
    2148             :      * Try to convert the message to UTF16 and write it with WriteConsoleW().
    2149             :      * Fall back on write() if anything fails.
    2150             :      *
    2151             :      * In contrast to write_eventlog(), don't skip straight to write() based
    2152             :      * on the applicable encodings.  Unlike WriteConsoleW(), write() depends
    2153             :      * on the suitability of the console output code page.  Since we put
    2154             :      * stderr into binary mode in SubPostmasterMain(), write() skips the
    2155             :      * necessary translation anyway.
    2156             :      *
    2157             :      * WriteConsoleW() will fail if stderr is redirected, so just fall through
    2158             :      * to writing unconverted to the logfile in this case.
    2159             :      *
    2160             :      * Since we palloc the structure required for conversion, also fall
    2161             :      * through to writing unconverted if we have not yet set up
    2162             :      * CurrentMemoryContext.
    2163             :      */
    2164             :     if (!in_error_recursion_trouble() &&
    2165             :         !redirection_done &&
    2166             :         CurrentMemoryContext != NULL)
    2167             :     {
    2168             :         WCHAR      *utf16;
    2169             :         int         utf16len;
    2170             : 
    2171             :         utf16 = pgwin32_message_to_UTF16(line, len, &utf16len);
    2172             :         if (utf16 != NULL)
    2173             :         {
    2174             :             HANDLE      stdHandle;
    2175             :             DWORD       written;
    2176             : 
    2177             :             stdHandle = GetStdHandle(STD_ERROR_HANDLE);
    2178             :             if (WriteConsoleW(stdHandle, utf16, utf16len, &written, NULL))
    2179             :             {
    2180             :                 pfree(utf16);
    2181             :                 return;
    2182             :             }
    2183             : 
    2184             :             /*
    2185             :              * In case WriteConsoleW() failed, fall back to writing the
    2186             :              * message unconverted.
    2187             :              */
    2188             :             pfree(utf16);
    2189             :         }
    2190             :     }
    2191             : #else
    2192             : 
    2193             :     /*
    2194             :      * Conversion on non-win32 platforms is not implemented yet. It requires
    2195             :      * non-throw version of pg_do_encoding_conversion(), that converts
    2196             :      * unconvertable characters to '?' without errors.
    2197             :      */
    2198             : #endif
    2199             : 
    2200             :     /*
    2201             :      * We ignore any error from write() here.  We have no useful way to report
    2202             :      * it ... certainly whining on stderr isn't likely to be productive.
    2203             :      */
    2204       68084 :     rc = write(fileno(stderr), line, len);
    2205             :     (void) rc;
    2206       68084 : }
    2207             : 
    2208             : /*
    2209             :  * setup formatted_log_time, for consistent times between CSV and regular logs
    2210             :  */
    2211             : static void
    2212      101030 : setup_formatted_log_time(void)
    2213             : {
    2214             :     pg_time_t   stamp_time;
    2215             :     char        msbuf[13];
    2216             : 
    2217      101030 :     if (!saved_timeval_set)
    2218             :     {
    2219       68108 :         gettimeofday(&saved_timeval, NULL);
    2220       68108 :         saved_timeval_set = true;
    2221             :     }
    2222             : 
    2223      101030 :     stamp_time = (pg_time_t) saved_timeval.tv_sec;
    2224             : 
    2225             :     /*
    2226             :      * Note: we expect that guc.c will ensure that log_timezone is set up (at
    2227             :      * least with a minimal GMT value) before Log_line_prefix can become
    2228             :      * nonempty or CSV mode can be selected.
    2229             :      */
    2230      101030 :     pg_strftime(formatted_log_time, FORMATTED_TS_LEN,
    2231             :     /* leave room for milliseconds... */
    2232             :                 "%Y-%m-%d %H:%M:%S     %Z",
    2233      101030 :                 pg_localtime(&stamp_time, log_timezone));
    2234             : 
    2235             :     /* 'paste' milliseconds into place... */
    2236      101030 :     sprintf(msbuf, ".%03d", (int) (saved_timeval.tv_usec / 1000));
    2237      101030 :     memcpy(formatted_log_time + 19, msbuf, 4);
    2238      101030 : }
    2239             : 
    2240             : /*
    2241             :  * setup formatted_start_time
    2242             :  */
    2243             : static void
    2244           0 : setup_formatted_start_time(void)
    2245             : {
    2246           0 :     pg_time_t   stamp_time = (pg_time_t) MyStartTime;
    2247             : 
    2248             :     /*
    2249             :      * Note: we expect that guc.c will ensure that log_timezone is set up (at
    2250             :      * least with a minimal GMT value) before Log_line_prefix can become
    2251             :      * nonempty or CSV mode can be selected.
    2252             :      */
    2253           0 :     pg_strftime(formatted_start_time, FORMATTED_TS_LEN,
    2254             :                 "%Y-%m-%d %H:%M:%S %Z",
    2255           0 :                 pg_localtime(&stamp_time, log_timezone));
    2256           0 : }
    2257             : 
    2258             : /*
    2259             :  * process_log_prefix_padding --- helper function for processing the format
    2260             :  * string in log_line_prefix
    2261             :  *
    2262             :  * Note: This function returns NULL if it finds something which
    2263             :  * it deems invalid in the format string.
    2264             :  */
    2265             : static const char *
    2266           0 : process_log_prefix_padding(const char *p, int *ppadding)
    2267             : {
    2268           0 :     int         paddingsign = 1;
    2269           0 :     int         padding = 0;
    2270             : 
    2271           0 :     if (*p == '-')
    2272             :     {
    2273           0 :         p++;
    2274             : 
    2275           0 :         if (*p == '\0')         /* Did the buf end in %- ? */
    2276           0 :             return NULL;
    2277           0 :         paddingsign = -1;
    2278             :     }
    2279             : 
    2280             :     /* generate an int version of the numerical string */
    2281           0 :     while (*p >= '0' && *p <= '9')
    2282           0 :         padding = padding * 10 + (*p++ - '0');
    2283             : 
    2284             :     /* format is invalid if it ends with the padding number */
    2285           0 :     if (*p == '\0')
    2286           0 :         return NULL;
    2287             : 
    2288           0 :     padding *= paddingsign;
    2289           0 :     *ppadding = padding;
    2290           0 :     return p;
    2291             : }
    2292             : 
    2293             : /*
    2294             :  * Format tag info for log lines; append to the provided buffer.
    2295             :  */
    2296             : static void
    2297      101030 : log_line_prefix(StringInfo buf, ErrorData *edata)
    2298             : {
    2299             :     /* static counter for line numbers */
    2300             :     static long log_line_number = 0;
    2301             : 
    2302             :     /* has counter been reset in current process? */
    2303             :     static int  log_my_pid = 0;
    2304             :     int         padding;
    2305             :     const char *p;
    2306             : 
    2307             :     /*
    2308             :      * This is one of the few places where we'd rather not inherit a static
    2309             :      * variable's value from the postmaster.  But since we will, reset it when
    2310             :      * MyProcPid changes. MyStartTime also changes when MyProcPid does, so
    2311             :      * reset the formatted start timestamp too.
    2312             :      */
    2313      101030 :     if (log_my_pid != MyProcPid)
    2314             :     {
    2315        8508 :         log_line_number = 0;
    2316        8508 :         log_my_pid = MyProcPid;
    2317        8508 :         formatted_start_time[0] = '\0';
    2318             :     }
    2319      101030 :     log_line_number++;
    2320             : 
    2321      101030 :     if (Log_line_prefix == NULL)
    2322        9360 :         return;                 /* in case guc hasn't run yet */
    2323             : 
    2324      951838 :     for (p = Log_line_prefix; *p != '\0'; p++)
    2325             :     {
    2326      860168 :         if (*p != '%')
    2327             :         {
    2328             :             /* literal char, just copy */
    2329      474518 :             appendStringInfoChar(buf, *p);
    2330      474518 :             continue;
    2331             :         }
    2332             : 
    2333             :         /* must be a '%', so skip to the next char */
    2334      385650 :         p++;
    2335      385650 :         if (*p == '\0')
    2336           0 :             break;              /* format error - ignore it */
    2337      385650 :         else if (*p == '%')
    2338             :         {
    2339             :             /* string contains %% */
    2340           0 :             appendStringInfoChar(buf, '%');
    2341           0 :             continue;
    2342             :         }
    2343             : 
    2344             : 
    2345             :         /*
    2346             :          * Process any formatting which may exist after the '%'.  Note that
    2347             :          * process_log_prefix_padding moves p past the padding number if it
    2348             :          * exists.
    2349             :          *
    2350             :          * Note: Since only '-', '0' to '9' are valid formatting characters we
    2351             :          * can do a quick check here to pre-check for formatting. If the char
    2352             :          * is not formatting then we can skip a useless function call.
    2353             :          *
    2354             :          * Further note: At least on some platforms, passing %*s rather than
    2355             :          * %s to appendStringInfo() is substantially slower, so many of the
    2356             :          * cases below avoid doing that unless non-zero padding is in fact
    2357             :          * specified.
    2358             :          */
    2359      385650 :         if (*p > '9')
    2360      385650 :             padding = 0;
    2361           0 :         else if ((p = process_log_prefix_padding(p, &padding)) == NULL)
    2362           0 :             break;
    2363             : 
    2364             :         /* process the option */
    2365      385650 :         switch (*p)
    2366             :         {
    2367       70398 :             case 'a':
    2368       70398 :                 if (MyProcPort)
    2369             :                 {
    2370       70398 :                     const char *appname = application_name;
    2371             : 
    2372       70398 :                     if (appname == NULL || *appname == '\0')
    2373         404 :                         appname = _("[unknown]");
    2374       70398 :                     if (padding != 0)
    2375           0 :                         appendStringInfo(buf, "%*s", padding, appname);
    2376             :                     else
    2377       70398 :                         appendStringInfoString(buf, appname);
    2378             :                 }
    2379           0 :                 else if (padding != 0)
    2380           0 :                     appendStringInfoSpaces(buf,
    2381             :                                            padding > 0 ? padding : -padding);
    2382             : 
    2383       70398 :                 break;
    2384       33434 :             case 'b':
    2385             :                 {
    2386             :                     const char *backend_type_str;
    2387             : 
    2388       33434 :                     if (MyProcPid == PostmasterPid)
    2389         950 :                         backend_type_str = "postmaster";
    2390       32484 :                     else if (MyBackendType == B_BG_WORKER)
    2391          66 :                         backend_type_str = MyBgworkerEntry->bgw_type;
    2392             :                     else
    2393       32418 :                         backend_type_str = GetBackendTypeDesc(MyBackendType);
    2394             : 
    2395       33434 :                     if (padding != 0)
    2396           0 :                         appendStringInfo(buf, "%*s", padding, backend_type_str);
    2397             :                     else
    2398       33434 :                         appendStringInfoString(buf, backend_type_str);
    2399       33434 :                     break;
    2400             :                 }
    2401           0 :             case 'u':
    2402           0 :                 if (MyProcPort)
    2403             :                 {
    2404           0 :                     const char *username = MyProcPort->user_name;
    2405             : 
    2406           0 :                     if (username == NULL || *username == '\0')
    2407           0 :                         username = _("[unknown]");
    2408           0 :                     if (padding != 0)
    2409           0 :                         appendStringInfo(buf, "%*s", padding, username);
    2410             :                     else
    2411           0 :                         appendStringInfoString(buf, username);
    2412             :                 }
    2413           0 :                 else if (padding != 0)
    2414           0 :                     appendStringInfoSpaces(buf,
    2415             :                                            padding > 0 ? padding : -padding);
    2416           0 :                 break;
    2417           0 :             case 'd':
    2418           0 :                 if (MyProcPort)
    2419             :                 {
    2420           0 :                     const char *dbname = MyProcPort->database_name;
    2421             : 
    2422           0 :                     if (dbname == NULL || *dbname == '\0')
    2423           0 :                         dbname = _("[unknown]");
    2424           0 :                     if (padding != 0)
    2425           0 :                         appendStringInfo(buf, "%*s", padding, dbname);
    2426             :                     else
    2427           0 :                         appendStringInfoString(buf, dbname);
    2428             :                 }
    2429           0 :                 else if (padding != 0)
    2430           0 :                     appendStringInfoSpaces(buf,
    2431             :                                            padding > 0 ? padding : -padding);
    2432           0 :                 break;
    2433           0 :             case 'c':
    2434           0 :                 if (padding != 0)
    2435             :                 {
    2436             :                     char        strfbuf[128];
    2437             : 
    2438           0 :                     snprintf(strfbuf, sizeof(strfbuf) - 1, "%lx.%x",
    2439             :                              (long) (MyStartTime), MyProcPid);
    2440           0 :                     appendStringInfo(buf, "%*s", padding, strfbuf);
    2441             :                 }
    2442             :                 else
    2443           0 :                     appendStringInfo(buf, "%lx.%x", (long) (MyStartTime), MyProcPid);
    2444           0 :                 break;
    2445      101030 :             case 'p':
    2446      101030 :                 if (padding != 0)
    2447           0 :                     appendStringInfo(buf, "%*d", padding, MyProcPid);
    2448             :                 else
    2449      101030 :                     appendStringInfo(buf, "%d", MyProcPid);
    2450      101030 :                 break;
    2451           0 :             case 'l':
    2452           0 :                 if (padding != 0)
    2453           0 :                     appendStringInfo(buf, "%*ld", padding, log_line_number);
    2454             :                 else
    2455           0 :                     appendStringInfo(buf, "%ld", log_line_number);
    2456           0 :                 break;
    2457      101030 :             case 'm':
    2458      101030 :                 setup_formatted_log_time();
    2459      101030 :                 if (padding != 0)
    2460           0 :                     appendStringInfo(buf, "%*s", padding, formatted_log_time);
    2461             :                 else
    2462      101030 :                     appendStringInfoString(buf, formatted_log_time);
    2463      101030 :                 break;
    2464           0 :             case 't':
    2465           0 :                 {
    2466           0 :                     pg_time_t   stamp_time = (pg_time_t) time(NULL);
    2467             :                     char        strfbuf[128];
    2468             : 
    2469           0 :                     pg_strftime(strfbuf, sizeof(strfbuf),
    2470             :                                 "%Y-%m-%d %H:%M:%S %Z",
    2471           0 :                                 pg_localtime(&stamp_time, log_timezone));
    2472           0 :                     if (padding != 0)
    2473           0 :                         appendStringInfo(buf, "%*s", padding, strfbuf);
    2474             :                     else
    2475           0 :                         appendStringInfoString(buf, strfbuf);
    2476             :                 }
    2477           0 :                 break;
    2478           0 :             case 'n':
    2479           0 :                 {
    2480             :                     char        strfbuf[128];
    2481             : 
    2482           0 :                     if (!saved_timeval_set)
    2483             :                     {
    2484           0 :                         gettimeofday(&saved_timeval, NULL);
    2485           0 :                         saved_timeval_set = true;
    2486             :                     }
    2487             : 
    2488           0 :                     snprintf(strfbuf, sizeof(strfbuf), "%ld.%03d",
    2489           0 :                              (long) saved_timeval.tv_sec,
    2490           0 :                              (int) (saved_timeval.tv_usec / 1000));
    2491             : 
    2492           0 :                     if (padding != 0)
    2493           0 :                         appendStringInfo(buf, "%*s", padding, strfbuf);
    2494             :                     else
    2495           0 :                         appendStringInfoString(buf, strfbuf);
    2496             :                 }
    2497           0 :                 break;
    2498           0 :             case 's':
    2499           0 :                 if (formatted_start_time[0] == '\0')
    2500           0 :                     setup_formatted_start_time();
    2501           0 :                 if (padding != 0)
    2502           0 :                     appendStringInfo(buf, "%*s", padding, formatted_start_time);
    2503             :                 else
    2504           0 :                     appendStringInfoString(buf, formatted_start_time);
    2505           0 :                 break;
    2506           0 :             case 'i':
    2507           0 :                 if (MyProcPort)
    2508             :                 {
    2509             :                     const char *psdisp;
    2510             :                     int         displen;
    2511             : 
    2512           0 :                     psdisp = get_ps_display(&displen);
    2513           0 :                     if (padding != 0)
    2514           0 :                         appendStringInfo(buf, "%*s", padding, psdisp);
    2515             :                     else
    2516           0 :                         appendBinaryStringInfo(buf, psdisp, displen);
    2517             : 
    2518             :                 }
    2519           0 :                 else if (padding != 0)
    2520           0 :                     appendStringInfoSpaces(buf,
    2521             :                                            padding > 0 ? padding : -padding);
    2522           0 :                 break;
    2523           0 :             case 'r':
    2524           0 :                 if (MyProcPort && MyProcPort->remote_host)
    2525             :                 {
    2526           0 :                     if (padding != 0)
    2527             :                     {
    2528           0 :                         if (MyProcPort->remote_port && MyProcPort->remote_port[0] != '\0')
    2529           0 :                         {
    2530             :                             /*
    2531             :                              * This option is slightly special as the port
    2532             :                              * number may be appended onto the end. Here we
    2533             :                              * need to build 1 string which contains the
    2534             :                              * remote_host and optionally the remote_port (if
    2535             :                              * set) so we can properly align the string.
    2536             :                              */
    2537             : 
    2538             :                             char       *hostport;
    2539             : 
    2540           0 :                             hostport = psprintf("%s(%s)", MyProcPort->remote_host, MyProcPort->remote_port);
    2541           0 :                             appendStringInfo(buf, "%*s", padding, hostport);
    2542           0 :                             pfree(hostport);
    2543             :                         }
    2544             :                         else
    2545           0 :                             appendStringInfo(buf, "%*s", padding, MyProcPort->remote_host);
    2546             :                     }
    2547             :                     else
    2548             :                     {
    2549             :                         /* padding is 0, so we don't need a temp buffer */
    2550           0 :                         appendStringInfoString(buf, MyProcPort->remote_host);
    2551           0 :                         if (MyProcPort->remote_port &&
    2552           0 :                             MyProcPort->remote_port[0] != '\0')
    2553           0 :                             appendStringInfo(buf, "(%s)",
    2554           0 :                                              MyProcPort->remote_port);
    2555             :                     }
    2556             : 
    2557             :                 }
    2558           0 :                 else if (padding != 0)
    2559           0 :                     appendStringInfoSpaces(buf,
    2560             :                                            padding > 0 ? padding : -padding);
    2561           0 :                 break;
    2562           0 :             case 'h':
    2563           0 :                 if (MyProcPort && MyProcPort->remote_host)
    2564             :                 {
    2565           0 :                     if (padding != 0)
    2566           0 :                         appendStringInfo(buf, "%*s", padding, MyProcPort->remote_host);
    2567             :                     else
    2568           0 :                         appendStringInfoString(buf, MyProcPort->remote_host);
    2569             :                 }
    2570           0 :                 else if (padding != 0)
    2571           0 :                     appendStringInfoSpaces(buf,
    2572             :                                            padding > 0 ? padding : -padding);
    2573           0 :                 break;
    2574       79758 :             case 'q':
    2575             :                 /* in postmaster and friends, stop if %q is seen */
    2576             :                 /* in a backend, just ignore */
    2577       79758 :                 if (MyProcPort == NULL)
    2578        9360 :                     return;
    2579       70398 :                 break;
    2580           0 :             case 'v':
    2581             :                 /* keep VXID format in sync with lockfuncs.c */
    2582           0 :                 if (MyProc != NULL && MyProc->backendId != InvalidBackendId)
    2583             :                 {
    2584           0 :                     if (padding != 0)
    2585             :                     {
    2586             :                         char        strfbuf[128];
    2587             : 
    2588           0 :                         snprintf(strfbuf, sizeof(strfbuf) - 1, "%d/%u",
    2589           0 :                                  MyProc->backendId, MyProc->lxid);
    2590           0 :                         appendStringInfo(buf, "%*s", padding, strfbuf);
    2591             :                     }
    2592             :                     else
    2593           0 :                         appendStringInfo(buf, "%d/%u", MyProc->backendId, MyProc->lxid);
    2594             :                 }
    2595           0 :                 else if (padding != 0)
    2596           0 :                     appendStringInfoSpaces(buf,
    2597             :                                            padding > 0 ? padding : -padding);
    2598           0 :                 break;
    2599           0 :             case 'x':
    2600           0 :                 if (padding != 0)
    2601           0 :                     appendStringInfo(buf, "%*u", padding, GetTopTransactionIdIfAny());
    2602             :                 else
    2603           0 :                     appendStringInfo(buf, "%u", GetTopTransactionIdIfAny());
    2604           0 :                 break;
    2605           0 :             case 'e':
    2606           0 :                 if (padding != 0)
    2607           0 :                     appendStringInfo(buf, "%*s", padding, unpack_sql_state(edata->sqlerrcode));
    2608             :                 else
    2609           0 :                     appendStringInfoString(buf, unpack_sql_state(edata->sqlerrcode));
    2610           0 :                 break;
    2611           0 :             default:
    2612             :                 /* format error - ignore it */
    2613           0 :                 break;
    2614             :         }
    2615             :     }
    2616             : }
    2617             : 
    2618             : /*
    2619             :  * append a CSV'd version of a string to a StringInfo
    2620             :  * We use the PostgreSQL defaults for CSV, i.e. quote = escape = '"'
    2621             :  * If it's NULL, append nothing.
    2622             :  */
    2623             : static inline void
    2624           0 : appendCSVLiteral(StringInfo buf, const char *data)
    2625             : {
    2626           0 :     const char *p = data;
    2627             :     char        c;
    2628             : 
    2629             :     /* avoid confusing an empty string with NULL */
    2630           0 :     if (p == NULL)
    2631           0 :         return;
    2632             : 
    2633           0 :     appendStringInfoCharMacro(buf, '"');
    2634           0 :     while ((c = *p++) != '\0')
    2635             :     {
    2636           0 :         if (c == '"')
    2637           0 :             appendStringInfoCharMacro(buf, '"');
    2638           0 :         appendStringInfoCharMacro(buf, c);
    2639             :     }
    2640           0 :     appendStringInfoCharMacro(buf, '"');
    2641             : }
    2642             : 
    2643             : /*
    2644             :  * Constructs the error message, depending on the Errordata it gets, in a CSV
    2645             :  * format which is described in doc/src/sgml/config.sgml.
    2646             :  */
    2647             : static void
    2648           0 : write_csvlog(ErrorData *edata)
    2649             : {
    2650             :     StringInfoData buf;
    2651           0 :     bool        print_stmt = false;
    2652             : 
    2653             :     /* static counter for line numbers */
    2654             :     static long log_line_number = 0;
    2655             : 
    2656             :     /* has counter been reset in current process? */
    2657             :     static int  log_my_pid = 0;
    2658             : 
    2659             :     /*
    2660             :      * This is one of the few places where we'd rather not inherit a static
    2661             :      * variable's value from the postmaster.  But since we will, reset it when
    2662             :      * MyProcPid changes.
    2663             :      */
    2664           0 :     if (log_my_pid != MyProcPid)
    2665             :     {
    2666           0 :         log_line_number = 0;
    2667           0 :         log_my_pid = MyProcPid;
    2668           0 :         formatted_start_time[0] = '\0';
    2669             :     }
    2670           0 :     log_line_number++;
    2671             : 
    2672           0 :     initStringInfo(&buf);
    2673             : 
    2674             :     /*
    2675             :      * timestamp with milliseconds
    2676             :      *
    2677             :      * Check if the timestamp is already calculated for the syslog message,
    2678             :      * and use it if so.  Otherwise, get the current timestamp.  This is done
    2679             :      * to put same timestamp in both syslog and csvlog messages.
    2680             :      */
    2681           0 :     if (formatted_log_time[0] == '\0')
    2682           0 :         setup_formatted_log_time();
    2683             : 
    2684           0 :     appendStringInfoString(&buf, formatted_log_time);
    2685           0 :     appendStringInfoChar(&buf, ',');
    2686             : 
    2687             :     /* username */
    2688           0 :     if (MyProcPort)
    2689           0 :         appendCSVLiteral(&buf, MyProcPort->user_name);
    2690           0 :     appendStringInfoChar(&buf, ',');
    2691             : 
    2692             :     /* database name */
    2693           0 :     if (MyProcPort)
    2694           0 :         appendCSVLiteral(&buf, MyProcPort->database_name);
    2695           0 :     appendStringInfoChar(&buf, ',');
    2696             : 
    2697             :     /* Process id  */
    2698           0 :     if (MyProcPid != 0)
    2699           0 :         appendStringInfo(&buf, "%d", MyProcPid);
    2700           0 :     appendStringInfoChar(&buf, ',');
    2701             : 
    2702             :     /* Remote host and port */
    2703           0 :     if (MyProcPort && MyProcPort->remote_host)
    2704             :     {
    2705           0 :         appendStringInfoChar(&buf, '"');
    2706           0 :         appendStringInfoString(&buf, MyProcPort->remote_host);
    2707           0 :         if (MyProcPort->remote_port && MyProcPort->remote_port[0] != '\0')
    2708             :         {
    2709           0 :             appendStringInfoChar(&buf, ':');
    2710           0 :             appendStringInfoString(&buf, MyProcPort->remote_port);
    2711             :         }
    2712           0 :         appendStringInfoChar(&buf, '"');
    2713             :     }
    2714           0 :     appendStringInfoChar(&buf, ',');
    2715             : 
    2716             :     /* session id */
    2717           0 :     appendStringInfo(&buf, "%lx.%x", (long) MyStartTime, MyProcPid);
    2718           0 :     appendStringInfoChar(&buf, ',');
    2719             : 
    2720             :     /* Line number */
    2721           0 :     appendStringInfo(&buf, "%ld", log_line_number);
    2722           0 :     appendStringInfoChar(&buf, ',');
    2723             : 
    2724             :     /* PS display */
    2725           0 :     if (MyProcPort)
    2726             :     {
    2727             :         StringInfoData msgbuf;
    2728             :         const char *psdisp;
    2729             :         int         displen;
    2730             : 
    2731           0 :         initStringInfo(&msgbuf);
    2732             : 
    2733           0 :         psdisp = get_ps_display(&displen);
    2734           0 :         appendBinaryStringInfo(&msgbuf, psdisp, displen);
    2735           0 :         appendCSVLiteral(&buf, msgbuf.data);
    2736             : 
    2737           0 :         pfree(msgbuf.data);
    2738             :     }
    2739           0 :     appendStringInfoChar(&buf, ',');
    2740             : 
    2741             :     /* session start timestamp */
    2742           0 :     if (formatted_start_time[0] == '\0')
    2743           0 :         setup_formatted_start_time();
    2744           0 :     appendStringInfoString(&buf, formatted_start_time);
    2745           0 :     appendStringInfoChar(&buf, ',');
    2746             : 
    2747             :     /* Virtual transaction id */
    2748             :     /* keep VXID format in sync with lockfuncs.c */
    2749           0 :     if (MyProc != NULL && MyProc->backendId != InvalidBackendId)
    2750           0 :         appendStringInfo(&buf, "%d/%u", MyProc->backendId, MyProc->lxid);
    2751           0 :     appendStringInfoChar(&buf, ',');
    2752             : 
    2753             :     /* Transaction id */
    2754           0 :     appendStringInfo(&buf, "%u", GetTopTransactionIdIfAny());
    2755           0 :     appendStringInfoChar(&buf, ',');
    2756             : 
    2757             :     /* Error severity */
    2758           0 :     appendStringInfoString(&buf, _(error_severity(edata->elevel)));
    2759           0 :     appendStringInfoChar(&buf, ',');
    2760             : 
    2761             :     /* SQL state code */
    2762           0 :     appendStringInfoString(&buf, unpack_sql_state(edata->sqlerrcode));
    2763           0 :     appendStringInfoChar(&buf, ',');
    2764             : 
    2765             :     /* errmessage */
    2766           0 :     appendCSVLiteral(&buf, edata->message);
    2767           0 :     appendStringInfoChar(&buf, ',');
    2768             : 
    2769             :     /* errdetail or errdetail_log */
    2770           0 :     if (edata->detail_log)
    2771           0 :         appendCSVLiteral(&buf, edata->detail_log);
    2772             :     else
    2773           0 :         appendCSVLiteral(&buf, edata->detail);
    2774           0 :     appendStringInfoChar(&buf, ',');
    2775             : 
    2776             :     /* errhint */
    2777           0 :     appendCSVLiteral(&buf, edata->hint);
    2778           0 :     appendStringInfoChar(&buf, ',');
    2779             : 
    2780             :     /* internal query */
    2781           0 :     appendCSVLiteral(&buf, edata->internalquery);
    2782           0 :     appendStringInfoChar(&buf, ',');
    2783             : 
    2784             :     /* if printed internal query, print internal pos too */
    2785           0 :     if (edata->internalpos > 0 && edata->internalquery != NULL)
    2786           0 :         appendStringInfo(&buf, "%d", edata->internalpos);
    2787           0 :     appendStringInfoChar(&buf, ',');
    2788             : 
    2789             :     /* errcontext */
    2790           0 :     if (!edata->hide_ctx)
    2791           0 :         appendCSVLiteral(&buf, edata->context);
    2792           0 :     appendStringInfoChar(&buf, ',');
    2793             : 
    2794             :     /* user query --- only reported if not disabled by the caller */
    2795           0 :     if (is_log_level_output(edata->elevel, log_min_error_statement) &&
    2796           0 :         debug_query_string != NULL &&
    2797           0 :         !edata->hide_stmt)
    2798           0 :         print_stmt = true;
    2799           0 :     if (print_stmt)
    2800           0 :         appendCSVLiteral(&buf, debug_query_string);
    2801           0 :     appendStringInfoChar(&buf, ',');
    2802           0 :     if (print_stmt && edata->cursorpos > 0)
    2803           0 :         appendStringInfo(&buf, "%d", edata->cursorpos);
    2804           0 :     appendStringInfoChar(&buf, ',');
    2805             : 
    2806             :     /* file error location */
    2807           0 :     if (Log_error_verbosity >= PGERROR_VERBOSE)
    2808             :     {
    2809             :         StringInfoData msgbuf;
    2810             : 
    2811           0 :         initStringInfo(&msgbuf);
    2812             : 
    2813           0 :         if (edata->funcname && edata->filename)
    2814           0 :             appendStringInfo(&msgbuf, "%s, %s:%d",
    2815             :                              edata->funcname, edata->filename,
    2816             :                              edata->lineno);
    2817           0 :         else if (edata->filename)
    2818           0 :             appendStringInfo(&msgbuf, "%s:%d",
    2819             :                              edata->filename, edata->lineno);
    2820           0 :         appendCSVLiteral(&buf, msgbuf.data);
    2821           0 :         pfree(msgbuf.data);
    2822             :     }
    2823           0 :     appendStringInfoChar(&buf, ',');
    2824             : 
    2825             :     /* application name */
    2826           0 :     if (application_name)
    2827           0 :         appendCSVLiteral(&buf, application_name);
    2828             : 
    2829           0 :     appendStringInfoChar(&buf, ',');
    2830             : 
    2831             :     /* backend type */
    2832           0 :     if (MyProcPid == PostmasterPid)
    2833           0 :         appendCSVLiteral(&buf, "postmaster");
    2834           0 :     else if (MyBackendType == B_BG_WORKER)
    2835           0 :         appendCSVLiteral(&buf, MyBgworkerEntry->bgw_type);
    2836             :     else
    2837           0 :         appendCSVLiteral(&buf, GetBackendTypeDesc(MyBackendType));
    2838             : 
    2839           0 :     appendStringInfoChar(&buf, '\n');
    2840             : 
    2841             :     /* If in the syslogger process, try to write messages direct to file */
    2842           0 :     if (MyBackendType == B_LOGGER)
    2843           0 :         write_syslogger_file(buf.data, buf.len, LOG_DESTINATION_CSVLOG);
    2844             :     else
    2845           0 :         write_pipe_chunks(buf.data, buf.len, LOG_DESTINATION_CSVLOG);
    2846             : 
    2847           0 :     pfree(buf.data);
    2848           0 : }
    2849             : 
    2850             : /*
    2851             :  * Unpack MAKE_SQLSTATE code. Note that this returns a pointer to a
    2852             :  * static buffer.
    2853             :  */
    2854             : char *
    2855       12484 : unpack_sql_state(int sql_state)
    2856             : {
    2857             :     static char buf[12];
    2858             :     int         i;
    2859             : 
    2860       74904 :     for (i = 0; i < 5; i++)
    2861             :     {
    2862       62420 :         buf[i] = PGUNSIXBIT(sql_state);
    2863       62420 :         sql_state >>= 6;
    2864             :     }
    2865             : 
    2866       12484 :     buf[i] = '\0';
    2867       12484 :     return buf;
    2868             : }
    2869             : 
    2870             : 
    2871             : /*
    2872             :  * Write error report to server's log
    2873             :  */
    2874             : static void
    2875       68110 : send_message_to_server_log(ErrorData *edata)
    2876             : {
    2877             :     StringInfoData buf;
    2878             : 
    2879       68110 :     initStringInfo(&buf);
    2880             : 
    2881       68110 :     saved_timeval_set = false;
    2882       68110 :     formatted_log_time[0] = '\0';
    2883             : 
    2884       68110 :     log_line_prefix(&buf, edata);
    2885       68110 :     appendStringInfo(&buf, "%s:  ", _(error_severity(edata->elevel)));
    2886             : 
    2887       68110 :     if (Log_error_verbosity >= PGERROR_VERBOSE)
    2888          78 :         appendStringInfo(&buf, "%s: ", unpack_sql_state(edata->sqlerrcode));
    2889             : 
    2890       68110 :     if (edata->message)
    2891       68110 :         append_with_tabs(&buf, edata->message);
    2892             :     else
    2893           0 :         append_with_tabs(&buf, _("missing error text"));
    2894             : 
    2895       68110 :     if (edata->cursorpos > 0)
    2896        4346 :         appendStringInfo(&buf, _(" at character %d"),
    2897             :                          edata->cursorpos);
    2898       63764 :     else if (edata->internalpos > 0)
    2899          46 :         appendStringInfo(&buf, _(" at character %d"),
    2900             :                          edata->internalpos);
    2901             : 
    2902       68110 :     appendStringInfoChar(&buf, '\n');
    2903             : 
    2904       68110 :     if (Log_error_verbosity >= PGERROR_DEFAULT)
    2905             :     {
    2906       68110 :         if (edata->detail_log)
    2907             :         {
    2908         308 :             log_line_prefix(&buf, edata);
    2909         308 :             appendStringInfoString(&buf, _("DETAIL:  "));
    2910         308 :             append_with_tabs(&buf, edata->detail_log);
    2911         308 :             appendStringInfoChar(&buf, '\n');
    2912             :         }
    2913       67802 :         else if (edata->detail)
    2914             :         {
    2915        7566 :             log_line_prefix(&buf, edata);
    2916        7566 :             appendStringInfoString(&buf, _("DETAIL:  "));
    2917        7566 :             append_with_tabs(&buf, edata->detail);
    2918        7566 :             appendStringInfoChar(&buf, '\n');
    2919             :         }
    2920       68110 :         if (edata->hint)
    2921             :         {
    2922        2548 :             log_line_prefix(&buf, edata);
    2923        2548 :             appendStringInfoString(&buf, _("HINT:  "));
    2924        2548 :             append_with_tabs(&buf, edata->hint);
    2925        2548 :             appendStringInfoChar(&buf, '\n');
    2926             :         }
    2927       68110 :         if (edata->internalquery)
    2928             :         {
    2929          46 :             log_line_prefix(&buf, edata);
    2930          46 :             appendStringInfoString(&buf, _("QUERY:  "));
    2931          46 :             append_with_tabs(&buf, edata->internalquery);
    2932          46 :             appendStringInfoChar(&buf, '\n');
    2933             :         }
    2934       68110 :         if (edata->context && !edata->hide_ctx)
    2935             :         {
    2936        2574 :             log_line_prefix(&buf, edata);
    2937        2574 :             appendStringInfoString(&buf, _("CONTEXT:  "));
    2938        2574 :             append_with_tabs(&buf, edata->context);
    2939        2574 :             appendStringInfoChar(&buf, '\n');
    2940             :         }
    2941       68110 :         if (edata->backtrace)
    2942             :         {
    2943           0 :             log_line_prefix(&buf, edata);
    2944           0 :             appendStringInfoString(&buf, _("BACKTRACE:  "));
    2945           0 :             append_with_tabs(&buf, edata->backtrace);
    2946           0 :             appendStringInfoChar(&buf, '\n');
    2947             :         }
    2948       68110 :         if (Log_error_verbosity >= PGERROR_VERBOSE)
    2949             :         {
    2950             :             /* assume no newlines in funcname or filename... */
    2951          78 :             if (edata->funcname && edata->filename)
    2952             :             {
    2953          78 :                 log_line_prefix(&buf, edata);
    2954          78 :                 appendStringInfo(&buf, _("LOCATION:  %s, %s:%d\n"),
    2955             :                                  edata->funcname, edata->filename,
    2956             :                                  edata->lineno);
    2957             :             }
    2958           0 :             else if (edata->filename)
    2959             :             {
    2960           0 :                 log_line_prefix(&buf, edata);
    2961           0 :                 appendStringInfo(&buf, _("LOCATION:  %s:%d\n"),
    2962             :                                  edata->filename, edata->lineno);
    2963             :             }
    2964             :         }
    2965             :     }
    2966             : 
    2967             :     /*
    2968             :      * If the user wants the query that generated this error logged, do it.
    2969             :      */
    2970       68110 :     if (is_log_level_output(edata->elevel, log_min_error_statement) &&
    2971       65920 :         debug_query_string != NULL &&
    2972       53736 :         !edata->hide_stmt)
    2973             :     {
    2974       19802 :         log_line_prefix(&buf, edata);
    2975       19802 :         appendStringInfoString(&buf, _("STATEMENT:  "));
    2976       19802 :         append_with_tabs(&buf, debug_query_string);
    2977       19802 :         appendStringInfoChar(&buf, '\n');
    2978             :     }
    2979             : 
    2980             : #ifdef HAVE_SYSLOG
    2981             :     /* Write to syslog, if enabled */
    2982       68110 :     if (Log_destination & LOG_DESTINATION_SYSLOG)
    2983             :     {
    2984             :         int         syslog_level;
    2985             : 
    2986           0 :         switch (edata->elevel)
    2987             :         {
    2988           0 :             case DEBUG5:
    2989             :             case DEBUG4:
    2990             :             case DEBUG3:
    2991             :             case DEBUG2:
    2992             :             case DEBUG1:
    2993           0 :                 syslog_level = LOG_DEBUG;
    2994           0 :                 break;
    2995           0 :             case LOG:
    2996             :             case LOG_SERVER_ONLY:
    2997             :             case INFO:
    2998           0 :                 syslog_level = LOG_INFO;
    2999           0 :                 break;
    3000           0 :             case NOTICE:
    3001             :             case WARNING:
    3002           0 :                 syslog_level = LOG_NOTICE;
    3003           0 :                 break;
    3004           0 :             case ERROR:
    3005           0 :                 syslog_level = LOG_WARNING;
    3006           0 :                 break;
    3007           0 :             case FATAL:
    3008           0 :                 syslog_level = LOG_ERR;
    3009           0 :                 break;
    3010           0 :             case PANIC:
    3011             :             default:
    3012           0 :                 syslog_level = LOG_CRIT;
    3013           0 :                 break;
    3014             :         }
    3015             : 
    3016           0 :         write_syslog(syslog_level, buf.data);
    3017             :     }
    3018             : #endif                          /* HAVE_SYSLOG */
    3019             : 
    3020             : #ifdef WIN32
    3021             :     /* Write to eventlog, if enabled */
    3022             :     if (Log_destination & LOG_DESTINATION_EVENTLOG)
    3023             :     {
    3024             :         write_eventlog(edata->elevel, buf.data, buf.len);
    3025             :     }
    3026             : #endif                          /* WIN32 */
    3027             : 
    3028             :     /* Write to stderr, if enabled */
    3029       68110 :     if ((Log_destination & LOG_DESTINATION_STDERR) || whereToSendOutput == DestDebug)
    3030             :     {
    3031             :         /*
    3032             :          * Use the chunking protocol if we know the syslogger should be
    3033             :          * catching stderr output, and we are not ourselves the syslogger.
    3034             :          * Otherwise, just do a vanilla write to stderr.
    3035             :          */
    3036       68110 :         if (redirection_done && MyBackendType != B_LOGGER)
    3037          24 :             write_pipe_chunks(buf.data, buf.len, LOG_DESTINATION_STDERR);
    3038             : #ifdef WIN32
    3039             : 
    3040             :         /*
    3041             :          * In a win32 service environment, there is no usable stderr. Capture
    3042             :          * anything going there and write it to the eventlog instead.
    3043             :          *
    3044             :          * If stderr redirection is active, it was OK to write to stderr above
    3045             :          * because that's really a pipe to the syslogger process.
    3046             :          */
    3047             :         else if (pgwin32_is_service())
    3048             :             write_eventlog(edata->elevel, buf.data, buf.len);
    3049             : #endif
    3050             :         else
    3051       68086 :             write_console(buf.data, buf.len);
    3052             :     }
    3053             : 
    3054             :     /* If in the syslogger process, try to write messages direct to file */
    3055       68110 :     if (MyBackendType == B_LOGGER)
    3056           0 :         write_syslogger_file(buf.data, buf.len, LOG_DESTINATION_STDERR);
    3057             : 
    3058             :     /* Write to CSV log if enabled */
    3059       68110 :     if (Log_destination & LOG_DESTINATION_CSVLOG)
    3060             :     {
    3061           0 :         if (redirection_done || MyBackendType == B_LOGGER)
    3062             :         {
    3063             :             /*
    3064             :              * send CSV data if it's safe to do so (syslogger doesn't need the
    3065             :              * pipe). First get back the space in the message buffer.
    3066             :              */
    3067           0 :             pfree(buf.data);
    3068           0 :             write_csvlog(edata);
    3069             :         }
    3070             :         else
    3071             :         {
    3072             :             /*
    3073             :              * syslogger not up (yet), so just dump the message to stderr,
    3074             :              * unless we already did so above.
    3075             :              */
    3076           0 :             if (!(Log_destination & LOG_DESTINATION_STDERR) &&
    3077           0 :                 whereToSendOutput != DestDebug)
    3078           0 :                 write_console(buf.data, buf.len);
    3079           0 :             pfree(buf.data);
    3080             :         }
    3081             :     }
    3082             :     else
    3083             :     {
    3084       68110 :         pfree(buf.data);
    3085             :     }
    3086       68110 : }
    3087             : 
    3088             : /*
    3089             :  * Send data to the syslogger using the chunked protocol
    3090             :  *
    3091             :  * Note: when there are multiple backends writing into the syslogger pipe,
    3092             :  * it's critical that each write go into the pipe indivisibly, and not
    3093             :  * get interleaved with data from other processes.  Fortunately, the POSIX
    3094             :  * spec requires that writes to pipes be atomic so long as they are not
    3095             :  * more than PIPE_BUF bytes long.  So we divide long messages into chunks
    3096             :  * that are no more than that length, and send one chunk per write() call.
    3097             :  * The collector process knows how to reassemble the chunks.
    3098             :  *
    3099             :  * Because of the atomic write requirement, there are only two possible
    3100             :  * results from write() here: -1 for failure, or the requested number of
    3101             :  * bytes.  There is not really anything we can do about a failure; retry would
    3102             :  * probably be an infinite loop, and we can't even report the error usefully.
    3103             :  * (There is noplace else we could send it!)  So we might as well just ignore
    3104             :  * the result from write().  However, on some platforms you get a compiler
    3105             :  * warning from ignoring write()'s result, so do a little dance with casting
    3106             :  * rc to void to shut up the compiler.
    3107             :  */
    3108             : static void
    3109          24 : write_pipe_chunks(char *data, int len, int dest)
    3110             : {
    3111             :     PipeProtoChunk p;
    3112          24 :     int         fd = fileno(stderr);
    3113             :     int         rc;
    3114             : 
    3115             :     Assert(len > 0);
    3116             : 
    3117          24 :     p.proto.nuls[0] = p.proto.nuls[1] = '\0';
    3118          24 :     p.proto.pid = MyProcPid;
    3119             : 
    3120             :     /* write all but the last chunk */
    3121          24 :     while (len > PIPE_MAX_PAYLOAD)
    3122             :     {
    3123           0 :         p.proto.is_last = (dest == LOG_DESTINATION_CSVLOG ? 'F' : 'f');
    3124           0 :         p.proto.len = PIPE_MAX_PAYLOAD;
    3125           0 :         memcpy(p.proto.data, data, PIPE_MAX_PAYLOAD);
    3126           0 :         rc = write(fd, &p, PIPE_HEADER_SIZE + PIPE_MAX_PAYLOAD);
    3127             :         (void) rc;
    3128           0 :         data += PIPE_MAX_PAYLOAD;
    3129           0 :         len -= PIPE_MAX_PAYLOAD;
    3130             :     }
    3131             : 
    3132             :     /* write the last chunk */
    3133          24 :     p.proto.is_last = (dest == LOG_DESTINATION_CSVLOG ? 'T' : 't');
    3134          24 :     p.proto.len = len;
    3135          24 :     memcpy(p.proto.data, data, len);
    3136          24 :     rc = write(fd, &p, PIPE_HEADER_SIZE + len);
    3137             :     (void) rc;
    3138          24 : }
    3139             : 
    3140             : 
    3141             : /*
    3142             :  * Append a text string to the error report being built for the client.
    3143             :  *
    3144             :  * This is ordinarily identical to pq_sendstring(), but if we are in
    3145             :  * error recursion trouble we skip encoding conversion, because of the
    3146             :  * possibility that the problem is a failure in the encoding conversion
    3147             :  * subsystem itself.  Code elsewhere should ensure that the passed-in
    3148             :  * strings will be plain 7-bit ASCII, and thus not in need of conversion,
    3149             :  * in such cases.  (In particular, we disable localization of error messages
    3150             :  * to help ensure that's true.)
    3151             :  */
    3152             : static void
    3153      249766 : err_sendstring(StringInfo buf, const char *str)
    3154             : {
    3155      249766 :     if (in_error_recursion_trouble())
    3156           0 :         pq_send_ascii_string(buf, str);
    3157             :     else
    3158      249766 :         pq_sendstring(buf, str);
    3159      249766 : }
    3160             : 
    3161             : /*
    3162             :  * Write error report to client
    3163             :  */
    3164             : static void
    3165       31630 : send_message_to_frontend(ErrorData *edata)
    3166             : {
    3167             :     StringInfoData msgbuf;
    3168             : 
    3169             :     /* 'N' (Notice) is for nonfatal conditions, 'E' is for errors */
    3170       31630 :     pq_beginmessage(&msgbuf, (edata->elevel < ERROR) ? 'N' : 'E');
    3171             : 
    3172       31630 :     if (PG_PROTOCOL_MAJOR(FrontendProtocol) >= 3)
    3173             :     {
    3174             :         /* New style with separate fields */
    3175             :         const char *sev;
    3176             :         char        tbuf[12];
    3177             :         int         ssval;
    3178             :         int         i;
    3179             : 
    3180       31630 :         sev = error_severity(edata->elevel);
    3181       31630 :         pq_sendbyte(&msgbuf, PG_DIAG_SEVERITY);
    3182       31630 :         err_sendstring(&msgbuf, _(sev));
    3183       31630 :         pq_sendbyte(&msgbuf, PG_DIAG_SEVERITY_NONLOCALIZED);
    3184       31630 :         err_sendstring(&msgbuf, sev);
    3185             : 
    3186             :         /* unpack MAKE_SQLSTATE code */
    3187       31630 :         ssval = edata->sqlerrcode;
    3188      189780 :         for (i = 0; i < 5; i++)
    3189             :         {
    3190      158150 :             tbuf[i] = PGUNSIXBIT(ssval);
    3191      158150 :             ssval >>= 6;
    3192             :         }
    3193       31630 :         tbuf[i] = '\0';
    3194             : 
    3195       31630 :         pq_sendbyte(&msgbuf, PG_DIAG_SQLSTATE);
    3196       31630 :         err_sendstring(&msgbuf, tbuf);
    3197             : 
    3198             :         /* M field is required per protocol, so always send something */
    3199       31630 :         pq_sendbyte(&msgbuf, PG_DIAG_MESSAGE_PRIMARY);
    3200       31630 :         if (edata->message)
    3201       31630 :             err_sendstring(&msgbuf, edata->message);
    3202             :         else
    3203           0 :             err_sendstring(&msgbuf, _("missing error text"));
    3204             : 
    3205       31630 :         if (edata->detail)
    3206             :         {
    3207        4982 :             pq_sendbyte(&msgbuf, PG_DIAG_MESSAGE_DETAIL);
    3208        4982 :             err_sendstring(&msgbuf, edata->detail);
    3209             :         }
    3210             : 
    3211             :         /* detail_log is intentionally not used here */
    3212             : 
    3213       31630 :         if (edata->hint)
    3214             :         {
    3215        2482 :             pq_sendbyte(&msgbuf, PG_DIAG_MESSAGE_HINT);
    3216        2482 :             err_sendstring(&msgbuf, edata->hint);
    3217             :         }
    3218             : 
    3219       31630 :         if (edata->context)
    3220             :         {
    3221        9984 :             pq_sendbyte(&msgbuf, PG_DIAG_CONTEXT);
    3222        9984 :             err_sendstring(&msgbuf, edata->context);
    3223             :         }
    3224             : 
    3225       31630 :         if (edata->schema_name)
    3226             :         {
    3227        2292 :             pq_sendbyte(&msgbuf, PG_DIAG_SCHEMA_NAME);
    3228        2292 :             err_sendstring(&msgbuf, edata->schema_name);
    3229             :         }
    3230             : 
    3231       31630 :         if (edata->table_name)
    3232             :         {
    3233        1828 :             pq_sendbyte(&msgbuf, PG_DIAG_TABLE_NAME);
    3234        1828 :             err_sendstring(&msgbuf, edata->table_name);
    3235             :         }
    3236             : 
    3237       31630 :         if (edata->column_name)
    3238             :         {
    3239         226 :             pq_sendbyte(&msgbuf, PG_DIAG_COLUMN_NAME);
    3240         226 :             err_sendstring(&msgbuf, edata->column_name);
    3241             :         }
    3242             : 
    3243       31630 :         if (edata->datatype_name)
    3244             :         {
    3245         474 :             pq_sendbyte(&msgbuf, PG_DIAG_DATATYPE_NAME);
    3246         474 :             err_sendstring(&msgbuf, edata->datatype_name);
    3247             :         }
    3248             : 
    3249       31630 :         if (edata->constraint_name)
    3250             :         {
    3251        1650 :             pq_sendbyte(&msgbuf, PG_DIAG_CONSTRAINT_NAME);
    3252        1650 :             err_sendstring(&msgbuf, edata->constraint_name);
    3253             :         }
    3254             : 
    3255       31630 :         if (edata->cursorpos > 0)
    3256             :         {
    3257        4346 :             snprintf(tbuf, sizeof(tbuf), "%d", edata->cursorpos);
    3258        4346 :             pq_sendbyte(&msgbuf, PG_DIAG_STATEMENT_POSITION);
    3259        4346 :             err_sendstring(&msgbuf, tbuf);
    3260             :         }
    3261             : 
    3262       31630 :         if (edata->internalpos > 0)
    3263             :         {
    3264          46 :             snprintf(tbuf, sizeof(tbuf), "%d", edata->internalpos);
    3265          46 :             pq_sendbyte(&msgbuf, PG_DIAG_INTERNAL_POSITION);
    3266          46 :             err_sendstring(&msgbuf, tbuf);
    3267             :         }
    3268             : 
    3269       31630 :         if (edata->internalquery)
    3270             :         {
    3271          46 :             pq_sendbyte(&msgbuf, PG_DIAG_INTERNAL_QUERY);
    3272          46 :             err_sendstring(&msgbuf, edata->internalquery);
    3273             :         }
    3274             : 
    3275       31630 :         if (edata->filename)
    3276             :         {
    3277       31630 :             pq_sendbyte(&msgbuf, PG_DIAG_SOURCE_FILE);
    3278       31630 :             err_sendstring(&msgbuf, edata->filename);
    3279             :         }
    3280             : 
    3281       31630 :         if (edata->lineno > 0)
    3282             :         {
    3283       31630 :             snprintf(tbuf, sizeof(tbuf), "%d", edata->lineno);
    3284       31630 :             pq_sendbyte(&msgbuf, PG_DIAG_SOURCE_LINE);
    3285       31630 :             err_sendstring(&msgbuf, tbuf);
    3286             :         }
    3287             : 
    3288       31630 :         if (edata->funcname)
    3289             :         {
    3290       31630 :             pq_sendbyte(&msgbuf, PG_DIAG_SOURCE_FUNCTION);
    3291       31630 :             err_sendstring(&msgbuf, edata->funcname);
    3292             :         }
    3293             : 
    3294       31630 :         pq_sendbyte(&msgbuf, '\0'); /* terminator */
    3295             :     }
    3296             :     else
    3297             :     {
    3298             :         /* Old style --- gin up a backwards-compatible message */
    3299             :         StringInfoData buf;
    3300             : 
    3301           0 :         initStringInfo(&buf);
    3302             : 
    3303           0 :         appendStringInfo(&buf, "%s:  ", _(error_severity(edata->elevel)));
    3304             : 
    3305           0 :         if (edata->show_funcname && edata->funcname)
    3306           0 :             appendStringInfo(&buf, "%s: ", edata->funcname);
    3307             : 
    3308           0 :         if (edata->message)
    3309           0 :             appendStringInfoString(&buf, edata->message);
    3310             :         else
    3311           0 :             appendStringInfoString(&buf, _("missing error text"));
    3312             : 
    3313           0 :         if (edata->cursorpos > 0)
    3314           0 :             appendStringInfo(&buf, _(" at character %d"),
    3315             :                              edata->cursorpos);
    3316           0 :         else if (edata->internalpos > 0)
    3317           0 :             appendStringInfo(&buf, _(" at character %d"),
    3318             :                              edata->internalpos);
    3319             : 
    3320           0 :         appendStringInfoChar(&buf, '\n');
    3321             : 
    3322           0 :         err_sendstring(&msgbuf, buf.data);
    3323             : 
    3324           0 :         pfree(buf.data);
    3325             :     }
    3326             : 
    3327       31630 :     pq_endmessage(&msgbuf);
    3328             : 
    3329             :     /*
    3330             :      * This flush is normally not necessary, since postgres.c will flush out
    3331             :      * waiting data when control returns to the main loop. But it seems best
    3332             :      * to leave it here, so that the client has some clue what happened if the
    3333             :      * backend dies before getting back to the main loop ... error/notice
    3334             :      * messages should not be a performance-critical path anyway, so an extra
    3335             :      * flush won't hurt much ...
    3336             :      */
    3337       31630 :     pq_flush();
    3338       31630 : }
    3339             : 
    3340             : 
    3341             : /*
    3342             :  * Support routines for formatting error messages.
    3343             :  */
    3344             : 
    3345             : 
    3346             : /*
    3347             :  * error_severity --- get string representing elevel
    3348             :  *
    3349             :  * The string is not localized here, but we mark the strings for translation
    3350             :  * so that callers can invoke _() on the result.
    3351             :  */
    3352             : static const char *
    3353       99740 : error_severity(int elevel)
    3354             : {
    3355             :     const char *prefix;
    3356             : 
    3357       99740 :     switch (elevel)
    3358             :     {
    3359         558 :         case DEBUG1:
    3360             :         case DEBUG2:
    3361             :         case DEBUG3:
    3362             :         case DEBUG4:
    3363             :         case DEBUG5:
    3364         558 :             prefix = gettext_noop("DEBUG");
    3365         558 :             break;
    3366       46708 :         case LOG:
    3367             :         case LOG_SERVER_ONLY:
    3368       46708 :             prefix = gettext_noop("LOG");
    3369       46708 :             break;
    3370         462 :         case INFO:
    3371         462 :             prefix = gettext_noop("INFO");
    3372         462 :             break;
    3373       10332 :         case NOTICE:
    3374       10332 :             prefix = gettext_noop("NOTICE");
    3375       10332 :             break;
    3376        3346 :         case WARNING:
    3377        3346 :             prefix = gettext_noop("WARNING");
    3378        3346 :             break;
    3379       37820 :         case ERROR:
    3380       37820 :             prefix = gettext_noop("ERROR");
    3381       37820 :             break;
    3382         514 :         case FATAL:
    3383         514 :             prefix = gettext_noop("FATAL");
    3384         514 :             break;
    3385           0 :         case PANIC:
    3386           0 :             prefix = gettext_noop("PANIC");
    3387           0 :             break;
    3388           0 :         default:
    3389           0 :             prefix = "???";
    3390           0 :             break;
    3391             :     }
    3392             : 
    3393       99740 :     return prefix;
    3394             : }
    3395             : 
    3396             : 
    3397             : /*
    3398             :  *  append_with_tabs
    3399             :  *
    3400             :  *  Append the string to the StringInfo buffer, inserting a tab after any
    3401             :  *  newline.
    3402             :  */
    3403             : static void
    3404      100954 : append_with_tabs(StringInfo buf, const char *str)
    3405             : {
    3406             :     char        ch;
    3407             : 
    3408    14738330 :     while ((ch = *str++) != '\0')
    3409             :     {
    3410    14637376 :         appendStringInfoCharMacro(buf, ch);
    3411    14637376 :         if (ch == '\n')
    3412       54776 :             appendStringInfoCharMacro(buf, '\t');
    3413             :     }
    3414      100954 : }
    3415             : 
    3416             : 
    3417             : /*
    3418             :  * Write errors to stderr (or by equal means when stderr is
    3419             :  * not available). Used before ereport/elog can be used
    3420             :  * safely (memory context, GUC load etc)
    3421             :  */
    3422             : void
    3423           0 : write_stderr(const char *fmt,...)
    3424             : {
    3425             :     va_list     ap;
    3426             : 
    3427             : #ifdef WIN32
    3428             :     char        errbuf[2048];   /* Arbitrary size? */
    3429             : #endif
    3430             : 
    3431           0 :     fmt = _(fmt);
    3432             : 
    3433           0 :     va_start(ap, fmt);
    3434             : #ifndef WIN32
    3435             :     /* On Unix, we just fprintf to stderr */
    3436           0 :     vfprintf(stderr, fmt, ap);
    3437           0 :     fflush(stderr);
    3438             : #else
    3439             :     vsnprintf(errbuf, sizeof(errbuf), fmt, ap);
    3440             : 
    3441             :     /*
    3442             :      * On Win32, we print to stderr if running on a console, or write to
    3443             :      * eventlog if running as a service
    3444             :      */
    3445             :     if (pgwin32_is_service())   /* Running as a service */
    3446             :     {
    3447             :         write_eventlog(ERROR, errbuf, strlen(errbuf));
    3448             :     }
    3449             :     else
    3450             :     {
    3451             :         /* Not running as service, write to stderr */
    3452             :         write_console(errbuf, strlen(errbuf));
    3453             :         fflush(stderr);
    3454             :     }
    3455             : #endif
    3456           0 :     va_end(ap);
    3457           0 : }
    3458             : 
    3459             : 
    3460             : /*
    3461             :  * is_log_level_output -- is elevel logically >= log_min_level?
    3462             :  *
    3463             :  * We use this for tests that should consider LOG to sort out-of-order,
    3464             :  * between ERROR and FATAL.  Generally this is the right thing for testing
    3465             :  * whether a message should go to the postmaster log, whereas a simple >=
    3466             :  * test is correct for testing whether the message should go to the client.
    3467             :  */
    3468             : static bool
    3469   101868858 : is_log_level_output(int elevel, int log_min_level)
    3470             : {
    3471   101868858 :     if (elevel == LOG || elevel == LOG_SERVER_ONLY)
    3472             :     {
    3473       93204 :         if (log_min_level == LOG || log_min_level <= ERROR)
    3474       93204 :             return true;
    3475             :     }
    3476   101775654 :     else if (log_min_level == LOG)
    3477             :     {
    3478             :         /* elevel != LOG */
    3479           0 :         if (elevel >= FATAL)
    3480           0 :             return true;
    3481             :     }
    3482             :     /* Neither is LOG */
    3483   101775654 :     else if (elevel >= log_min_level)
    3484       41964 :         return true;
    3485             : 
    3486   101733690 :     return false;
    3487             : }
    3488             : 
    3489             : /*
    3490             :  * Adjust the level of a recovery-related message per trace_recovery_messages.
    3491             :  *
    3492             :  * The argument is the default log level of the message, eg, DEBUG2.  (This
    3493             :  * should only be applied to DEBUGn log messages, otherwise it's a no-op.)
    3494             :  * If the level is >= trace_recovery_messages, we return LOG, causing the
    3495             :  * message to be logged unconditionally (for most settings of
    3496             :  * log_min_messages).  Otherwise, we return the argument unchanged.
    3497             :  * The message will then be shown based on the setting of log_min_messages.
    3498             :  *
    3499             :  * Intention is to keep this for at least the whole of the 9.0 production
    3500             :  * release, so we can more easily diagnose production problems in the field.
    3501             :  * It should go away eventually, though, because it's an ugly and
    3502             :  * hard-to-explain kluge.
    3503             :  */
    3504             : int
    3505      210154 : trace_recovery(int trace_level)
    3506             : {
    3507      210154 :     if (trace_level < LOG &&
    3508      210154 :         trace_level >= trace_recovery_messages)
    3509           0 :         return LOG;
    3510             : 
    3511      210154 :     return trace_level;
    3512             : }

Generated by: LCOV version 1.13