Skip to content

Commit

Permalink
Add "safe" call for function cast
Browse files Browse the repository at this point in the history
  • Loading branch information
robozmey committed Dec 11, 2024
1 parent 2c055ae commit 5e8414e
Show file tree
Hide file tree
Showing 4 changed files with 58 additions and 5 deletions.
17 changes: 13 additions & 4 deletions contrib/try_convert/try_convert.c
Original file line number Diff line number Diff line change
Expand Up @@ -191,14 +191,19 @@ try_convert_from_function(Datum value, int32 typmod, Oid funcId, bool *is_failed
{
Datum res = 0;

ErrorSaveContext escontext = {T_ErrorSaveContext, false};;

PG_TRY();
{
res = OidFunctionCall3(funcId, value, typmod, true);
res = OidFunctionCall3Safe(funcId, value, typmod, true, &escontext);

if (escontext.error_occurred) {
*is_failed = true;
}
}
PG_CATCH();
{
*is_failed = true;
FlushErrorState(); /// TODO replace
res = 0;
}
PG_END_TRY();

Expand Down Expand Up @@ -233,7 +238,7 @@ try_convert_via_io(Datum value, Oid sourceTypeId, Oid targetTypeId, int32 target
Datum res = 0;
char *string;

ErrorSaveContext escontext = {T_ErrorSaveContext, false};;
ErrorSaveContext escontext = {T_ErrorSaveContext, false};

PG_TRY();
{
Expand All @@ -249,6 +254,10 @@ try_convert_via_io(Datum value, Oid sourceTypeId, Oid targetTypeId, int32 target
if (escontext.error_occurred) {
*is_failed = true;
}
}
PG_CATCH();
{
res = 0;
}
PG_END_TRY();

Expand Down
2 changes: 1 addition & 1 deletion src/backend/utils/adt/int.c
Original file line number Diff line number Diff line change
Expand Up @@ -344,7 +344,7 @@ i4toi2(PG_FUNCTION_ARGS)
int32 arg1 = PG_GETARG_INT32(0);

if (arg1 < SHRT_MIN || arg1 > SHRT_MAX)
ereport(ERROR,
ereturn(fcinfo->context, 0,
(errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
errmsg("smallint out of range")));

Expand Down
35 changes: 35 additions & 0 deletions src/backend/utils/fmgr/fmgr.c
Original file line number Diff line number Diff line change
Expand Up @@ -1888,6 +1888,41 @@ OidFunctionCall9Coll(Oid functionId, Oid collation, Datum arg1, Datum arg2,
return result;
}

/*

*/
Datum
OidFunctionCall3CollSafe(Oid functionId, Oid collation, Datum arg1, Datum arg2,
Datum arg3, fmNodePtr escontext)
{
FmgrInfo flinfo;
FunctionCallInfoData fcinfo;
Datum result;

fmgr_info(functionId, &flinfo);

InitFunctionCallInfoData(fcinfo, &flinfo, 3, collation, escontext, NULL);

fcinfo.arg[0] = arg1;
fcinfo.arg[1] = arg2;
fcinfo.arg[2] = arg3;
fcinfo.argnull[0] = false;
fcinfo.argnull[1] = false;
fcinfo.argnull[2] = false;

result = FunctionCallInvoke(&fcinfo);

/* Result value is garbage, and could be null, if an error was reported */
if (SOFT_ERROR_OCCURRED(escontext))
return (Datum) 0;

/* Check for null result, since caller is clearly not expecting one */
if (fcinfo.isnull)
elog(ERROR, "function %u returned NULL", flinfo.fn_oid);

return result;
}


/*
* Special cases for convenient invocation of datatype I/O functions.
Expand Down
9 changes: 9 additions & 0 deletions src/include/fmgr.h
Original file line number Diff line number Diff line change
Expand Up @@ -579,6 +579,11 @@ extern Datum OidFunctionCall9Coll(Oid functionId, Oid collation,
Datum arg6, Datum arg7, Datum arg8,
Datum arg9);


extern Datum OidFunctionCall3CollSafe(Oid functionId, Oid collation,
Datum arg1, Datum arg2,
Datum arg3, fmNodePtr escontext);

/* These macros allow the collation argument to be omitted (with a default of
* InvalidOid, ie, no collation). They exist mostly for backwards
* compatibility of source code.
Expand Down Expand Up @@ -641,6 +646,10 @@ extern Datum OidFunctionCall9Coll(Oid functionId, Oid collation,
OidFunctionCall9Coll(functionId, InvalidOid, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9)


#define OidFunctionCall3Safe(functionId, arg1, arg2, arg3, escontext) \
OidFunctionCall3CollSafe(functionId, InvalidOid, arg1, arg2, arg3, escontext)


/* Special cases for convenient invocation of datatype I/O functions. */
extern Datum InputFunctionCall(FmgrInfo *flinfo, char *str,
Oid typioparam, int32 typmod);
Expand Down

0 comments on commit 5e8414e

Please sign in to comment.