aboutsummaryrefslogtreecommitdiff
path: root/src/include/nodes/miscnodes.h
diff options
context:
space:
mode:
authorTom Lane <tgl@sss.pgh.pa.us>2022-12-09 09:58:38 -0500
committerTom Lane <tgl@sss.pgh.pa.us>2022-12-09 09:58:38 -0500
commitd9f7f5d32f201bec61fef8104aafcb77cecb4dcb (patch)
tree07683a0da7bb8a78be11afa43fe23e5b23490896 /src/include/nodes/miscnodes.h
parentbeecbe8e5001249f0ad51f828d66238dd5160072 (diff)
downloadpostgresql-d9f7f5d32f201bec61fef8104aafcb77cecb4dcb.tar.gz
postgresql-d9f7f5d32f201bec61fef8104aafcb77cecb4dcb.zip
Create infrastructure for "soft" error reporting.
Postgres' standard mechanism for reporting errors (ereport() or elog()) is used for all sorts of error conditions. This means that throwing an exception via ereport(ERROR) requires an expensive transaction or subtransaction abort and cleanup, since the exception catcher dare not make many assumptions about what has gone wrong. There are situations where we would rather have a lighter-weight mechanism for dealing with errors that are known to be safe to recover from without a full transaction cleanup. This commit creates infrastructure to let us adapt existing error-reporting code for that purpose. See the included documentation changes for details. Follow-on commits will provide test code and usage examples. The near-term plan is to convert most if not all datatype input functions to report invalid input "softly". This will enable implementing some SQL/JSON features cleanly and without the cost of subtransactions, and it will also allow creating COPY options to deal with bad input without cancelling the whole COPY. This patch is mostly by me, but it owes very substantial debt to earlier work by Nikita Glukhov, Andrew Dunstan, and Amul Sul. Thanks also to Andres Freund for review. Discussion: https://postgr.es/m/3bbbb0df-7382-bf87-9737-340ba096e034@postgrespro.ru
Diffstat (limited to 'src/include/nodes/miscnodes.h')
-rw-r--r--src/include/nodes/miscnodes.h56
1 files changed, 56 insertions, 0 deletions
diff --git a/src/include/nodes/miscnodes.h b/src/include/nodes/miscnodes.h
new file mode 100644
index 00000000000..b50ee60352d
--- /dev/null
+++ b/src/include/nodes/miscnodes.h
@@ -0,0 +1,56 @@
+/*-------------------------------------------------------------------------
+ *
+ * miscnodes.h
+ * Definitions for hard-to-classify node types.
+ *
+ * Node types declared here are not part of parse trees, plan trees,
+ * or execution state trees. We only assign them NodeTag values because
+ * IsA() tests provide a convenient way to disambiguate what kind of
+ * structure is being passed through assorted APIs, such as function
+ * "context" pointers.
+ *
+ *
+ * Portions Copyright (c) 1996-2022, PostgreSQL Global Development Group
+ * Portions Copyright (c) 1994, Regents of the University of California
+ *
+ * src/include/nodes/miscnodes.h
+ *
+ *-------------------------------------------------------------------------
+ */
+#ifndef MISCNODES_H
+#define MISCNODES_H
+
+#include "nodes/nodes.h"
+
+/*
+ * ErrorSaveContext -
+ * function call context node for handling of "soft" errors
+ *
+ * A caller wishing to trap soft errors must initialize a struct like this
+ * with all fields zero/NULL except for the NodeTag. Optionally, set
+ * details_wanted = true if more than the bare knowledge that a soft error
+ * occurred is required. The struct is then passed to a SQL-callable function
+ * via the FunctionCallInfo.context field; or below the level of SQL calls,
+ * it could be passed to a subroutine directly.
+ *
+ * After calling code that might report an error this way, check
+ * error_occurred to see if an error happened. If so, and if details_wanted
+ * is true, error_data has been filled with error details (stored in the
+ * callee's memory context!). FreeErrorData() can be called to release
+ * error_data, although that step is typically not necessary if the called
+ * code was run in a short-lived context.
+ */
+typedef struct ErrorSaveContext
+{
+ NodeTag type;
+ bool error_occurred; /* set to true if we detect a soft error */
+ bool details_wanted; /* does caller want more info than that? */
+ ErrorData *error_data; /* details of error, if so */
+} ErrorSaveContext;
+
+/* Often-useful macro for checking if a soft error was reported */
+#define SOFT_ERROR_OCCURRED(escontext) \
+ ((escontext) != NULL && IsA(escontext, ErrorSaveContext) && \
+ ((ErrorSaveContext *) (escontext))->error_occurred)
+
+#endif /* MISCNODES_H */