Thanks for showing interest in this. The issue comes from this situation.
insert into tb select '{"a": "foo", "b": 100000000}';
select cast(a->'a' as numeric) from tb;
NUMERIC_VALUE_OUT_OF_RANGE smallint out of range
the call stack is:
1 in errstart_cold of elog.c:333
2 in numeric_int2 of numeric.c:4503
3 in DirectFunctionCall1Coll of fmgr.c:785
4 in jsonb_int2 of jsonb.c:2086
There are 2 different errcode involved here and there are two different
functions that play part in it (jsonb_numeric and numeric_int2). and
the error code jsonb_numeric used is improper as well.
The difference is not very huge, but it would be cool if we can make
it better, If something really improves here, it will make the code in [0]
cleaner as well. the bad code in [0]:
+Datum
+jsonb_finish_numeric(PG_FUNCTION_ARGS)
+{
+ JsonbValue *v = (JsonbValue *)PG_GETARG_POINTER(0);
+ Oid final_oid = PG_GETARG_OID(1);
+ if (v->type != jbvNumeric)
+ cannotCastJsonbValue(v->type, format_type_be(final_oid));
+ PG_RETURN_NUMERIC(v->val.numeric);
+}
To match the error message in the older version, I have to input
a {final_oid} argument in jsonb_finish_numeric function which
is not good.
As to how to redesign the error message is a bit confusing to
me, it would be good to see the proposal code as well.