Skip to main content

pgrx_pg_sys/submodules/
elog.rs

1//LICENSE Portions Copyright 2019-2021 ZomboDB, LLC.
2//LICENSE
3//LICENSE Portions Copyright 2021-2023 Technology Concepts & Design, Inc.
4//LICENSE
5//LICENSE Portions Copyright 2023-2023 PgCentral Foundation, Inc. <contact@pgcentral.org>
6//LICENSE
7//LICENSE All rights reserved.
8//LICENSE
9//LICENSE Use of this source code is governed by the MIT license that can be found in the LICENSE file.
10//! Access to Postgres' logging system
11
12/// Postgres' various logging levels
13#[allow(dead_code)]
14#[derive(Clone, Copy, Debug, Ord, PartialOrd, PartialEq, Eq)]
15pub enum PgLogLevel {
16    /// Debugging messages, in categories of decreasing detail
17    DEBUG5 = crate::DEBUG5 as isize,
18
19    /// Debugging messages, in categories of decreasing detail
20    DEBUG4 = crate::DEBUG4 as isize,
21
22    /// Debugging messages, in categories of decreasing detail
23    DEBUG3 = crate::DEBUG3 as isize,
24
25    /// Debugging messages, in categories of decreasing detail
26    DEBUG2 = crate::DEBUG2 as isize,
27
28    /// Debugging messages, in categories of decreasing detail
29    /// NOTE:  used by GUC debug_* variables
30    DEBUG1 = crate::DEBUG1 as isize,
31
32    /// Server operational messages; sent only to server log by default.
33    LOG = crate::LOG as isize,
34
35    /// Same as LOG for server reporting, but never sent to client.
36    #[allow(non_camel_case_types)]
37    LOG_SERVER_ONLY = crate::LOG_SERVER_ONLY as isize,
38
39    /// Messages specifically requested by user (eg VACUUM VERBOSE output); always sent to client
40    /// regardless of client_min_messages, but by default not sent to server log.
41    INFO = crate::INFO as isize,
42
43    /// Helpful messages to users about query operation; sent to client and not to server log by default.
44    NOTICE = crate::NOTICE as isize,
45
46    /// Warnings.  \[NOTICE\] is for expected messages like implicit sequence creation by SERIAL.
47    /// \[WARNING\] is for unexpected messages.
48    WARNING = crate::WARNING as isize,
49
50    /// user error - abort transaction; return to known state
51    ERROR = crate::PGERROR as isize,
52
53    /// fatal error - abort process
54    FATAL = crate::FATAL as isize,
55
56    /// take down the other backends with me
57    PANIC = crate::PANIC as isize,
58}
59
60impl From<isize> for PgLogLevel {
61    #[inline]
62    fn from(i: isize) -> Self {
63        if i == PgLogLevel::DEBUG5 as isize {
64            PgLogLevel::DEBUG5
65        } else if i == PgLogLevel::DEBUG4 as isize {
66            PgLogLevel::DEBUG4
67        } else if i == PgLogLevel::DEBUG3 as isize {
68            PgLogLevel::DEBUG3
69        } else if i == PgLogLevel::DEBUG2 as isize {
70            PgLogLevel::DEBUG2
71        } else if i == PgLogLevel::DEBUG1 as isize {
72            PgLogLevel::DEBUG1
73        } else if i == PgLogLevel::INFO as isize {
74            PgLogLevel::INFO
75        } else if i == PgLogLevel::NOTICE as isize {
76            PgLogLevel::NOTICE
77        } else if i == PgLogLevel::WARNING as isize {
78            PgLogLevel::WARNING
79        } else if i == PgLogLevel::ERROR as isize {
80            PgLogLevel::ERROR
81        } else if i == PgLogLevel::FATAL as isize {
82            PgLogLevel::FATAL
83        } else if i == PgLogLevel::PANIC as isize {
84            PgLogLevel::PANIC
85        } else {
86            // ERROR seems like a good default
87            PgLogLevel::ERROR
88        }
89    }
90}
91
92impl From<i32> for PgLogLevel {
93    #[inline]
94    fn from(i: i32) -> Self {
95        (i as isize).into()
96    }
97}
98
99impl PgLogLevel {
100    /// Denotes whether this log level will be logged to the server/client log, or would it result
101    /// in a no-op.
102    #[doc(hidden)]
103    #[inline]
104    pub fn is_interesting(&self) -> bool {
105        #[cfg(not(feature = "pg13"))]
106        {
107            unsafe { crate::message_level_is_interesting(*self as _) }
108        }
109        #[cfg(feature = "pg13")]
110        {
111            let level = *self as i32;
112            unsafe {
113                level >= crate::PGERROR as i32
114                    || level >= crate::log_min_messages
115                    || level >= crate::client_min_messages
116            }
117        }
118    }
119}
120
121// Trait used by the elog/ereport macros to convert message arguments into
122// `Cow<'static, str>` for `ErrorReport`. This allows:
123//   - `fmt::Arguments` for plain literals → `Cow::Borrowed` via `as_str()` (zero allocation)
124//   - `fmt::Arguments` with placeholders → `Cow::Owned` via `.to_string()` (one allocation)
125//   - `String` → `Cow::Owned` (zero extra allocation, moved)
126#[doc(hidden)]
127pub trait IntoMessage {
128    fn into_message(self) -> std::borrow::Cow<'static, str>;
129}
130
131impl IntoMessage for &'static str {
132    #[inline]
133    fn into_message(self) -> std::borrow::Cow<'static, str> {
134        std::borrow::Cow::Borrowed(self)
135    }
136}
137
138impl IntoMessage for String {
139    #[inline]
140    fn into_message(self) -> std::borrow::Cow<'static, str> {
141        std::borrow::Cow::Owned(self)
142    }
143}
144
145impl IntoMessage for std::fmt::Arguments<'_> {
146    #[inline]
147    fn into_message(self) -> std::borrow::Cow<'static, str> {
148        // `as_str()` returns `Some(&'static str)` for plain literals (e.g. `format_args!("hello")`)
149        // avoiding heap allocation entirely via `Cow::Borrowed`.
150        // For format strings with placeholders it returns `None`, falling back to `.to_string()`.
151        match self.as_str() {
152            Some(s) => std::borrow::Cow::Borrowed(s),
153            None => std::borrow::Cow::Owned(self.to_string()),
154        }
155    }
156}
157
158/// Log to Postgres' `debug5` log level.
159///
160/// This macro accepts arguments like the [`println`] and [`format`] macros.
161/// See [`fmt`](std::fmt) for information about options.
162///
163/// The output these logs goes to the PostgreSQL log file at `DEBUG5` level, depending on how the
164/// [PostgreSQL settings](https://www.postgresql.org/docs/current/runtime-config-logging.html) are configured.
165#[macro_export]
166macro_rules! debug5 {
167    ($($arg:tt)*) => { $crate::ereport!($crate::elog::PgLogLevel::DEBUG5, $crate::errcodes::PgSqlErrorCode::ERRCODE_SUCCESSFUL_COMPLETION, format_args!($($arg)*)) };
168}
169
170/// Log to Postgres' `debug4` log level.
171///
172/// This macro accepts arguments like the [`println`] and [`format`] macros.
173/// See [`fmt`](std::fmt) for information about options.
174///
175/// The output these logs goes to the PostgreSQL log file at `DEBUG4` level, depending on how the
176/// [PostgreSQL settings](https://www.postgresql.org/docs/current/runtime-config-logging.html) are configured.
177#[macro_export]
178macro_rules! debug4 {
179    ($($arg:tt)*) => { $crate::ereport!($crate::elog::PgLogLevel::DEBUG4, $crate::errcodes::PgSqlErrorCode::ERRCODE_SUCCESSFUL_COMPLETION, format_args!($($arg)*)) };
180}
181
182/// Log to Postgres' `debug3` log level.
183///
184/// This macro accepts arguments like the [`println`] and [`format`] macros.
185/// See [`fmt`](std::fmt) for information about options.
186///
187/// The output these logs goes to the PostgreSQL log file at `DEBUG3` level, depending on how the
188/// [PostgreSQL settings](https://www.postgresql.org/docs/current/runtime-config-logging.html) are configured.
189#[macro_export]
190macro_rules! debug3 {
191    ($($arg:tt)*) => { $crate::ereport!($crate::elog::PgLogLevel::DEBUG3, $crate::errcodes::PgSqlErrorCode::ERRCODE_SUCCESSFUL_COMPLETION, format_args!($($arg)*)) };
192}
193
194/// Log to Postgres' `debug2` log level.
195///
196/// This macro accepts arguments like the [`println`] and [`format`] macros.
197/// See [`fmt`](std::fmt) for information about options.
198///
199/// The output these logs goes to the PostgreSQL log file at `DEBUG2` level, depending on how the
200/// [PostgreSQL settings](https://www.postgresql.org/docs/current/runtime-config-logging.html) are configured.
201#[macro_export]
202macro_rules! debug2 {
203    ($($arg:tt)*) => { $crate::ereport!($crate::elog::PgLogLevel::DEBUG2, $crate::errcodes::PgSqlErrorCode::ERRCODE_SUCCESSFUL_COMPLETION, format_args!($($arg)*)) };
204}
205
206/// Log to Postgres' `debug1` log level.
207///
208/// This macro accepts arguments like the [`println`] and [`format`] macros.
209/// See [`fmt`](std::fmt) for information about options.
210///
211/// The output these logs goes to the PostgreSQL log file at `DEBUG1` level, depending on how the
212/// [PostgreSQL settings](https://www.postgresql.org/docs/current/runtime-config-logging.html) are configured.
213#[macro_export]
214macro_rules! debug1 {
215    ($($arg:tt)*) => { $crate::ereport!($crate::elog::PgLogLevel::DEBUG1, $crate::errcodes::PgSqlErrorCode::ERRCODE_SUCCESSFUL_COMPLETION, format_args!($($arg)*)) };
216}
217
218/// Log to Postgres' `log` log level.
219///
220/// This macro accepts arguments like the [`println`] and [`format`] macros.
221/// See [`fmt`](std::fmt) for information about options.
222///
223/// The output these logs goes to the PostgreSQL log file at `LOG` level, depending on how the
224/// [PostgreSQL settings](https://www.postgresql.org/docs/current/runtime-config-logging.html) are configured.
225#[macro_export]
226macro_rules! log {
227    ($($arg:tt)*) => { $crate::ereport!($crate::elog::PgLogLevel::LOG, $crate::errcodes::PgSqlErrorCode::ERRCODE_SUCCESSFUL_COMPLETION, format_args!($($arg)*)) };
228}
229
230/// Log to Postgres' `info` log level.
231///
232/// This macro accepts arguments like the [`println`] and [`format`] macros.
233/// See [`fmt`](std::fmt) for information about options.
234#[macro_export]
235macro_rules! info {
236    ($($arg:tt)*) => { $crate::ereport!($crate::elog::PgLogLevel::INFO, $crate::errcodes::PgSqlErrorCode::ERRCODE_SUCCESSFUL_COMPLETION, format_args!($($arg)*)) };
237}
238
239/// Log to Postgres' `notice` log level.
240///
241/// This macro accepts arguments like the [`println`] and [`format`] macros.
242/// See [`fmt`](std::fmt) for information about options.
243#[macro_export]
244macro_rules! notice {
245    ($($arg:tt)*) => { $crate::ereport!($crate::elog::PgLogLevel::NOTICE, $crate::errcodes::PgSqlErrorCode::ERRCODE_SUCCESSFUL_COMPLETION, format_args!($($arg)*)) };
246}
247
248/// Log to Postgres' `warning` log level.
249///
250/// This macro accepts arguments like the [`println`] and [`format`] macros.
251/// See [`fmt`](std::fmt) for information about options.
252#[macro_export]
253macro_rules! warning {
254    ($($arg:tt)*) => { $crate::ereport!($crate::elog::PgLogLevel::WARNING, $crate::errcodes::PgSqlErrorCode::ERRCODE_WARNING, format_args!($($arg)*)) };
255}
256
257/// Log to Postgres' `error` log level.  This will abort the current Postgres transaction.
258///
259/// This macro accepts arguments like the [`println`] and [`format`] macros.
260/// See [`fmt`](std::fmt) for information about options.
261#[macro_export]
262macro_rules! error {
263    ($($arg:tt)*) => {{ $crate::ereport!($crate::elog::PgLogLevel::ERROR, $crate::errcodes::PgSqlErrorCode::ERRCODE_INTERNAL_ERROR, format_args!($($arg)*)); unreachable!() }};
264}
265
266/// Log to Postgres' `fatal` log level.  This will abort the current Postgres backend connection process.
267///
268/// This macro accepts arguments like the [`println`] and [`format`] macros.
269/// See [`fmt`](std::fmt) for information about options.
270#[allow(non_snake_case)]
271#[macro_export]
272macro_rules! FATAL {
273    ($($arg:tt)*) => {{ $crate::ereport!($crate::elog::PgLogLevel::FATAL, $crate::errcodes::PgSqlErrorCode::ERRCODE_INTERNAL_ERROR, format_args!($($arg)*)); unreachable!() }};
274}
275
276/// Log to Postgres' `panic` log level.  This will cause the entire Postgres cluster to crash.
277///
278/// This macro accepts arguments like the [`println`] and [`format`] macros.
279/// See [`fmt`](std::fmt) for information about options.
280#[allow(non_snake_case)]
281#[macro_export]
282macro_rules! PANIC {
283    ($($arg:tt)*) => {{ $crate::ereport!($crate::elog::PgLogLevel::PANIC, $crate::errcodes::PgSqlErrorCode::ERRCODE_INTERNAL_ERROR, format_args!($($arg)*)); unreachable!() }};
284}
285
286// shamelessly borrowed from https://docs.rs/stdext/0.2.1/src/stdext/macros.rs.html#61-72
287/// This macro returns the name of the enclosing function.
288/// As the internal implementation is based on the [`std::any::type_name`], this macro derives
289/// all the limitations of this function.
290///
291/// [`std::any::type_name`]: https://doc.rust-lang.org/std/any/fn.type_name.html
292#[macro_export]
293macro_rules! function_name {
294    () => {{
295        // Okay, this is ugly, I get it. However, this is the best we can get on a stable rust.
296        fn f() {}
297        fn type_name_of<T>(_: T) -> &'static str {
298            core::any::type_name::<T>()
299        }
300        let name = type_name_of(f);
301        // `3` is the length of the `::f`.
302        &name[..name.len() - 3]
303    }};
304}
305
306/// Sends some kind of message to Postgres, and if it's a [PgLogLevel::ERROR] or greater, Postgres'
307/// error handling takes over and, in the case of [PgLogLevel::ERROR], aborts the current transaction.
308///
309/// This macro is necessary when one needs to supply a specific SQL error code as part of their
310/// error message.
311///
312/// The argument order is:
313/// - `log_level: [PgLogLevel]`
314/// - `error_code: [PgSqlErrorCode]`
315/// - `message: String`
316/// - (optional) `detail: String`
317///
318/// ## Examples
319///
320/// ```rust,no_run
321/// # use pgrx_pg_sys::ereport;
322/// # use pgrx_pg_sys::elog::PgLogLevel;
323/// # use pgrx_pg_sys::errcodes::PgSqlErrorCode;
324/// ereport!(PgLogLevel::ERROR, PgSqlErrorCode::ERRCODE_INTERNAL_ERROR, "oh noes!"); // abort the transaction
325/// ```
326///
327/// ```rust,no_run
328/// # use pgrx_pg_sys::ereport;
329/// # use pgrx_pg_sys::elog::PgLogLevel;
330/// # use pgrx_pg_sys::errcodes::PgSqlErrorCode;
331/// ereport!(PgLogLevel::LOG, PgSqlErrorCode::ERRCODE_SUCCESSFUL_COMPLETION, "this is just a message"); // log output only
332/// ```
333#[macro_export]
334macro_rules! ereport {
335    (ERROR, $errcode:expr, $message:expr $(, $detail:expr)? $(,)?) => {
336        $crate::panic::ErrorReport::new($errcode, $crate::elog::IntoMessage::into_message($message), $crate::function_name!())
337            $(.set_detail($detail))?
338            .report($crate::elog::PgLogLevel::ERROR);
339        unreachable!();
340    };
341
342    (PANIC, $errcode:expr, $message:expr $(, $detail:expr)? $(,)?) => {
343        $crate::panic::ErrorReport::new($errcode, $crate::elog::IntoMessage::into_message($message), $crate::function_name!())
344            $(.set_detail($detail))?
345            .report($crate::elog::PgLogLevel::PANIC);
346        unreachable!();
347    };
348
349    (FATAL, $errcode:expr, $message:expr $(, $detail:expr)? $(,)?) => {
350        $crate::panic::ErrorReport::new($errcode, $crate::elog::IntoMessage::into_message($message), $crate::function_name!())
351            $(.set_detail($detail))?
352            .report($crate::elog::PgLogLevel::FATAL);
353        unreachable!();
354    };
355
356    (WARNING, $errcode:expr, $message:expr $(, $detail:expr)? $(,)?) => {
357        if $crate::elog::PgLogLevel::WARNING.is_interesting() {
358            $crate::panic::ErrorReport::new($errcode, $crate::elog::IntoMessage::into_message($message), $crate::function_name!())
359                $(.set_detail($detail))?
360                .report($crate::elog::PgLogLevel::WARNING)
361        }
362    };
363
364    (NOTICE, $errcode:expr, $message:expr $(, $detail:expr)? $(,)?) => {
365        if $crate::elog::PgLogLevel::NOTICE.is_interesting() {
366            $crate::panic::ErrorReport::new($errcode, $crate::elog::IntoMessage::into_message($message), $crate::function_name!())
367                $(.set_detail($detail))?
368                .report($crate::elog::PgLogLevel::NOTICE)
369        }
370    };
371
372    (INFO, $errcode:expr, $message:expr $(, $detail:expr)? $(,)?) => {
373        if $crate::elog::PgLogLevel::INFO.is_interesting() {
374            $crate::panic::ErrorReport::new($errcode, $crate::elog::IntoMessage::into_message($message), $crate::function_name!())
375                $(.set_detail($detail))?
376                .report($crate::elog::PgLogLevel::INFO)
377        }
378    };
379
380    (LOG, $errcode:expr, $message:expr $(, $detail:expr)? $(,)?) => {
381        if $crate::elog::PgLogLevel::LOG.is_interesting() {
382            $crate::panic::ErrorReport::new($errcode, $crate::elog::IntoMessage::into_message($message), $crate::function_name!())
383                $(.set_detail($detail))?
384                .report($crate::elog::PgLogLevel::LOG)
385        }
386    };
387
388    (DEBUG5, $errcode:expr, $message:expr $(, $detail:expr)? $(,)?) => {
389        if $crate::elog::PgLogLevel::DEBUG5.is_interesting() {
390            $crate::panic::ErrorReport::new($errcode, $crate::elog::IntoMessage::into_message($message), $crate::function_name!())
391                $(.set_detail($detail))?
392                .report($crate::elog::PgLogLevel::DEBUG5)
393        }
394    };
395
396    (DEBUG4, $errcode:expr, $message:expr $(, $detail:expr)? $(,)?) => {
397        if $crate::elog::PgLogLevel::DEBUG4.is_interesting() {
398            $crate::panic::ErrorReport::new($errcode, $crate::elog::IntoMessage::into_message($message), $crate::function_name!())
399                $(.set_detail($detail))?
400                .report($crate::elog::PgLogLevel::DEBUG4)
401        }
402    };
403
404    (DEBUG3, $errcode:expr, $message:expr $(, $detail:expr)? $(,)?) => {
405        if $crate::elog::PgLogLevel::DEBUG3.is_interesting() {
406            $crate::panic::ErrorReport::new($errcode, $crate::elog::IntoMessage::into_message($message), $crate::function_name!())
407                $(.set_detail($detail))?
408                .report($crate::elog::PgLogLevel::DEBUG3)
409        }
410    };
411
412    (DEBUG2, $errcode:expr, $message:expr $(, $detail:expr)? $(,)?) => {
413        if $crate::elog::PgLogLevel::DEBUG2.is_interesting() {
414            $crate::panic::ErrorReport::new($errcode, $crate::elog::IntoMessage::into_message($message), $crate::function_name!())
415                $(.set_detail($detail))?
416                .report($crate::elog::PgLogLevel::DEBUG2)
417        }
418    };
419
420    (DEBUG1, $errcode:expr, $message:expr $(, $detail:expr)? $(,)?) => {
421        if $crate::elog::PgLogLevel::DEBUG1.is_interesting() {
422            $crate::panic::ErrorReport::new($errcode, $crate::elog::IntoMessage::into_message($message), $crate::function_name!())
423                $(.set_detail($detail))?
424                .report($crate::elog::PgLogLevel::DEBUG1)
425        }
426    };
427
428    ($loglevel:expr, $errcode:expr, $message:expr $(, $detail:expr)? $(,)?) => {
429        if $loglevel.is_interesting() {
430            $crate::panic::ErrorReport::new($errcode, $crate::elog::IntoMessage::into_message($message), $crate::function_name!())
431                $(.set_detail($detail))?
432                .report($loglevel);
433        }
434    };
435}
436
437/// Is an interrupt pending?
438#[inline]
439pub fn interrupt_pending() -> bool {
440    unsafe { crate::InterruptPending != 0 }
441}
442
443/// Send some kind of message to Postgres similar to the ereport macro, while specifying
444/// a text domain, analogous to Postgres' `ereport_domain` C macro.
445///
446/// The argument order is:
447/// - `log_level: [PgLogLevel]`
448/// - `error_code: [PgSqlErrorCode]`
449/// - `message: String`
450/// - (optional) `detail: String`
451///
452/// ## Examples
453///
454/// ```rust,no_run
455/// # use pgrx_pg_sys::ereport_domain;
456/// # use pgrx_pg_sys::elog::PgLogLevel;
457/// # use pgrx_pg_sys::errcodes::PgSqlErrorCode;
458/// ereport_domain!(PgLogLevel::ERROR, "my_extension", PgSqlErrorCode::ERRCODE_INTERNAL_ERROR, "oh noes!");
459/// ```
460///
461/// ```rust,no_run
462/// # use pgrx_pg_sys::ereport_domain;
463/// # use pgrx_pg_sys::elog::PgLogLevel;
464/// # use pgrx_pg_sys::errcodes::PgSqlErrorCode;
465/// ereport_domain!(PgLogLevel::LOG, "my_extension", PgSqlErrorCode::ERRCODE_SUCCESSFUL_COMPLETION, "translated message");
466/// ```
467#[macro_export]
468macro_rules! ereport_domain {
469    (ERROR, $domain:expr, $errcode:expr, $message:expr $(, $detail:expr)? $(,)?) => {
470        $crate::panic::ErrorReport::new($errcode, $crate::elog::IntoMessage::into_message($message), $crate::function_name!())
471            .set_domain($domain)
472            $(.set_detail($detail))?
473            .report($crate::elog::PgLogLevel::ERROR);
474        unreachable!();
475    };
476
477    (PANIC, $domain:expr, $errcode:expr, $message:expr $(, $detail:expr)? $(,)?) => {
478        $crate::panic::ErrorReport::new($errcode, $crate::elog::IntoMessage::into_message($message), $crate::function_name!())
479            .set_domain($domain)
480            $(.set_detail($detail))?
481            .report($crate::elog::PgLogLevel::PANIC);
482        unreachable!();
483    };
484
485    (FATAL, $domain:expr, $errcode:expr, $message:expr $(, $detail:expr)? $(,)?) => {
486        $crate::panic::ErrorReport::new($errcode, $crate::elog::IntoMessage::into_message($message), $crate::function_name!())
487            .set_domain($domain)
488            $(.set_detail($detail))?
489            .report($crate::elog::PgLogLevel::FATAL);
490        unreachable!();
491    };
492
493    (WARNING, $domain:expr, $errcode:expr, $message:expr $(, $detail:expr)? $(,)?) => {
494        if $crate::elog::PgLogLevel::WARNING.is_interesting() {
495            $crate::panic::ErrorReport::new($errcode, $crate::elog::IntoMessage::into_message($message), $crate::function_name!())
496                .set_domain($domain)
497                $(.set_detail($detail))?
498                .report($crate::elog::PgLogLevel::WARNING)
499        }
500    };
501
502    (NOTICE, $domain:expr, $errcode:expr, $message:expr $(, $detail:expr)? $(,)?) => {
503        if $crate::elog::PgLogLevel::NOTICE.is_interesting() {
504            $crate::panic::ErrorReport::new($errcode, $crate::elog::IntoMessage::into_message($message), $crate::function_name!())
505                .set_domain($domain)
506                $(.set_detail($detail))?
507                .report($crate::elog::PgLogLevel::NOTICE)
508        }
509    };
510
511    (INFO, $domain:expr, $errcode:expr, $message:expr $(, $detail:expr)? $(,)?) => {
512        if $crate::elog::PgLogLevel::INFO.is_interesting() {
513            $crate::panic::ErrorReport::new($errcode, $crate::elog::IntoMessage::into_message($message), $crate::function_name!())
514                .set_domain($domain)
515                $(.set_detail($detail))?
516                .report($crate::elog::PgLogLevel::INFO)
517        }
518    };
519
520    (LOG, $domain:expr, $errcode:expr, $message:expr $(, $detail:expr)? $(,)?) => {
521        if $crate::elog::PgLogLevel::LOG.is_interesting() {
522            $crate::panic::ErrorReport::new($errcode, $crate::elog::IntoMessage::into_message($message), $crate::function_name!())
523                .set_domain($domain)
524                $(.set_detail($detail))?
525                .report($crate::elog::PgLogLevel::LOG)
526        }
527    };
528
529    (DEBUG5, $domain:expr, $errcode:expr, $message:expr $(, $detail:expr)? $(,)?) => {
530        if $crate::elog::PgLogLevel::DEBUG5.is_interesting() {
531            $crate::panic::ErrorReport::new($errcode, $crate::elog::IntoMessage::into_message($message), $crate::function_name!())
532                .set_domain($domain)
533                $(.set_detail($detail))?
534                .report($crate::elog::PgLogLevel::DEBUG5)
535        }
536    };
537
538    (DEBUG4, $domain:expr, $errcode:expr, $message:expr $(, $detail:expr)? $(,)?) => {
539        if $crate::elog::PgLogLevel::DEBUG4.is_interesting() {
540            $crate::panic::ErrorReport::new($errcode, $crate::elog::IntoMessage::into_message($message), $crate::function_name!())
541                .set_domain($domain)
542                $(.set_detail($detail))?
543                .report($crate::elog::PgLogLevel::DEBUG4)
544        }
545    };
546
547    (DEBUG3, $domain:expr, $errcode:expr, $message:expr $(, $detail:expr)? $(,)?) => {
548        if $crate::elog::PgLogLevel::DEBUG3.is_interesting() {
549            $crate::panic::ErrorReport::new($errcode, $crate::elog::IntoMessage::into_message($message), $crate::function_name!())
550                .set_domain($domain)
551                $(.set_detail($detail))?
552                .report($crate::elog::PgLogLevel::DEBUG3)
553        }
554    };
555
556    (DEBUG2, $domain:expr, $errcode:expr, $message:expr $(, $detail:expr)? $(,)?) => {
557        if $crate::elog::PgLogLevel::DEBUG2.is_interesting() {
558            $crate::panic::ErrorReport::new($errcode, $crate::elog::IntoMessage::into_message($message), $crate::function_name!())
559                .set_domain($domain)
560                $(.set_detail($detail))?
561                .report($crate::elog::PgLogLevel::DEBUG2)
562        }
563    };
564
565    (DEBUG1, $domain:expr, $errcode:expr, $message:expr $(, $detail:expr)? $(,)?) => {
566        if $crate::elog::PgLogLevel::DEBUG1.is_interesting() {
567            $crate::panic::ErrorReport::new($errcode, $crate::elog::IntoMessage::into_message($message), $crate::function_name!())
568                .set_domain($domain)
569                $(.set_detail($detail))?
570                .report($crate::elog::PgLogLevel::DEBUG1)
571        }
572    };
573
574    ($loglevel:expr, $domain:expr, $errcode:expr, $message:expr $(, $detail:expr)? $(,)?) => {
575        if $loglevel.is_interesting() {
576            $crate::panic::ErrorReport::new($errcode, $crate::elog::IntoMessage::into_message($message), $crate::function_name!())
577                .set_domain($domain)
578                $(.set_detail($detail))?
579                .report($loglevel);
580        }
581    };
582}
583
584/// If an interrupt is pending (perhaps a user-initiated "cancel query" message to this backend),
585/// this will safely abort the current transaction
586#[macro_export]
587macro_rules! check_for_interrupts {
588    () => {
589        #[allow(unused_unsafe)]
590        unsafe {
591            if $crate::InterruptPending != 0 {
592                $crate::ProcessInterrupts();
593            }
594        }
595    };
596}