pg_query 1.0.2 → 2.0.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (107) hide show
  1. checksums.yaml +5 -5
  2. data/CHANGELOG.md +162 -40
  3. data/README.md +80 -69
  4. data/Rakefile +85 -4
  5. data/ext/pg_query/extconf.rb +4 -32
  6. data/ext/pg_query/guc-file.c +0 -0
  7. data/ext/pg_query/pg_query.c +104 -0
  8. data/ext/pg_query/pg_query.pb-c.c +37628 -0
  9. data/ext/pg_query/pg_query_deparse.c +9953 -0
  10. data/ext/pg_query/pg_query_fingerprint.c +292 -0
  11. data/ext/pg_query/pg_query_fingerprint.h +8 -0
  12. data/ext/pg_query/pg_query_internal.h +24 -0
  13. data/ext/pg_query/pg_query_json_plpgsql.c +738 -0
  14. data/ext/pg_query/pg_query_json_plpgsql.h +9 -0
  15. data/ext/pg_query/pg_query_normalize.c +437 -0
  16. data/ext/pg_query/pg_query_outfuncs.h +10 -0
  17. data/ext/pg_query/pg_query_outfuncs_json.c +297 -0
  18. data/ext/pg_query/pg_query_outfuncs_protobuf.c +237 -0
  19. data/ext/pg_query/pg_query_parse.c +148 -0
  20. data/ext/pg_query/pg_query_parse_plpgsql.c +460 -0
  21. data/ext/pg_query/pg_query_readfuncs.h +11 -0
  22. data/ext/pg_query/pg_query_readfuncs_protobuf.c +142 -0
  23. data/ext/pg_query/pg_query_ruby.c +108 -12
  24. data/ext/pg_query/pg_query_scan.c +173 -0
  25. data/ext/pg_query/pg_query_split.c +221 -0
  26. data/ext/pg_query/protobuf-c.c +3660 -0
  27. data/ext/pg_query/src_backend_catalog_namespace.c +1051 -0
  28. data/ext/pg_query/src_backend_catalog_pg_proc.c +142 -0
  29. data/ext/pg_query/src_backend_commands_define.c +117 -0
  30. data/ext/pg_query/src_backend_libpq_pqcomm.c +651 -0
  31. data/ext/pg_query/src_backend_nodes_bitmapset.c +513 -0
  32. data/ext/pg_query/src_backend_nodes_copyfuncs.c +6013 -0
  33. data/ext/pg_query/src_backend_nodes_equalfuncs.c +4003 -0
  34. data/ext/pg_query/src_backend_nodes_extensible.c +99 -0
  35. data/ext/pg_query/src_backend_nodes_list.c +922 -0
  36. data/ext/pg_query/src_backend_nodes_makefuncs.c +417 -0
  37. data/ext/pg_query/src_backend_nodes_nodeFuncs.c +1363 -0
  38. data/ext/pg_query/src_backend_nodes_value.c +84 -0
  39. data/ext/pg_query/src_backend_parser_gram.c +47456 -0
  40. data/ext/pg_query/src_backend_parser_parse_expr.c +313 -0
  41. data/ext/pg_query/src_backend_parser_parser.c +497 -0
  42. data/ext/pg_query/src_backend_parser_scan.c +7091 -0
  43. data/ext/pg_query/src_backend_parser_scansup.c +160 -0
  44. data/ext/pg_query/src_backend_postmaster_postmaster.c +2230 -0
  45. data/ext/pg_query/src_backend_storage_ipc_ipc.c +192 -0
  46. data/ext/pg_query/src_backend_storage_lmgr_s_lock.c +370 -0
  47. data/ext/pg_query/src_backend_tcop_postgres.c +776 -0
  48. data/ext/pg_query/src_backend_utils_adt_datum.c +326 -0
  49. data/ext/pg_query/src_backend_utils_adt_expandeddatum.c +98 -0
  50. data/ext/pg_query/src_backend_utils_adt_format_type.c +136 -0
  51. data/ext/pg_query/src_backend_utils_adt_ruleutils.c +1683 -0
  52. data/ext/pg_query/src_backend_utils_error_assert.c +74 -0
  53. data/ext/pg_query/src_backend_utils_error_elog.c +1748 -0
  54. data/ext/pg_query/src_backend_utils_fmgr_fmgr.c +570 -0
  55. data/ext/pg_query/src_backend_utils_hash_dynahash.c +1086 -0
  56. data/ext/pg_query/src_backend_utils_init_globals.c +168 -0
  57. data/ext/pg_query/src_backend_utils_mb_mbutils.c +839 -0
  58. data/ext/pg_query/src_backend_utils_misc_guc.c +1831 -0
  59. data/ext/pg_query/src_backend_utils_mmgr_aset.c +1560 -0
  60. data/ext/pg_query/src_backend_utils_mmgr_mcxt.c +1006 -0
  61. data/ext/pg_query/src_common_encnames.c +158 -0
  62. data/ext/pg_query/src_common_keywords.c +39 -0
  63. data/ext/pg_query/src_common_kwlist_d.h +1081 -0
  64. data/ext/pg_query/src_common_kwlookup.c +91 -0
  65. data/ext/pg_query/src_common_psprintf.c +158 -0
  66. data/ext/pg_query/src_common_string.c +86 -0
  67. data/ext/pg_query/src_common_stringinfo.c +336 -0
  68. data/ext/pg_query/src_common_wchar.c +1651 -0
  69. data/ext/pg_query/src_pl_plpgsql_src_pl_comp.c +1133 -0
  70. data/ext/pg_query/src_pl_plpgsql_src_pl_funcs.c +877 -0
  71. data/ext/pg_query/src_pl_plpgsql_src_pl_gram.c +6533 -0
  72. data/ext/pg_query/src_pl_plpgsql_src_pl_handler.c +107 -0
  73. data/ext/pg_query/src_pl_plpgsql_src_pl_reserved_kwlist_d.h +123 -0
  74. data/ext/pg_query/src_pl_plpgsql_src_pl_scanner.c +671 -0
  75. data/ext/pg_query/src_pl_plpgsql_src_pl_unreserved_kwlist_d.h +255 -0
  76. data/ext/pg_query/src_port_erand48.c +127 -0
  77. data/ext/pg_query/src_port_pg_bitutils.c +246 -0
  78. data/ext/pg_query/src_port_pgsleep.c +69 -0
  79. data/ext/pg_query/src_port_pgstrcasecmp.c +83 -0
  80. data/ext/pg_query/src_port_qsort.c +240 -0
  81. data/ext/pg_query/src_port_random.c +31 -0
  82. data/ext/pg_query/src_port_snprintf.c +1449 -0
  83. data/ext/pg_query/src_port_strerror.c +324 -0
  84. data/ext/pg_query/src_port_strnlen.c +39 -0
  85. data/ext/pg_query/xxhash.c +43 -0
  86. data/lib/pg_query.rb +7 -4
  87. data/lib/pg_query/constants.rb +21 -0
  88. data/lib/pg_query/deparse.rb +16 -991
  89. data/lib/pg_query/filter_columns.rb +86 -85
  90. data/lib/pg_query/fingerprint.rb +122 -87
  91. data/lib/pg_query/json_field_names.rb +1402 -0
  92. data/lib/pg_query/node.rb +31 -0
  93. data/lib/pg_query/param_refs.rb +42 -37
  94. data/lib/pg_query/parse.rb +220 -200
  95. data/lib/pg_query/parse_error.rb +1 -1
  96. data/lib/pg_query/pg_query_pb.rb +3211 -0
  97. data/lib/pg_query/scan.rb +23 -0
  98. data/lib/pg_query/treewalker.rb +24 -40
  99. data/lib/pg_query/truncate.rb +64 -43
  100. data/lib/pg_query/version.rb +2 -2
  101. metadata +102 -11
  102. data/ext/pg_query/pg_query_ruby.h +0 -10
  103. data/lib/pg_query/deep_dup.rb +0 -16
  104. data/lib/pg_query/deparse/alter_table.rb +0 -42
  105. data/lib/pg_query/deparse/interval.rb +0 -105
  106. data/lib/pg_query/legacy_parsetree.rb +0 -109
  107. data/lib/pg_query/node_types.rb +0 -282
@@ -0,0 +1,74 @@
1
+ /*--------------------------------------------------------------------
2
+ * Symbols referenced in this file:
3
+ * - ExceptionalCondition
4
+ *--------------------------------------------------------------------
5
+ */
6
+
7
+ /*-------------------------------------------------------------------------
8
+ *
9
+ * assert.c
10
+ * Assert code.
11
+ *
12
+ * Portions Copyright (c) 1996-2020, PostgreSQL Global Development Group
13
+ * Portions Copyright (c) 1994, Regents of the University of California
14
+ *
15
+ *
16
+ * IDENTIFICATION
17
+ * src/backend/utils/error/assert.c
18
+ *
19
+ * NOTE
20
+ * This should eventually work with elog()
21
+ *
22
+ *-------------------------------------------------------------------------
23
+ */
24
+ #include "postgres.h"
25
+
26
+ #include <unistd.h>
27
+ #ifdef HAVE_EXECINFO_H
28
+ #include <execinfo.h>
29
+ #endif
30
+
31
+ /*
32
+ * ExceptionalCondition - Handles the failure of an Assert()
33
+ */
34
+ void
35
+ ExceptionalCondition(const char *conditionName,
36
+ const char *errorType,
37
+ const char *fileName,
38
+ int lineNumber)
39
+ {
40
+ if (!PointerIsValid(conditionName)
41
+ || !PointerIsValid(fileName)
42
+ || !PointerIsValid(errorType))
43
+ write_stderr("TRAP: ExceptionalCondition: bad arguments\n");
44
+ else
45
+ {
46
+ write_stderr("TRAP: %s(\"%s\", File: \"%s\", Line: %d)\n",
47
+ errorType, conditionName,
48
+ fileName, lineNumber);
49
+ }
50
+
51
+ /* Usually this shouldn't be needed, but make sure the msg went out */
52
+ fflush(stderr);
53
+
54
+ #ifdef HAVE_BACKTRACE_SYMBOLS
55
+ {
56
+ void *buf[100];
57
+ int nframes;
58
+
59
+ nframes = backtrace(buf, lengthof(buf));
60
+ backtrace_symbols_fd(buf, nframes, fileno(stderr));
61
+ }
62
+ #endif
63
+
64
+ #ifdef SLEEP_ON_ASSERT
65
+
66
+ /*
67
+ * It would be nice to use pg_usleep() here, but only does 2000 sec or 33
68
+ * minutes, which seems too short.
69
+ */
70
+ sleep(1000000);
71
+ #endif
72
+
73
+ abort();
74
+ }
@@ -0,0 +1,1748 @@
1
+ /*--------------------------------------------------------------------
2
+ * Symbols referenced in this file:
3
+ * - errstart
4
+ * - PG_exception_stack
5
+ * - write_stderr
6
+ * - err_gettext
7
+ * - in_error_recursion_trouble
8
+ * - error_context_stack
9
+ * - errordata_stack_depth
10
+ * - errordata
11
+ * - is_log_level_output
12
+ * - recursion_depth
13
+ * - errmsg_internal
14
+ * - errcode
15
+ * - errmsg
16
+ * - errdetail
17
+ * - errfinish
18
+ * - pg_re_throw
19
+ * - EmitErrorReport
20
+ * - emit_log_hook
21
+ * - send_message_to_server_log
22
+ * - send_message_to_frontend
23
+ * - matches_backtrace_functions
24
+ * - set_backtrace
25
+ * - geterrcode
26
+ * - errhint
27
+ * - errposition
28
+ * - internalerrposition
29
+ * - internalerrquery
30
+ * - geterrposition
31
+ * - getinternalerrposition
32
+ * - set_errcontext_domain
33
+ * - errcontext_msg
34
+ * - CopyErrorData
35
+ * - FlushErrorState
36
+ *--------------------------------------------------------------------
37
+ */
38
+
39
+ /*-------------------------------------------------------------------------
40
+ *
41
+ * elog.c
42
+ * error logging and reporting
43
+ *
44
+ * Because of the extremely high rate at which log messages can be generated,
45
+ * we need to be mindful of the performance cost of obtaining any information
46
+ * that may be logged. Also, it's important to keep in mind that this code may
47
+ * get called from within an aborted transaction, in which case operations
48
+ * such as syscache lookups are unsafe.
49
+ *
50
+ * Some notes about recursion and errors during error processing:
51
+ *
52
+ * We need to be robust about recursive-error scenarios --- for example,
53
+ * if we run out of memory, it's important to be able to report that fact.
54
+ * There are a number of considerations that go into this.
55
+ *
56
+ * First, distinguish between re-entrant use and actual recursion. It
57
+ * is possible for an error or warning message to be emitted while the
58
+ * parameters for an error message are being computed. In this case
59
+ * errstart has been called for the outer message, and some field values
60
+ * may have already been saved, but we are not actually recursing. We handle
61
+ * this by providing a (small) stack of ErrorData records. The inner message
62
+ * can be computed and sent without disturbing the state of the outer message.
63
+ * (If the inner message is actually an error, this isn't very interesting
64
+ * because control won't come back to the outer message generator ... but
65
+ * if the inner message is only debug or log data, this is critical.)
66
+ *
67
+ * Second, actual recursion will occur if an error is reported by one of
68
+ * the elog.c routines or something they call. By far the most probable
69
+ * scenario of this sort is "out of memory"; and it's also the nastiest
70
+ * to handle because we'd likely also run out of memory while trying to
71
+ * report this error! Our escape hatch for this case is to reset the
72
+ * ErrorContext to empty before trying to process the inner error. Since
73
+ * ErrorContext is guaranteed to have at least 8K of space in it (see mcxt.c),
74
+ * we should be able to process an "out of memory" message successfully.
75
+ * Since we lose the prior error state due to the reset, we won't be able
76
+ * to return to processing the original error, but we wouldn't have anyway.
77
+ * (NOTE: the escape hatch is not used for recursive situations where the
78
+ * inner message is of less than ERROR severity; in that case we just
79
+ * try to process it and return normally. Usually this will work, but if
80
+ * it ends up in infinite recursion, we will PANIC due to error stack
81
+ * overflow.)
82
+ *
83
+ *
84
+ * Portions Copyright (c) 1996-2020, PostgreSQL Global Development Group
85
+ * Portions Copyright (c) 1994, Regents of the University of California
86
+ *
87
+ *
88
+ * IDENTIFICATION
89
+ * src/backend/utils/error/elog.c
90
+ *
91
+ *-------------------------------------------------------------------------
92
+ */
93
+ #include "postgres.h"
94
+
95
+ #include <fcntl.h>
96
+ #include <time.h>
97
+ #include <unistd.h>
98
+ #include <signal.h>
99
+ #include <ctype.h>
100
+ #ifdef HAVE_SYSLOG
101
+ #include <syslog.h>
102
+ #endif
103
+ #ifdef HAVE_EXECINFO_H
104
+ #include <execinfo.h>
105
+ #endif
106
+
107
+ #include "access/transam.h"
108
+ #include "access/xact.h"
109
+ #include "libpq/libpq.h"
110
+ #include "libpq/pqformat.h"
111
+ #include "mb/pg_wchar.h"
112
+ #include "miscadmin.h"
113
+ #include "postmaster/bgworker.h"
114
+ #include "postmaster/postmaster.h"
115
+ #include "postmaster/syslogger.h"
116
+ #include "storage/ipc.h"
117
+ #include "storage/proc.h"
118
+ #include "tcop/tcopprot.h"
119
+ #include "utils/guc.h"
120
+ #include "utils/memutils.h"
121
+ #include "utils/ps_status.h"
122
+
123
+
124
+ /* In this module, access gettext() via err_gettext() */
125
+ #undef _
126
+ #define _(x) err_gettext(x)
127
+
128
+
129
+ /* Global variables */
130
+ __thread ErrorContextCallback *error_context_stack = NULL;
131
+
132
+
133
+ __thread sigjmp_buf *PG_exception_stack = NULL;
134
+
135
+
136
+ extern bool redirection_done;
137
+
138
+ /*
139
+ * Hook for intercepting messages before they are sent to the server log.
140
+ * Note that the hook will not get called for messages that are suppressed
141
+ * by log_min_messages. Also note that logging hooks implemented in preload
142
+ * libraries will miss any log messages that are generated before the
143
+ * library is loaded.
144
+ */
145
+ __thread emit_log_hook_type emit_log_hook = NULL;
146
+
147
+
148
+ /* GUC parameters */
149
+
150
+ /* format for extra log line info */
151
+
152
+
153
+
154
+
155
+
156
+ #ifdef HAVE_SYSLOG
157
+
158
+ /*
159
+ * Max string length to send to syslog(). Note that this doesn't count the
160
+ * sequence-number prefix we add, and of course it doesn't count the prefix
161
+ * added by syslog itself. Solaris and sysklogd truncate the final message
162
+ * at 1024 bytes, so this value leaves 124 bytes for those prefixes. (Most
163
+ * other syslog implementations seem to have limits of 2KB or so.)
164
+ */
165
+ #ifndef PG_SYSLOG_LIMIT
166
+ #define PG_SYSLOG_LIMIT 900
167
+ #endif
168
+
169
+
170
+
171
+
172
+
173
+ static void write_syslog(int level, const char *line);
174
+ #endif
175
+
176
+ #ifdef WIN32
177
+ extern char *event_source;
178
+
179
+ static void write_eventlog(int level, const char *line, int len);
180
+ #endif
181
+
182
+ /* We provide a small stack of ErrorData records for re-entrant cases */
183
+ #define ERRORDATA_STACK_SIZE 5
184
+
185
+ static __thread ErrorData errordata[ERRORDATA_STACK_SIZE];
186
+
187
+
188
+ static __thread int errordata_stack_depth = -1;
189
+ /* index of topmost active frame */
190
+
191
+ static __thread int recursion_depth = 0;
192
+ /* to detect actual recursion */
193
+
194
+ /*
195
+ * Saved timeval and buffers for formatted timestamps that might be used by
196
+ * both log_line_prefix and csv logs.
197
+ */
198
+
199
+
200
+
201
+ #define FORMATTED_TS_LEN 128
202
+
203
+
204
+
205
+
206
+ /* Macro for checking errordata_stack_depth is reasonable */
207
+ #define CHECK_STACK_DEPTH() \
208
+ do { \
209
+ if (errordata_stack_depth < 0) \
210
+ { \
211
+ errordata_stack_depth = -1; \
212
+ ereport(ERROR, (errmsg_internal("errstart was not called"))); \
213
+ } \
214
+ } while (0)
215
+
216
+
217
+ static const char *err_gettext(const char *str) pg_attribute_format_arg(1);
218
+ static pg_noinline void set_backtrace(ErrorData *edata, int num_skip);
219
+ static void set_errdata_field(MemoryContextData *cxt, char **ptr, const char *str);
220
+ static void write_console(const char *line, int len);
221
+ static void setup_formatted_log_time(void);
222
+ static void setup_formatted_start_time(void);
223
+ static const char *process_log_prefix_padding(const char *p, int *padding);
224
+ static void log_line_prefix(StringInfo buf, ErrorData *edata);
225
+ static void write_csvlog(ErrorData *edata);
226
+ static void send_message_to_server_log(ErrorData *edata);
227
+ static void write_pipe_chunks(char *data, int len, int dest);
228
+ static void send_message_to_frontend(ErrorData *edata);
229
+ static const char *error_severity(int elevel);
230
+ static void append_with_tabs(StringInfo buf, const char *str);
231
+ static bool is_log_level_output(int elevel, int log_min_level);
232
+
233
+
234
+ /*
235
+ * in_error_recursion_trouble --- are we at risk of infinite error recursion?
236
+ *
237
+ * This function exists to provide common control of various fallback steps
238
+ * that we take if we think we are facing infinite error recursion. See the
239
+ * callers for details.
240
+ */
241
+ bool
242
+ in_error_recursion_trouble(void)
243
+ {
244
+ /* Pull the plug if recurse more than once */
245
+ return (recursion_depth > 2);
246
+ }
247
+
248
+ /*
249
+ * One of those fallback steps is to stop trying to localize the error
250
+ * message, since there's a significant probability that that's exactly
251
+ * what's causing the recursion.
252
+ */
253
+ static inline const char *
254
+ err_gettext(const char *str)
255
+ {
256
+ #ifdef ENABLE_NLS
257
+ if (in_error_recursion_trouble())
258
+ return str;
259
+ else
260
+ return gettext(str);
261
+ #else
262
+ return str;
263
+ #endif
264
+ }
265
+
266
+
267
+ /*
268
+ * errstart --- begin an error-reporting cycle
269
+ *
270
+ * Create and initialize error stack entry. Subsequently, errmsg() and
271
+ * perhaps other routines will be called to further populate the stack entry.
272
+ * Finally, errfinish() will be called to actually process the error report.
273
+ *
274
+ * Returns true in normal case. Returns false to short-circuit the error
275
+ * report (if it's a warning or lower and not to be reported anywhere).
276
+ */
277
+ bool
278
+ errstart(int elevel, const char *domain)
279
+ {
280
+ ErrorData *edata;
281
+ bool output_to_server;
282
+ bool output_to_client = false;
283
+ int i;
284
+
285
+ /*
286
+ * Check some cases in which we want to promote an error into a more
287
+ * severe error. None of this logic applies for non-error messages.
288
+ */
289
+ if (elevel >= ERROR)
290
+ {
291
+ /*
292
+ * If we are inside a critical section, all errors become PANIC
293
+ * errors. See miscadmin.h.
294
+ */
295
+ if (CritSectionCount > 0)
296
+ elevel = PANIC;
297
+
298
+ /*
299
+ * Check reasons for treating ERROR as FATAL:
300
+ *
301
+ * 1. we have no handler to pass the error to (implies we are in the
302
+ * postmaster or in backend startup).
303
+ *
304
+ * 2. ExitOnAnyError mode switch is set (initdb uses this).
305
+ *
306
+ * 3. the error occurred after proc_exit has begun to run. (It's
307
+ * proc_exit's responsibility to see that this doesn't turn into
308
+ * infinite recursion!)
309
+ */
310
+ if (elevel == ERROR)
311
+ {
312
+ if (PG_exception_stack == NULL ||
313
+ ExitOnAnyError ||
314
+ proc_exit_inprogress)
315
+ elevel = FATAL;
316
+ }
317
+
318
+ /*
319
+ * If the error level is ERROR or more, errfinish is not going to
320
+ * return to caller; therefore, if there is any stacked error already
321
+ * in progress it will be lost. This is more or less okay, except we
322
+ * do not want to have a FATAL or PANIC error downgraded because the
323
+ * reporting process was interrupted by a lower-grade error. So check
324
+ * the stack and make sure we panic if panic is warranted.
325
+ */
326
+ for (i = 0; i <= errordata_stack_depth; i++)
327
+ elevel = Max(elevel, errordata[i].elevel);
328
+ }
329
+
330
+ /*
331
+ * Now decide whether we need to process this report at all; if it's
332
+ * warning or less and not enabled for logging, just return false without
333
+ * starting up any error logging machinery.
334
+ */
335
+
336
+ /* Determine whether message is enabled for server log output */
337
+ output_to_server = is_log_level_output(elevel, log_min_messages);
338
+
339
+ /* Determine whether message is enabled for client output */
340
+ if (whereToSendOutput == DestRemote && elevel != LOG_SERVER_ONLY)
341
+ {
342
+ /*
343
+ * client_min_messages is honored only after we complete the
344
+ * authentication handshake. This is required both for security
345
+ * reasons and because many clients can't handle NOTICE messages
346
+ * during authentication.
347
+ */
348
+ if (ClientAuthInProgress)
349
+ output_to_client = (elevel >= ERROR);
350
+ else
351
+ output_to_client = (elevel >= client_min_messages ||
352
+ elevel == INFO);
353
+ }
354
+
355
+ /* Skip processing effort if non-error message will not be output */
356
+ if (elevel < ERROR && !output_to_server && !output_to_client)
357
+ return false;
358
+
359
+ /*
360
+ * We need to do some actual work. Make sure that memory context
361
+ * initialization has finished, else we can't do anything useful.
362
+ */
363
+ if (ErrorContext == NULL)
364
+ {
365
+ /* Oops, hard crash time; very little we can do safely here */
366
+ write_stderr("error occurred before error message processing is available\n");
367
+ exit(2);
368
+ }
369
+
370
+ /*
371
+ * Okay, crank up a stack entry to store the info in.
372
+ */
373
+
374
+ if (recursion_depth++ > 0 && elevel >= ERROR)
375
+ {
376
+ /*
377
+ * Oops, error during error processing. Clear ErrorContext as
378
+ * discussed at top of file. We will not return to the original
379
+ * error's reporter or handler, so we don't need it.
380
+ */
381
+ MemoryContextReset(ErrorContext);
382
+
383
+ /*
384
+ * Infinite error recursion might be due to something broken in a
385
+ * context traceback routine. Abandon them too. We also abandon
386
+ * attempting to print the error statement (which, if long, could
387
+ * itself be the source of the recursive failure).
388
+ */
389
+ if (in_error_recursion_trouble())
390
+ {
391
+ error_context_stack = NULL;
392
+ debug_query_string = NULL;
393
+ }
394
+ }
395
+ if (++errordata_stack_depth >= ERRORDATA_STACK_SIZE)
396
+ {
397
+ /*
398
+ * Wups, stack not big enough. We treat this as a PANIC condition
399
+ * because it suggests an infinite loop of errors during error
400
+ * recovery.
401
+ */
402
+ errordata_stack_depth = -1; /* make room on stack */
403
+ ereport(PANIC, (errmsg_internal("ERRORDATA_STACK_SIZE exceeded")));
404
+ }
405
+
406
+ /* Initialize data for this error frame */
407
+ edata = &errordata[errordata_stack_depth];
408
+ MemSet(edata, 0, sizeof(ErrorData));
409
+ edata->elevel = elevel;
410
+ edata->output_to_server = output_to_server;
411
+ edata->output_to_client = output_to_client;
412
+ /* the default text domain is the backend's */
413
+ edata->domain = domain ? domain : PG_TEXTDOMAIN("postgres");
414
+ /* initialize context_domain the same way (see set_errcontext_domain()) */
415
+ edata->context_domain = edata->domain;
416
+ /* Select default errcode based on elevel */
417
+ if (elevel >= ERROR)
418
+ edata->sqlerrcode = ERRCODE_INTERNAL_ERROR;
419
+ else if (elevel == WARNING)
420
+ edata->sqlerrcode = ERRCODE_WARNING;
421
+ else
422
+ edata->sqlerrcode = ERRCODE_SUCCESSFUL_COMPLETION;
423
+ /* errno is saved here so that error parameter eval can't change it */
424
+ edata->saved_errno = errno;
425
+
426
+ /*
427
+ * Any allocations for this error state level should go into ErrorContext
428
+ */
429
+ edata->assoc_context = ErrorContext;
430
+
431
+ recursion_depth--;
432
+ return true;
433
+ }
434
+
435
+ /*
436
+ * Checks whether the given funcname matches backtrace_functions; see
437
+ * check_backtrace_functions.
438
+ */
439
+ static bool
440
+ matches_backtrace_functions(const char *funcname)
441
+ {
442
+ char *p;
443
+
444
+ if (!backtrace_symbol_list || funcname == NULL || funcname[0] == '\0')
445
+ return false;
446
+
447
+ p = backtrace_symbol_list;
448
+ for (;;)
449
+ {
450
+ if (*p == '\0') /* end of backtrace_symbol_list */
451
+ break;
452
+
453
+ if (strcmp(funcname, p) == 0)
454
+ return true;
455
+ p += strlen(p) + 1;
456
+ }
457
+
458
+ return false;
459
+ }
460
+
461
+ /*
462
+ * errfinish --- end an error-reporting cycle
463
+ *
464
+ * Produce the appropriate error report(s) and pop the error stack.
465
+ *
466
+ * If elevel, as passed to errstart(), is ERROR or worse, control does not
467
+ * return to the caller. See elog.h for the error level definitions.
468
+ */
469
+ void
470
+ errfinish(const char *filename, int lineno, const char *funcname)
471
+ {
472
+ ErrorData *edata = &errordata[errordata_stack_depth];
473
+ int elevel;
474
+ MemoryContext oldcontext;
475
+ ErrorContextCallback *econtext;
476
+
477
+ recursion_depth++;
478
+ CHECK_STACK_DEPTH();
479
+
480
+ /* Save the last few bits of error state into the stack entry */
481
+ if (filename)
482
+ {
483
+ const char *slash;
484
+
485
+ /* keep only base name, useful especially for vpath builds */
486
+ slash = strrchr(filename, '/');
487
+ if (slash)
488
+ filename = slash + 1;
489
+ }
490
+
491
+ edata->filename = filename;
492
+ edata->lineno = lineno;
493
+ edata->funcname = funcname;
494
+
495
+ elevel = edata->elevel;
496
+
497
+ /*
498
+ * Do processing in ErrorContext, which we hope has enough reserved space
499
+ * to report an error.
500
+ */
501
+ oldcontext = MemoryContextSwitchTo(ErrorContext);
502
+
503
+ if (!edata->backtrace &&
504
+ edata->funcname &&
505
+ backtrace_functions &&
506
+ matches_backtrace_functions(edata->funcname))
507
+ set_backtrace(edata, 2);
508
+
509
+ /*
510
+ * Call any context callback functions. Errors occurring in callback
511
+ * functions will be treated as recursive errors --- this ensures we will
512
+ * avoid infinite recursion (see errstart).
513
+ */
514
+ for (econtext = error_context_stack;
515
+ econtext != NULL;
516
+ econtext = econtext->previous)
517
+ econtext->callback(econtext->arg);
518
+
519
+ /*
520
+ * If ERROR (not more nor less) we pass it off to the current handler.
521
+ * Printing it and popping the stack is the responsibility of the handler.
522
+ */
523
+ if (elevel == ERROR)
524
+ {
525
+ /*
526
+ * We do some minimal cleanup before longjmp'ing so that handlers can
527
+ * execute in a reasonably sane state.
528
+ *
529
+ * Reset InterruptHoldoffCount in case we ereport'd from inside an
530
+ * interrupt holdoff section. (We assume here that no handler will
531
+ * itself be inside a holdoff section. If necessary, such a handler
532
+ * could save and restore InterruptHoldoffCount for itself, but this
533
+ * should make life easier for most.)
534
+ */
535
+ InterruptHoldoffCount = 0;
536
+ QueryCancelHoldoffCount = 0;
537
+
538
+ CritSectionCount = 0; /* should be unnecessary, but... */
539
+
540
+ /*
541
+ * Note that we leave CurrentMemoryContext set to ErrorContext. The
542
+ * handler should reset it to something else soon.
543
+ */
544
+
545
+ recursion_depth--;
546
+ PG_RE_THROW();
547
+ }
548
+
549
+ /*
550
+ * If we are doing FATAL or PANIC, abort any old-style COPY OUT in
551
+ * progress, so that we can report the message before dying. (Without
552
+ * this, pq_putmessage will refuse to send the message at all, which is
553
+ * what we want for NOTICE messages, but not for fatal exits.) This hack
554
+ * is necessary because of poor design of old-style copy protocol.
555
+ */
556
+ if (elevel >= FATAL && whereToSendOutput == DestRemote)
557
+ pq_endcopyout(true);
558
+
559
+ /* Emit the message to the right places */
560
+ EmitErrorReport();
561
+
562
+ /* Now free up subsidiary data attached to stack entry, and release it */
563
+ if (edata->message)
564
+ pfree(edata->message);
565
+ if (edata->detail)
566
+ pfree(edata->detail);
567
+ if (edata->detail_log)
568
+ pfree(edata->detail_log);
569
+ if (edata->hint)
570
+ pfree(edata->hint);
571
+ if (edata->context)
572
+ pfree(edata->context);
573
+ if (edata->backtrace)
574
+ pfree(edata->backtrace);
575
+ if (edata->schema_name)
576
+ pfree(edata->schema_name);
577
+ if (edata->table_name)
578
+ pfree(edata->table_name);
579
+ if (edata->column_name)
580
+ pfree(edata->column_name);
581
+ if (edata->datatype_name)
582
+ pfree(edata->datatype_name);
583
+ if (edata->constraint_name)
584
+ pfree(edata->constraint_name);
585
+ if (edata->internalquery)
586
+ pfree(edata->internalquery);
587
+
588
+ errordata_stack_depth--;
589
+
590
+ /* Exit error-handling context */
591
+ MemoryContextSwitchTo(oldcontext);
592
+ recursion_depth--;
593
+
594
+ /*
595
+ * Perform error recovery action as specified by elevel.
596
+ */
597
+ if (elevel == FATAL)
598
+ {
599
+ /*
600
+ * For a FATAL error, we let proc_exit clean up and exit.
601
+ *
602
+ * If we just reported a startup failure, the client will disconnect
603
+ * on receiving it, so don't send any more to the client.
604
+ */
605
+ if (PG_exception_stack == NULL && whereToSendOutput == DestRemote)
606
+ whereToSendOutput = DestNone;
607
+
608
+ /*
609
+ * fflush here is just to improve the odds that we get to see the
610
+ * error message, in case things are so hosed that proc_exit crashes.
611
+ * Any other code you might be tempted to add here should probably be
612
+ * in an on_proc_exit or on_shmem_exit callback instead.
613
+ */
614
+ fflush(stdout);
615
+ fflush(stderr);
616
+
617
+ /*
618
+ * Do normal process-exit cleanup, then return exit code 1 to indicate
619
+ * FATAL termination. The postmaster may or may not consider this
620
+ * worthy of panic, depending on which subprocess returns it.
621
+ */
622
+ proc_exit(1);
623
+ }
624
+
625
+ if (elevel >= PANIC)
626
+ {
627
+ /*
628
+ * Serious crash time. Postmaster will observe SIGABRT process exit
629
+ * status and kill the other backends too.
630
+ *
631
+ * XXX: what if we are *in* the postmaster? abort() won't kill our
632
+ * children...
633
+ */
634
+ fflush(stdout);
635
+ fflush(stderr);
636
+ abort();
637
+ }
638
+
639
+ /*
640
+ * Check for cancel/die interrupt first --- this is so that the user can
641
+ * stop a query emitting tons of notice or warning messages, even if it's
642
+ * in a loop that otherwise fails to check for interrupts.
643
+ */
644
+ CHECK_FOR_INTERRUPTS();
645
+ }
646
+
647
+
648
+ /*
649
+ * errcode --- add SQLSTATE error code to the current error
650
+ *
651
+ * The code is expected to be represented as per MAKE_SQLSTATE().
652
+ */
653
+ int
654
+ errcode(int sqlerrcode)
655
+ {
656
+ ErrorData *edata = &errordata[errordata_stack_depth];
657
+
658
+ /* we don't bother incrementing recursion_depth */
659
+ CHECK_STACK_DEPTH();
660
+
661
+ edata->sqlerrcode = sqlerrcode;
662
+
663
+ return 0; /* return value does not matter */
664
+ }
665
+
666
+
667
+ /*
668
+ * errcode_for_file_access --- add SQLSTATE error code to the current error
669
+ *
670
+ * The SQLSTATE code is chosen based on the saved errno value. We assume
671
+ * that the failing operation was some type of disk file access.
672
+ *
673
+ * NOTE: the primary error message string should generally include %m
674
+ * when this is used.
675
+ */
676
+ #ifdef EROFS
677
+ #endif
678
+ #if defined(ENOTEMPTY) && (ENOTEMPTY != EEXIST) /* same code on AIX */
679
+ #endif
680
+
681
+ /*
682
+ * errcode_for_socket_access --- add SQLSTATE error code to the current error
683
+ *
684
+ * The SQLSTATE code is chosen based on the saved errno value. We assume
685
+ * that the failing operation was some type of socket access.
686
+ *
687
+ * NOTE: the primary error message string should generally include %m
688
+ * when this is used.
689
+ */
690
+ #ifdef ECONNRESET
691
+ #endif
692
+
693
+
694
+ /*
695
+ * This macro handles expansion of a format string and associated parameters;
696
+ * it's common code for errmsg(), errdetail(), etc. Must be called inside
697
+ * a routine that is declared like "const char *fmt, ..." and has an edata
698
+ * pointer set up. The message is assigned to edata->targetfield, or
699
+ * appended to it if appendval is true. The message is subject to translation
700
+ * if translateit is true.
701
+ *
702
+ * Note: we pstrdup the buffer rather than just transferring its storage
703
+ * to the edata field because the buffer might be considerably larger than
704
+ * really necessary.
705
+ */
706
+ #define EVALUATE_MESSAGE(domain, targetfield, appendval, translateit) \
707
+ { \
708
+ StringInfoData buf; \
709
+ /* Internationalize the error format string */ \
710
+ if ((translateit) && !in_error_recursion_trouble()) \
711
+ fmt = dgettext((domain), fmt); \
712
+ initStringInfo(&buf); \
713
+ if ((appendval) && edata->targetfield) { \
714
+ appendStringInfoString(&buf, edata->targetfield); \
715
+ appendStringInfoChar(&buf, '\n'); \
716
+ } \
717
+ /* Generate actual output --- have to use appendStringInfoVA */ \
718
+ for (;;) \
719
+ { \
720
+ va_list args; \
721
+ int needed; \
722
+ errno = edata->saved_errno; \
723
+ va_start(args, fmt); \
724
+ needed = appendStringInfoVA(&buf, fmt, args); \
725
+ va_end(args); \
726
+ if (needed == 0) \
727
+ break; \
728
+ enlargeStringInfo(&buf, needed); \
729
+ } \
730
+ /* Save the completed message into the stack item */ \
731
+ if (edata->targetfield) \
732
+ pfree(edata->targetfield); \
733
+ edata->targetfield = pstrdup(buf.data); \
734
+ pfree(buf.data); \
735
+ }
736
+
737
+ /*
738
+ * Same as above, except for pluralized error messages. The calling routine
739
+ * must be declared like "const char *fmt_singular, const char *fmt_plural,
740
+ * unsigned long n, ...". Translation is assumed always wanted.
741
+ */
742
+ #define EVALUATE_MESSAGE_PLURAL(domain, targetfield, appendval) \
743
+ { \
744
+ const char *fmt; \
745
+ StringInfoData buf; \
746
+ /* Internationalize the error format string */ \
747
+ if (!in_error_recursion_trouble()) \
748
+ fmt = dngettext((domain), fmt_singular, fmt_plural, n); \
749
+ else \
750
+ fmt = (n == 1 ? fmt_singular : fmt_plural); \
751
+ initStringInfo(&buf); \
752
+ if ((appendval) && edata->targetfield) { \
753
+ appendStringInfoString(&buf, edata->targetfield); \
754
+ appendStringInfoChar(&buf, '\n'); \
755
+ } \
756
+ /* Generate actual output --- have to use appendStringInfoVA */ \
757
+ for (;;) \
758
+ { \
759
+ va_list args; \
760
+ int needed; \
761
+ errno = edata->saved_errno; \
762
+ va_start(args, n); \
763
+ needed = appendStringInfoVA(&buf, fmt, args); \
764
+ va_end(args); \
765
+ if (needed == 0) \
766
+ break; \
767
+ enlargeStringInfo(&buf, needed); \
768
+ } \
769
+ /* Save the completed message into the stack item */ \
770
+ if (edata->targetfield) \
771
+ pfree(edata->targetfield); \
772
+ edata->targetfield = pstrdup(buf.data); \
773
+ pfree(buf.data); \
774
+ }
775
+
776
+
777
+ /*
778
+ * errmsg --- add a primary error message text to the current error
779
+ *
780
+ * In addition to the usual %-escapes recognized by printf, "%m" in
781
+ * fmt is replaced by the error message for the caller's value of errno.
782
+ *
783
+ * Note: no newline is needed at the end of the fmt string, since
784
+ * ereport will provide one for the output methods that need it.
785
+ */
786
+ int
787
+ errmsg(const char *fmt,...)
788
+ {
789
+ ErrorData *edata = &errordata[errordata_stack_depth];
790
+ MemoryContext oldcontext;
791
+
792
+ recursion_depth++;
793
+ CHECK_STACK_DEPTH();
794
+ oldcontext = MemoryContextSwitchTo(edata->assoc_context);
795
+
796
+ edata->message_id = fmt;
797
+ EVALUATE_MESSAGE(edata->domain, message, false, true);
798
+
799
+ MemoryContextSwitchTo(oldcontext);
800
+ recursion_depth--;
801
+ return 0; /* return value does not matter */
802
+ }
803
+
804
+ /*
805
+ * Add a backtrace to the containing ereport() call. This is intended to be
806
+ * added temporarily during debugging.
807
+ */
808
+
809
+
810
+ /*
811
+ * Compute backtrace data and add it to the supplied ErrorData. num_skip
812
+ * specifies how many inner frames to skip. Use this to avoid showing the
813
+ * internal backtrace support functions in the backtrace. This requires that
814
+ * this and related functions are not inlined.
815
+ */
816
+ static void
817
+ set_backtrace(ErrorData *edata, int num_skip)
818
+ {
819
+ StringInfoData errtrace;
820
+
821
+ initStringInfo(&errtrace);
822
+
823
+ #ifdef HAVE_BACKTRACE_SYMBOLS
824
+ {
825
+ void *buf[100];
826
+ int nframes;
827
+ char **strfrms;
828
+
829
+ nframes = backtrace(buf, lengthof(buf));
830
+ strfrms = backtrace_symbols(buf, nframes);
831
+ if (strfrms == NULL)
832
+ return;
833
+
834
+ for (int i = num_skip; i < nframes; i++)
835
+ appendStringInfo(&errtrace, "\n%s", strfrms[i]);
836
+ free(strfrms);
837
+ }
838
+ #else
839
+ appendStringInfoString(&errtrace,
840
+ "backtrace generation is not supported by this installation");
841
+ #endif
842
+
843
+ edata->backtrace = errtrace.data;
844
+ }
845
+
846
+ /*
847
+ * errmsg_internal --- add a primary error message text to the current error
848
+ *
849
+ * This is exactly like errmsg() except that strings passed to errmsg_internal
850
+ * are not translated, and are customarily left out of the
851
+ * internationalization message dictionary. This should be used for "can't
852
+ * happen" cases that are probably not worth spending translation effort on.
853
+ * We also use this for certain cases where we *must* not try to translate
854
+ * the message because the translation would fail and result in infinite
855
+ * error recursion.
856
+ */
857
+ int
858
+ errmsg_internal(const char *fmt,...)
859
+ {
860
+ ErrorData *edata = &errordata[errordata_stack_depth];
861
+ MemoryContext oldcontext;
862
+
863
+ recursion_depth++;
864
+ CHECK_STACK_DEPTH();
865
+ oldcontext = MemoryContextSwitchTo(edata->assoc_context);
866
+
867
+ edata->message_id = fmt;
868
+ EVALUATE_MESSAGE(edata->domain, message, false, false);
869
+
870
+ MemoryContextSwitchTo(oldcontext);
871
+ recursion_depth--;
872
+ return 0; /* return value does not matter */
873
+ }
874
+
875
+
876
+ /*
877
+ * errmsg_plural --- add a primary error message text to the current error,
878
+ * with support for pluralization of the message text
879
+ */
880
+
881
+
882
+
883
+ /*
884
+ * errdetail --- add a detail error message text to the current error
885
+ */
886
+ int
887
+ errdetail(const char *fmt,...)
888
+ {
889
+ ErrorData *edata = &errordata[errordata_stack_depth];
890
+ MemoryContext oldcontext;
891
+
892
+ recursion_depth++;
893
+ CHECK_STACK_DEPTH();
894
+ oldcontext = MemoryContextSwitchTo(edata->assoc_context);
895
+
896
+ EVALUATE_MESSAGE(edata->domain, detail, false, true);
897
+
898
+ MemoryContextSwitchTo(oldcontext);
899
+ recursion_depth--;
900
+ return 0; /* return value does not matter */
901
+ }
902
+
903
+
904
+ /*
905
+ * errdetail_internal --- add a detail error message text to the current error
906
+ *
907
+ * This is exactly like errdetail() except that strings passed to
908
+ * errdetail_internal are not translated, and are customarily left out of the
909
+ * internationalization message dictionary. This should be used for detail
910
+ * messages that seem not worth translating for one reason or another
911
+ * (typically, that they don't seem to be useful to average users).
912
+ */
913
+
914
+
915
+
916
+ /*
917
+ * errdetail_log --- add a detail_log error message text to the current error
918
+ */
919
+
920
+
921
+ /*
922
+ * errdetail_log_plural --- add a detail_log error message text to the current error
923
+ * with support for pluralization of the message text
924
+ */
925
+
926
+
927
+
928
+ /*
929
+ * errdetail_plural --- add a detail error message text to the current error,
930
+ * with support for pluralization of the message text
931
+ */
932
+
933
+
934
+
935
+ /*
936
+ * errhint --- add a hint error message text to the current error
937
+ */
938
+ int
939
+ errhint(const char *fmt,...)
940
+ {
941
+ ErrorData *edata = &errordata[errordata_stack_depth];
942
+ MemoryContext oldcontext;
943
+
944
+ recursion_depth++;
945
+ CHECK_STACK_DEPTH();
946
+ oldcontext = MemoryContextSwitchTo(edata->assoc_context);
947
+
948
+ EVALUATE_MESSAGE(edata->domain, hint, false, true);
949
+
950
+ MemoryContextSwitchTo(oldcontext);
951
+ recursion_depth--;
952
+ return 0; /* return value does not matter */
953
+ }
954
+
955
+
956
+ /*
957
+ * errcontext_msg --- add a context error message text to the current error
958
+ *
959
+ * Unlike other cases, multiple calls are allowed to build up a stack of
960
+ * context information. We assume earlier calls represent more-closely-nested
961
+ * states.
962
+ */
963
+ int
964
+ errcontext_msg(const char *fmt,...)
965
+ {
966
+ ErrorData *edata = &errordata[errordata_stack_depth];
967
+ MemoryContext oldcontext;
968
+
969
+ recursion_depth++;
970
+ CHECK_STACK_DEPTH();
971
+ oldcontext = MemoryContextSwitchTo(edata->assoc_context);
972
+
973
+ EVALUATE_MESSAGE(edata->context_domain, context, true, true);
974
+
975
+ MemoryContextSwitchTo(oldcontext);
976
+ recursion_depth--;
977
+ return 0; /* return value does not matter */
978
+ }
979
+
980
+ /*
981
+ * set_errcontext_domain --- set message domain to be used by errcontext()
982
+ *
983
+ * errcontext_msg() can be called from a different module than the original
984
+ * ereport(), so we cannot use the message domain passed in errstart() to
985
+ * translate it. Instead, each errcontext_msg() call should be preceded by
986
+ * a set_errcontext_domain() call to specify the domain. This is usually
987
+ * done transparently by the errcontext() macro.
988
+ */
989
+ int
990
+ set_errcontext_domain(const char *domain)
991
+ {
992
+ ErrorData *edata = &errordata[errordata_stack_depth];
993
+
994
+ /* we don't bother incrementing recursion_depth */
995
+ CHECK_STACK_DEPTH();
996
+
997
+ /* the default text domain is the backend's */
998
+ edata->context_domain = domain ? domain : PG_TEXTDOMAIN("postgres");
999
+
1000
+ return 0; /* return value does not matter */
1001
+ }
1002
+
1003
+
1004
+ /*
1005
+ * errhidestmt --- optionally suppress STATEMENT: field of log entry
1006
+ *
1007
+ * This should be called if the message text already includes the statement.
1008
+ */
1009
+
1010
+
1011
+ /*
1012
+ * errhidecontext --- optionally suppress CONTEXT: field of log entry
1013
+ *
1014
+ * This should only be used for verbose debugging messages where the repeated
1015
+ * inclusion of context would bloat the log volume too much.
1016
+ */
1017
+
1018
+
1019
+
1020
+ /*
1021
+ * errfunction --- add reporting function name to the current error
1022
+ *
1023
+ * This is used when backwards compatibility demands that the function
1024
+ * name appear in messages sent to old-protocol clients. Note that the
1025
+ * passed string is expected to be a non-freeable constant string.
1026
+ */
1027
+
1028
+
1029
+ /*
1030
+ * errposition --- add cursor position to the current error
1031
+ */
1032
+ int
1033
+ errposition(int cursorpos)
1034
+ {
1035
+ ErrorData *edata = &errordata[errordata_stack_depth];
1036
+
1037
+ /* we don't bother incrementing recursion_depth */
1038
+ CHECK_STACK_DEPTH();
1039
+
1040
+ edata->cursorpos = cursorpos;
1041
+
1042
+ return 0; /* return value does not matter */
1043
+ }
1044
+
1045
+ /*
1046
+ * internalerrposition --- add internal cursor position to the current error
1047
+ */
1048
+ int
1049
+ internalerrposition(int cursorpos)
1050
+ {
1051
+ ErrorData *edata = &errordata[errordata_stack_depth];
1052
+
1053
+ /* we don't bother incrementing recursion_depth */
1054
+ CHECK_STACK_DEPTH();
1055
+
1056
+ edata->internalpos = cursorpos;
1057
+
1058
+ return 0; /* return value does not matter */
1059
+ }
1060
+
1061
+ /*
1062
+ * internalerrquery --- add internal query text to the current error
1063
+ *
1064
+ * Can also pass NULL to drop the internal query text entry. This case
1065
+ * is intended for use in error callback subroutines that are editorializing
1066
+ * on the layout of the error report.
1067
+ */
1068
+ int
1069
+ internalerrquery(const char *query)
1070
+ {
1071
+ ErrorData *edata = &errordata[errordata_stack_depth];
1072
+
1073
+ /* we don't bother incrementing recursion_depth */
1074
+ CHECK_STACK_DEPTH();
1075
+
1076
+ if (edata->internalquery)
1077
+ {
1078
+ pfree(edata->internalquery);
1079
+ edata->internalquery = NULL;
1080
+ }
1081
+
1082
+ if (query)
1083
+ edata->internalquery = MemoryContextStrdup(edata->assoc_context, query);
1084
+
1085
+ return 0; /* return value does not matter */
1086
+ }
1087
+
1088
+ /*
1089
+ * err_generic_string -- used to set individual ErrorData string fields
1090
+ * identified by PG_DIAG_xxx codes.
1091
+ *
1092
+ * This intentionally only supports fields that don't use localized strings,
1093
+ * so that there are no translation considerations.
1094
+ *
1095
+ * Most potential callers should not use this directly, but instead prefer
1096
+ * higher-level abstractions, such as errtablecol() (see relcache.c).
1097
+ */
1098
+
1099
+
1100
+ /*
1101
+ * set_errdata_field --- set an ErrorData string field
1102
+ */
1103
+
1104
+
1105
+ /*
1106
+ * geterrcode --- return the currently set SQLSTATE error code
1107
+ *
1108
+ * This is only intended for use in error callback subroutines, since there
1109
+ * is no other place outside elog.c where the concept is meaningful.
1110
+ */
1111
+ int
1112
+ geterrcode(void)
1113
+ {
1114
+ ErrorData *edata = &errordata[errordata_stack_depth];
1115
+
1116
+ /* we don't bother incrementing recursion_depth */
1117
+ CHECK_STACK_DEPTH();
1118
+
1119
+ return edata->sqlerrcode;
1120
+ }
1121
+
1122
+ /*
1123
+ * geterrposition --- return the currently set error position (0 if none)
1124
+ *
1125
+ * This is only intended for use in error callback subroutines, since there
1126
+ * is no other place outside elog.c where the concept is meaningful.
1127
+ */
1128
+ int
1129
+ geterrposition(void)
1130
+ {
1131
+ ErrorData *edata = &errordata[errordata_stack_depth];
1132
+
1133
+ /* we don't bother incrementing recursion_depth */
1134
+ CHECK_STACK_DEPTH();
1135
+
1136
+ return edata->cursorpos;
1137
+ }
1138
+
1139
+ /*
1140
+ * getinternalerrposition --- same for internal error position
1141
+ *
1142
+ * This is only intended for use in error callback subroutines, since there
1143
+ * is no other place outside elog.c where the concept is meaningful.
1144
+ */
1145
+ int
1146
+ getinternalerrposition(void)
1147
+ {
1148
+ ErrorData *edata = &errordata[errordata_stack_depth];
1149
+
1150
+ /* we don't bother incrementing recursion_depth */
1151
+ CHECK_STACK_DEPTH();
1152
+
1153
+ return edata->internalpos;
1154
+ }
1155
+
1156
+
1157
+ /*
1158
+ * Functions to allow construction of error message strings separately from
1159
+ * the ereport() call itself.
1160
+ *
1161
+ * The expected calling convention is
1162
+ *
1163
+ * pre_format_elog_string(errno, domain), var = format_elog_string(format,...)
1164
+ *
1165
+ * which can be hidden behind a macro such as GUC_check_errdetail(). We
1166
+ * assume that any functions called in the arguments of format_elog_string()
1167
+ * cannot result in re-entrant use of these functions --- otherwise the wrong
1168
+ * text domain might be used, or the wrong errno substituted for %m. This is
1169
+ * okay for the current usage with GUC check hooks, but might need further
1170
+ * effort someday.
1171
+ *
1172
+ * The result of format_elog_string() is stored in ErrorContext, and will
1173
+ * therefore survive until FlushErrorState() is called.
1174
+ */
1175
+
1176
+
1177
+
1178
+
1179
+
1180
+
1181
+
1182
+
1183
+ /*
1184
+ * Actual output of the top-of-stack error message
1185
+ *
1186
+ * In the ereport(ERROR) case this is called from PostgresMain (or not at all,
1187
+ * if the error is caught by somebody). For all other severity levels this
1188
+ * is called by errfinish.
1189
+ */
1190
+ void
1191
+ EmitErrorReport(void)
1192
+ {
1193
+ ErrorData *edata = &errordata[errordata_stack_depth];
1194
+ MemoryContext oldcontext;
1195
+
1196
+ recursion_depth++;
1197
+ CHECK_STACK_DEPTH();
1198
+ oldcontext = MemoryContextSwitchTo(edata->assoc_context);
1199
+
1200
+ /*
1201
+ * Call hook before sending message to log. The hook function is allowed
1202
+ * to turn off edata->output_to_server, so we must recheck that afterward.
1203
+ * Making any other change in the content of edata is not considered
1204
+ * supported.
1205
+ *
1206
+ * Note: the reason why the hook can only turn off output_to_server, and
1207
+ * not turn it on, is that it'd be unreliable: we will never get here at
1208
+ * all if errstart() deems the message uninteresting. A hook that could
1209
+ * make decisions in that direction would have to hook into errstart(),
1210
+ * where it would have much less information available. emit_log_hook is
1211
+ * intended for custom log filtering and custom log message transmission
1212
+ * mechanisms.
1213
+ *
1214
+ * The log hook has access to both the translated and original English
1215
+ * error message text, which is passed through to allow it to be used as a
1216
+ * message identifier. Note that the original text is not available for
1217
+ * detail, detail_log, hint and context text elements.
1218
+ */
1219
+ if (edata->output_to_server && emit_log_hook)
1220
+ (*emit_log_hook) (edata);
1221
+
1222
+ /* Send to server log, if enabled */
1223
+ if (edata->output_to_server)
1224
+ send_message_to_server_log(edata);
1225
+
1226
+ /* Send to client, if enabled */
1227
+ if (edata->output_to_client)
1228
+ send_message_to_frontend(edata);
1229
+
1230
+ MemoryContextSwitchTo(oldcontext);
1231
+ recursion_depth--;
1232
+ }
1233
+
1234
+ /*
1235
+ * CopyErrorData --- obtain a copy of the topmost error stack entry
1236
+ *
1237
+ * This is only for use in error handler code. The data is copied into the
1238
+ * current memory context, so callers should always switch away from
1239
+ * ErrorContext first; otherwise it will be lost when FlushErrorState is done.
1240
+ */
1241
+ ErrorData *
1242
+ CopyErrorData(void)
1243
+ {
1244
+ ErrorData *edata = &errordata[errordata_stack_depth];
1245
+ ErrorData *newedata;
1246
+
1247
+ /*
1248
+ * we don't increment recursion_depth because out-of-memory here does not
1249
+ * indicate a problem within the error subsystem.
1250
+ */
1251
+ CHECK_STACK_DEPTH();
1252
+
1253
+ Assert(CurrentMemoryContext != ErrorContext);
1254
+
1255
+ /* Copy the struct itself */
1256
+ newedata = (ErrorData *) palloc(sizeof(ErrorData));
1257
+ memcpy(newedata, edata, sizeof(ErrorData));
1258
+
1259
+ /* Make copies of separately-allocated fields */
1260
+ if (newedata->message)
1261
+ newedata->message = pstrdup(newedata->message);
1262
+ if (newedata->detail)
1263
+ newedata->detail = pstrdup(newedata->detail);
1264
+ if (newedata->detail_log)
1265
+ newedata->detail_log = pstrdup(newedata->detail_log);
1266
+ if (newedata->hint)
1267
+ newedata->hint = pstrdup(newedata->hint);
1268
+ if (newedata->context)
1269
+ newedata->context = pstrdup(newedata->context);
1270
+ if (newedata->backtrace)
1271
+ newedata->backtrace = pstrdup(newedata->backtrace);
1272
+ if (newedata->schema_name)
1273
+ newedata->schema_name = pstrdup(newedata->schema_name);
1274
+ if (newedata->table_name)
1275
+ newedata->table_name = pstrdup(newedata->table_name);
1276
+ if (newedata->column_name)
1277
+ newedata->column_name = pstrdup(newedata->column_name);
1278
+ if (newedata->datatype_name)
1279
+ newedata->datatype_name = pstrdup(newedata->datatype_name);
1280
+ if (newedata->constraint_name)
1281
+ newedata->constraint_name = pstrdup(newedata->constraint_name);
1282
+ if (newedata->internalquery)
1283
+ newedata->internalquery = pstrdup(newedata->internalquery);
1284
+
1285
+ /* Use the calling context for string allocation */
1286
+ newedata->assoc_context = CurrentMemoryContext;
1287
+
1288
+ return newedata;
1289
+ }
1290
+
1291
+ /*
1292
+ * FreeErrorData --- free the structure returned by CopyErrorData.
1293
+ *
1294
+ * Error handlers should use this in preference to assuming they know all
1295
+ * the separately-allocated fields.
1296
+ */
1297
+
1298
+
1299
+ /*
1300
+ * FlushErrorState --- flush the error state after error recovery
1301
+ *
1302
+ * This should be called by an error handler after it's done processing
1303
+ * the error; or as soon as it's done CopyErrorData, if it intends to
1304
+ * do stuff that is likely to provoke another error. You are not "out" of
1305
+ * the error subsystem until you have done this.
1306
+ */
1307
+ void
1308
+ FlushErrorState(void)
1309
+ {
1310
+ /*
1311
+ * Reset stack to empty. The only case where it would be more than one
1312
+ * deep is if we serviced an error that interrupted construction of
1313
+ * another message. We assume control escaped out of that message
1314
+ * construction and won't ever go back.
1315
+ */
1316
+ errordata_stack_depth = -1;
1317
+ recursion_depth = 0;
1318
+ /* Delete all data in ErrorContext */
1319
+ MemoryContextResetAndDeleteChildren(ErrorContext);
1320
+ }
1321
+
1322
+ /*
1323
+ * ThrowErrorData --- report an error described by an ErrorData structure
1324
+ *
1325
+ * This is somewhat like ReThrowError, but it allows elevels besides ERROR,
1326
+ * and the boolean flags such as output_to_server are computed via the
1327
+ * default rules rather than being copied from the given ErrorData.
1328
+ * This is primarily used to re-report errors originally reported by
1329
+ * background worker processes and then propagated (with or without
1330
+ * modification) to the backend responsible for them.
1331
+ */
1332
+
1333
+
1334
+ /*
1335
+ * ReThrowError --- re-throw a previously copied error
1336
+ *
1337
+ * A handler can do CopyErrorData/FlushErrorState to get out of the error
1338
+ * subsystem, then do some processing, and finally ReThrowError to re-throw
1339
+ * the original error. This is slower than just PG_RE_THROW() but should
1340
+ * be used if the "some processing" is likely to incur another error.
1341
+ */
1342
+
1343
+
1344
+ /*
1345
+ * pg_re_throw --- out-of-line implementation of PG_RE_THROW() macro
1346
+ */
1347
+ void
1348
+ pg_re_throw(void)
1349
+ {
1350
+ /* If possible, throw the error to the next outer setjmp handler */
1351
+ if (PG_exception_stack != NULL)
1352
+ siglongjmp(*PG_exception_stack, 1);
1353
+ else
1354
+ {
1355
+ /*
1356
+ * If we get here, elog(ERROR) was thrown inside a PG_TRY block, which
1357
+ * we have now exited only to discover that there is no outer setjmp
1358
+ * handler to pass the error to. Had the error been thrown outside
1359
+ * the block to begin with, we'd have promoted the error to FATAL, so
1360
+ * the correct behavior is to make it FATAL now; that is, emit it and
1361
+ * then call proc_exit.
1362
+ */
1363
+ ErrorData *edata = &errordata[errordata_stack_depth];
1364
+
1365
+ Assert(errordata_stack_depth >= 0);
1366
+ Assert(edata->elevel == ERROR);
1367
+ edata->elevel = FATAL;
1368
+
1369
+ /*
1370
+ * At least in principle, the increase in severity could have changed
1371
+ * where-to-output decisions, so recalculate. This should stay in
1372
+ * sync with errstart(), which see for comments.
1373
+ */
1374
+ if (IsPostmasterEnvironment)
1375
+ edata->output_to_server = is_log_level_output(FATAL,
1376
+ log_min_messages);
1377
+ else
1378
+ edata->output_to_server = (FATAL >= log_min_messages);
1379
+ if (whereToSendOutput == DestRemote)
1380
+ edata->output_to_client = true;
1381
+
1382
+ /*
1383
+ * We can use errfinish() for the rest, but we don't want it to call
1384
+ * any error context routines a second time. Since we know we are
1385
+ * about to exit, it should be OK to just clear the context stack.
1386
+ */
1387
+ error_context_stack = NULL;
1388
+
1389
+ errfinish(edata->filename, edata->lineno, edata->funcname);
1390
+ }
1391
+
1392
+ /* Doesn't return ... */
1393
+ ExceptionalCondition("pg_re_throw tried to return", "FailedAssertion",
1394
+ __FILE__, __LINE__);
1395
+ }
1396
+
1397
+
1398
+ /*
1399
+ * GetErrorContextStack - Return the context stack, for display/diags
1400
+ *
1401
+ * Returns a pstrdup'd string in the caller's context which includes the PG
1402
+ * error call stack. It is the caller's responsibility to ensure this string
1403
+ * is pfree'd (or its context cleaned up) when done.
1404
+ *
1405
+ * This information is collected by traversing the error contexts and calling
1406
+ * each context's callback function, each of which is expected to call
1407
+ * errcontext() to return a string which can be presented to the user.
1408
+ */
1409
+
1410
+
1411
+
1412
+ /*
1413
+ * Initialization of error output file
1414
+ */
1415
+
1416
+
1417
+
1418
+ #ifdef HAVE_SYSLOG
1419
+
1420
+ /*
1421
+ * Set or update the parameters for syslog logging
1422
+ */
1423
+
1424
+
1425
+
1426
+ /*
1427
+ * Write a message line to syslog
1428
+ */
1429
+
1430
+ #endif /* HAVE_SYSLOG */
1431
+
1432
+ #ifdef WIN32
1433
+ /*
1434
+ * Get the PostgreSQL equivalent of the Windows ANSI code page. "ANSI" system
1435
+ * interfaces (e.g. CreateFileA()) expect string arguments in this encoding.
1436
+ * Every process in a given system will find the same value at all times.
1437
+ */
1438
+ static int
1439
+ GetACPEncoding(void)
1440
+ {
1441
+ static int encoding = -2;
1442
+
1443
+ if (encoding == -2)
1444
+ encoding = pg_codepage_to_encoding(GetACP());
1445
+
1446
+ return encoding;
1447
+ }
1448
+
1449
+ /*
1450
+ * Write a message line to the windows event log
1451
+ */
1452
+ static void
1453
+ write_eventlog(int level, const char *line, int len)
1454
+ {
1455
+ WCHAR *utf16;
1456
+ int eventlevel = EVENTLOG_ERROR_TYPE;
1457
+ static HANDLE evtHandle = INVALID_HANDLE_VALUE;
1458
+
1459
+ if (evtHandle == INVALID_HANDLE_VALUE)
1460
+ {
1461
+ evtHandle = RegisterEventSource(NULL,
1462
+ event_source ? event_source : DEFAULT_EVENT_SOURCE);
1463
+ if (evtHandle == NULL)
1464
+ {
1465
+ evtHandle = INVALID_HANDLE_VALUE;
1466
+ return;
1467
+ }
1468
+ }
1469
+
1470
+ switch (level)
1471
+ {
1472
+ case DEBUG5:
1473
+ case DEBUG4:
1474
+ case DEBUG3:
1475
+ case DEBUG2:
1476
+ case DEBUG1:
1477
+ case LOG:
1478
+ case LOG_SERVER_ONLY:
1479
+ case INFO:
1480
+ case NOTICE:
1481
+ eventlevel = EVENTLOG_INFORMATION_TYPE;
1482
+ break;
1483
+ case WARNING:
1484
+ eventlevel = EVENTLOG_WARNING_TYPE;
1485
+ break;
1486
+ case ERROR:
1487
+ case FATAL:
1488
+ case PANIC:
1489
+ default:
1490
+ eventlevel = EVENTLOG_ERROR_TYPE;
1491
+ break;
1492
+ }
1493
+
1494
+ /*
1495
+ * If message character encoding matches the encoding expected by
1496
+ * ReportEventA(), call it to avoid the hazards of conversion. Otherwise,
1497
+ * try to convert the message to UTF16 and write it with ReportEventW().
1498
+ * Fall back on ReportEventA() if conversion failed.
1499
+ *
1500
+ * Since we palloc the structure required for conversion, also fall
1501
+ * through to writing unconverted if we have not yet set up
1502
+ * CurrentMemoryContext.
1503
+ *
1504
+ * Also verify that we are not on our way into error recursion trouble due
1505
+ * to error messages thrown deep inside pgwin32_message_to_UTF16().
1506
+ */
1507
+ if (!in_error_recursion_trouble() &&
1508
+ CurrentMemoryContext != NULL &&
1509
+ GetMessageEncoding() != GetACPEncoding())
1510
+ {
1511
+ utf16 = pgwin32_message_to_UTF16(line, len, NULL);
1512
+ if (utf16)
1513
+ {
1514
+ ReportEventW(evtHandle,
1515
+ eventlevel,
1516
+ 0,
1517
+ 0, /* All events are Id 0 */
1518
+ NULL,
1519
+ 1,
1520
+ 0,
1521
+ (LPCWSTR *) &utf16,
1522
+ NULL);
1523
+ /* XXX Try ReportEventA() when ReportEventW() fails? */
1524
+
1525
+ pfree(utf16);
1526
+ return;
1527
+ }
1528
+ }
1529
+ ReportEventA(evtHandle,
1530
+ eventlevel,
1531
+ 0,
1532
+ 0, /* All events are Id 0 */
1533
+ NULL,
1534
+ 1,
1535
+ 0,
1536
+ &line,
1537
+ NULL);
1538
+ }
1539
+ #endif /* WIN32 */
1540
+
1541
+ #ifdef WIN32
1542
+ #else
1543
+ #endif
1544
+
1545
+ /*
1546
+ * setup formatted_log_time, for consistent times between CSV and regular logs
1547
+ */
1548
+
1549
+
1550
+ /*
1551
+ * setup formatted_start_time
1552
+ */
1553
+
1554
+
1555
+ /*
1556
+ * process_log_prefix_padding --- helper function for processing the format
1557
+ * string in log_line_prefix
1558
+ *
1559
+ * Note: This function returns NULL if it finds something which
1560
+ * it deems invalid in the format string.
1561
+ */
1562
+
1563
+
1564
+ /*
1565
+ * Format tag info for log lines; append to the provided buffer.
1566
+ */
1567
+
1568
+
1569
+ /*
1570
+ * append a CSV'd version of a string to a StringInfo
1571
+ * We use the PostgreSQL defaults for CSV, i.e. quote = escape = '"'
1572
+ * If it's NULL, append nothing.
1573
+ */
1574
+
1575
+
1576
+ /*
1577
+ * Constructs the error message, depending on the Errordata it gets, in a CSV
1578
+ * format which is described in doc/src/sgml/config.sgml.
1579
+ */
1580
+
1581
+
1582
+ /*
1583
+ * Unpack MAKE_SQLSTATE code. Note that this returns a pointer to a
1584
+ * static buffer.
1585
+ */
1586
+
1587
+
1588
+
1589
+ /*
1590
+ * Write error report to server's log
1591
+ */
1592
+ static void send_message_to_server_log(ErrorData *edata) {}
1593
+
1594
+
1595
+ /*
1596
+ * Send data to the syslogger using the chunked protocol
1597
+ *
1598
+ * Note: when there are multiple backends writing into the syslogger pipe,
1599
+ * it's critical that each write go into the pipe indivisibly, and not
1600
+ * get interleaved with data from other processes. Fortunately, the POSIX
1601
+ * spec requires that writes to pipes be atomic so long as they are not
1602
+ * more than PIPE_BUF bytes long. So we divide long messages into chunks
1603
+ * that are no more than that length, and send one chunk per write() call.
1604
+ * The collector process knows how to reassemble the chunks.
1605
+ *
1606
+ * Because of the atomic write requirement, there are only two possible
1607
+ * results from write() here: -1 for failure, or the requested number of
1608
+ * bytes. There is not really anything we can do about a failure; retry would
1609
+ * probably be an infinite loop, and we can't even report the error usefully.
1610
+ * (There is noplace else we could send it!) So we might as well just ignore
1611
+ * the result from write(). However, on some platforms you get a compiler
1612
+ * warning from ignoring write()'s result, so do a little dance with casting
1613
+ * rc to void to shut up the compiler.
1614
+ */
1615
+
1616
+
1617
+
1618
+ /*
1619
+ * Append a text string to the error report being built for the client.
1620
+ *
1621
+ * This is ordinarily identical to pq_sendstring(), but if we are in
1622
+ * error recursion trouble we skip encoding conversion, because of the
1623
+ * possibility that the problem is a failure in the encoding conversion
1624
+ * subsystem itself. Code elsewhere should ensure that the passed-in
1625
+ * strings will be plain 7-bit ASCII, and thus not in need of conversion,
1626
+ * in such cases. (In particular, we disable localization of error messages
1627
+ * to help ensure that's true.)
1628
+ */
1629
+
1630
+
1631
+ /*
1632
+ * Write error report to client
1633
+ */
1634
+ static void send_message_to_frontend(ErrorData *edata) {}
1635
+
1636
+
1637
+
1638
+ /*
1639
+ * Support routines for formatting error messages.
1640
+ */
1641
+
1642
+
1643
+ /*
1644
+ * error_severity --- get string representing elevel
1645
+ *
1646
+ * The string is not localized here, but we mark the strings for translation
1647
+ * so that callers can invoke _() on the result.
1648
+ */
1649
+
1650
+
1651
+
1652
+ /*
1653
+ * append_with_tabs
1654
+ *
1655
+ * Append the string to the StringInfo buffer, inserting a tab after any
1656
+ * newline.
1657
+ */
1658
+
1659
+
1660
+
1661
+ /*
1662
+ * Write errors to stderr (or by equal means when stderr is
1663
+ * not available). Used before ereport/elog can be used
1664
+ * safely (memory context, GUC load etc)
1665
+ */
1666
+ void
1667
+ write_stderr(const char *fmt,...)
1668
+ {
1669
+ va_list ap;
1670
+
1671
+ #ifdef WIN32
1672
+ char errbuf[2048]; /* Arbitrary size? */
1673
+ #endif
1674
+
1675
+ fmt = _(fmt);
1676
+
1677
+ va_start(ap, fmt);
1678
+ #ifndef WIN32
1679
+ /* On Unix, we just fprintf to stderr */
1680
+ vfprintf(stderr, fmt, ap);
1681
+ fflush(stderr);
1682
+ #else
1683
+ vsnprintf(errbuf, sizeof(errbuf), fmt, ap);
1684
+
1685
+ /*
1686
+ * On Win32, we print to stderr if running on a console, or write to
1687
+ * eventlog if running as a service
1688
+ */
1689
+ if (pgwin32_is_service()) /* Running as a service */
1690
+ {
1691
+ write_eventlog(ERROR, errbuf, strlen(errbuf));
1692
+ }
1693
+ else
1694
+ {
1695
+ /* Not running as service, write to stderr */
1696
+ write_console(errbuf, strlen(errbuf));
1697
+ fflush(stderr);
1698
+ }
1699
+ #endif
1700
+ va_end(ap);
1701
+ }
1702
+
1703
+
1704
+ /*
1705
+ * is_log_level_output -- is elevel logically >= log_min_level?
1706
+ *
1707
+ * We use this for tests that should consider LOG to sort out-of-order,
1708
+ * between ERROR and FATAL. Generally this is the right thing for testing
1709
+ * whether a message should go to the postmaster log, whereas a simple >=
1710
+ * test is correct for testing whether the message should go to the client.
1711
+ */
1712
+ static bool
1713
+ is_log_level_output(int elevel, int log_min_level)
1714
+ {
1715
+ if (elevel == LOG || elevel == LOG_SERVER_ONLY)
1716
+ {
1717
+ if (log_min_level == LOG || log_min_level <= ERROR)
1718
+ return true;
1719
+ }
1720
+ else if (log_min_level == LOG)
1721
+ {
1722
+ /* elevel != LOG */
1723
+ if (elevel >= FATAL)
1724
+ return true;
1725
+ }
1726
+ /* Neither is LOG */
1727
+ else if (elevel >= log_min_level)
1728
+ return true;
1729
+
1730
+ return false;
1731
+ }
1732
+
1733
+ /*
1734
+ * Adjust the level of a recovery-related message per trace_recovery_messages.
1735
+ *
1736
+ * The argument is the default log level of the message, eg, DEBUG2. (This
1737
+ * should only be applied to DEBUGn log messages, otherwise it's a no-op.)
1738
+ * If the level is >= trace_recovery_messages, we return LOG, causing the
1739
+ * message to be logged unconditionally (for most settings of
1740
+ * log_min_messages). Otherwise, we return the argument unchanged.
1741
+ * The message will then be shown based on the setting of log_min_messages.
1742
+ *
1743
+ * Intention is to keep this for at least the whole of the 9.0 production
1744
+ * release, so we can more easily diagnose production problems in the field.
1745
+ * It should go away eventually, though, because it's an ugly and
1746
+ * hard-to-explain kluge.
1747
+ */
1748
+