Re: Strange behavior with polygon and NaN

Поиск
Список
Период
Сортировка
От Kyotaro Horiguchi
Тема Re: Strange behavior with polygon and NaN
Дата
Msg-id 20201221.173011.1537000578589078865.horikyota.ntt@gmail.com
обсуждение исходный текст
Ответ на Re: Strange behavior with polygon and NaN  (Tom Lane <tgl@sss.pgh.pa.us>)
Список pgsql-hackers
At Tue, 01 Dec 2020 10:03:42 -0500, Tom Lane <tgl@sss.pgh.pa.us> wrote in 
> I think it should be "needs review" now.

Conflicted with some commit(s) uncertain to me. Rebased.

regards.

-- 
Kyotaro Horiguchi
NTT Open Source Software Center
From 26d9edeccf3f3111a7e0ff049aa6e3ba3746dce9 Mon Sep 17 00:00:00 2001
From: Kyotaro Horiguchi <horikyoga.ntt@gmail.com>
Date: Fri, 13 Nov 2020 13:31:20 +0900
Subject: [PATCH v8] fix geometric nan handling

---
 doc/src/sgml/func.sgml                     |  17 ++
 src/backend/utils/adt/geo_ops.c            | 337 ++++++++++++++++++---
 src/include/utils/float.h                  |  22 ++
 src/test/regress/expected/create_index.out |   2 +-
 src/test/regress/expected/geometry.out     | 331 +++++++++-----------
 5 files changed, 485 insertions(+), 224 deletions(-)

diff --git a/doc/src/sgml/func.sgml b/doc/src/sgml/func.sgml
index d5cd705eeb..2f7f3c633c 100644
--- a/doc/src/sgml/func.sgml
+++ b/doc/src/sgml/func.sgml
@@ -10855,6 +10855,23 @@ CREATE TYPE rainbow AS ENUM ('red', 'orange', 'yellow', 'green', 'blue', 'purple
     </para>
    </note>
 
+   <caution>
+     <para>
+       NaN and Infinity make geometric functions and operators behave
+       inconsistently. Geometric operators or functions that return a boolean
+       return false for operands that contain NaNs. Number-returning functions
+       and operators return NaN in most cases but sometimes return a valid
+       value if no NaNs are met while actual calculation.  Object-returning ones
+       yield an object that contain NaNs depending to the operation.  Likewise
+       the objects containing Infinity can make geometric operators and
+       functions behave inconsistently. For example (point
+       '(Infinity,Infinity)' <-> line '{-1,0,5}') is Infinity but (point
+       '(Infinity,Infinity)' <-> line '{0,-1,5}') is NaN. It can never
+       be a value other than these, but you should consider it uncertain how
+       geometric operators behave for objects containing Infinity.
+     </para>
+   </caution>
+
    <table id="functions-geometry-func-table">
     <title>Geometric Functions</title>
     <tgroup cols="1">
diff --git a/src/backend/utils/adt/geo_ops.c b/src/backend/utils/adt/geo_ops.c
index c1dc511a1a..e74bf3031e 100644
--- a/src/backend/utils/adt/geo_ops.c
+++ b/src/backend/utils/adt/geo_ops.c
@@ -904,9 +904,9 @@ box_intersect(PG_FUNCTION_ARGS)
 
     result = (BOX *) palloc(sizeof(BOX));
 
-    result->high.x = float8_min(box1->high.x, box2->high.x);
+    result->high.x = float8_min_nan(box1->high.x, box2->high.x);
     result->low.x = float8_max(box1->low.x, box2->low.x);
-    result->high.y = float8_min(box1->high.y, box2->high.y);
+    result->high.y = float8_min_nan(box1->high.y, box2->high.y);
     result->low.y = float8_max(box1->low.y, box2->low.y);
 
     PG_RETURN_BOX_P(result);
@@ -1061,15 +1061,23 @@ line_construct(LINE *result, Point *pt, float8 m)
         result->A = -1.0;
         result->B = 0.0;
         result->C = pt->x;
+
+        /* Avoid creating a valid line from an invalid point */
+        if (likely(!isnan(pt->x) && !isnan(pt->y)))
+            return;
     }
-    else if (m == 0)
+    else if (m == 0.0)
     {
         /* horizontal - use "y = C" */
         result->A = 0.0;
         result->B = -1.0;
         result->C = pt->y;
+
+        /* Avoid creating a valid line from an invalid point */
+        if (likely(!isnan(pt->x) && !isnan(pt->y)))
+            return;
     }
-    else
+    else if (!isnan(m))
     {
         /* use "mx - y + yinter = 0" */
         result->A = m;
@@ -1078,7 +1086,12 @@ line_construct(LINE *result, Point *pt, float8 m)
         /* on some platforms, the preceding expression tends to produce -0 */
         if (result->C == 0.0)
             result->C = 0.0;
+
+        if (likely(!isnan(result->C)))
+            return;
     }
+
+    result->A = result->B = result->C = get_float8_nan();
 }
 
 /* line_construct_pp()
@@ -1091,6 +1104,7 @@ line_construct_pp(PG_FUNCTION_ARGS)
     Point       *pt2 = PG_GETARG_POINT_P(1);
     LINE       *result = (LINE *) palloc(sizeof(LINE));
 
+    /* NaNs are considered to be equal by point_eq_point */
     if (point_eq_point(pt1, pt2))
         ereport(ERROR,
                 (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
@@ -1111,8 +1125,12 @@ line_intersect(PG_FUNCTION_ARGS)
 {
     LINE       *l1 = PG_GETARG_LINE_P(0);
     LINE       *l2 = PG_GETARG_LINE_P(1);
+    Point        xp;
 
-    PG_RETURN_BOOL(line_interpt_line(NULL, l1, l2));
+    if (line_interpt_line(&xp, l1, l2) && !isnan(xp.x) && !isnan(xp.y))
+        PG_RETURN_BOOL(true);
+    else
+        PG_RETURN_BOOL(false);
 }
 
 Datum
@@ -1130,14 +1148,17 @@ line_perp(PG_FUNCTION_ARGS)
     LINE       *l1 = PG_GETARG_LINE_P(0);
     LINE       *l2 = PG_GETARG_LINE_P(1);
 
+    if (unlikely(isnan(l1->C) || isnan(l2->C)))
+        return false;
+
     if (FPzero(l1->A))
-        PG_RETURN_BOOL(FPzero(l2->B));
+        PG_RETURN_BOOL(FPzero(l2->B) && !isnan(l1->B) && !isnan(l2->A));
     if (FPzero(l2->A))
-        PG_RETURN_BOOL(FPzero(l1->B));
+        PG_RETURN_BOOL(FPzero(l1->B) && !isnan(l2->B) && !isnan(l1->A));
     if (FPzero(l1->B))
-        PG_RETURN_BOOL(FPzero(l2->A));
+        PG_RETURN_BOOL(FPzero(l2->A) && !isnan(l1->A) && !isnan(l2->B));
     if (FPzero(l2->B))
-        PG_RETURN_BOOL(FPzero(l1->A));
+        PG_RETURN_BOOL(FPzero(l1->A) && !isnan(l2->A) && !isnan(l1->B));
 
     PG_RETURN_BOOL(FPeq(float8_div(float8_mul(l1->A, l2->A),
                                    float8_mul(l1->B, l2->B)), -1.0));
@@ -1148,7 +1169,7 @@ line_vertical(PG_FUNCTION_ARGS)
 {
     LINE       *line = PG_GETARG_LINE_P(0);
 
-    PG_RETURN_BOOL(FPzero(line->B));
+    PG_RETURN_BOOL(FPzero(line->B) && !isnan(line->A) && !isnan(line->C));
 }
 
 Datum
@@ -1156,7 +1177,7 @@ line_horizontal(PG_FUNCTION_ARGS)
 {
     LINE       *line = PG_GETARG_LINE_P(0);
 
-    PG_RETURN_BOOL(FPzero(line->A));
+    PG_RETURN_BOOL(FPzero(line->A) && !isnan(line->B) && !isnan(line->C));
 }
 
 
@@ -1206,9 +1227,20 @@ static inline float8
 line_sl(LINE *line)
 {
     if (FPzero(line->A))
+    {
+        /* C is likely to be NaN than B */
+        if (unlikely(isnan(line->C) || isnan(line->B)))
+            return get_float8_nan();
         return 0.0;
+    }
     if (FPzero(line->B))
+    {
+        /* C is likely to be NaN than A */
+        if (unlikely(isnan(line->C) || isnan(line->A)))
+            return get_float8_nan();
         return get_float8_infinity();
+    }
+
     return float8_div(line->A, -line->B);
 }
 
@@ -1220,9 +1252,20 @@ static inline float8
 line_invsl(LINE *line)
 {
     if (FPzero(line->A))
+    {
+        /* C is likely to be NaN than B */
+        if (unlikely(isnan(line->C) || isnan(line->B)))
+            return get_float8_nan();
         return get_float8_infinity();
+    }
+
     if (FPzero(line->B))
+    {
+        /* C is likely to be NaN than A */
+        if (unlikely(isnan(line->C) || isnan(line->A)))
+            return get_float8_nan();
         return 0.0;
+    }
     return float8_div(line->B, line->A);
 }
 
@@ -1235,14 +1278,23 @@ line_distance(PG_FUNCTION_ARGS)
 {
     LINE       *l1 = PG_GETARG_LINE_P(0);
     LINE       *l2 = PG_GETARG_LINE_P(1);
+    Point        xp;
     float8        ratio;
 
-    if (line_interpt_line(NULL, l1, l2))    /* intersecting? */
+    if (line_interpt_line(&xp, l1, l2)) /* intersecting? */
+    {
+        /* return NaN if NaN is involved */
+        if (isnan(xp.x) || isnan(xp.y))
+            PG_RETURN_FLOAT8(get_float8_nan());
+
         PG_RETURN_FLOAT8(0.0);
+    }
 
-    if (!FPzero(l1->A) && !isnan(l1->A) && !FPzero(l2->A) && !isnan(l2->A))
+    if (unlikely(isnan(l1->A) || isnan(l1->B) || isnan(l2->A) || isnan(l2->B)))
+        ratio = get_float8_nan();
+    else if (!FPzero(l1->A) && !FPzero(l2->A))
         ratio = float8_div(l1->A, l2->A);
-    else if (!FPzero(l1->B) && !isnan(l1->B) && !FPzero(l2->B) && !isnan(l2->B))
+    else if (!FPzero(l1->B) && !FPzero(l2->B))
         ratio = float8_div(l1->B, l2->B);
     else
         ratio = 1.0;
@@ -1264,8 +1316,13 @@ line_interpt(PG_FUNCTION_ARGS)
 
     result = (Point *) palloc(sizeof(Point));
 
-    if (!line_interpt_line(result, l1, l2))
+    if (!line_interpt_line(result, l1, l2) ||
+        isnan(result->x) || isnan(result->y))
+    {
+        pfree(result);
         PG_RETURN_NULL();
+    }
+
     PG_RETURN_POINT_P(result);
 }
 
@@ -1291,6 +1348,7 @@ line_interpt_line(Point *result, LINE *l1, LINE *l2)
 
     if (!FPzero(l1->B))
     {
+        /* l1 is not virtucal */
         if (FPeq(l2->A, float8_mul(l1->A, float8_div(l2->B, l1->B))))
             return false;
 
@@ -1298,18 +1356,34 @@ line_interpt_line(Point *result, LINE *l1, LINE *l2)
                                  float8_mul(l2->B, l1->C)),
                        float8_mi(float8_mul(l1->A, l2->B),
                                  float8_mul(l2->A, l1->B)));
-        y = float8_div(-float8_pl(float8_mul(l1->A, x), l1->C), l1->B);
-    }
-    else if (!FPzero(l2->B))
-    {
-        if (FPeq(l1->A, float8_mul(l2->A, float8_div(l1->B, l2->B))))
-            return false;
-
-        x = float8_div(float8_mi(float8_mul(l2->B, l1->C),
-                                 float8_mul(l1->B, l2->C)),
+        /*
+         * You might want to simplify this expression by using x, but that can
+         * introduce unnecessary indeterminants (inf-inf) into the calculation,
+         * which leads to a wrong result.
+         * (For example, (-1, -1, Inf) and (1, -1, 0))
+         */
+        y = float8_div(float8_mi(float8_mul(l1->A, l2->C),
+                                 float8_mul(l2->A, l1->C)),
                        float8_mi(float8_mul(l2->A, l1->B),
                                  float8_mul(l1->A, l2->B)));
-        y = float8_div(-float8_pl(float8_mul(l2->A, x), l2->C), l2->B);
+    }
+    else if (!FPzero(l2->B))
+    {
+        /* l2 is not virtical */
+        /*
+         * We know that l1 is vertical here. The lines cannot be parallel and
+         * the x-coord of the cross point is -C/A of l1.
+         */
+        x = -float8_div(l1->C, l1->A);
+
+        /*
+         * When l2->A is zero, y is determined independently from x even if it
+         * is Inf.
+         */
+        if (FPzero(l2->A))
+            y = -float8_div(l2->C, l2->B);
+        else
+            y = float8_div(-float8_pl(float8_mul(l2->A, x), l2->C), l2->B);
     }
     else
         return false;
@@ -1639,8 +1713,8 @@ path_inter(PG_FUNCTION_ARGS)
     {
         b1.high.x = float8_max(p1->p[i].x, b1.high.x);
         b1.high.y = float8_max(p1->p[i].y, b1.high.y);
-        b1.low.x = float8_min(p1->p[i].x, b1.low.x);
-        b1.low.y = float8_min(p1->p[i].y, b1.low.y);
+        b1.low.x = float8_min_nan(p1->p[i].x, b1.low.x);
+        b1.low.y = float8_min_nan(p1->p[i].y, b1.low.y);
     }
     b2.high.x = b2.low.x = p2->p[0].x;
     b2.high.y = b2.low.y = p2->p[0].y;
@@ -1648,8 +1722,8 @@ path_inter(PG_FUNCTION_ARGS)
     {
         b2.high.x = float8_max(p2->p[i].x, b2.high.x);
         b2.high.y = float8_max(p2->p[i].y, b2.high.y);
-        b2.low.x = float8_min(p2->p[i].x, b2.low.x);
-        b2.low.y = float8_min(p2->p[i].y, b2.low.y);
+        b2.low.x = float8_min_nan(p2->p[i].x, b2.low.x);
+        b2.low.y = float8_min_nan(p2->p[i].y, b2.low.y);
     }
     if (!box_ov(&b1, &b2))
         PG_RETURN_BOOL(false);
@@ -1739,6 +1813,11 @@ path_distance(PG_FUNCTION_ARGS)
             statlseg_construct(&seg2, &p2->p[jprev], &p2->p[j]);
 
             tmp = lseg_closept_lseg(NULL, &seg1, &seg2);
+
+            /* return NULL immediately if NaN is involved */
+            if (isnan(tmp))
+                PG_RETURN_NULL();
+
             if (!have_min || float8_lt(tmp, min))
             {
                 min = tmp;
@@ -1992,9 +2071,19 @@ static inline float8
 point_sl(Point *pt1, Point *pt2)
 {
     if (FPeq(pt1->x, pt2->x))
+    {
+        if (unlikely(isnan(pt1->y) || isnan(pt2->y)))
+            return get_float8_nan();
         return get_float8_infinity();
+    }
+
     if (FPeq(pt1->y, pt2->y))
+    {
+        if (unlikely(isnan(pt1->x) || isnan(pt2->x)))
+            return get_float8_nan();
         return 0.0;
+    }
+
     return float8_div(float8_mi(pt1->y, pt2->y), float8_mi(pt1->x, pt2->x));
 }
 
@@ -2008,9 +2097,19 @@ static inline float8
 point_invsl(Point *pt1, Point *pt2)
 {
     if (FPeq(pt1->x, pt2->x))
+    {
+        if (unlikely(isnan(pt1->y) || isnan(pt2->y)))
+            return get_float8_nan();
         return 0.0;
+    }
+
     if (FPeq(pt1->y, pt2->y))
+    {
+        if (unlikely(isnan(pt1->x) || isnan(pt2->x)))
+            return get_float8_nan();
         return get_float8_infinity();
+    }
+
     return float8_div(float8_mi(pt1->x, pt2->x), float8_mi(pt2->y, pt1->y));
 }
 
@@ -2426,6 +2525,11 @@ dist_ppath_internal(Point *pt, PATH *path)
 
         statlseg_construct(&lseg, &path->p[iprev], &path->p[i]);
         tmp = lseg_closept_point(NULL, &lseg, pt);
+
+        /* return NaN if NaN is involved */
+        if (unlikely(isnan(tmp)))
+            return tmp;
+
         if (!have_min || float8_lt(tmp, result))
         {
             result = tmp;
@@ -2657,6 +2761,8 @@ dist_ppoly_internal(Point *pt, POLYGON *poly)
         d = lseg_closept_point(NULL, &seg, pt);
         if (float8_lt(d, result))
             result = d;
+        else if (unlikely(isnan(d)))
+            return get_float8_nan();
     }
 
     return result;
@@ -2686,7 +2792,8 @@ lseg_interpt_line(Point *result, LSEG *lseg, LINE *line)
      * intersection point, we are done.
      */
     line_construct(&tmp, &lseg->p[0], lseg_sl(lseg));
-    if (!line_interpt_line(&interpt, &tmp, line))
+    if (!line_interpt_line(&interpt, &tmp, line) ||
+        unlikely(isnan(interpt.x) || isnan(interpt.y)))
         return false;
 
     /*
@@ -2728,6 +2835,78 @@ line_closept_point(Point *result, LINE *line, Point *point)
 {
     Point        closept;
     LINE        tmp;
+    float8        val;
+
+    /*
+     * Treat specially the cases where A = 0 and B = 0, which we regard the
+     * line is perfectly horizontal and vertical correspondingly, not applying
+     * the normal formula involving the behavior of inf*0 =NaN defined by
+     * IEEE754.
+     */
+    if (FPzero(line->A))
+    {
+        float8 y;
+
+        /* the line is horizontal */
+        Assert(!FPzero(line->B));
+
+        y = -line->C / line->B;
+
+        /* Avoid -0 */
+        if (y == 0.0)
+            y = 0.0;
+
+        if (result != NULL)
+        {
+            result->x = point->x;
+            result->y = y;
+        }
+
+        if (unlikely(isnan(point->x)))
+            return get_float8_nan();
+
+        return fabs(point->y - y);
+    }
+    else if (FPzero(line->B))
+    {
+        float x;
+
+        /* the line is virtical */
+        Assert(!FPzero(line->A));
+
+        x = -line->C / line->A;
+
+        /* Avoid -0 */
+        if (x == 0)
+            x = 0;
+
+        if (result != NULL)
+        {
+            result->x = x;
+            result->y = point->y;
+        }
+
+        if (unlikely(isnan(point->y)))
+            return get_float8_nan();
+
+        return fabs(point->x - x);
+    }
+
+    /*
+     * If it is unclear whether the point is on the line or not, then the
+     * results are ill-defined.  This eliminates cases where any of the given
+     * coordinates are NaN, as well as cases where infinite coordinates give
+     * rise to Inf - Inf, 0 * Inf, etc.
+     */
+    val = float8_pl(float8_pl(float8_mul(line->A, point->x),
+                              float8_mul(line->B, point->y)),
+                    line->C);
+    if (unlikely(isnan(val)))
+    {
+        if (result != NULL)
+            result->x = result->y = get_float8_nan();
+        return get_float8_nan();
+    }
 
     /*
      * We drop a perpendicular to find the intersection point.  Ordinarily we
@@ -2738,7 +2917,7 @@ line_closept_point(Point *result, LINE *line, Point *point)
     if (!line_interpt_line(&closept, &tmp, line))
     {
         if (result != NULL)
-            *result = *point;
+            result->x = result->y = get_float8_nan();
 
         return get_float8_nan();
     }
@@ -2746,7 +2925,17 @@ line_closept_point(Point *result, LINE *line, Point *point)
     if (result != NULL)
         *result = closept;
 
-    return point_dt(&closept, point);
+    /*
+     * If the closest point contains Inf's, the closest point may lose
+     * arithmetic relationship with the point which lets point_dt wrongly give
+     * NaN. To avoid that kind of failure, we calculate the distance using the
+     * following formula instead of using the closest point.
+     *
+     * | A*x + B*y + C | / sqrt(A^2 + B^2)
+     *
+     * The dividend have been already calculated so just divide it.
+     */
+    return float8_div(fabs(val), HYPOT(line->A, line->B));
 }
 
 Datum
@@ -2758,7 +2947,9 @@ close_pl(PG_FUNCTION_ARGS)
 
     result = (Point *) palloc(sizeof(Point));
 
-    if (isnan(line_closept_point(result, line, pt)))
+    (void) line_closept_point(result, line, pt);
+
+    if (unlikely(isnan(result->x) || isnan(result->y)))
         PG_RETURN_NULL();
 
     PG_RETURN_POINT_P(result);
@@ -2815,6 +3006,7 @@ lseg_closept_lseg(Point *result, LSEG *on_lseg, LSEG *to_lseg)
     Point        point;
     float8        dist,
                 d;
+    bool        anynan = false;
 
     /* First, we handle the case when the line segments are intersecting. */
     if (lseg_interpt_lseg(result, on_lseg, to_lseg))
@@ -2826,6 +3018,7 @@ lseg_closept_lseg(Point *result, LSEG *on_lseg, LSEG *to_lseg)
      */
     dist = lseg_closept_point(result, on_lseg, &to_lseg->p[0]);
     d = lseg_closept_point(&point, on_lseg, &to_lseg->p[1]);
+    anynan |= (isnan(dist) || isnan(d));
     if (float8_lt(d, dist))
     {
         dist = d;
@@ -2835,6 +3028,7 @@ lseg_closept_lseg(Point *result, LSEG *on_lseg, LSEG *to_lseg)
 
     /* The closest point can still be one of the endpoints, so we test them. */
     d = lseg_closept_point(NULL, to_lseg, &on_lseg->p[0]);
+    anynan |= isnan(d);
     if (float8_lt(d, dist))
     {
         dist = d;
@@ -2842,6 +3036,7 @@ lseg_closept_lseg(Point *result, LSEG *on_lseg, LSEG *to_lseg)
             *result = on_lseg->p[0];
     }
     d = lseg_closept_point(NULL, to_lseg, &on_lseg->p[1]);
+    anynan |= isnan(d);
     if (float8_lt(d, dist))
     {
         dist = d;
@@ -2849,6 +3044,12 @@ lseg_closept_lseg(Point *result, LSEG *on_lseg, LSEG *to_lseg)
             *result = on_lseg->p[1];
     }
 
+    if (unlikely(anynan))
+    {
+        if (result != NULL)
+            result->x = result->y = get_float8_nan();
+        return get_float8_nan();
+    }
     return dist;
 }
 
@@ -2885,6 +3086,7 @@ box_closept_point(Point *result, BOX *box, Point *pt)
     Point        point,
                 closept;
     LSEG        lseg;
+    bool        anynan = false;
 
     if (box_contain_point(box, pt))
     {
@@ -2899,9 +3101,10 @@ box_closept_point(Point *result, BOX *box, Point *pt)
     point.y = box->high.y;
     statlseg_construct(&lseg, &box->low, &point);
     dist = lseg_closept_point(result, &lseg, pt);
-
+    anynan |= isnan(dist);
     statlseg_construct(&lseg, &box->high, &point);
     d = lseg_closept_point(&closept, &lseg, pt);
+    anynan |= isnan(d);
     if (float8_lt(d, dist))
     {
         dist = d;
@@ -2913,6 +3116,7 @@ box_closept_point(Point *result, BOX *box, Point *pt)
     point.y = box->low.y;
     statlseg_construct(&lseg, &box->low, &point);
     d = lseg_closept_point(&closept, &lseg, pt);
+    anynan |= isnan(d);
     if (float8_lt(d, dist))
     {
         dist = d;
@@ -2922,6 +3126,7 @@ box_closept_point(Point *result, BOX *box, Point *pt)
 
     statlseg_construct(&lseg, &box->high, &point);
     d = lseg_closept_point(&closept, &lseg, pt);
+    anynan |= isnan(d);
     if (float8_lt(d, dist))
     {
         dist = d;
@@ -2929,6 +3134,13 @@ box_closept_point(Point *result, BOX *box, Point *pt)
             *result = closept;
     }
 
+    if (unlikely(anynan))
+    {
+        if (result != NULL)
+            result->x = result->y = get_float8_nan();
+        return get_float8_nan();
+    }
+
     return dist;
 }
 
@@ -3000,6 +3212,7 @@ close_sl(PG_FUNCTION_ARGS)
  * even because of simple roundoff issues, there may not be a single closest
  * point.  We are likely to set the result to the second endpoint in these
  * cases.
+ * Returns Nan and stores {NaN,NaN} to result if NaN is involved,
  */
 static float8
 lseg_closept_line(Point *result, LSEG *lseg, LINE *line)
@@ -3022,6 +3235,14 @@ lseg_closept_line(Point *result, LSEG *lseg, LINE *line)
     }
     else
     {
+        /* return NaN if any of the two is NaN */
+        if (unlikely(isnan(dist1) || isnan(dist2)))
+        {
+            if (result != NULL)
+                result->x = result->y = get_float8_nan();
+            return get_float8_nan();
+        }
+
         if (result != NULL)
             *result = lseg->p[1];
 
@@ -3147,9 +3368,32 @@ close_lb(PG_FUNCTION_ARGS)
 static bool
 line_contain_point(LINE *line, Point *point)
 {
-    return FPzero(float8_pl(float8_pl(float8_mul(line->A, point->x),
-                                      float8_mul(line->B, point->y)),
-                            line->C));
+    /*
+     * Treat specially way the cases where A = 0 and B = 0, which we regard the
+     * line is perfectly horizontal and vertical correspondingly to avoid the
+     * normal formula based on the IEEE754's definitions yields unwanted NaNs.
+     */
+    if (line->A == 0.0)
+    {
+        /* the line is horizontal */
+        Assert(line->B != 0.0);
+
+        /* inf == inf here */
+        return FPeq(point->y, -line->C / line->B);
+    }
+    else if (line->B == 0.0)
+    {
+        /* the line is vertical */
+        Assert(line->A != 0.0);
+
+        /* inf == inf here */
+        return FPeq(point->x, -line->C / line->A);
+    }
+
+    return FPzero(float8_pl(
+                      float8_pl(float8_mul(line->A, point->x),
+                                float8_mul(line->B, point->y)),
+                      line->C));
 }
 
 Datum
@@ -3448,6 +3692,12 @@ make_bound_box(POLYGON *poly)
     y2 = y1 = poly->p[0].y;
     for (i = 1; i < poly->npts; i++)
     {
+        /* if NaN found, make an invalid boundbox */
+        if (unlikely(isnan(poly->p[i].x) || isnan(poly->p[i].y)))
+        {
+            x1 = x2 = y1 = y2 = get_float8_nan();
+            break;
+        }
         if (float8_lt(poly->p[i].x, x1))
             x1 = poly->p[i].x;
         if (float8_gt(poly->p[i].x, x2))
@@ -3923,6 +4173,11 @@ lseg_inside_poly(Point *a, Point *b, POLYGON *poly, int start)
     t.p[1] = *b;
     s.p[0] = poly->p[(start == 0) ? (poly->npts - 1) : (start - 1)];
 
+    /* Fast path. Check against boundbox. Also checks NaNs. */
+    if (!box_contain_point(&poly->boundbox, a) ||
+        !box_contain_point(&poly->boundbox, b))
+        return false;
+
     for (i = start; i < poly->npts && res; i++)
     {
         Point        interpt;
@@ -5362,6 +5617,10 @@ point_inside(Point *p, int npts, Point *plist)
     x0 = float8_mi(plist[0].x, p->x);
     y0 = float8_mi(plist[0].y, p->y);
 
+    /* NaN makes the point cannot be inside the polygon */
+    if (unlikely(isnan(x0) || isnan(y0) || isnan(p->x) || isnan(p->y)))
+        return 0;
+
     prev_x = x0;
     prev_y = y0;
     /* loop over polygon points and aggregate total_cross */
@@ -5371,6 +5630,10 @@ point_inside(Point *p, int npts, Point *plist)
         x = float8_mi(plist[i].x, p->x);
         y = float8_mi(plist[i].y, p->y);
 
+        /* NaN makes the point cannot be inside the polygon */
+        if (unlikely(isnan(x) || isnan(y)))
+            return 0;
+
         /* compute previous to current point crossing */
         if ((cross = lseg_crossing(x, y, prev_x, prev_y)) == POINT_ON_POLYGON)
             return 2;
diff --git a/src/include/utils/float.h b/src/include/utils/float.h
index 79bf8daca8..52bcf853f2 100644
--- a/src/include/utils/float.h
+++ b/src/include/utils/float.h
@@ -353,4 +353,26 @@ float8_max(const float8 val1, const float8 val2)
     return float8_gt(val1, val2) ? val1 : val2;
 }
 
+/*
+ * These two functions return NaN if either input is NaN, else the smaller
+ * of the two inputs.  This does NOT follow our usual sort rule, but it is
+ * convenient in some places.  (Note that float4_max and float8_max act this
+ * way anyway, so no similar variant is needed for them.)
+ */
+static inline float4
+float4_min_nan(const float4 val1, const float4 val2)
+{
+    return (isnan(val1) ? val1 :
+            (isnan(val2) ? val2 :
+             (val1 < val2 ? val1 : val2)));
+}
+
+static inline float8
+float8_min_nan(const float8 val1, const float8 val2)
+{
+    return (isnan(val1) ? val1 :
+            (isnan(val2) ? val2 :
+             (val1 < val2 ? val1 : val2)));
+}
+
 #endif                            /* FLOAT_H */
diff --git a/src/test/regress/expected/create_index.out b/src/test/regress/expected/create_index.out
index fc6afab58a..3605186c44 100644
--- a/src/test/regress/expected/create_index.out
+++ b/src/test/regress/expected/create_index.out
@@ -139,7 +139,7 @@ SELECT count(*) FROM point_tbl WHERE box '(0,0,100,100)' @> f1;
 SELECT count(*) FROM point_tbl WHERE f1 <@ polygon '(0,0),(0,100),(100,100),(50,50),(100,0),(0,0)';
  count 
 -------
-     5
+     4
 (1 row)
 
 SELECT count(*) FROM point_tbl WHERE f1 <@ circle '<(50,50),50>';
diff --git a/src/test/regress/expected/geometry.out b/src/test/regress/expected/geometry.out
index 84f7eabb66..1ae14c4d4b 100644
--- a/src/test/regress/expected/geometry.out
+++ b/src/test/regress/expected/geometry.out
@@ -517,7 +517,7 @@ SELECT p.f1, l.s, p.f1 <-> l.s AS dist_pl, l.s <-> p.f1 AS dist_lp FROM POINT_TB
  (-3,4)            | {0,3,0}                               |                  4 |                  4
  (-3,4)            | {1,-1,0}                              |      4.94974746831 |      4.94974746831
  (-3,4)            | {-0.4,-1,-6}                          |      8.17059487979 |      8.17059487979
- (-3,4)            | {-0.000184615384615,-1,15.3846153846} |      11.3851690368 |      11.3851690368
+ (-3,4)            | {-0.000184615384615,-1,15.3846153846} |      11.3851690367 |      11.3851690367
  (-3,4)            | {3,NaN,5}                             |                NaN |                NaN
  (-3,4)            | {NaN,NaN,NaN}                         |                NaN |                NaN
  (-3,4)            | {0,-1,3}                              |                  1 |                  1
@@ -537,7 +537,7 @@ SELECT p.f1, l.s, p.f1 <-> l.s AS dist_pl, l.s <-> p.f1 AS dist_lp FROM POINT_TB
  (-5,-12)          | {0,3,0}                               |                 12 |                 12
  (-5,-12)          | {1,-1,0}                              |      4.94974746831 |      4.94974746831
  (-5,-12)          | {-0.4,-1,-6}                          |      7.42781352708 |      7.42781352708
- (-5,-12)          | {-0.000184615384615,-1,15.3846153846} |      27.3855379948 |      27.3855379948
+ (-5,-12)          | {-0.000184615384615,-1,15.3846153846} |      27.3855379949 |      27.3855379949
  (-5,-12)          | {3,NaN,5}                             |                NaN |                NaN
  (-5,-12)          | {NaN,NaN,NaN}                         |                NaN |                NaN
  (-5,-12)          | {0,-1,3}                              |                 15 |                 15
@@ -553,7 +553,7 @@ SELECT p.f1, l.s, p.f1 <-> l.s AS dist_pl, l.s <-> p.f1 AS dist_lp FROM POINT_TB
  (1e-300,-1e-300)  | {0,-1,3}                              |                  3 |                  3
  (1e-300,-1e-300)  | {-1,0,3}                              |                  3 |                  3
  (1e+300,Infinity) | {0,-1,5}                              |           Infinity |           Infinity
- (1e+300,Infinity) | {1,0,5}                               |                NaN |                NaN
+ (1e+300,Infinity) | {1,0,5}                               |             1e+300 |             1e+300
  (1e+300,Infinity) | {0,3,0}                               |           Infinity |           Infinity
  (1e+300,Infinity) | {1,-1,0}                              |           Infinity |           Infinity
  (1e+300,Infinity) | {-0.4,-1,-6}                          |           Infinity |           Infinity
@@ -561,16 +561,16 @@ SELECT p.f1, l.s, p.f1 <-> l.s AS dist_pl, l.s <-> p.f1 AS dist_lp FROM POINT_TB
  (1e+300,Infinity) | {3,NaN,5}                             |                NaN |                NaN
  (1e+300,Infinity) | {NaN,NaN,NaN}                         |                NaN |                NaN
  (1e+300,Infinity) | {0,-1,3}                              |           Infinity |           Infinity
- (1e+300,Infinity) | {-1,0,3}                              |                NaN |                NaN
- (Infinity,1e+300) | {0,-1,5}                              |                NaN |                NaN
+ (1e+300,Infinity) | {-1,0,3}                              |             1e+300 |             1e+300
+ (Infinity,1e+300) | {0,-1,5}                              |             1e+300 |             1e+300
  (Infinity,1e+300) | {1,0,5}                               |           Infinity |           Infinity
- (Infinity,1e+300) | {0,3,0}                               |                NaN |                NaN
- (Infinity,1e+300) | {1,-1,0}                              |                NaN |                NaN
- (Infinity,1e+300) | {-0.4,-1,-6}                          |                NaN |                NaN
- (Infinity,1e+300) | {-0.000184615384615,-1,15.3846153846} |                NaN |                NaN
+ (Infinity,1e+300) | {0,3,0}                               |             1e+300 |             1e+300
+ (Infinity,1e+300) | {1,-1,0}                              |           Infinity |           Infinity
+ (Infinity,1e+300) | {-0.4,-1,-6}                          |           Infinity |           Infinity
+ (Infinity,1e+300) | {-0.000184615384615,-1,15.3846153846} |           Infinity |           Infinity
  (Infinity,1e+300) | {3,NaN,5}                             |                NaN |                NaN
  (Infinity,1e+300) | {NaN,NaN,NaN}                         |                NaN |                NaN
- (Infinity,1e+300) | {0,-1,3}                              |                NaN |                NaN
+ (Infinity,1e+300) | {0,-1,3}                              |             1e+300 |             1e+300
  (Infinity,1e+300) | {-1,0,3}                              |           Infinity |           Infinity
  (NaN,NaN)         | {0,-1,5}                              |                NaN |                NaN
  (NaN,NaN)         | {1,0,5}                               |                NaN |                NaN
@@ -587,7 +587,7 @@ SELECT p.f1, l.s, p.f1 <-> l.s AS dist_pl, l.s <-> p.f1 AS dist_lp FROM POINT_TB
  (10,10)           | {0,3,0}                               |                 10 |                 10
  (10,10)           | {1,-1,0}                              |                  0 |                  0
  (10,10)           | {-0.4,-1,-6}                          |      18.5695338177 |      18.5695338177
- (10,10)           | {-0.000184615384615,-1,15.3846153846} |      5.38276913903 |      5.38276913903
+ (10,10)           | {-0.000184615384615,-1,15.3846153846} |      5.38276913904 |      5.38276913904
  (10,10)           | {3,NaN,5}                             |                NaN |                NaN
  (10,10)           | {NaN,NaN,NaN}                         |                NaN |                NaN
  (10,10)           | {0,-1,3}                              |                  7 |                  7
@@ -653,7 +653,7 @@ SELECT p.f1, l.s, p.f1 <-> l.s AS dist_ps, l.s <-> p.f1 AS dist_sp FROM POINT_TB
  (1e+300,Infinity) | [(11,22),(33,44)]             |           Infinity |           Infinity
  (1e+300,Infinity) | [(-10,2),(-10,3)]             |           Infinity |           Infinity
  (1e+300,Infinity) | [(0,-20),(30,-20)]            |           Infinity |           Infinity
- (1e+300,Infinity) | [(NaN,1),(NaN,90)]            |           Infinity |           Infinity
+ (1e+300,Infinity) | [(NaN,1),(NaN,90)]            |                NaN |                NaN
  (Infinity,1e+300) | [(1,2),(3,4)]                 |           Infinity |           Infinity
  (Infinity,1e+300) | [(0,0),(6,6)]                 |           Infinity |           Infinity
  (Infinity,1e+300) | [(10,-10),(-3,-4)]            |           Infinity |           Infinity
@@ -892,13 +892,13 @@ SELECT p.f1, p1.f1, p.f1 <-> p1.f1 AS dist_ppoly, p1.f1 <-> p.f1 AS dist_polyp F
  (Infinity,1e+300) | ((1,2),(7,8),(5,6),(3,-4)) |      Infinity |      Infinity
  (Infinity,1e+300) | ((0,0))                    |      Infinity |      Infinity
  (Infinity,1e+300) | ((0,1),(0,1))              |      Infinity |      Infinity
- (NaN,NaN)         | ((2,0),(2,4),(0,0))        |             0 |             0
- (NaN,NaN)         | ((3,1),(3,3),(1,0))        |             0 |             0
- (NaN,NaN)         | ((1,2),(3,4),(5,6),(7,8))  |             0 |             0
- (NaN,NaN)         | ((7,8),(5,6),(3,4),(1,2))  |             0 |             0
- (NaN,NaN)         | ((1,2),(7,8),(5,6),(3,-4)) |             0 |             0
- (NaN,NaN)         | ((0,0))                    |             0 |             0
- (NaN,NaN)         | ((0,1),(0,1))              |             0 |             0
+ (NaN,NaN)         | ((2,0),(2,4),(0,0))        |           NaN |           NaN
+ (NaN,NaN)         | ((3,1),(3,3),(1,0))        |           NaN |           NaN
+ (NaN,NaN)         | ((1,2),(3,4),(5,6),(7,8))  |           NaN |           NaN
+ (NaN,NaN)         | ((7,8),(5,6),(3,4),(1,2))  |           NaN |           NaN
+ (NaN,NaN)         | ((1,2),(7,8),(5,6),(3,-4)) |           NaN |           NaN
+ (NaN,NaN)         | ((0,0))                    |           NaN |           NaN
+ (NaN,NaN)         | ((0,1),(0,1))              |           NaN |           NaN
  (10,10)           | ((2,0),(2,4),(0,0))        |            10 |            10
  (10,10)           | ((3,1),(3,3),(1,0))        | 9.89949493661 | 9.89949493661
  (10,10)           | ((1,2),(3,4),(5,6),(7,8))  | 3.60555127546 | 3.60555127546
@@ -919,7 +919,7 @@ SELECT p1.f1, p2.f1, line(p1.f1, p2.f1)
  (0,0)             | (-5,-12)          | {2.4,-1,0}
  (0,0)             | (1e+300,Infinity) | {-1,0,0}
  (0,0)             | (Infinity,1e+300) | {0,-1,0}
- (0,0)             | (NaN,NaN)         | {NaN,-1,NaN}
+ (0,0)             | (NaN,NaN)         | {NaN,NaN,NaN}
  (0,0)             | (10,10)           | {1,-1,0}
  (-10,0)           | (0,0)             | {0,-1,0}
  (-10,0)           | (-3,4)            | {0.571428571429,-1,5.71428571429}
@@ -928,7 +928,7 @@ SELECT p1.f1, p2.f1, line(p1.f1, p2.f1)
  (-10,0)           | (1e-300,-1e-300)  | {0,-1,0}
  (-10,0)           | (1e+300,Infinity) | {-1,0,-10}
  (-10,0)           | (Infinity,1e+300) | {0,-1,0}
- (-10,0)           | (NaN,NaN)         | {NaN,-1,NaN}
+ (-10,0)           | (NaN,NaN)         | {NaN,NaN,NaN}
  (-10,0)           | (10,10)           | {0.5,-1,5}
  (-3,4)            | (0,0)             | {-1.33333333333,-1,0}
  (-3,4)            | (-10,0)           | {0.571428571429,-1,5.71428571429}
@@ -937,7 +937,7 @@ SELECT p1.f1, p2.f1, line(p1.f1, p2.f1)
  (-3,4)            | (1e-300,-1e-300)  | {-1.33333333333,-1,0}
  (-3,4)            | (1e+300,Infinity) | {-1,0,-3}
  (-3,4)            | (Infinity,1e+300) | {0,-1,4}
- (-3,4)            | (NaN,NaN)         | {NaN,-1,NaN}
+ (-3,4)            | (NaN,NaN)         | {NaN,NaN,NaN}
  (-3,4)            | (10,10)           | {0.461538461538,-1,5.38461538462}
  (5.1,34.5)        | (0,0)             | {6.76470588235,-1,0}
  (5.1,34.5)        | (-10,0)           | {2.28476821192,-1,22.8476821192}
@@ -946,7 +946,7 @@ SELECT p1.f1, p2.f1, line(p1.f1, p2.f1)
  (5.1,34.5)        | (1e-300,-1e-300)  | {6.76470588235,-1,0}
  (5.1,34.5)        | (1e+300,Infinity) | {-1,0,5.1}
  (5.1,34.5)        | (Infinity,1e+300) | {0,-1,34.5}
- (5.1,34.5)        | (NaN,NaN)         | {NaN,-1,NaN}
+ (5.1,34.5)        | (NaN,NaN)         | {NaN,NaN,NaN}
  (5.1,34.5)        | (10,10)           | {-5,-1,60}
  (-5,-12)          | (0,0)             | {2.4,-1,0}
  (-5,-12)          | (-10,0)           | {-2.4,-1,-24}
@@ -955,7 +955,7 @@ SELECT p1.f1, p2.f1, line(p1.f1, p2.f1)
  (-5,-12)          | (1e-300,-1e-300)  | {2.4,-1,0}
  (-5,-12)          | (1e+300,Infinity) | {-1,0,-5}
  (-5,-12)          | (Infinity,1e+300) | {0,-1,-12}
- (-5,-12)          | (NaN,NaN)         | {NaN,-1,NaN}
+ (-5,-12)          | (NaN,NaN)         | {NaN,NaN,NaN}
  (-5,-12)          | (10,10)           | {1.46666666667,-1,-4.66666666667}
  (1e-300,-1e-300)  | (-10,0)           | {0,-1,-1e-300}
  (1e-300,-1e-300)  | (-3,4)            | {-1.33333333333,-1,3.33333333333e-301}
@@ -963,7 +963,7 @@ SELECT p1.f1, p2.f1, line(p1.f1, p2.f1)
  (1e-300,-1e-300)  | (-5,-12)          | {2.4,-1,-3.4e-300}
  (1e-300,-1e-300)  | (1e+300,Infinity) | {-1,0,1e-300}
  (1e-300,-1e-300)  | (Infinity,1e+300) | {0,-1,-1e-300}
- (1e-300,-1e-300)  | (NaN,NaN)         | {NaN,-1,NaN}
+ (1e-300,-1e-300)  | (NaN,NaN)         | {NaN,NaN,NaN}
  (1e-300,-1e-300)  | (10,10)           | {1,-1,-2e-300}
  (1e+300,Infinity) | (0,0)             | {-1,0,1e+300}
  (1e+300,Infinity) | (-10,0)           | {-1,0,1e+300}
@@ -971,8 +971,8 @@ SELECT p1.f1, p2.f1, line(p1.f1, p2.f1)
  (1e+300,Infinity) | (5.1,34.5)        | {-1,0,1e+300}
  (1e+300,Infinity) | (-5,-12)          | {-1,0,1e+300}
  (1e+300,Infinity) | (1e-300,-1e-300)  | {-1,0,1e+300}
- (1e+300,Infinity) | (Infinity,1e+300) | {NaN,-1,NaN}
- (1e+300,Infinity) | (NaN,NaN)         | {NaN,-1,NaN}
+ (1e+300,Infinity) | (Infinity,1e+300) | {NaN,NaN,NaN}
+ (1e+300,Infinity) | (NaN,NaN)         | {NaN,NaN,NaN}
  (1e+300,Infinity) | (10,10)           | {-1,0,1e+300}
  (Infinity,1e+300) | (0,0)             | {0,-1,1e+300}
  (Infinity,1e+300) | (-10,0)           | {0,-1,1e+300}
@@ -980,18 +980,18 @@ SELECT p1.f1, p2.f1, line(p1.f1, p2.f1)
  (Infinity,1e+300) | (5.1,34.5)        | {0,-1,1e+300}
  (Infinity,1e+300) | (-5,-12)          | {0,-1,1e+300}
  (Infinity,1e+300) | (1e-300,-1e-300)  | {0,-1,1e+300}
- (Infinity,1e+300) | (1e+300,Infinity) | {NaN,-1,NaN}
- (Infinity,1e+300) | (NaN,NaN)         | {NaN,-1,NaN}
+ (Infinity,1e+300) | (1e+300,Infinity) | {NaN,NaN,NaN}
+ (Infinity,1e+300) | (NaN,NaN)         | {NaN,NaN,NaN}
  (Infinity,1e+300) | (10,10)           | {0,-1,1e+300}
- (NaN,NaN)         | (0,0)             | {NaN,-1,NaN}
- (NaN,NaN)         | (-10,0)           | {NaN,-1,NaN}
- (NaN,NaN)         | (-3,4)            | {NaN,-1,NaN}
- (NaN,NaN)         | (5.1,34.5)        | {NaN,-1,NaN}
- (NaN,NaN)         | (-5,-12)          | {NaN,-1,NaN}
- (NaN,NaN)         | (1e-300,-1e-300)  | {NaN,-1,NaN}
- (NaN,NaN)         | (1e+300,Infinity) | {NaN,-1,NaN}
- (NaN,NaN)         | (Infinity,1e+300) | {NaN,-1,NaN}
- (NaN,NaN)         | (10,10)           | {NaN,-1,NaN}
+ (NaN,NaN)         | (0,0)             | {NaN,NaN,NaN}
+ (NaN,NaN)         | (-10,0)           | {NaN,NaN,NaN}
+ (NaN,NaN)         | (-3,4)            | {NaN,NaN,NaN}
+ (NaN,NaN)         | (5.1,34.5)        | {NaN,NaN,NaN}
+ (NaN,NaN)         | (-5,-12)          | {NaN,NaN,NaN}
+ (NaN,NaN)         | (1e-300,-1e-300)  | {NaN,NaN,NaN}
+ (NaN,NaN)         | (1e+300,Infinity) | {NaN,NaN,NaN}
+ (NaN,NaN)         | (Infinity,1e+300) | {NaN,NaN,NaN}
+ (NaN,NaN)         | (10,10)           | {NaN,NaN,NaN}
  (10,10)           | (0,0)             | {1,-1,0}
  (10,10)           | (-10,0)           | {0.5,-1,5}
  (10,10)           | (-3,4)            | {0.461538461538,-1,5.38461538462}
@@ -1000,7 +1000,7 @@ SELECT p1.f1, p2.f1, line(p1.f1, p2.f1)
  (10,10)           | (1e-300,-1e-300)  | {1,-1,0}
  (10,10)           | (1e+300,Infinity) | {-1,0,10}
  (10,10)           | (Infinity,1e+300) | {0,-1,10}
- (10,10)           | (NaN,NaN)         | {NaN,-1,NaN}
+ (10,10)           | (NaN,NaN)         | {NaN,NaN,NaN}
 (88 rows)
 
 -- Closest point to line
@@ -1068,24 +1068,24 @@ SELECT p.f1, l.s, p.f1 ## l.s FROM POINT_TBL p, LINE_TBL l;
  (1e-300,-1e-300)  | {0,-1,3}                              | (1e-300,3)
  (1e-300,-1e-300)  | {-1,0,3}                              | (3,-1e-300)
  (1e+300,Infinity) | {0,-1,5}                              | (1e+300,5)
- (1e+300,Infinity) | {1,0,5}                               | 
+ (1e+300,Infinity) | {1,0,5}                               | (-5,Infinity)
  (1e+300,Infinity) | {0,3,0}                               | (1e+300,0)
- (1e+300,Infinity) | {1,-1,0}                              | (Infinity,NaN)
- (1e+300,Infinity) | {-0.4,-1,-6}                          | (-Infinity,NaN)
- (1e+300,Infinity) | {-0.000184615384615,-1,15.3846153846} | (-Infinity,NaN)
+ (1e+300,Infinity) | {1,-1,0}                              | (Infinity,Infinity)
+ (1e+300,Infinity) | {-0.4,-1,-6}                          | (-Infinity,Infinity)
+ (1e+300,Infinity) | {-0.000184615384615,-1,15.3846153846} | (-Infinity,Infinity)
  (1e+300,Infinity) | {3,NaN,5}                             | 
  (1e+300,Infinity) | {NaN,NaN,NaN}                         | 
  (1e+300,Infinity) | {0,-1,3}                              | (1e+300,3)
- (1e+300,Infinity) | {-1,0,3}                              | 
- (Infinity,1e+300) | {0,-1,5}                              | 
+ (1e+300,Infinity) | {-1,0,3}                              | (3,Infinity)
+ (Infinity,1e+300) | {0,-1,5}                              | (Infinity,5)
  (Infinity,1e+300) | {1,0,5}                               | (-5,1e+300)
- (Infinity,1e+300) | {0,3,0}                               | 
- (Infinity,1e+300) | {1,-1,0}                              | 
- (Infinity,1e+300) | {-0.4,-1,-6}                          | 
- (Infinity,1e+300) | {-0.000184615384615,-1,15.3846153846} | 
+ (Infinity,1e+300) | {0,3,0}                               | (Infinity,0)
+ (Infinity,1e+300) | {1,-1,0}                              | (Infinity,Infinity)
+ (Infinity,1e+300) | {-0.4,-1,-6}                          | (Infinity,-Infinity)
+ (Infinity,1e+300) | {-0.000184615384615,-1,15.3846153846} | (Infinity,-Infinity)
  (Infinity,1e+300) | {3,NaN,5}                             | 
  (Infinity,1e+300) | {NaN,NaN,NaN}                         | 
- (Infinity,1e+300) | {0,-1,3}                              | 
+ (Infinity,1e+300) | {0,-1,3}                              | (Infinity,3)
  (Infinity,1e+300) | {-1,0,3}                              | (3,1e+300)
  (NaN,NaN)         | {0,-1,5}                              | 
  (NaN,NaN)         | {1,0,5}                               | 
@@ -1168,7 +1168,7 @@ SELECT p.f1, l.s, p.f1 ## l.s FROM POINT_TBL p, LSEG_TBL l;
  (1e+300,Infinity) | [(11,22),(33,44)]             | (33,44)
  (1e+300,Infinity) | [(-10,2),(-10,3)]             | (-10,3)
  (1e+300,Infinity) | [(0,-20),(30,-20)]            | (30,-20)
- (1e+300,Infinity) | [(NaN,1),(NaN,90)]            | (NaN,90)
+ (1e+300,Infinity) | [(NaN,1),(NaN,90)]            | 
  (Infinity,1e+300) | [(1,2),(3,4)]                 | (3,4)
  (Infinity,1e+300) | [(0,0),(6,6)]                 | (6,6)
  (Infinity,1e+300) | [(10,-10),(-3,-4)]            | (-3,-4)
@@ -1278,12 +1278,7 @@ SELECT p.f1, p1.f1 FROM POINT_TBL p, PATH_TBL p1 WHERE p.f1 <@ p1.f1;
 ------------------+---------------------------
  (0,0)            | [(0,0),(3,0),(4,5),(1,6)]
  (1e-300,-1e-300) | [(0,0),(3,0),(4,5),(1,6)]
- (NaN,NaN)        | ((1,2),(3,4))
- (NaN,NaN)        | ((1,2),(3,4))
- (NaN,NaN)        | ((1,2),(3,4))
- (NaN,NaN)        | ((10,20))
- (NaN,NaN)        | ((11,12),(13,14))
-(7 rows)
+(2 rows)
 
 --
 -- Lines
@@ -1371,8 +1366,8 @@ SELECT l1.s, l2.s, l1.s <-> l2.s FROM LINE_TBL l1, LINE_TBL l2;
  {0,-1,5}                              | {1,-1,0}                              |        0
  {0,-1,5}                              | {-0.4,-1,-6}                          |        0
  {0,-1,5}                              | {-0.000184615384615,-1,15.3846153846} |        0
- {0,-1,5}                              | {3,NaN,5}                             |        0
- {0,-1,5}                              | {NaN,NaN,NaN}                         |        0
+ {0,-1,5}                              | {3,NaN,5}                             |      NaN
+ {0,-1,5}                              | {NaN,NaN,NaN}                         |      NaN
  {0,-1,5}                              | {0,-1,3}                              |        2
  {0,-1,5}                              | {-1,0,3}                              |        0
  {1,0,5}                               | {0,-1,5}                              |        0
@@ -1381,8 +1376,8 @@ SELECT l1.s, l2.s, l1.s <-> l2.s FROM LINE_TBL l1, LINE_TBL l2;
  {1,0,5}                               | {1,-1,0}                              |        0
  {1,0,5}                               | {-0.4,-1,-6}                          |        0
  {1,0,5}                               | {-0.000184615384615,-1,15.3846153846} |        0
- {1,0,5}                               | {3,NaN,5}                             |        0
- {1,0,5}                               | {NaN,NaN,NaN}                         |        0
+ {1,0,5}                               | {3,NaN,5}                             |      NaN
+ {1,0,5}                               | {NaN,NaN,NaN}                         |      NaN
  {1,0,5}                               | {0,-1,3}                              |        0
  {1,0,5}                               | {-1,0,3}                              |        8
  {0,3,0}                               | {0,-1,5}                              |        5
@@ -1391,8 +1386,8 @@ SELECT l1.s, l2.s, l1.s <-> l2.s FROM LINE_TBL l1, LINE_TBL l2;
  {0,3,0}                               | {1,-1,0}                              |        0
  {0,3,0}                               | {-0.4,-1,-6}                          |        0
  {0,3,0}                               | {-0.000184615384615,-1,15.3846153846} |        0
- {0,3,0}                               | {3,NaN,5}                             |        0
- {0,3,0}                               | {NaN,NaN,NaN}                         |        0
+ {0,3,0}                               | {3,NaN,5}                             |      NaN
+ {0,3,0}                               | {NaN,NaN,NaN}                         |      NaN
  {0,3,0}                               | {0,-1,3}                              |        3
  {0,3,0}                               | {-1,0,3}                              |        0
  {1,-1,0}                              | {0,-1,5}                              |        0
@@ -1401,8 +1396,8 @@ SELECT l1.s, l2.s, l1.s <-> l2.s FROM LINE_TBL l1, LINE_TBL l2;
  {1,-1,0}                              | {1,-1,0}                              |        0
  {1,-1,0}                              | {-0.4,-1,-6}                          |        0
  {1,-1,0}                              | {-0.000184615384615,-1,15.3846153846} |        0
- {1,-1,0}                              | {3,NaN,5}                             |        0
- {1,-1,0}                              | {NaN,NaN,NaN}                         |        0
+ {1,-1,0}                              | {3,NaN,5}                             |      NaN
+ {1,-1,0}                              | {NaN,NaN,NaN}                         |      NaN
  {1,-1,0}                              | {0,-1,3}                              |        0
  {1,-1,0}                              | {-1,0,3}                              |        0
  {-0.4,-1,-6}                          | {0,-1,5}                              |        0
@@ -1411,8 +1406,8 @@ SELECT l1.s, l2.s, l1.s <-> l2.s FROM LINE_TBL l1, LINE_TBL l2;
  {-0.4,-1,-6}                          | {1,-1,0}                              |        0
  {-0.4,-1,-6}                          | {-0.4,-1,-6}                          |        0
  {-0.4,-1,-6}                          | {-0.000184615384615,-1,15.3846153846} |        0
- {-0.4,-1,-6}                          | {3,NaN,5}                             |        0
- {-0.4,-1,-6}                          | {NaN,NaN,NaN}                         |        0
+ {-0.4,-1,-6}                          | {3,NaN,5}                             |      NaN
+ {-0.4,-1,-6}                          | {NaN,NaN,NaN}                         |      NaN
  {-0.4,-1,-6}                          | {0,-1,3}                              |        0
  {-0.4,-1,-6}                          | {-1,0,3}                              |        0
  {-0.000184615384615,-1,15.3846153846} | {0,-1,5}                              |        0
@@ -1421,38 +1416,38 @@ SELECT l1.s, l2.s, l1.s <-> l2.s FROM LINE_TBL l1, LINE_TBL l2;
  {-0.000184615384615,-1,15.3846153846} | {1,-1,0}                              |        0
  {-0.000184615384615,-1,15.3846153846} | {-0.4,-1,-6}                          |        0
  {-0.000184615384615,-1,15.3846153846} | {-0.000184615384615,-1,15.3846153846} |        0
- {-0.000184615384615,-1,15.3846153846} | {3,NaN,5}                             |        0
- {-0.000184615384615,-1,15.3846153846} | {NaN,NaN,NaN}                         |        0
+ {-0.000184615384615,-1,15.3846153846} | {3,NaN,5}                             |      NaN
+ {-0.000184615384615,-1,15.3846153846} | {NaN,NaN,NaN}                         |      NaN
  {-0.000184615384615,-1,15.3846153846} | {0,-1,3}                              |        0
  {-0.000184615384615,-1,15.3846153846} | {-1,0,3}                              |        0
- {3,NaN,5}                             | {0,-1,5}                              |        0
- {3,NaN,5}                             | {1,0,5}                               |        0
- {3,NaN,5}                             | {0,3,0}                               |        0
- {3,NaN,5}                             | {1,-1,0}                              |        0
- {3,NaN,5}                             | {-0.4,-1,-6}                          |        0
- {3,NaN,5}                             | {-0.000184615384615,-1,15.3846153846} |        0
- {3,NaN,5}                             | {3,NaN,5}                             |        0
- {3,NaN,5}                             | {NaN,NaN,NaN}                         |        0
- {3,NaN,5}                             | {0,-1,3}                              |        0
- {3,NaN,5}                             | {-1,0,3}                              |        0
- {NaN,NaN,NaN}                         | {0,-1,5}                              |        0
- {NaN,NaN,NaN}                         | {1,0,5}                               |        0
- {NaN,NaN,NaN}                         | {0,3,0}                               |        0
- {NaN,NaN,NaN}                         | {1,-1,0}                              |        0
- {NaN,NaN,NaN}                         | {-0.4,-1,-6}                          |        0
- {NaN,NaN,NaN}                         | {-0.000184615384615,-1,15.3846153846} |        0
- {NaN,NaN,NaN}                         | {3,NaN,5}                             |        0
- {NaN,NaN,NaN}                         | {NaN,NaN,NaN}                         |        0
- {NaN,NaN,NaN}                         | {0,-1,3}                              |        0
- {NaN,NaN,NaN}                         | {-1,0,3}                              |        0
+ {3,NaN,5}                             | {0,-1,5}                              |      NaN
+ {3,NaN,5}                             | {1,0,5}                               |      NaN
+ {3,NaN,5}                             | {0,3,0}                               |      NaN
+ {3,NaN,5}                             | {1,-1,0}                              |      NaN
+ {3,NaN,5}                             | {-0.4,-1,-6}                          |      NaN
+ {3,NaN,5}                             | {-0.000184615384615,-1,15.3846153846} |      NaN
+ {3,NaN,5}                             | {3,NaN,5}                             |      NaN
+ {3,NaN,5}                             | {NaN,NaN,NaN}                         |      NaN
+ {3,NaN,5}                             | {0,-1,3}                              |      NaN
+ {3,NaN,5}                             | {-1,0,3}                              |      NaN
+ {NaN,NaN,NaN}                         | {0,-1,5}                              |      NaN
+ {NaN,NaN,NaN}                         | {1,0,5}                               |      NaN
+ {NaN,NaN,NaN}                         | {0,3,0}                               |      NaN
+ {NaN,NaN,NaN}                         | {1,-1,0}                              |      NaN
+ {NaN,NaN,NaN}                         | {-0.4,-1,-6}                          |      NaN
+ {NaN,NaN,NaN}                         | {-0.000184615384615,-1,15.3846153846} |      NaN
+ {NaN,NaN,NaN}                         | {3,NaN,5}                             |      NaN
+ {NaN,NaN,NaN}                         | {NaN,NaN,NaN}                         |      NaN
+ {NaN,NaN,NaN}                         | {0,-1,3}                              |      NaN
+ {NaN,NaN,NaN}                         | {-1,0,3}                              |      NaN
  {0,-1,3}                              | {0,-1,5}                              |        2
  {0,-1,3}                              | {1,0,5}                               |        0
  {0,-1,3}                              | {0,3,0}                               |        3
  {0,-1,3}                              | {1,-1,0}                              |        0
  {0,-1,3}                              | {-0.4,-1,-6}                          |        0
  {0,-1,3}                              | {-0.000184615384615,-1,15.3846153846} |        0
- {0,-1,3}                              | {3,NaN,5}                             |        0
- {0,-1,3}                              | {NaN,NaN,NaN}                         |        0
+ {0,-1,3}                              | {3,NaN,5}                             |      NaN
+ {0,-1,3}                              | {NaN,NaN,NaN}                         |      NaN
  {0,-1,3}                              | {0,-1,3}                              |        0
  {0,-1,3}                              | {-1,0,3}                              |        0
  {-1,0,3}                              | {0,-1,5}                              |        0
@@ -1461,8 +1456,8 @@ SELECT l1.s, l2.s, l1.s <-> l2.s FROM LINE_TBL l1, LINE_TBL l2;
  {-1,0,3}                              | {1,-1,0}                              |        0
  {-1,0,3}                              | {-0.4,-1,-6}                          |        0
  {-1,0,3}                              | {-0.000184615384615,-1,15.3846153846} |        0
- {-1,0,3}                              | {3,NaN,5}                             |        0
- {-1,0,3}                              | {NaN,NaN,NaN}                         |        0
+ {-1,0,3}                              | {3,NaN,5}                             |      NaN
+ {-1,0,3}                              | {NaN,NaN,NaN}                         |      NaN
  {-1,0,3}                              | {0,-1,3}                              |        0
  {-1,0,3}                              | {-1,0,3}                              |        0
 (100 rows)
@@ -1480,31 +1475,23 @@ SELECT l1.s, l2.s FROM LINE_TBL l1, LINE_TBL l2 WHERE l1.s ?# l2.s;
  {0,-1,5}                              | {1,-1,0}
  {0,-1,5}                              | {-0.4,-1,-6}
  {0,-1,5}                              | {-0.000184615384615,-1,15.3846153846}
- {0,-1,5}                              | {3,NaN,5}
- {0,-1,5}                              | {NaN,NaN,NaN}
  {0,-1,5}                              | {-1,0,3}
  {1,0,5}                               | {0,-1,5}
  {1,0,5}                               | {0,3,0}
  {1,0,5}                               | {1,-1,0}
  {1,0,5}                               | {-0.4,-1,-6}
  {1,0,5}                               | {-0.000184615384615,-1,15.3846153846}
- {1,0,5}                               | {3,NaN,5}
- {1,0,5}                               | {NaN,NaN,NaN}
  {1,0,5}                               | {0,-1,3}
  {0,3,0}                               | {1,0,5}
  {0,3,0}                               | {1,-1,0}
  {0,3,0}                               | {-0.4,-1,-6}
  {0,3,0}                               | {-0.000184615384615,-1,15.3846153846}
- {0,3,0}                               | {3,NaN,5}
- {0,3,0}                               | {NaN,NaN,NaN}
  {0,3,0}                               | {-1,0,3}
  {1,-1,0}                              | {0,-1,5}
  {1,-1,0}                              | {1,0,5}
  {1,-1,0}                              | {0,3,0}
  {1,-1,0}                              | {-0.4,-1,-6}
  {1,-1,0}                              | {-0.000184615384615,-1,15.3846153846}
- {1,-1,0}                              | {3,NaN,5}
- {1,-1,0}                              | {NaN,NaN,NaN}
  {1,-1,0}                              | {0,-1,3}
  {1,-1,0}                              | {-1,0,3}
  {-0.4,-1,-6}                          | {0,-1,5}
@@ -1512,8 +1499,6 @@ SELECT l1.s, l2.s FROM LINE_TBL l1, LINE_TBL l2 WHERE l1.s ?# l2.s;
  {-0.4,-1,-6}                          | {0,3,0}
  {-0.4,-1,-6}                          | {1,-1,0}
  {-0.4,-1,-6}                          | {-0.000184615384615,-1,15.3846153846}
- {-0.4,-1,-6}                          | {3,NaN,5}
- {-0.4,-1,-6}                          | {NaN,NaN,NaN}
  {-0.4,-1,-6}                          | {0,-1,3}
  {-0.4,-1,-6}                          | {-1,0,3}
  {-0.000184615384615,-1,15.3846153846} | {0,-1,5}
@@ -1521,46 +1506,20 @@ SELECT l1.s, l2.s FROM LINE_TBL l1, LINE_TBL l2 WHERE l1.s ?# l2.s;
  {-0.000184615384615,-1,15.3846153846} | {0,3,0}
  {-0.000184615384615,-1,15.3846153846} | {1,-1,0}
  {-0.000184615384615,-1,15.3846153846} | {-0.4,-1,-6}
- {-0.000184615384615,-1,15.3846153846} | {3,NaN,5}
- {-0.000184615384615,-1,15.3846153846} | {NaN,NaN,NaN}
  {-0.000184615384615,-1,15.3846153846} | {0,-1,3}
  {-0.000184615384615,-1,15.3846153846} | {-1,0,3}
- {3,NaN,5}                             | {0,-1,5}
- {3,NaN,5}                             | {1,0,5}
- {3,NaN,5}                             | {0,3,0}
- {3,NaN,5}                             | {1,-1,0}
- {3,NaN,5}                             | {-0.4,-1,-6}
- {3,NaN,5}                             | {-0.000184615384615,-1,15.3846153846}
- {3,NaN,5}                             | {3,NaN,5}
- {3,NaN,5}                             | {NaN,NaN,NaN}
- {3,NaN,5}                             | {0,-1,3}
- {3,NaN,5}                             | {-1,0,3}
- {NaN,NaN,NaN}                         | {0,-1,5}
- {NaN,NaN,NaN}                         | {1,0,5}
- {NaN,NaN,NaN}                         | {0,3,0}
- {NaN,NaN,NaN}                         | {1,-1,0}
- {NaN,NaN,NaN}                         | {-0.4,-1,-6}
- {NaN,NaN,NaN}                         | {-0.000184615384615,-1,15.3846153846}
- {NaN,NaN,NaN}                         | {3,NaN,5}
- {NaN,NaN,NaN}                         | {NaN,NaN,NaN}
- {NaN,NaN,NaN}                         | {0,-1,3}
- {NaN,NaN,NaN}                         | {-1,0,3}
  {0,-1,3}                              | {1,0,5}
  {0,-1,3}                              | {1,-1,0}
  {0,-1,3}                              | {-0.4,-1,-6}
  {0,-1,3}                              | {-0.000184615384615,-1,15.3846153846}
- {0,-1,3}                              | {3,NaN,5}
- {0,-1,3}                              | {NaN,NaN,NaN}
  {0,-1,3}                              | {-1,0,3}
  {-1,0,3}                              | {0,-1,5}
  {-1,0,3}                              | {0,3,0}
  {-1,0,3}                              | {1,-1,0}
  {-1,0,3}                              | {-0.4,-1,-6}
  {-1,0,3}                              | {-0.000184615384615,-1,15.3846153846}
- {-1,0,3}                              | {3,NaN,5}
- {-1,0,3}                              | {NaN,NaN,NaN}
  {-1,0,3}                              | {0,-1,3}
-(84 rows)
+(48 rows)
 
 -- Intersect with box
 SELECT l.s, b.f1 FROM LINE_TBL l, BOX_TBL b WHERE l.s ?# b.f1;
@@ -1583,16 +1542,16 @@ SELECT l.s, b.f1 FROM LINE_TBL l, BOX_TBL b WHERE l.s ?# b.f1;
 
 -- Intersection point with line
 SELECT l1.s, l2.s, l1.s # l2.s FROM LINE_TBL l1, LINE_TBL l2;
-                   s                   |                   s                   |             ?column?              
----------------------------------------+---------------------------------------+-----------------------------------
+                   s                   |                   s                   |            ?column?             
+---------------------------------------+---------------------------------------+---------------------------------
  {0,-1,5}                              | {0,-1,5}                              | 
  {0,-1,5}                              | {1,0,5}                               | (-5,5)
  {0,-1,5}                              | {0,3,0}                               | 
  {0,-1,5}                              | {1,-1,0}                              | (5,5)
  {0,-1,5}                              | {-0.4,-1,-6}                          | (-27.5,5)
  {0,-1,5}                              | {-0.000184615384615,-1,15.3846153846} | (56250,5)
- {0,-1,5}                              | {3,NaN,5}                             | (NaN,NaN)
- {0,-1,5}                              | {NaN,NaN,NaN}                         | (NaN,NaN)
+ {0,-1,5}                              | {3,NaN,5}                             | 
+ {0,-1,5}                              | {NaN,NaN,NaN}                         | 
  {0,-1,5}                              | {0,-1,3}                              | 
  {0,-1,5}                              | {-1,0,3}                              | (3,5)
  {1,0,5}                               | {0,-1,5}                              | (-5,5)
@@ -1601,8 +1560,8 @@ SELECT l1.s, l2.s, l1.s # l2.s FROM LINE_TBL l1, LINE_TBL l2;
  {1,0,5}                               | {1,-1,0}                              | (-5,-5)
  {1,0,5}                               | {-0.4,-1,-6}                          | (-5,-4)
  {1,0,5}                               | {-0.000184615384615,-1,15.3846153846} | (-5,15.3855384615)
- {1,0,5}                               | {3,NaN,5}                             | (NaN,NaN)
- {1,0,5}                               | {NaN,NaN,NaN}                         | (NaN,NaN)
+ {1,0,5}                               | {3,NaN,5}                             | 
+ {1,0,5}                               | {NaN,NaN,NaN}                         | 
  {1,0,5}                               | {0,-1,3}                              | (-5,3)
  {1,0,5}                               | {-1,0,3}                              | 
  {0,3,0}                               | {0,-1,5}                              | 
@@ -1611,8 +1570,8 @@ SELECT l1.s, l2.s, l1.s # l2.s FROM LINE_TBL l1, LINE_TBL l2;
  {0,3,0}                               | {1,-1,0}                              | (0,0)
  {0,3,0}                               | {-0.4,-1,-6}                          | (-15,0)
  {0,3,0}                               | {-0.000184615384615,-1,15.3846153846} | (83333.3333333,0)
- {0,3,0}                               | {3,NaN,5}                             | (NaN,NaN)
- {0,3,0}                               | {NaN,NaN,NaN}                         | (NaN,NaN)
+ {0,3,0}                               | {3,NaN,5}                             | 
+ {0,3,0}                               | {NaN,NaN,NaN}                         | 
  {0,3,0}                               | {0,-1,3}                              | 
  {0,3,0}                               | {-1,0,3}                              | (3,0)
  {1,-1,0}                              | {0,-1,5}                              | (5,5)
@@ -1621,8 +1580,8 @@ SELECT l1.s, l2.s, l1.s # l2.s FROM LINE_TBL l1, LINE_TBL l2;
  {1,-1,0}                              | {1,-1,0}                              | 
  {1,-1,0}                              | {-0.4,-1,-6}                          | (-4.28571428571,-4.28571428571)
  {1,-1,0}                              | {-0.000184615384615,-1,15.3846153846} | (15.3817756722,15.3817756722)
- {1,-1,0}                              | {3,NaN,5}                             | (NaN,NaN)
- {1,-1,0}                              | {NaN,NaN,NaN}                         | (NaN,NaN)
+ {1,-1,0}                              | {3,NaN,5}                             | 
+ {1,-1,0}                              | {NaN,NaN,NaN}                         | 
  {1,-1,0}                              | {0,-1,3}                              | (3,3)
  {1,-1,0}                              | {-1,0,3}                              | (3,3)
  {-0.4,-1,-6}                          | {0,-1,5}                              | (-27.5,5)
@@ -1631,48 +1590,48 @@ SELECT l1.s, l2.s, l1.s # l2.s FROM LINE_TBL l1, LINE_TBL l2;
  {-0.4,-1,-6}                          | {1,-1,0}                              | (-4.28571428571,-4.28571428571)
  {-0.4,-1,-6}                          | {-0.4,-1,-6}                          | 
  {-0.4,-1,-6}                          | {-0.000184615384615,-1,15.3846153846} | (-53.4862244113,15.3944897645)
- {-0.4,-1,-6}                          | {3,NaN,5}                             | (NaN,NaN)
- {-0.4,-1,-6}                          | {NaN,NaN,NaN}                         | (NaN,NaN)
+ {-0.4,-1,-6}                          | {3,NaN,5}                             | 
+ {-0.4,-1,-6}                          | {NaN,NaN,NaN}                         | 
  {-0.4,-1,-6}                          | {0,-1,3}                              | (-22.5,3)
  {-0.4,-1,-6}                          | {-1,0,3}                              | (3,-7.2)
  {-0.000184615384615,-1,15.3846153846} | {0,-1,5}                              | (56250,5)
  {-0.000184615384615,-1,15.3846153846} | {1,0,5}                               | (-5,15.3855384615)
- {-0.000184615384615,-1,15.3846153846} | {0,3,0}                               | (83333.3333333,-1.7763568394e-15)
+ {-0.000184615384615,-1,15.3846153846} | {0,3,0}                               | (83333.3333333,0)
  {-0.000184615384615,-1,15.3846153846} | {1,-1,0}                              | (15.3817756722,15.3817756722)
  {-0.000184615384615,-1,15.3846153846} | {-0.4,-1,-6}                          | (-53.4862244113,15.3944897645)
  {-0.000184615384615,-1,15.3846153846} | {-0.000184615384615,-1,15.3846153846} | 
- {-0.000184615384615,-1,15.3846153846} | {3,NaN,5}                             | (NaN,NaN)
- {-0.000184615384615,-1,15.3846153846} | {NaN,NaN,NaN}                         | (NaN,NaN)
+ {-0.000184615384615,-1,15.3846153846} | {3,NaN,5}                             | 
+ {-0.000184615384615,-1,15.3846153846} | {NaN,NaN,NaN}                         | 
  {-0.000184615384615,-1,15.3846153846} | {0,-1,3}                              | (67083.3333333,3)
  {-0.000184615384615,-1,15.3846153846} | {-1,0,3}                              | (3,15.3840615385)
- {3,NaN,5}                             | {0,-1,5}                              | (NaN,NaN)
- {3,NaN,5}                             | {1,0,5}                               | (NaN,NaN)
- {3,NaN,5}                             | {0,3,0}                               | (NaN,NaN)
- {3,NaN,5}                             | {1,-1,0}                              | (NaN,NaN)
- {3,NaN,5}                             | {-0.4,-1,-6}                          | (NaN,NaN)
- {3,NaN,5}                             | {-0.000184615384615,-1,15.3846153846} | (NaN,NaN)
- {3,NaN,5}                             | {3,NaN,5}                             | (NaN,NaN)
- {3,NaN,5}                             | {NaN,NaN,NaN}                         | (NaN,NaN)
- {3,NaN,5}                             | {0,-1,3}                              | (NaN,NaN)
- {3,NaN,5}                             | {-1,0,3}                              | (NaN,NaN)
- {NaN,NaN,NaN}                         | {0,-1,5}                              | (NaN,NaN)
- {NaN,NaN,NaN}                         | {1,0,5}                               | (NaN,NaN)
- {NaN,NaN,NaN}                         | {0,3,0}                               | (NaN,NaN)
- {NaN,NaN,NaN}                         | {1,-1,0}                              | (NaN,NaN)
- {NaN,NaN,NaN}                         | {-0.4,-1,-6}                          | (NaN,NaN)
- {NaN,NaN,NaN}                         | {-0.000184615384615,-1,15.3846153846} | (NaN,NaN)
- {NaN,NaN,NaN}                         | {3,NaN,5}                             | (NaN,NaN)
- {NaN,NaN,NaN}                         | {NaN,NaN,NaN}                         | (NaN,NaN)
- {NaN,NaN,NaN}                         | {0,-1,3}                              | (NaN,NaN)
- {NaN,NaN,NaN}                         | {-1,0,3}                              | (NaN,NaN)
+ {3,NaN,5}                             | {0,-1,5}                              | 
+ {3,NaN,5}                             | {1,0,5}                               | 
+ {3,NaN,5}                             | {0,3,0}                               | 
+ {3,NaN,5}                             | {1,-1,0}                              | 
+ {3,NaN,5}                             | {-0.4,-1,-6}                          | 
+ {3,NaN,5}                             | {-0.000184615384615,-1,15.3846153846} | 
+ {3,NaN,5}                             | {3,NaN,5}                             | 
+ {3,NaN,5}                             | {NaN,NaN,NaN}                         | 
+ {3,NaN,5}                             | {0,-1,3}                              | 
+ {3,NaN,5}                             | {-1,0,3}                              | 
+ {NaN,NaN,NaN}                         | {0,-1,5}                              | 
+ {NaN,NaN,NaN}                         | {1,0,5}                               | 
+ {NaN,NaN,NaN}                         | {0,3,0}                               | 
+ {NaN,NaN,NaN}                         | {1,-1,0}                              | 
+ {NaN,NaN,NaN}                         | {-0.4,-1,-6}                          | 
+ {NaN,NaN,NaN}                         | {-0.000184615384615,-1,15.3846153846} | 
+ {NaN,NaN,NaN}                         | {3,NaN,5}                             | 
+ {NaN,NaN,NaN}                         | {NaN,NaN,NaN}                         | 
+ {NaN,NaN,NaN}                         | {0,-1,3}                              | 
+ {NaN,NaN,NaN}                         | {-1,0,3}                              | 
  {0,-1,3}                              | {0,-1,5}                              | 
  {0,-1,3}                              | {1,0,5}                               | (-5,3)
  {0,-1,3}                              | {0,3,0}                               | 
  {0,-1,3}                              | {1,-1,0}                              | (3,3)
  {0,-1,3}                              | {-0.4,-1,-6}                          | (-22.5,3)
  {0,-1,3}                              | {-0.000184615384615,-1,15.3846153846} | (67083.3333333,3)
- {0,-1,3}                              | {3,NaN,5}                             | (NaN,NaN)
- {0,-1,3}                              | {NaN,NaN,NaN}                         | (NaN,NaN)
+ {0,-1,3}                              | {3,NaN,5}                             | 
+ {0,-1,3}                              | {NaN,NaN,NaN}                         | 
  {0,-1,3}                              | {0,-1,3}                              | 
  {0,-1,3}                              | {-1,0,3}                              | (3,3)
  {-1,0,3}                              | {0,-1,5}                              | (3,5)
@@ -1681,16 +1640,16 @@ SELECT l1.s, l2.s, l1.s # l2.s FROM LINE_TBL l1, LINE_TBL l2;
  {-1,0,3}                              | {1,-1,0}                              | (3,3)
  {-1,0,3}                              | {-0.4,-1,-6}                          | (3,-7.2)
  {-1,0,3}                              | {-0.000184615384615,-1,15.3846153846} | (3,15.3840615385)
- {-1,0,3}                              | {3,NaN,5}                             | (NaN,NaN)
- {-1,0,3}                              | {NaN,NaN,NaN}                         | (NaN,NaN)
+ {-1,0,3}                              | {3,NaN,5}                             | 
+ {-1,0,3}                              | {NaN,NaN,NaN}                         | 
  {-1,0,3}                              | {0,-1,3}                              | (3,3)
  {-1,0,3}                              | {-1,0,3}                              | 
 (100 rows)
 
 -- Closest point to line segment
 SELECT l.s, l1.s, l.s ## l1.s FROM LINE_TBL l, LSEG_TBL l1;
-                   s                   |               s               |             ?column?              
----------------------------------------+-------------------------------+-----------------------------------
+                   s                   |               s               |            ?column?            
+---------------------------------------+-------------------------------+--------------------------------
  {0,-1,5}                              | [(1,2),(3,4)]                 | (3,4)
  {0,-1,5}                              | [(0,0),(6,6)]                 | (5,5)
  {0,-1,5}                              | [(10,-10),(-3,-4)]            | (-3,-4)
@@ -1710,7 +1669,7 @@ SELECT l.s, l1.s, l.s ## l1.s FROM LINE_TBL l, LSEG_TBL l1;
  {0,3,0}                               | [(1,2),(3,4)]                 | (1,2)
  {0,3,0}                               | [(0,0),(6,6)]                 | (0,0)
  {0,3,0}                               | [(10,-10),(-3,-4)]            | (-3,-4)
- {0,3,0}                               | [(-1000000,200),(300000,-40)] | (83333.3333333,-1.7763568394e-15)
+ {0,3,0}                               | [(-1000000,200),(300000,-40)] | (83333.3333333,0)
  {0,3,0}                               | [(11,22),(33,44)]             | (11,22)
  {0,3,0}                               | [(-10,2),(-10,3)]             | (-10,2)
  {0,3,0}                               | [(0,-20),(30,-20)]            | 
@@ -3735,13 +3694,13 @@ SELECT p.f1, poly.f1, poly.f1 @> p.f1 AS contains
  (Infinity,1e+300) | ((1,2),(7,8),(5,6),(3,-4)) | f
  (Infinity,1e+300) | ((0,0))                    | f
  (Infinity,1e+300) | ((0,1),(0,1))              | f
- (NaN,NaN)         | ((2,0),(2,4),(0,0))        | t
- (NaN,NaN)         | ((3,1),(3,3),(1,0))        | t
- (NaN,NaN)         | ((1,2),(3,4),(5,6),(7,8))  | t
- (NaN,NaN)         | ((7,8),(5,6),(3,4),(1,2))  | t
- (NaN,NaN)         | ((1,2),(7,8),(5,6),(3,-4)) | t
- (NaN,NaN)         | ((0,0))                    | t
- (NaN,NaN)         | ((0,1),(0,1))              | t
+ (NaN,NaN)         | ((2,0),(2,4),(0,0))        | f
+ (NaN,NaN)         | ((3,1),(3,3),(1,0))        | f
+ (NaN,NaN)         | ((1,2),(3,4),(5,6),(7,8))  | f
+ (NaN,NaN)         | ((7,8),(5,6),(3,4),(1,2))  | f
+ (NaN,NaN)         | ((1,2),(7,8),(5,6),(3,-4)) | f
+ (NaN,NaN)         | ((0,0))                    | f
+ (NaN,NaN)         | ((0,1),(0,1))              | f
  (10,10)           | ((2,0),(2,4),(0,0))        | f
  (10,10)           | ((3,1),(3,3),(1,0))        | f
  (10,10)           | ((1,2),(3,4),(5,6),(7,8))  | f
@@ -3811,13 +3770,13 @@ SELECT p.f1, poly.f1, p.f1 <@ poly.f1 AS contained
  (Infinity,1e+300) | ((1,2),(7,8),(5,6),(3,-4)) | f
  (Infinity,1e+300) | ((0,0))                    | f
  (Infinity,1e+300) | ((0,1),(0,1))              | f
- (NaN,NaN)         | ((2,0),(2,4),(0,0))        | t
- (NaN,NaN)         | ((3,1),(3,3),(1,0))        | t
- (NaN,NaN)         | ((1,2),(3,4),(5,6),(7,8))  | t
- (NaN,NaN)         | ((7,8),(5,6),(3,4),(1,2))  | t
- (NaN,NaN)         | ((1,2),(7,8),(5,6),(3,-4)) | t
- (NaN,NaN)         | ((0,0))                    | t
- (NaN,NaN)         | ((0,1),(0,1))              | t
+ (NaN,NaN)         | ((2,0),(2,4),(0,0))        | f
+ (NaN,NaN)         | ((3,1),(3,3),(1,0))        | f
+ (NaN,NaN)         | ((1,2),(3,4),(5,6),(7,8))  | f
+ (NaN,NaN)         | ((7,8),(5,6),(3,4),(1,2))  | f
+ (NaN,NaN)         | ((1,2),(7,8),(5,6),(3,-4)) | f
+ (NaN,NaN)         | ((0,0))                    | f
+ (NaN,NaN)         | ((0,1),(0,1))              | f
  (10,10)           | ((2,0),(2,4),(0,0))        | f
  (10,10)           | ((3,1),(3,3),(1,0))        | f
  (10,10)           | ((1,2),(3,4),(5,6),(7,8))  | f
-- 
2.27.0


В списке pgsql-hackers по дате отправления:

Предыдущее
От: Magnus Hagander
Дата:
Сообщение: Re: Commit fest manager for 2021-01
Следующее
От: Pavel Stehule
Дата:
Сообщение: bad dependency in pg_dump output related to support function breaks binary upgrade