aboutsummaryrefslogtreecommitdiff
path: root/src/backend/utils/adt/misc.c
diff options
context:
space:
mode:
authorMichael Paquier <michael@paquier.xyz>2023-02-28 08:04:13 +0900
committerMichael Paquier <michael@paquier.xyz>2023-02-28 08:04:13 +0900
commitb8da37b3ada2e547983538b3e49f8079f85ce120 (patch)
treed3ecf7af84a5b492e7a2b62b79df0398f3c8bccd /src/backend/utils/adt/misc.c
parent728560db7d868b3ded9a8675742083ab89bcff7c (diff)
downloadpostgresql-b8da37b3ada2e547983538b3e49f8079f85ce120.tar.gz
postgresql-b8da37b3ada2e547983538b3e49f8079f85ce120.zip
Rework pg_input_error_message(), now renamed pg_input_error_info()
pg_input_error_info() is now a SQL function able to return a row with more than just the error message generated for incorrect data type inputs when these are able to handle soft failures, returning more contents of ErrorData, as of: - The error message (same as before). - The error detail, if set. - The error hint, if set. - SQL error code. All the regression tests that relied on pg_input_error_message() are updated to reflect the effects of the rename. Per discussion with Tom Lane and Andrew Dunstan. Author: Nathan Bossart Discussion: https://postgr.es/m/139a68e1-bd1f-a9a7-b5fe-0be9845c6311@dunslane.net
Diffstat (limited to 'src/backend/utils/adt/misc.c')
-rw-r--r--src/backend/utils/adt/misc.c44
1 files changed, 36 insertions, 8 deletions
diff --git a/src/backend/utils/adt/misc.c b/src/backend/utils/adt/misc.c
index f95256efd3d..5d78d6dc060 100644
--- a/src/backend/utils/adt/misc.c
+++ b/src/backend/utils/adt/misc.c
@@ -660,32 +660,60 @@ pg_input_is_valid(PG_FUNCTION_ARGS)
}
/*
- * pg_input_error_message - test whether string is valid input for datatype.
+ * pg_input_error_info - test whether string is valid input for datatype.
*
- * Returns NULL if OK, else the primary message string from the error.
+ * Returns NULL if OK, else the primary message, detail message, hint message
+ * and sql error code from the error.
*
* This will only work usefully if the datatype's input function has been
* updated to return "soft" errors via errsave/ereturn.
*/
Datum
-pg_input_error_message(PG_FUNCTION_ARGS)
+pg_input_error_info(PG_FUNCTION_ARGS)
{
text *txt = PG_GETARG_TEXT_PP(0);
text *typname = PG_GETARG_TEXT_PP(1);
ErrorSaveContext escontext = {T_ErrorSaveContext};
+ TupleDesc tupdesc;
+ Datum values[4];
+ bool isnull[4];
+
+ if (get_call_result_type(fcinfo, NULL, &tupdesc) != TYPEFUNC_COMPOSITE)
+ elog(ERROR, "return type must be a row type");
/* Enable details_wanted */
escontext.details_wanted = true;
if (pg_input_is_valid_common(fcinfo, txt, typname,
&escontext))
- PG_RETURN_NULL();
+ memset(isnull, true, sizeof(isnull));
+ else
+ {
+ char *sqlstate;
+
+ Assert(escontext.error_occurred);
+ Assert(escontext.error_data != NULL);
+ Assert(escontext.error_data->message != NULL);
+
+ memset(isnull, false, sizeof(isnull));
- Assert(escontext.error_occurred);
- Assert(escontext.error_data != NULL);
- Assert(escontext.error_data->message != NULL);
+ values[0] = CStringGetTextDatum(escontext.error_data->message);
+
+ if (escontext.error_data->detail != NULL)
+ values[1] = CStringGetTextDatum(escontext.error_data->detail);
+ else
+ isnull[1] = true;
+
+ if (escontext.error_data->hint != NULL)
+ values[2] = CStringGetTextDatum(escontext.error_data->hint);
+ else
+ isnull[2] = true;
+
+ sqlstate = unpack_sql_state(escontext.error_data->sqlerrcode);
+ values[3] = CStringGetTextDatum(sqlstate);
+ }
- PG_RETURN_TEXT_P(cstring_to_text(escontext.error_data->message));
+ return HeapTupleGetDatum(heap_form_tuple(tupdesc, values, isnull));
}
/* Common subroutine for the above */