diff --git a/src/backend/utils/adt/float.c b/src/backend/utils/adt/float.c index a06fef42901..362c29ab803 100644 --- a/src/backend/utils/adt/float.c +++ b/src/backend/utils/adt/float.c @@ -123,6 +123,30 @@ float_zero_divide_error(void) errmsg("division by zero"))); } +float8 +float_overflow_error_ext(struct Node *escontext) +{ + ereturn(escontext, 0.0, + errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE), + errmsg("value out of range: overflow")); +} + +float8 +float_underflow_error_ext(struct Node *escontext) +{ + ereturn(escontext, 0.0, + errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE), + errmsg("value out of range: underflow")); +} + +float8 +float_zero_divide_error_ext(struct Node *escontext) +{ + ereturn(escontext, 0.0, + (errcode(ERRCODE_DIVISION_BY_ZERO), + errmsg("division by zero"))); +} + /* * Returns -1 if 'val' represents negative infinity, 1 if 'val' @@ -1216,9 +1240,9 @@ dtof(PG_FUNCTION_ARGS) result = (float4) num; if (unlikely(isinf(result)) && !isinf(num)) - float_overflow_error(); + float_overflow_error_ext(fcinfo->context); if (unlikely(result == 0.0f) && num != 0.0) - float_underflow_error(); + float_underflow_error_ext(fcinfo->context); PG_RETURN_FLOAT4(result); } diff --git a/src/backend/utils/adt/geo_ops.c b/src/backend/utils/adt/geo_ops.c index bfb4859b4cb..cbc4621e9b2 100644 --- a/src/backend/utils/adt/geo_ops.c +++ b/src/backend/utils/adt/geo_ops.c @@ -77,12 +77,12 @@ enum path_delim /* Routines for points */ static inline void point_construct(Point *result, float8 x, float8 y); -static inline void point_add_point(Point *result, Point *pt1, Point *pt2); +static inline void point_add_point(Point *result, Point *pt1, Point *pt2, Node *escontext); static inline void point_sub_point(Point *result, Point *pt1, Point *pt2); static inline void point_mul_point(Point *result, Point *pt1, Point *pt2); static inline void point_div_point(Point *result, Point *pt1, Point *pt2); static inline bool point_eq_point(Point *pt1, Point *pt2); -static inline float8 point_dt(Point *pt1, Point *pt2); +static inline float8 point_dt(Point *pt1, Point *pt2, Node *escontext); static inline float8 point_sl(Point *pt1, Point *pt2); static int point_inside(Point *p, int npts, Point *plist); @@ -108,7 +108,7 @@ static float8 lseg_closept_lseg(Point *result, LSEG *on_lseg, LSEG *to_lseg); /* Routines for boxes */ static inline void box_construct(BOX *result, Point *pt1, Point *pt2); -static void box_cn(Point *center, BOX *box); +static void box_cn(Point *center, BOX *box, Node *escontext); static bool box_ov(BOX *box1, BOX *box2); static float8 box_ar(BOX *box); static float8 box_ht(BOX *box); @@ -125,7 +125,7 @@ static float8 circle_ar(CIRCLE *circle); /* Routines for polygons */ static void make_bound_box(POLYGON *poly); -static void poly_to_circle(CIRCLE *result, POLYGON *poly); +static void poly_to_circle(CIRCLE *result, POLYGON *poly, Node *escontext); static bool lseg_inside_poly(Point *a, Point *b, POLYGON *poly, int start); static bool poly_contain_poly(POLYGON *contains_poly, POLYGON *contained_poly); static bool plist_same(int npts, Point *p1, Point *p2); @@ -836,10 +836,10 @@ box_distance(PG_FUNCTION_ARGS) Point a, b; - box_cn(&a, box1); - box_cn(&b, box2); + box_cn(&a, box1, NULL); + box_cn(&b, box2, NULL); - PG_RETURN_FLOAT8(point_dt(&a, &b)); + PG_RETURN_FLOAT8(point_dt(&a, &b, NULL)); } @@ -851,7 +851,9 @@ box_center(PG_FUNCTION_ARGS) BOX *box = PG_GETARG_BOX_P(0); Point *result = palloc_object(Point); - box_cn(result, box); + box_cn(result, box, fcinfo->context); + if (SOFT_ERROR_OCCURRED(fcinfo->context)) + PG_RETURN_NULL(); PG_RETURN_POINT_P(result); } @@ -869,12 +871,27 @@ box_ar(BOX *box) /* box_cn - stores the centerpoint of the box into *center. */ static void -box_cn(Point *center, BOX *box) +box_cn(Point *center, BOX *box, Node *escontext) { - center->x = float8_div(float8_pl(box->high.x, box->low.x), 2.0); - center->y = float8_div(float8_pl(box->high.y, box->low.y), 2.0); -} + float8 x; + float8 y; + x = float8_pl_safe(box->high.x, box->low.x, escontext); + if (SOFT_ERROR_OCCURRED(escontext)) + return; + + center->x = float8_div_safe(x, 2.0, escontext); + if (SOFT_ERROR_OCCURRED(escontext)) + return; + + y = float8_pl_safe(box->high.y, box->low.y, escontext); + if (SOFT_ERROR_OCCURRED(escontext)) + return; + + center->y = float8_div_safe(y, 2.0, escontext); + if (SOFT_ERROR_OCCURRED(escontext)) + return; +} /* box_wd - returns the width (length) of the box * (horizontal magnitude). @@ -1808,7 +1825,7 @@ path_length(PG_FUNCTION_ARGS) iprev = path->npts - 1; /* include the closure segment */ } - result = float8_pl(result, point_dt(&path->p[iprev], &path->p[i])); + result = float8_pl(result, point_dt(&path->p[iprev], &path->p[i], NULL)); } PG_RETURN_FLOAT8(result); @@ -1995,13 +2012,24 @@ point_distance(PG_FUNCTION_ARGS) Point *pt1 = PG_GETARG_POINT_P(0); Point *pt2 = PG_GETARG_POINT_P(1); - PG_RETURN_FLOAT8(point_dt(pt1, pt2)); + PG_RETURN_FLOAT8(point_dt(pt1, pt2, NULL)); } static inline float8 -point_dt(Point *pt1, Point *pt2) +point_dt(Point *pt1, Point *pt2, Node *escontext) { - return hypot(float8_mi(pt1->x, pt2->x), float8_mi(pt1->y, pt2->y)); + float8 x; + float8 y; + + x = float8_mi_safe(pt1->x, pt2->x, escontext); + if (unlikely(SOFT_ERROR_OCCURRED(escontext))) + return 0.0; + + y = float8_mi_safe(pt1->y, pt2->y, escontext); + if (unlikely(SOFT_ERROR_OCCURRED(escontext))) + return 0.0; + + return hypot(x, y); } Datum @@ -2173,7 +2201,7 @@ lseg_length(PG_FUNCTION_ARGS) { LSEG *lseg = PG_GETARG_LSEG_P(0); - PG_RETURN_FLOAT8(point_dt(&lseg->p[0], &lseg->p[1])); + PG_RETURN_FLOAT8(point_dt(&lseg->p[0], &lseg->p[1], NULL)); } /*---------------------------------------------------------- @@ -2258,8 +2286,8 @@ lseg_lt(PG_FUNCTION_ARGS) LSEG *l1 = PG_GETARG_LSEG_P(0); LSEG *l2 = PG_GETARG_LSEG_P(1); - PG_RETURN_BOOL(FPlt(point_dt(&l1->p[0], &l1->p[1]), - point_dt(&l2->p[0], &l2->p[1]))); + PG_RETURN_BOOL(FPlt(point_dt(&l1->p[0], &l1->p[1], NULL), + point_dt(&l2->p[0], &l2->p[1], NULL))); } Datum @@ -2268,8 +2296,8 @@ lseg_le(PG_FUNCTION_ARGS) LSEG *l1 = PG_GETARG_LSEG_P(0); LSEG *l2 = PG_GETARG_LSEG_P(1); - PG_RETURN_BOOL(FPle(point_dt(&l1->p[0], &l1->p[1]), - point_dt(&l2->p[0], &l2->p[1]))); + PG_RETURN_BOOL(FPle(point_dt(&l1->p[0], &l1->p[1], NULL), + point_dt(&l2->p[0], &l2->p[1], NULL))); } Datum @@ -2278,8 +2306,8 @@ lseg_gt(PG_FUNCTION_ARGS) LSEG *l1 = PG_GETARG_LSEG_P(0); LSEG *l2 = PG_GETARG_LSEG_P(1); - PG_RETURN_BOOL(FPgt(point_dt(&l1->p[0], &l1->p[1]), - point_dt(&l2->p[0], &l2->p[1]))); + PG_RETURN_BOOL(FPgt(point_dt(&l1->p[0], &l1->p[1], NULL), + point_dt(&l2->p[0], &l2->p[1], NULL))); } Datum @@ -2288,8 +2316,8 @@ lseg_ge(PG_FUNCTION_ARGS) LSEG *l1 = PG_GETARG_LSEG_P(0); LSEG *l2 = PG_GETARG_LSEG_P(1); - PG_RETURN_BOOL(FPge(point_dt(&l1->p[0], &l1->p[1]), - point_dt(&l2->p[0], &l2->p[1]))); + PG_RETURN_BOOL(FPge(point_dt(&l1->p[0], &l1->p[1], NULL), + point_dt(&l2->p[0], &l2->p[1], NULL))); } @@ -2317,13 +2345,31 @@ lseg_center(PG_FUNCTION_ARGS) { LSEG *lseg = PG_GETARG_LSEG_P(0); Point *result; + float8 x; + float8 y; result = palloc_object(Point); - result->x = float8_div(float8_pl(lseg->p[0].x, lseg->p[1].x), 2.0); - result->y = float8_div(float8_pl(lseg->p[0].y, lseg->p[1].y), 2.0); + x = float8_pl_safe(lseg->p[0].x, lseg->p[1].x, fcinfo->context); + if (SOFT_ERROR_OCCURRED(fcinfo->context)) + goto fail; + + result->x = float8_div_safe(x, 2.0, fcinfo->context); + if (SOFT_ERROR_OCCURRED(fcinfo->context)) + goto fail; + + y = float8_pl_safe(lseg->p[0].y, lseg->p[1].y, fcinfo->context); + if (SOFT_ERROR_OCCURRED(fcinfo->context)) + goto fail; + + result->y = float8_div_safe(y, 2.0, fcinfo->context); + if (SOFT_ERROR_OCCURRED(fcinfo->context)) + goto fail; PG_RETURN_POINT_P(result); + +fail: + PG_RETURN_NULL(); } @@ -2743,7 +2789,7 @@ line_closept_point(Point *result, LINE *line, Point *point) if (result != NULL) *result = closept; - return point_dt(&closept, point); + return point_dt(&closept, point, NULL); } Datum @@ -2784,7 +2830,7 @@ lseg_closept_point(Point *result, LSEG *lseg, Point *pt) if (result != NULL) *result = closept; - return point_dt(&closept, pt); + return point_dt(&closept, pt, NULL); } Datum @@ -3108,9 +3154,9 @@ on_pl(PG_FUNCTION_ARGS) static bool lseg_contain_point(LSEG *lseg, Point *pt) { - return FPeq(point_dt(pt, &lseg->p[0]) + - point_dt(pt, &lseg->p[1]), - point_dt(&lseg->p[0], &lseg->p[1])); + return FPeq(point_dt(pt, &lseg->p[0], NULL) + + point_dt(pt, &lseg->p[1], NULL), + point_dt(&lseg->p[0], &lseg->p[1], NULL)); } Datum @@ -3176,11 +3222,11 @@ on_ppath(PG_FUNCTION_ARGS) if (!path->closed) { n = path->npts - 1; - a = point_dt(pt, &path->p[0]); + a = point_dt(pt, &path->p[0], NULL); for (i = 0; i < n; i++) { - b = point_dt(pt, &path->p[i + 1]); - if (FPeq(float8_pl(a, b), point_dt(&path->p[i], &path->p[i + 1]))) + b = point_dt(pt, &path->p[i + 1], NULL); + if (FPeq(float8_pl(a, b), point_dt(&path->p[i], &path->p[i + 1], NULL))) PG_RETURN_BOOL(true); a = b; } @@ -3277,7 +3323,7 @@ box_interpt_lseg(Point *result, BOX *box, LSEG *lseg) if (result != NULL) { - box_cn(&point, box); + box_cn(&point, box, NULL); lseg_closept_point(result, lseg, &point); } @@ -4108,11 +4154,20 @@ construct_point(PG_FUNCTION_ARGS) static inline void -point_add_point(Point *result, Point *pt1, Point *pt2) +point_add_point(Point *result, Point *pt1, Point *pt2, Node *escontext) { - point_construct(result, - float8_pl(pt1->x, pt2->x), - float8_pl(pt1->y, pt2->y)); + float8 x; + float8 y; + + x = float8_pl_safe(pt1->x, pt2->x, escontext); + if (SOFT_ERROR_OCCURRED(escontext)) + return; + + y = float8_pl_safe(pt1->y, pt2->y, escontext); + if (SOFT_ERROR_OCCURRED(escontext)) + return; + + point_construct(result, x, y); } Datum @@ -4124,7 +4179,7 @@ point_add(PG_FUNCTION_ARGS) result = palloc_object(Point); - point_add_point(result, p1, p2); + point_add_point(result, p1, p2, NULL); PG_RETURN_POINT_P(result); } @@ -4236,8 +4291,8 @@ box_add(PG_FUNCTION_ARGS) result = palloc_object(BOX); - point_add_point(&result->high, &box->high, p); - point_add_point(&result->low, &box->low, p); + point_add_point(&result->high, &box->high, p, NULL); + point_add_point(&result->low, &box->low, p, NULL); PG_RETURN_BOX_P(result); } @@ -4400,7 +4455,7 @@ path_add_pt(PG_FUNCTION_ARGS) int i; for (i = 0; i < path->npts; i++) - point_add_point(&path->p[i], &path->p[i], point); + point_add_point(&path->p[i], &path->p[i], point, NULL); PG_RETURN_PATH_P(path); } @@ -4458,7 +4513,7 @@ path_poly(PG_FUNCTION_ARGS) /* This is not very consistent --- other similar cases return NULL ... */ if (!path->closed) - ereport(ERROR, + ereturn(fcinfo->context, (Datum) 0, (errcode(ERRCODE_INVALID_PARAMETER_VALUE), errmsg("open path cannot be converted to polygon"))); @@ -4508,7 +4563,10 @@ poly_center(PG_FUNCTION_ARGS) result = palloc_object(Point); - poly_to_circle(&circle, poly); + poly_to_circle(&circle, poly, fcinfo->context); + if (SOFT_ERROR_OCCURRED(fcinfo->context)) + PG_RETURN_NULL(); + *result = circle.center; PG_RETURN_POINT_P(result); @@ -4766,7 +4824,7 @@ circle_overlap(PG_FUNCTION_ARGS) CIRCLE *circle1 = PG_GETARG_CIRCLE_P(0); CIRCLE *circle2 = PG_GETARG_CIRCLE_P(1); - PG_RETURN_BOOL(FPle(point_dt(&circle1->center, &circle2->center), + PG_RETURN_BOOL(FPle(point_dt(&circle1->center, &circle2->center, NULL), float8_pl(circle1->radius, circle2->radius))); } @@ -4828,7 +4886,7 @@ circle_contained(PG_FUNCTION_ARGS) CIRCLE *circle1 = PG_GETARG_CIRCLE_P(0); CIRCLE *circle2 = PG_GETARG_CIRCLE_P(1); - PG_RETURN_BOOL(FPle(point_dt(&circle1->center, &circle2->center), + PG_RETURN_BOOL(FPle(point_dt(&circle1->center, &circle2->center, NULL), float8_mi(circle2->radius, circle1->radius))); } @@ -4840,7 +4898,7 @@ circle_contain(PG_FUNCTION_ARGS) CIRCLE *circle1 = PG_GETARG_CIRCLE_P(0); CIRCLE *circle2 = PG_GETARG_CIRCLE_P(1); - PG_RETURN_BOOL(FPle(point_dt(&circle1->center, &circle2->center), + PG_RETURN_BOOL(FPle(point_dt(&circle1->center, &circle2->center, NULL), float8_mi(circle1->radius, circle2->radius))); } @@ -4970,7 +5028,7 @@ circle_add_pt(PG_FUNCTION_ARGS) result = palloc_object(CIRCLE); - point_add_point(&result->center, &circle->center, point); + point_add_point(&result->center, &circle->center, point, NULL); result->radius = circle->radius; PG_RETURN_CIRCLE_P(result); @@ -5069,7 +5127,7 @@ circle_distance(PG_FUNCTION_ARGS) CIRCLE *circle2 = PG_GETARG_CIRCLE_P(1); float8 result; - result = float8_mi(point_dt(&circle1->center, &circle2->center), + result = float8_mi(point_dt(&circle1->center, &circle2->center, NULL), float8_pl(circle1->radius, circle2->radius)); if (result < 0.0) result = 0.0; @@ -5085,7 +5143,7 @@ circle_contain_pt(PG_FUNCTION_ARGS) Point *point = PG_GETARG_POINT_P(1); float8 d; - d = point_dt(&circle->center, point); + d = point_dt(&circle->center, point, NULL); PG_RETURN_BOOL(d <= circle->radius); } @@ -5097,7 +5155,7 @@ pt_contained_circle(PG_FUNCTION_ARGS) CIRCLE *circle = PG_GETARG_CIRCLE_P(1); float8 d; - d = point_dt(&circle->center, point); + d = point_dt(&circle->center, point, NULL); PG_RETURN_BOOL(d <= circle->radius); } @@ -5112,7 +5170,7 @@ dist_pc(PG_FUNCTION_ARGS) CIRCLE *circle = PG_GETARG_CIRCLE_P(1); float8 result; - result = float8_mi(point_dt(point, &circle->center), + result = float8_mi(point_dt(point, &circle->center, NULL), circle->radius); if (result < 0.0) result = 0.0; @@ -5130,7 +5188,7 @@ dist_cpoint(PG_FUNCTION_ARGS) Point *point = PG_GETARG_POINT_P(1); float8 result; - result = float8_mi(point_dt(point, &circle->center), circle->radius); + result = float8_mi(point_dt(point, &circle->center, NULL), circle->radius); if (result < 0.0) result = 0.0; @@ -5191,14 +5249,30 @@ circle_box(PG_FUNCTION_ARGS) box = palloc_object(BOX); - delta = float8_div(circle->radius, sqrt(2.0)); + delta = float8_div_safe(circle->radius, sqrt(2.0), fcinfo->context); + if (SOFT_ERROR_OCCURRED(fcinfo->context)) + goto fail; - box->high.x = float8_pl(circle->center.x, delta); - box->low.x = float8_mi(circle->center.x, delta); - box->high.y = float8_pl(circle->center.y, delta); - box->low.y = float8_mi(circle->center.y, delta); + box->high.x = float8_pl_safe(circle->center.x, delta, fcinfo->context); + if (SOFT_ERROR_OCCURRED(fcinfo->context)) + goto fail; + + box->low.x = float8_mi_safe(circle->center.x, delta, fcinfo->context); + if (SOFT_ERROR_OCCURRED(fcinfo->context)) + goto fail; + + box->high.y = float8_pl_safe(circle->center.y, delta, fcinfo->context); + if (SOFT_ERROR_OCCURRED(fcinfo->context)) + goto fail; + + box->low.y = float8_mi_safe(circle->center.y, delta, fcinfo->context); + if (SOFT_ERROR_OCCURRED(fcinfo->context)) + goto fail; PG_RETURN_BOX_P(box); + +fail: + PG_RETURN_NULL(); } /* box_circle() @@ -5209,15 +5283,37 @@ box_circle(PG_FUNCTION_ARGS) { BOX *box = PG_GETARG_BOX_P(0); CIRCLE *circle; + float8 x; + float8 y; circle = palloc_object(CIRCLE); - circle->center.x = float8_div(float8_pl(box->high.x, box->low.x), 2.0); - circle->center.y = float8_div(float8_pl(box->high.y, box->low.y), 2.0); + x = float8_pl_safe(box->high.x, box->low.x, fcinfo->context); + if (SOFT_ERROR_OCCURRED(fcinfo->context)) + goto fail; - circle->radius = point_dt(&circle->center, &box->high); + circle->center.x = float8_div_safe(x, 2.0, fcinfo->context); + if (SOFT_ERROR_OCCURRED(fcinfo->context)) + goto fail; + + y = float8_pl_safe(box->high.y, box->low.y, fcinfo->context); + if (SOFT_ERROR_OCCURRED(fcinfo->context)) + goto fail; + + circle->center.y = float8_div_safe(y, 2.0, fcinfo->context); + if (SOFT_ERROR_OCCURRED(fcinfo->context)) + goto fail; + + circle->radius = point_dt(&circle->center, &box->high, + fcinfo->context); + + if (SOFT_ERROR_OCCURRED(fcinfo->context)) + goto fail; PG_RETURN_CIRCLE_P(circle); + +fail: + PG_RETURN_NULL(); } @@ -5282,9 +5378,10 @@ circle_poly(PG_FUNCTION_ARGS) * rather than straight average values of points - tgl 97/01/21. */ static void -poly_to_circle(CIRCLE *result, POLYGON *poly) +poly_to_circle(CIRCLE *result, POLYGON *poly, Node *escontext) { int i; + float8 x; Assert(poly->npts > 0); @@ -5293,14 +5390,34 @@ poly_to_circle(CIRCLE *result, POLYGON *poly) result->radius = 0; for (i = 0; i < poly->npts; i++) - point_add_point(&result->center, &result->center, &poly->p[i]); - result->center.x = float8_div(result->center.x, poly->npts); - result->center.y = float8_div(result->center.y, poly->npts); + { + point_add_point(&result->center, &result->center, &poly->p[i], escontext); + if (SOFT_ERROR_OCCURRED(escontext)) + return; + } + + result->center.x = float8_div_safe(result->center.x, poly->npts, escontext); + if (SOFT_ERROR_OCCURRED(escontext)) + return; + + result->center.y = float8_div_safe(result->center.y, poly->npts, escontext); + if (SOFT_ERROR_OCCURRED(escontext)) + return; for (i = 0; i < poly->npts; i++) - result->radius = float8_pl(result->radius, - point_dt(&poly->p[i], &result->center)); - result->radius = float8_div(result->radius, poly->npts); + { + x = point_dt(&poly->p[i], &result->center, escontext); + if (SOFT_ERROR_OCCURRED(escontext)) + return; + + result->radius = float8_pl_safe(result->radius, x, escontext); + if (SOFT_ERROR_OCCURRED(escontext)) + return; + } + + result->radius = float8_div_safe(result->radius, poly->npts, escontext); + if (SOFT_ERROR_OCCURRED(escontext)) + return; } Datum @@ -5311,7 +5428,9 @@ poly_circle(PG_FUNCTION_ARGS) result = palloc_object(CIRCLE); - poly_to_circle(result, poly); + poly_to_circle(result, poly, fcinfo->context); + if (SOFT_ERROR_OCCURRED(fcinfo->context)) + PG_RETURN_NULL(); PG_RETURN_CIRCLE_P(result); } diff --git a/src/include/utils/float.h b/src/include/utils/float.h index b340678ca92..ffa743d6273 100644 --- a/src/include/utils/float.h +++ b/src/include/utils/float.h @@ -33,6 +33,9 @@ extern PGDLLIMPORT int extra_float_digits; pg_noreturn extern void float_overflow_error(void); pg_noreturn extern void float_underflow_error(void); pg_noreturn extern void float_zero_divide_error(void); +extern float8 float_overflow_error_ext(struct Node *escontext); +extern float8 float_underflow_error_ext(struct Node *escontext); +extern float8 float_zero_divide_error_ext(struct Node *escontext); extern int is_infinite(float8 val); extern float8 float8in_internal(char *num, char **endptr_p, const char *type_name, const char *orig_string, @@ -110,17 +113,23 @@ float4_pl(const float4 val1, const float4 val2) } static inline float8 -float8_pl(const float8 val1, const float8 val2) +float8_pl_safe(const float8 val1, const float8 val2, struct Node *escontext) { float8 result; result = val1 + val2; if (unlikely(isinf(result)) && !isinf(val1) && !isinf(val2)) - float_overflow_error(); + return float_overflow_error_ext(escontext); return result; } +static inline float8 +float8_pl(const float8 val1, const float8 val2) +{ + return float8_pl_safe(val1, val2, NULL); +} + static inline float4 float4_mi(const float4 val1, const float4 val2) { @@ -134,17 +143,23 @@ float4_mi(const float4 val1, const float4 val2) } static inline float8 -float8_mi(const float8 val1, const float8 val2) +float8_mi_safe(const float8 val1, const float8 val2, struct Node *escontext) { float8 result; result = val1 - val2; if (unlikely(isinf(result)) && !isinf(val1) && !isinf(val2)) - float_overflow_error(); + return float_overflow_error_ext(escontext); return result; } +static inline float8 +float8_mi(const float8 val1, const float8 val2) +{ + return float8_mi_safe(val1, val2, NULL); +} + static inline float4 float4_mul(const float4 val1, const float4 val2) { @@ -160,19 +175,25 @@ float4_mul(const float4 val1, const float4 val2) } static inline float8 -float8_mul(const float8 val1, const float8 val2) +float8_mul_safe(const float8 val1, const float8 val2, struct Node *escontext) { float8 result; result = val1 * val2; if (unlikely(isinf(result)) && !isinf(val1) && !isinf(val2)) - float_overflow_error(); + return float_overflow_error_ext(escontext); if (unlikely(result == 0.0) && val1 != 0.0 && val2 != 0.0) - float_underflow_error(); + return float_underflow_error_ext(escontext); return result; } +static inline float8 +float8_mul(const float8 val1, const float8 val2) +{ + return float8_mul_safe(val1, val2, NULL); +} + static inline float4 float4_div(const float4 val1, const float4 val2) { @@ -190,21 +211,27 @@ float4_div(const float4 val1, const float4 val2) } static inline float8 -float8_div(const float8 val1, const float8 val2) +float8_div_safe(const float8 val1, const float8 val2, struct Node *escontext) { float8 result; if (unlikely(val2 == 0.0) && !isnan(val1)) - float_zero_divide_error(); + return float_zero_divide_error_ext(escontext); result = val1 / val2; if (unlikely(isinf(result)) && !isinf(val1)) - float_overflow_error(); + return float_overflow_error_ext(escontext); if (unlikely(result == 0.0) && val1 != 0.0 && !isinf(val2)) - float_underflow_error(); + return float_underflow_error_ext(escontext); return result; } +static inline float8 +float8_div(const float8 val1, const float8 val2) +{ + return float8_div_safe(val1, val2, NULL); +} + /* * Routines for NaN-aware comparisons *