summaryrefslogtreecommitdiff
path: root/src/backend/utils/adt/domains.c
diff options
context:
space:
mode:
authorAmit Langote2024-01-24 04:35:28 +0000
committerAmit Langote2024-01-24 06:04:33 +0000
commit1edb3b491bee373bdfcbfc1c2707b5428c2023b9 (patch)
tree4654edfbf17a4b68b5763c45829d0b0b372f2aaa /src/backend/utils/adt/domains.c
parentaaaf9449ec6be62cb0d30ed3588dc384f56274bf (diff)
Adjust populate_record_field() to handle errors softly
This adds a Node *escontext parameter to it and a bunch of functions downstream to it, replacing any ereport()s in that path by either errsave() or ereturn() as appropriate. This also adds code to those functions where necessary to return early upon encountering a soft error. The changes here are mainly intended to suppress errors in the functions of jsonfuncs.c. Functions in any external modules, such as arrayfuncs.c, that those functions may in turn call are not changed here based on the assumption that the various checks in jsonfuncs.c functions should ensure that only values that are structurally valid get passed to the functions in those external modules. An exception is made for domain_check() to allow handling domain constraint violation errors softly. For testing, this adds a function jsonb_populate_record_valid(), which returns true if jsonb_populate_record() would finish without causing an error for the provided JSON object, false otherwise. Note that jsonb_populate_record() internally calls populate_record(), which in turn uses populate_record_field(). Extracted from a much larger patch to add SQL/JSON query functions. Author: Nikita Glukhov <[email protected]> Author: Teodor Sigaev <[email protected]> Author: Oleg Bartunov <[email protected]> Author: Alexander Korotkov <[email protected]> Author: Andrew Dunstan <[email protected]> Author: Amit Langote <[email protected]> Reviewers have included (in no particular order) Andres Freund, Alexander Korotkov, Pavel Stehule, Andrew Alsup, Erik Rijkers, Zihong Yu, Himanshu Upadhyaya, Daniel Gustafsson, Justin Pryzby, Álvaro Herrera, Jian He, Peter Eisentraut Discussion: https://postgr.es/m/[email protected] Discussion: https://postgr.es/m/[email protected] Discussion: https://postgr.es/m/abd9b83b-aa66-f230-3d6d-734817f0995d%40postgresql.org Discussion: https://postgr.es/m/CA+HiwqHROpf9e644D8BRqYvaAPmgBZVup-xKMDPk-nd4EpgzHw@mail.gmail.com Discussion: https://postgr.es/m/CA+HiwqE4XTdfb1nW=Ojoy_tQSRhYt-q_kb6i5d4xcKyrLC1Nbg@mail.gmail.com
Diffstat (limited to 'src/backend/utils/adt/domains.c')
-rw-r--r--src/backend/utils/adt/domains.c33
1 files changed, 32 insertions, 1 deletions
diff --git a/src/backend/utils/adt/domains.c b/src/backend/utils/adt/domains.c
index 9f6e1a15adb..21791105da8 100644
--- a/src/backend/utils/adt/domains.c
+++ b/src/backend/utils/adt/domains.c
@@ -40,6 +40,9 @@
#include "utils/syscache.h"
#include "utils/typcache.h"
+static bool domain_check_internal(Datum value, bool isnull, Oid domainType,
+ void **extra, MemoryContext mcxt,
+ Node *escontext);
/*
* structure to cache state across multiple calls
@@ -343,6 +346,32 @@ void
domain_check(Datum value, bool isnull, Oid domainType,
void **extra, MemoryContext mcxt)
{
+ (void) domain_check_internal(value, isnull, domainType, extra, mcxt,
+ NULL);
+}
+
+/* Error-safe variant of domain_check(). */
+bool
+domain_check_safe(Datum value, bool isnull, Oid domainType,
+ void **extra, MemoryContext mcxt,
+ Node *escontext)
+{
+ return domain_check_internal(value, isnull, domainType, extra, mcxt,
+ escontext);
+}
+
+/*
+ * domain_check_internal
+ * Workhorse for domain_check() and domain_check_safe()
+ *
+ * Returns false if an error occurred in domain_check_input() and 'escontext'
+ * points to an ErrorSaveContext, true otherwise.
+ */
+static bool
+domain_check_internal(Datum value, bool isnull, Oid domainType,
+ void **extra, MemoryContext mcxt,
+ Node *escontext)
+{
DomainIOData *my_extra = NULL;
if (mcxt == NULL)
@@ -365,7 +394,9 @@ domain_check(Datum value, bool isnull, Oid domainType,
/*
* Do the necessary checks to ensure it's a valid domain value.
*/
- domain_check_input(value, isnull, my_extra, NULL);
+ domain_check_input(value, isnull, my_extra, escontext);
+
+ return !SOFT_ERROR_OCCURRED(escontext);
}
/*