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

Generated by: LCOV version 1.13