aboutsummaryrefslogtreecommitdiff
path: root/src/backend/utils/adt/domains.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/backend/utils/adt/domains.c')
-rw-r--r--src/backend/utils/adt/domains.c36
1 files changed, 26 insertions, 10 deletions
diff --git a/src/backend/utils/adt/domains.c b/src/backend/utils/adt/domains.c
index 3de0cb01a2c..99aeaddb5d2 100644
--- a/src/backend/utils/adt/domains.c
+++ b/src/backend/utils/adt/domains.c
@@ -126,9 +126,14 @@ domain_state_setup(Oid domainType, bool binary, MemoryContext mcxt)
* This is roughly similar to the handling of CoerceToDomain nodes in
* execExpr*.c, but we execute each constraint separately, rather than
* compiling them in-line within a larger expression.
+ *
+ * If escontext points to an ErrorStateContext, any failures are reported
+ * there, otherwise they are ereport'ed. Note that we do not attempt to do
+ * soft reporting of errors raised during execution of CHECK constraints.
*/
static void
-domain_check_input(Datum value, bool isnull, DomainIOData *my_extra)
+domain_check_input(Datum value, bool isnull, DomainIOData *my_extra,
+ Node *escontext)
{
ExprContext *econtext = my_extra->econtext;
ListCell *l;
@@ -144,11 +149,14 @@ domain_check_input(Datum value, bool isnull, DomainIOData *my_extra)
{
case DOM_CONSTRAINT_NOTNULL:
if (isnull)
- ereport(ERROR,
+ {
+ errsave(escontext,
(errcode(ERRCODE_NOT_NULL_VIOLATION),
errmsg("domain %s does not allow null values",
format_type_be(my_extra->domain_type)),
errdatatype(my_extra->domain_type)));
+ goto fail;
+ }
break;
case DOM_CONSTRAINT_CHECK:
{
@@ -179,13 +187,16 @@ domain_check_input(Datum value, bool isnull, DomainIOData *my_extra)
econtext->domainValue_isNull = isnull;
if (!ExecCheck(con->check_exprstate, econtext))
- ereport(ERROR,
+ {
+ errsave(escontext,
(errcode(ERRCODE_CHECK_VIOLATION),
errmsg("value for domain %s violates check constraint \"%s\"",
format_type_be(my_extra->domain_type),
con->name),
errdomainconstraint(my_extra->domain_type,
con->name)));
+ goto fail;
+ }
break;
}
default:
@@ -200,6 +211,7 @@ domain_check_input(Datum value, bool isnull, DomainIOData *my_extra)
* per-tuple memory. This avoids leaking non-memory resources, if
* anything in the expression(s) has any.
*/
+fail:
if (econtext)
ReScanExprContext(econtext);
}
@@ -213,6 +225,7 @@ domain_in(PG_FUNCTION_ARGS)
{
char *string;
Oid domainType;
+ Node *escontext = fcinfo->context;
DomainIOData *my_extra;
Datum value;
@@ -245,15 +258,18 @@ domain_in(PG_FUNCTION_ARGS)
/*
* Invoke the base type's typinput procedure to convert the data.
*/
- value = InputFunctionCall(&my_extra->proc,
- string,
- my_extra->typioparam,
- my_extra->typtypmod);
+ if (!InputFunctionCallSafe(&my_extra->proc,
+ string,
+ my_extra->typioparam,
+ my_extra->typtypmod,
+ escontext,
+ &value))
+ PG_RETURN_NULL();
/*
* Do the necessary checks to ensure it's a valid domain value.
*/
- domain_check_input(value, (string == NULL), my_extra);
+ domain_check_input(value, (string == NULL), my_extra, escontext);
if (string == NULL)
PG_RETURN_NULL();
@@ -309,7 +325,7 @@ domain_recv(PG_FUNCTION_ARGS)
/*
* Do the necessary checks to ensure it's a valid domain value.
*/
- domain_check_input(value, (buf == NULL), my_extra);
+ domain_check_input(value, (buf == NULL), my_extra, NULL);
if (buf == NULL)
PG_RETURN_NULL();
@@ -349,7 +365,7 @@ 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);
+ domain_check_input(value, isnull, my_extra, NULL);
}
/*