diff --git a/src/backend/utils/adt/geo_ops.c b/src/backend/utils/adt/geo_ops.c index 8530354..0f4f763 100644 --- a/src/backend/utils/adt/geo_ops.c +++ b/src/backend/utils/adt/geo_ops.c @@ -974,20 +974,25 @@ line_recv(PG_FUNCTION_ARGS) { StringInfo buf = (StringInfo) PG_GETARG_POINTER(0); LINE *line; line = (LINE *) palloc(sizeof(LINE)); line->A = pq_getmsgfloat8(buf); line->B = pq_getmsgfloat8(buf); line->C = pq_getmsgfloat8(buf); + if (FPzero(line->A) && FPzero(line->B)) + ereport(ERROR, + (errcode(ERRCODE_INVALID_TEXT_REPRESENTATION), + errmsg("invalid line specification: A and B cannot both be zero"))); + PG_RETURN_LINE_P(line); } /* * line_send - converts line to binary format */ Datum line_send(PG_FUNCTION_ARGS) { LINE *line = PG_GETARG_LINE_P(0); @@ -1146,34 +1151,29 @@ line_horizontal(PG_FUNCTION_ARGS) LINE *line = PG_GETARG_LINE_P(0); PG_RETURN_BOOL(FPzero(line->A)); } Datum line_eq(PG_FUNCTION_ARGS) { LINE *l1 = PG_GETARG_LINE_P(0); LINE *l2 = PG_GETARG_LINE_P(1); - double k; - if (!FPzero(l2->A)) - k = l1->A / l2->A; - else if (!FPzero(l2->B)) - k = l1->B / l2->B; - else if (!FPzero(l2->C)) - k = l1->C / l2->C; + if (!FPzero(l1->A)) + PG_RETURN_BOOL(!FPzero(l2->A) && + FPeq(l1->A * l2->B, l2->A * l1->B) && + FPeq(l1->A * l2->C, l2->A * l1->C)); else - k = 1.0; - - PG_RETURN_BOOL(FPeq(l1->A, k * l2->A) && - FPeq(l1->B, k * l2->B) && - FPeq(l1->C, k * l2->C)); + PG_RETURN_BOOL(!FPzero(l2->B) && + FPeq(l1->A * l2->B, l2->A * l1->B) && + FPeq(l1->B * l2->C, l2->B * l1->C)); } /*---------------------------------------------------------- * Line arithmetic routines. *---------------------------------------------------------*/ /* line_distance() * Distance between two lines. */ @@ -1182,23 +1182,23 @@ line_distance(PG_FUNCTION_ARGS) { LINE *l1 = PG_GETARG_LINE_P(0); LINE *l2 = PG_GETARG_LINE_P(1); float8 result; Point *tmp; if (!DatumGetBool(DirectFunctionCall2(line_parallel, LinePGetDatum(l1), LinePGetDatum(l2)))) PG_RETURN_FLOAT8(0.0); - if (FPzero(l1->B)) /* vertical? */ + if (FPzero(l1->A) || FPzero(l1->B)) /* horizontal or vertical? */ PG_RETURN_FLOAT8(fabs(l1->C - l2->C)); - tmp = point_construct(0.0, l1->C); + tmp = point_construct(0.0, -l1->C / l1->B); result = dist_pl_internal(tmp, l2); PG_RETURN_FLOAT8(result); } /* line_interpt() * Point where two lines l1, l2 intersect (if any) */ Datum line_interpt(PG_FUNCTION_ARGS) { @@ -2720,28 +2720,28 @@ close_pl(PG_FUNCTION_ARGS) Point *pt = PG_GETARG_POINT_P(0); LINE *line = PG_GETARG_LINE_P(1); Point *result; LINE *tmp; double invm; result = (Point *) palloc(sizeof(Point)); if (FPzero(line->B)) /* vertical? */ { - result->x = line->C; + result->x = -line->C / line->A; result->y = pt->y; PG_RETURN_POINT_P(result); } if (FPzero(line->A)) /* horizontal? */ { result->x = pt->x; - result->y = line->C; + result->y = -line->C / line->B; PG_RETURN_POINT_P(result); } /* drop a perpendicular and find the intersection point */ /* invert and flip the sign on the slope to get a perpendicular */ invm = line->B / line->A; tmp = line_construct_pm(pt, invm); result = line_interpt_internal(tmp, line); Assert(result != NULL); PG_RETURN_POINT_P(result);