Skip to content

Commit fcc1050

Browse files
jianhe-funCommitfest Bot
authored andcommitted
error safe for casting jsonb to other types per pg_cast
select castsource::regtype, casttarget::regtype, castfunc, castcontext,castmethod, pp.prosrc, pp.proname from pg_cast pc join pg_proc pp on pp.oid = pc.castfunc and pc.castfunc > 0 and castsource::regtype = 'jsonb'::regtype order by castsource::regtype; castsource | casttarget | castfunc | castcontext | castmethod | prosrc | proname ------------+------------------+----------+-------------+------------+---------------+--------- jsonb | boolean | 3556 | e | f | jsonb_bool | bool jsonb | numeric | 3449 | e | f | jsonb_numeric | numeric jsonb | smallint | 3450 | e | f | jsonb_int2 | int2 jsonb | integer | 3451 | e | f | jsonb_int4 | int4 jsonb | bigint | 3452 | e | f | jsonb_int8 | int8 jsonb | real | 3453 | e | f | jsonb_float4 | float4 jsonb | double precision | 2580 | e | f | jsonb_float8 | float8 (7 rows) discussion: https://postgr.es/m/CADkLM=fv1JfY4Ufa-jcwwNbjQixNViskQ8jZu3Tz_p656i_4hQ@mail.gmail.com
1 parent e08d082 commit fcc1050

File tree

1 file changed

+75
-16
lines changed

1 file changed

+75
-16
lines changed

src/backend/utils/adt/jsonb.c

Lines changed: 75 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -2005,7 +2005,7 @@ JsonbExtractScalar(JsonbContainer *jbc, JsonbValue *res)
20052005
* Emit correct, translatable cast error message
20062006
*/
20072007
static void
2008-
cannotCastJsonbValue(enum jbvType type, const char *sqltype)
2008+
cannotCastJsonbValue(enum jbvType type, const char *sqltype, Node *escontext)
20092009
{
20102010
static const struct
20112011
{
@@ -2026,9 +2026,12 @@ cannotCastJsonbValue(enum jbvType type, const char *sqltype)
20262026

20272027
for (i = 0; i < lengthof(messages); i++)
20282028
if (messages[i].type == type)
2029-
ereport(ERROR,
2029+
{
2030+
errsave(escontext,
20302031
(errcode(ERRCODE_INVALID_PARAMETER_VALUE),
20312032
errmsg(messages[i].msg, sqltype)));
2033+
return;
2034+
}
20322035

20332036
/* should be unreachable */
20342037
elog(ERROR, "unknown jsonb type: %d", (int) type);
@@ -2041,7 +2044,11 @@ jsonb_bool(PG_FUNCTION_ARGS)
20412044
JsonbValue v;
20422045

20432046
if (!JsonbExtractScalar(&in->root, &v))
2044-
cannotCastJsonbValue(v.type, "boolean");
2047+
{
2048+
cannotCastJsonbValue(v.type, "boolean", fcinfo->context);
2049+
2050+
PG_RETURN_NULL();
2051+
}
20452052

20462053
if (v.type == jbvNull)
20472054
{
@@ -2050,7 +2057,11 @@ jsonb_bool(PG_FUNCTION_ARGS)
20502057
}
20512058

20522059
if (v.type != jbvBool)
2053-
cannotCastJsonbValue(v.type, "boolean");
2060+
{
2061+
cannotCastJsonbValue(v.type, "boolean", fcinfo->context);
2062+
2063+
PG_RETURN_NULL();
2064+
}
20542065

20552066
PG_FREE_IF_COPY(in, 0);
20562067

@@ -2065,7 +2076,11 @@ jsonb_numeric(PG_FUNCTION_ARGS)
20652076
Numeric retValue;
20662077

20672078
if (!JsonbExtractScalar(&in->root, &v))
2068-
cannotCastJsonbValue(v.type, "numeric");
2079+
{
2080+
cannotCastJsonbValue(v.type, "numeric", fcinfo->context);
2081+
2082+
PG_RETURN_NULL();
2083+
}
20692084

20702085
if (v.type == jbvNull)
20712086
{
@@ -2074,7 +2089,11 @@ jsonb_numeric(PG_FUNCTION_ARGS)
20742089
}
20752090

20762091
if (v.type != jbvNumeric)
2077-
cannotCastJsonbValue(v.type, "numeric");
2092+
{
2093+
cannotCastJsonbValue(v.type, "numeric", fcinfo->context);
2094+
2095+
PG_RETURN_NULL();
2096+
}
20782097

20792098
/*
20802099
* v.val.numeric points into jsonb body, so we need to make a copy to
@@ -2095,7 +2114,11 @@ jsonb_int2(PG_FUNCTION_ARGS)
20952114
Datum retValue;
20962115

20972116
if (!JsonbExtractScalar(&in->root, &v))
2098-
cannotCastJsonbValue(v.type, "smallint");
2117+
{
2118+
cannotCastJsonbValue(v.type, "smallint", fcinfo->context);
2119+
2120+
PG_RETURN_NULL();
2121+
}
20992122

21002123
if (v.type == jbvNull)
21012124
{
@@ -2104,7 +2127,11 @@ jsonb_int2(PG_FUNCTION_ARGS)
21042127
}
21052128

21062129
if (v.type != jbvNumeric)
2107-
cannotCastJsonbValue(v.type, "smallint");
2130+
{
2131+
cannotCastJsonbValue(v.type, "smallint", fcinfo->context);
2132+
2133+
PG_RETURN_NULL();
2134+
}
21082135

21092136
retValue = DirectFunctionCall1(numeric_int2,
21102137
NumericGetDatum(v.val.numeric));
@@ -2122,7 +2149,11 @@ jsonb_int4(PG_FUNCTION_ARGS)
21222149
Datum retValue;
21232150

21242151
if (!JsonbExtractScalar(&in->root, &v))
2125-
cannotCastJsonbValue(v.type, "integer");
2152+
{
2153+
cannotCastJsonbValue(v.type, "integer", fcinfo->context);
2154+
2155+
PG_RETURN_NULL();
2156+
}
21262157

21272158
if (v.type == jbvNull)
21282159
{
@@ -2131,7 +2162,11 @@ jsonb_int4(PG_FUNCTION_ARGS)
21312162
}
21322163

21332164
if (v.type != jbvNumeric)
2134-
cannotCastJsonbValue(v.type, "integer");
2165+
{
2166+
cannotCastJsonbValue(v.type, "integer", fcinfo->context);
2167+
2168+
PG_RETURN_NULL();
2169+
}
21352170

21362171
retValue = DirectFunctionCall1(numeric_int4,
21372172
NumericGetDatum(v.val.numeric));
@@ -2149,7 +2184,11 @@ jsonb_int8(PG_FUNCTION_ARGS)
21492184
Datum retValue;
21502185

21512186
if (!JsonbExtractScalar(&in->root, &v))
2152-
cannotCastJsonbValue(v.type, "bigint");
2187+
{
2188+
cannotCastJsonbValue(v.type, "bigint", fcinfo->context);
2189+
2190+
PG_RETURN_NULL();
2191+
}
21532192

21542193
if (v.type == jbvNull)
21552194
{
@@ -2158,7 +2197,11 @@ jsonb_int8(PG_FUNCTION_ARGS)
21582197
}
21592198

21602199
if (v.type != jbvNumeric)
2161-
cannotCastJsonbValue(v.type, "bigint");
2200+
{
2201+
cannotCastJsonbValue(v.type, "bigint", fcinfo->context);
2202+
2203+
PG_RETURN_NULL();
2204+
}
21622205

21632206
retValue = DirectFunctionCall1(numeric_int8,
21642207
NumericGetDatum(v.val.numeric));
@@ -2176,7 +2219,11 @@ jsonb_float4(PG_FUNCTION_ARGS)
21762219
Datum retValue;
21772220

21782221
if (!JsonbExtractScalar(&in->root, &v))
2179-
cannotCastJsonbValue(v.type, "real");
2222+
{
2223+
cannotCastJsonbValue(v.type, "real", fcinfo->context);
2224+
2225+
PG_RETURN_NULL();
2226+
}
21802227

21812228
if (v.type == jbvNull)
21822229
{
@@ -2185,7 +2232,11 @@ jsonb_float4(PG_FUNCTION_ARGS)
21852232
}
21862233

21872234
if (v.type != jbvNumeric)
2188-
cannotCastJsonbValue(v.type, "real");
2235+
{
2236+
cannotCastJsonbValue(v.type, "real", fcinfo->context);
2237+
2238+
PG_RETURN_NULL();
2239+
}
21892240

21902241
retValue = DirectFunctionCall1(numeric_float4,
21912242
NumericGetDatum(v.val.numeric));
@@ -2203,7 +2254,11 @@ jsonb_float8(PG_FUNCTION_ARGS)
22032254
Datum retValue;
22042255

22052256
if (!JsonbExtractScalar(&in->root, &v))
2206-
cannotCastJsonbValue(v.type, "double precision");
2257+
{
2258+
cannotCastJsonbValue(v.type, "double precision", fcinfo->context);
2259+
2260+
PG_RETURN_NULL();
2261+
}
22072262

22082263
if (v.type == jbvNull)
22092264
{
@@ -2212,7 +2267,11 @@ jsonb_float8(PG_FUNCTION_ARGS)
22122267
}
22132268

22142269
if (v.type != jbvNumeric)
2215-
cannotCastJsonbValue(v.type, "double precision");
2270+
{
2271+
cannotCastJsonbValue(v.type, "double precision", fcinfo->context);
2272+
2273+
PG_RETURN_NULL();
2274+
}
22162275

22172276
retValue = DirectFunctionCall1(numeric_float8,
22182277
NumericGetDatum(v.val.numeric));

0 commit comments

Comments
 (0)