/* 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);
/* 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);
/* 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);
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));
}
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);
}
/* 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).
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);
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
{
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));
}
/*----------------------------------------------------------
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
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
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
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)));
}
{
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();
}
if (result != NULL)
*result = closept;
- return point_dt(&closept, point);
+ return point_dt(&closept, point, NULL);
}
Datum
if (result != NULL)
*result = closept;
- return point_dt(&closept, pt);
+ return point_dt(&closept, pt, NULL);
}
Datum
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
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;
}
if (result != NULL)
{
- box_cn(&point, box);
+ box_cn(&point, box, NULL);
lseg_closept_point(result, lseg, &point);
}
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
result = palloc_object(Point);
- point_add_point(result, p1, p2);
+ point_add_point(result, p1, p2, NULL);
PG_RETURN_POINT_P(result);
}
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);
}
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);
}
/* 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")));
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);
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)));
}
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)));
}
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)));
}
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);
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;
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);
}
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);
}
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;
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;
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_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->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->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()
{
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->center.x = float8_div_safe(x, 2.0, fcinfo->context);
+ if (SOFT_ERROR_OCCURRED(fcinfo->context))
+ goto fail;
- circle->radius = point_dt(&circle->center, &box->high);
+ 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();
}
* 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);
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
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);
}