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

Generated by: LCOV version 1.11