PG_RETURN_NUMERIC(int64_to_numeric(val));
 }
 
-
-Datum
-numeric_int8(PG_FUNCTION_ARGS)
+int64
+numeric_int8_opt_error(Numeric num, bool *have_error)
 {
-       Numeric         num = PG_GETARG_NUMERIC(0);
        NumericVar      x;
        int64           result;
 
+       if (have_error)
+               *have_error = false;
+
        if (NUMERIC_IS_SPECIAL(num))
        {
-               if (NUMERIC_IS_NAN(num))
-                       ereport(ERROR,
-                                       (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
-                                        errmsg("cannot convert NaN to %s", "bigint")));
+               if (have_error)
+               {
+                       *have_error = true;
+                       return 0;
+               }
                else
-                       ereport(ERROR,
-                                       (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
-                                        errmsg("cannot convert infinity to %s", "bigint")));
+               {
+                       if (NUMERIC_IS_NAN(num))
+                               ereport(ERROR,
+                                               (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
+                                                errmsg("cannot convert NaN to %s", "bigint")));
+                       else
+                               ereport(ERROR,
+                                               (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
+                                                errmsg("cannot convert infinity to %s", "bigint")));
+               }
        }
 
-       /* Convert to variable format and thence to int8 */
+       /* Convert to variable format, then convert to int8 */
        init_var_from_num(num, &x);
 
        if (!numericvar_to_int64(&x, &result))
-               ereport(ERROR,
-                               (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
-                                errmsg("bigint out of range")));
+       {
+               if (have_error)
+               {
+                       *have_error = true;
+                       return 0;
+               }
+               else
+               {
+                       ereport(ERROR,
+                                       (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
+                                        errmsg("bigint out of range")));
+               }
+       }
+
+       return result;
+}
+
+Datum
+numeric_int8(PG_FUNCTION_ARGS)
+{
+       Numeric         num = PG_GETARG_NUMERIC(0);
 
-       PG_RETURN_INT64(result);
+       PG_RETURN_INT64(numeric_int8_opt_error(num, NULL));
 }