Skip to content

Commit b18df55

Browse files
jianhe-funCommitfest Bot
authored andcommitted
error safe for casting numeric 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 = 'numeric'::regtype order by castsource::regtype; castsource | casttarget | castfunc | castcontext | castmethod | prosrc | proname ------------+------------------+----------+-------------+------------+----------------+--------- numeric | bigint | 1779 | a | f | numeric_int8 | int8 numeric | smallint | 1783 | a | f | numeric_int2 | int2 numeric | integer | 1744 | a | f | numeric_int4 | int4 numeric | real | 1745 | i | f | numeric_float4 | float4 numeric | double precision | 1746 | i | f | numeric_float8 | float8 numeric | money | 3824 | a | f | numeric_cash | money numeric | numeric | 1703 | i | f | numeric | numeric (7 rows) discussion: https://postgr.es/m/CACJufxHCMzrHOW=wRe8L30rMhB3sjwAv1LE928Fa7sxMu1Tx-g@mail.gmail.com
1 parent fcb6db8 commit b18df55

File tree

1 file changed

+53
-15
lines changed

1 file changed

+53
-15
lines changed

src/backend/utils/adt/numeric.c

Lines changed: 53 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1244,7 +1244,8 @@ numeric (PG_FUNCTION_ARGS)
12441244
*/
12451245
if (NUMERIC_IS_SPECIAL(num))
12461246
{
1247-
(void) apply_typmod_special(num, typmod, NULL);
1247+
if (!apply_typmod_special(num, typmod, fcinfo->context))
1248+
PG_RETURN_NULL();
12481249
PG_RETURN_NUMERIC(duplicate_numeric(num));
12491250
}
12501251

@@ -1295,8 +1296,9 @@ numeric (PG_FUNCTION_ARGS)
12951296
init_var(&var);
12961297

12971298
set_var_from_num(num, &var);
1298-
(void) apply_typmod(&var, typmod, NULL);
1299-
new = make_result(&var);
1299+
if (!apply_typmod(&var, typmod, fcinfo->context))
1300+
PG_RETURN_NULL();
1301+
new = make_result_safe(&var, fcinfo->context);
13001302

13011303
free_var(&var);
13021304

@@ -3019,7 +3021,10 @@ numeric_mul(PG_FUNCTION_ARGS)
30193021
Numeric num2 = PG_GETARG_NUMERIC(1);
30203022
Numeric res;
30213023

3022-
res = numeric_mul_safe(num1, num2, NULL);
3024+
res = numeric_mul_safe(num1, num2, fcinfo->context);
3025+
3026+
if (unlikely(SOFT_ERROR_OCCURRED(fcinfo->context)))
3027+
PG_RETURN_NULL();
30233028

30243029
PG_RETURN_NUMERIC(res);
30253030
}
@@ -4393,9 +4398,15 @@ numeric_int4_safe(Numeric num, Node *escontext)
43934398
Datum
43944399
numeric_int4(PG_FUNCTION_ARGS)
43954400
{
4401+
int32 result;
43964402
Numeric num = PG_GETARG_NUMERIC(0);
43974403

4398-
PG_RETURN_INT32(numeric_int4_safe(num, NULL));
4404+
result = numeric_int4_safe(num, fcinfo->context);
4405+
4406+
if (unlikely(SOFT_ERROR_OCCURRED(fcinfo->context)))
4407+
PG_RETURN_NULL();
4408+
4409+
PG_RETURN_INT32(result);
43994410
}
44004411

44014412
/*
@@ -4463,9 +4474,15 @@ numeric_int8_safe(Numeric num, Node *escontext)
44634474
Datum
44644475
numeric_int8(PG_FUNCTION_ARGS)
44654476
{
4477+
int64 result;
44664478
Numeric num = PG_GETARG_NUMERIC(0);
44674479

4468-
PG_RETURN_INT64(numeric_int8_safe(num, NULL));
4480+
result = numeric_int8_safe(num, fcinfo->context);
4481+
4482+
if (unlikely(SOFT_ERROR_OCCURRED(fcinfo->context)))
4483+
PG_RETURN_NULL();
4484+
4485+
PG_RETURN_INT64(result);
44694486
}
44704487

44714488

@@ -4489,28 +4506,38 @@ numeric_int2(PG_FUNCTION_ARGS)
44894506
if (NUMERIC_IS_SPECIAL(num))
44904507
{
44914508
if (NUMERIC_IS_NAN(num))
4492-
ereport(ERROR,
4509+
errsave(fcinfo->context,
44934510
(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
44944511
errmsg("cannot convert NaN to %s", "smallint")));
44954512
else
4496-
ereport(ERROR,
4513+
errsave(fcinfo->context,
44974514
(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
44984515
errmsg("cannot convert infinity to %s", "smallint")));
4516+
4517+
PG_RETURN_NULL();
44994518
}
45004519

45014520
/* Convert to variable format and thence to int8 */
45024521
init_var_from_num(num, &x);
45034522

45044523
if (!numericvar_to_int64(&x, &val))
4505-
ereport(ERROR,
4524+
{
4525+
errsave(fcinfo->context,
45064526
(errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
45074527
errmsg("smallint out of range")));
45084528

4529+
PG_RETURN_NULL();
4530+
}
4531+
45094532
if (unlikely(val < PG_INT16_MIN) || unlikely(val > PG_INT16_MAX))
4510-
ereport(ERROR,
4533+
{
4534+
errsave(fcinfo->context,
45114535
(errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
45124536
errmsg("smallint out of range")));
45134537

4538+
PG_RETURN_NULL();
4539+
}
4540+
45144541
/* Down-convert to int2 */
45154542
result = (int16) val;
45164543

@@ -4572,10 +4599,14 @@ numeric_float8(PG_FUNCTION_ARGS)
45724599

45734600
tmp = DatumGetCString(DirectFunctionCall1(numeric_out,
45744601
NumericGetDatum(num)));
4575-
4576-
result = DirectFunctionCall1(float8in, CStringGetDatum(tmp));
4577-
4578-
pfree(tmp);
4602+
if (!DirectInputFunctionCallSafe(float8in, tmp,
4603+
InvalidOid, -1,
4604+
(Node *) fcinfo->context,
4605+
&result))
4606+
{
4607+
pfree(tmp);
4608+
PG_RETURN_NULL();
4609+
}
45794610

45804611
PG_RETURN_DATUM(result);
45814612
}
@@ -4667,7 +4698,14 @@ numeric_float4(PG_FUNCTION_ARGS)
46674698
tmp = DatumGetCString(DirectFunctionCall1(numeric_out,
46684699
NumericGetDatum(num)));
46694700

4670-
result = DirectFunctionCall1(float4in, CStringGetDatum(tmp));
4701+
if (!DirectInputFunctionCallSafe(float4in, tmp,
4702+
InvalidOid, -1,
4703+
(Node *) fcinfo->context,
4704+
&result))
4705+
{
4706+
pfree(tmp);
4707+
PG_RETURN_NULL();
4708+
}
46714709

46724710
pfree(tmp);
46734711

0 commit comments

Comments
 (0)