Re: Strange behavior with polygon and NaN - Mailing list pgsql-hackers

From Tom Lane
Subject Re: Strange behavior with polygon and NaN
Date
Msg-id 1456736.1605905866@sss.pgh.pa.us
Whole thread Raw
In response to Re: Strange behavior with polygon and NaN  (Kyotaro Horiguchi <horikyota.ntt@gmail.com>)
Responses Re: Strange behavior with polygon and NaN
Re: Strange behavior with polygon and NaN
List pgsql-hackers
I spent some more time looking at this patch.

Some experimentation shows that the changes around bounding box
calculation (ie float8_min_nan() and its call sites) seem to be
completely pointless: removing them doesn't change any of the regression
results.  Nor does using float8_min_nan() in the other two bounding-box
calculations I'd asked about.  So I think we should just drop that set
of changes and stick with the rule that bounding box upper and lower
values are sorted as per float.h comparison rules.  This isn't that hard
to work with: if you want to know whether any NaNs are in the box, test
the upper limit (and *not* the lower limit) for isnan().  Moreover, even
if we wanted a different coding rule, we really can't have it because we
will still need to work with existing on-disk values that have bounding
boxes computed the old way.

I don't much like anything about float8_coef_mul().  In the first place,
FPzero() is an ugly, badly designed condition that we should be trying
to get rid of not add more dependencies on.  In the second place, it's
really unclear why allowing 0 times Inf to be something other than NaN
is a good idea, and it's even less clear why allowing small-but-not-zero
times Inf to be zero rather than Inf is a good idea.  In the third
place, the asymmetry between the two inputs looks more like a bug than
something we should actually want.

After some time spent staring at the specific case of line_closept_point
and its callers, I decided that the real problems there are twofold.
First, the API, or at least the callers' interpretation of this
undocumented point, is that whether the distance is undefined (NaN) is
equivalent to whether the closest point is undefined.  This is not so;
in some cases we know that the distance is infinite even though we can't
calculate a unique closest point.  Second, it's not making any attempt
to eliminate undefined cases up front.  We can do that pretty easily
by plugging the point's coordinates into the line's equation Ax+By+C
and seeing whether we get a NaN.  The attached 0002 is a subset patch
that just fixes these two issues, and I like the results it produces.

I wonder now whether the problems around line_interpt_line() and the
other intersection-ish functions wouldn't be better handled in a similar
way, by making changes to their API specs to be clearer about what
happens with NaNs and trying to eliminate ill-defined cases explicitly.
I've not tried to code that though.

Changing pg_hypot() the way you've done here is right out.  See the
comment for the function: what it is doing now is per all the relevant
standards, and your patch breaks that.  It's extremely unlikely that
doing it differently from IEEE and POSIX is a good idea.

Attached are the same old 0001 (adding the extra point_tbl entry)
and a small 0002 that fixes just line_closept_point.  I've not
tried to figure out just which of the rest of your diffs should be
dropped given that.  I did note though that the example you add
to func.sgml doesn't apply to this version of line_closept_point:

regression=# select point '(Infinity,Infinity)' <-> line '{-1,0,5}';
 ?column? 
----------
      NaN
(1 row)

regression=# select point '(Infinity,Infinity)' <-> line '{0,-1,5}';
 ?column? 
----------
      NaN
(1 row)

            regards, tom lane

diff --git a/src/test/regress/expected/create_index.out b/src/test/regress/expected/create_index.out
index 93a8736a3f..76679bae8d 100644
--- a/src/test/regress/expected/create_index.out
+++ b/src/test/regress/expected/create_index.out
@@ -157,7 +157,7 @@ SELECT count(*) FROM point_tbl p WHERE p.f1 << '(0.0, 0.0)';
 SELECT count(*) FROM point_tbl p WHERE p.f1 >> '(0.0, 0.0)';
  count
 -------
-     3
+     4
 (1 row)

 SELECT count(*) FROM point_tbl p WHERE p.f1 <^ '(0.0, 0.0)';
@@ -169,7 +169,7 @@ SELECT count(*) FROM point_tbl p WHERE p.f1 <^ '(0.0, 0.0)';
 SELECT count(*) FROM point_tbl p WHERE p.f1 >^ '(0.0, 0.0)';
  count
 -------
-     4
+     5
 (1 row)

 SELECT count(*) FROM point_tbl p WHERE p.f1 ~= '(-5, -12)';
@@ -188,10 +188,11 @@ SELECT * FROM point_tbl ORDER BY f1 <-> '0,1';
  (10,10)
  (-5,-12)
  (5.1,34.5)
+ (Infinity,1e+300)
  (1e+300,Infinity)
  (NaN,NaN)

-(10 rows)
+(11 rows)

 SELECT * FROM point_tbl WHERE f1 IS NULL;
  f1
@@ -202,16 +203,17 @@ SELECT * FROM point_tbl WHERE f1 IS NULL;
 SELECT * FROM point_tbl WHERE f1 IS NOT NULL ORDER BY f1 <-> '0,1';
         f1
 -------------------
- (1e-300,-1e-300)
  (0,0)
+ (1e-300,-1e-300)
  (-3,4)
  (-10,0)
  (10,10)
  (-5,-12)
  (5.1,34.5)
  (1e+300,Infinity)
+ (Infinity,1e+300)
  (NaN,NaN)
-(9 rows)
+(10 rows)

 SELECT * FROM point_tbl WHERE f1 <@ '(-10,-10),(10,10)':: box ORDER BY f1 <-> '0,1';
         f1
@@ -464,7 +466,7 @@ SELECT count(*) FROM point_tbl p WHERE p.f1 >> '(0.0, 0.0)';
 SELECT count(*) FROM point_tbl p WHERE p.f1 >> '(0.0, 0.0)';
  count
 -------
-     3
+     4
 (1 row)

 EXPLAIN (COSTS OFF)
@@ -494,7 +496,7 @@ SELECT count(*) FROM point_tbl p WHERE p.f1 >^ '(0.0, 0.0)';
 SELECT count(*) FROM point_tbl p WHERE p.f1 >^ '(0.0, 0.0)';
  count
 -------
-     4
+     5
 (1 row)

 EXPLAIN (COSTS OFF)
@@ -530,10 +532,11 @@ SELECT * FROM point_tbl ORDER BY f1 <-> '0,1';
  (10,10)
  (-5,-12)
  (5.1,34.5)
+ (Infinity,1e+300)
  (1e+300,Infinity)
  (NaN,NaN)

-(10 rows)
+(11 rows)

 EXPLAIN (COSTS OFF)
 SELECT * FROM point_tbl WHERE f1 IS NULL;
@@ -568,9 +571,10 @@ SELECT * FROM point_tbl WHERE f1 IS NOT NULL ORDER BY f1 <-> '0,1';
  (10,10)
  (-5,-12)
  (5.1,34.5)
+ (Infinity,1e+300)
  (1e+300,Infinity)
  (NaN,NaN)
-(9 rows)
+(10 rows)

 EXPLAIN (COSTS OFF)
 SELECT * FROM point_tbl WHERE f1 <@ '(-10,-10),(10,10)':: box ORDER BY f1 <-> '0,1';
diff --git a/src/test/regress/expected/geometry.out b/src/test/regress/expected/geometry.out
index 5b9d37030f..81202a4c33 100644
--- a/src/test/regress/expected/geometry.out
+++ b/src/test/regress/expected/geometry.out
@@ -120,6 +120,7 @@ SELECT p1.f1, p2.f1, slope(p1.f1, p2.f1) FROM POINT_TBL p1, POINT_TBL p2;
  (0,0)             | (-5,-12)          |                2.4
  (0,0)             | (1e-300,-1e-300)  | 1.79769313486e+308
  (0,0)             | (1e+300,Infinity) |           Infinity
+ (0,0)             | (Infinity,1e+300) |                  0
  (0,0)             | (NaN,NaN)         |                NaN
  (0,0)             | (10,10)           |                  1
  (-10,0)           | (0,0)             |                  0
@@ -129,6 +130,7 @@ SELECT p1.f1, p2.f1, slope(p1.f1, p2.f1) FROM POINT_TBL p1, POINT_TBL p2;
  (-10,0)           | (-5,-12)          |               -2.4
  (-10,0)           | (1e-300,-1e-300)  |                  0
  (-10,0)           | (1e+300,Infinity) |           Infinity
+ (-10,0)           | (Infinity,1e+300) |                  0
  (-10,0)           | (NaN,NaN)         |                NaN
  (-10,0)           | (10,10)           |                0.5
  (-3,4)            | (0,0)             |     -1.33333333333
@@ -138,6 +140,7 @@ SELECT p1.f1, p2.f1, slope(p1.f1, p2.f1) FROM POINT_TBL p1, POINT_TBL p2;
  (-3,4)            | (-5,-12)          |                  8
  (-3,4)            | (1e-300,-1e-300)  |     -1.33333333333
  (-3,4)            | (1e+300,Infinity) |           Infinity
+ (-3,4)            | (Infinity,1e+300) |                  0
  (-3,4)            | (NaN,NaN)         |                NaN
  (-3,4)            | (10,10)           |     0.461538461538
  (5.1,34.5)        | (0,0)             |      6.76470588235
@@ -147,6 +150,7 @@ SELECT p1.f1, p2.f1, slope(p1.f1, p2.f1) FROM POINT_TBL p1, POINT_TBL p2;
  (5.1,34.5)        | (-5,-12)          |      4.60396039604
  (5.1,34.5)        | (1e-300,-1e-300)  |      6.76470588235
  (5.1,34.5)        | (1e+300,Infinity) |           Infinity
+ (5.1,34.5)        | (Infinity,1e+300) |                  0
  (5.1,34.5)        | (NaN,NaN)         |                NaN
  (5.1,34.5)        | (10,10)           |                 -5
  (-5,-12)          | (0,0)             |                2.4
@@ -156,6 +160,7 @@ SELECT p1.f1, p2.f1, slope(p1.f1, p2.f1) FROM POINT_TBL p1, POINT_TBL p2;
  (-5,-12)          | (-5,-12)          | 1.79769313486e+308
  (-5,-12)          | (1e-300,-1e-300)  |                2.4
  (-5,-12)          | (1e+300,Infinity) |           Infinity
+ (-5,-12)          | (Infinity,1e+300) |                  0
  (-5,-12)          | (NaN,NaN)         |                NaN
  (-5,-12)          | (10,10)           |      1.46666666667
  (1e-300,-1e-300)  | (0,0)             | 1.79769313486e+308
@@ -165,6 +170,7 @@ SELECT p1.f1, p2.f1, slope(p1.f1, p2.f1) FROM POINT_TBL p1, POINT_TBL p2;
  (1e-300,-1e-300)  | (-5,-12)          |                2.4
  (1e-300,-1e-300)  | (1e-300,-1e-300)  | 1.79769313486e+308
  (1e-300,-1e-300)  | (1e+300,Infinity) |           Infinity
+ (1e-300,-1e-300)  | (Infinity,1e+300) |                  0
  (1e-300,-1e-300)  | (NaN,NaN)         |                NaN
  (1e-300,-1e-300)  | (10,10)           |                  1
  (1e+300,Infinity) | (0,0)             |           Infinity
@@ -174,8 +180,19 @@ SELECT p1.f1, p2.f1, slope(p1.f1, p2.f1) FROM POINT_TBL p1, POINT_TBL p2;
  (1e+300,Infinity) | (-5,-12)          |           Infinity
  (1e+300,Infinity) | (1e-300,-1e-300)  |           Infinity
  (1e+300,Infinity) | (1e+300,Infinity) | 1.79769313486e+308
+ (1e+300,Infinity) | (Infinity,1e+300) |                NaN
  (1e+300,Infinity) | (NaN,NaN)         |                NaN
  (1e+300,Infinity) | (10,10)           |           Infinity
+ (Infinity,1e+300) | (0,0)             |                  0
+ (Infinity,1e+300) | (-10,0)           |                  0
+ (Infinity,1e+300) | (-3,4)            |                  0
+ (Infinity,1e+300) | (5.1,34.5)        |                  0
+ (Infinity,1e+300) | (-5,-12)          |                  0
+ (Infinity,1e+300) | (1e-300,-1e-300)  |                  0
+ (Infinity,1e+300) | (1e+300,Infinity) |                NaN
+ (Infinity,1e+300) | (Infinity,1e+300) |                  0
+ (Infinity,1e+300) | (NaN,NaN)         |                NaN
+ (Infinity,1e+300) | (10,10)           |                  0
  (NaN,NaN)         | (0,0)             |                NaN
  (NaN,NaN)         | (-10,0)           |                NaN
  (NaN,NaN)         | (-3,4)            |                NaN
@@ -183,6 +200,7 @@ SELECT p1.f1, p2.f1, slope(p1.f1, p2.f1) FROM POINT_TBL p1, POINT_TBL p2;
  (NaN,NaN)         | (-5,-12)          |                NaN
  (NaN,NaN)         | (1e-300,-1e-300)  |                NaN
  (NaN,NaN)         | (1e+300,Infinity) |                NaN
+ (NaN,NaN)         | (Infinity,1e+300) |                NaN
  (NaN,NaN)         | (NaN,NaN)         |                NaN
  (NaN,NaN)         | (10,10)           |                NaN
  (10,10)           | (0,0)             |                  1
@@ -192,14 +210,15 @@ SELECT p1.f1, p2.f1, slope(p1.f1, p2.f1) FROM POINT_TBL p1, POINT_TBL p2;
  (10,10)           | (-5,-12)          |      1.46666666667
  (10,10)           | (1e-300,-1e-300)  |                  1
  (10,10)           | (1e+300,Infinity) |           Infinity
+ (10,10)           | (Infinity,1e+300) |                  0
  (10,10)           | (NaN,NaN)         |                NaN
  (10,10)           | (10,10)           | 1.79769313486e+308
-(81 rows)
+(100 rows)

 -- Add point
 SELECT p1.f1, p2.f1, p1.f1 + p2.f1 FROM POINT_TBL p1, POINT_TBL p2;
-        f1         |        f1         |     ?column?
--------------------+-------------------+-------------------
+        f1         |        f1         |      ?column?
+-------------------+-------------------+---------------------
  (0,0)             | (0,0)             | (0,0)
  (0,0)             | (-10,0)           | (-10,0)
  (0,0)             | (-3,4)            | (-3,4)
@@ -207,6 +226,7 @@ SELECT p1.f1, p2.f1, p1.f1 + p2.f1 FROM POINT_TBL p1, POINT_TBL p2;
  (0,0)             | (-5,-12)          | (-5,-12)
  (0,0)             | (1e-300,-1e-300)  | (1e-300,-1e-300)
  (0,0)             | (1e+300,Infinity) | (1e+300,Infinity)
+ (0,0)             | (Infinity,1e+300) | (Infinity,1e+300)
  (0,0)             | (NaN,NaN)         | (NaN,NaN)
  (0,0)             | (10,10)           | (10,10)
  (-10,0)           | (0,0)             | (-10,0)
@@ -216,6 +236,7 @@ SELECT p1.f1, p2.f1, p1.f1 + p2.f1 FROM POINT_TBL p1, POINT_TBL p2;
  (-10,0)           | (-5,-12)          | (-15,-12)
  (-10,0)           | (1e-300,-1e-300)  | (-10,-1e-300)
  (-10,0)           | (1e+300,Infinity) | (1e+300,Infinity)
+ (-10,0)           | (Infinity,1e+300) | (Infinity,1e+300)
  (-10,0)           | (NaN,NaN)         | (NaN,NaN)
  (-10,0)           | (10,10)           | (0,10)
  (-3,4)            | (0,0)             | (-3,4)
@@ -225,6 +246,7 @@ SELECT p1.f1, p2.f1, p1.f1 + p2.f1 FROM POINT_TBL p1, POINT_TBL p2;
  (-3,4)            | (-5,-12)          | (-8,-8)
  (-3,4)            | (1e-300,-1e-300)  | (-3,4)
  (-3,4)            | (1e+300,Infinity) | (1e+300,Infinity)
+ (-3,4)            | (Infinity,1e+300) | (Infinity,1e+300)
  (-3,4)            | (NaN,NaN)         | (NaN,NaN)
  (-3,4)            | (10,10)           | (7,14)
  (5.1,34.5)        | (0,0)             | (5.1,34.5)
@@ -234,6 +256,7 @@ SELECT p1.f1, p2.f1, p1.f1 + p2.f1 FROM POINT_TBL p1, POINT_TBL p2;
  (5.1,34.5)        | (-5,-12)          | (0.1,22.5)
  (5.1,34.5)        | (1e-300,-1e-300)  | (5.1,34.5)
  (5.1,34.5)        | (1e+300,Infinity) | (1e+300,Infinity)
+ (5.1,34.5)        | (Infinity,1e+300) | (Infinity,1e+300)
  (5.1,34.5)        | (NaN,NaN)         | (NaN,NaN)
  (5.1,34.5)        | (10,10)           | (15.1,44.5)
  (-5,-12)          | (0,0)             | (-5,-12)
@@ -243,6 +266,7 @@ SELECT p1.f1, p2.f1, p1.f1 + p2.f1 FROM POINT_TBL p1, POINT_TBL p2;
  (-5,-12)          | (-5,-12)          | (-10,-24)
  (-5,-12)          | (1e-300,-1e-300)  | (-5,-12)
  (-5,-12)          | (1e+300,Infinity) | (1e+300,Infinity)
+ (-5,-12)          | (Infinity,1e+300) | (Infinity,1e+300)
  (-5,-12)          | (NaN,NaN)         | (NaN,NaN)
  (-5,-12)          | (10,10)           | (5,-2)
  (1e-300,-1e-300)  | (0,0)             | (1e-300,-1e-300)
@@ -252,6 +276,7 @@ SELECT p1.f1, p2.f1, p1.f1 + p2.f1 FROM POINT_TBL p1, POINT_TBL p2;
  (1e-300,-1e-300)  | (-5,-12)          | (-5,-12)
  (1e-300,-1e-300)  | (1e-300,-1e-300)  | (2e-300,-2e-300)
  (1e-300,-1e-300)  | (1e+300,Infinity) | (1e+300,Infinity)
+ (1e-300,-1e-300)  | (Infinity,1e+300) | (Infinity,1e+300)
  (1e-300,-1e-300)  | (NaN,NaN)         | (NaN,NaN)
  (1e-300,-1e-300)  | (10,10)           | (10,10)
  (1e+300,Infinity) | (0,0)             | (1e+300,Infinity)
@@ -261,8 +286,19 @@ SELECT p1.f1, p2.f1, p1.f1 + p2.f1 FROM POINT_TBL p1, POINT_TBL p2;
  (1e+300,Infinity) | (-5,-12)          | (1e+300,Infinity)
  (1e+300,Infinity) | (1e-300,-1e-300)  | (1e+300,Infinity)
  (1e+300,Infinity) | (1e+300,Infinity) | (2e+300,Infinity)
+ (1e+300,Infinity) | (Infinity,1e+300) | (Infinity,Infinity)
  (1e+300,Infinity) | (NaN,NaN)         | (NaN,NaN)
  (1e+300,Infinity) | (10,10)           | (1e+300,Infinity)
+ (Infinity,1e+300) | (0,0)             | (Infinity,1e+300)
+ (Infinity,1e+300) | (-10,0)           | (Infinity,1e+300)
+ (Infinity,1e+300) | (-3,4)            | (Infinity,1e+300)
+ (Infinity,1e+300) | (5.1,34.5)        | (Infinity,1e+300)
+ (Infinity,1e+300) | (-5,-12)          | (Infinity,1e+300)
+ (Infinity,1e+300) | (1e-300,-1e-300)  | (Infinity,1e+300)
+ (Infinity,1e+300) | (1e+300,Infinity) | (Infinity,Infinity)
+ (Infinity,1e+300) | (Infinity,1e+300) | (Infinity,2e+300)
+ (Infinity,1e+300) | (NaN,NaN)         | (NaN,NaN)
+ (Infinity,1e+300) | (10,10)           | (Infinity,1e+300)
  (NaN,NaN)         | (0,0)             | (NaN,NaN)
  (NaN,NaN)         | (-10,0)           | (NaN,NaN)
  (NaN,NaN)         | (-3,4)            | (NaN,NaN)
@@ -270,6 +306,7 @@ SELECT p1.f1, p2.f1, p1.f1 + p2.f1 FROM POINT_TBL p1, POINT_TBL p2;
  (NaN,NaN)         | (-5,-12)          | (NaN,NaN)
  (NaN,NaN)         | (1e-300,-1e-300)  | (NaN,NaN)
  (NaN,NaN)         | (1e+300,Infinity) | (NaN,NaN)
+ (NaN,NaN)         | (Infinity,1e+300) | (NaN,NaN)
  (NaN,NaN)         | (NaN,NaN)         | (NaN,NaN)
  (NaN,NaN)         | (10,10)           | (NaN,NaN)
  (10,10)           | (0,0)             | (10,10)
@@ -279,14 +316,15 @@ SELECT p1.f1, p2.f1, p1.f1 + p2.f1 FROM POINT_TBL p1, POINT_TBL p2;
  (10,10)           | (-5,-12)          | (5,-2)
  (10,10)           | (1e-300,-1e-300)  | (10,10)
  (10,10)           | (1e+300,Infinity) | (1e+300,Infinity)
+ (10,10)           | (Infinity,1e+300) | (Infinity,1e+300)
  (10,10)           | (NaN,NaN)         | (NaN,NaN)
  (10,10)           | (10,10)           | (20,20)
-(81 rows)
+(100 rows)

 -- Subtract point
 SELECT p1.f1, p2.f1, p1.f1 - p2.f1 FROM POINT_TBL p1, POINT_TBL p2;
-        f1         |        f1         |      ?column?
--------------------+-------------------+---------------------
+        f1         |        f1         |       ?column?
+-------------------+-------------------+----------------------
  (0,0)             | (0,0)             | (0,0)
  (0,0)             | (-10,0)           | (10,0)
  (0,0)             | (-3,4)            | (3,-4)
@@ -294,6 +332,7 @@ SELECT p1.f1, p2.f1, p1.f1 - p2.f1 FROM POINT_TBL p1, POINT_TBL p2;
  (0,0)             | (-5,-12)          | (5,12)
  (0,0)             | (1e-300,-1e-300)  | (-1e-300,1e-300)
  (0,0)             | (1e+300,Infinity) | (-1e+300,-Infinity)
+ (0,0)             | (Infinity,1e+300) | (-Infinity,-1e+300)
  (0,0)             | (NaN,NaN)         | (NaN,NaN)
  (0,0)             | (10,10)           | (-10,-10)
  (-10,0)           | (0,0)             | (-10,0)
@@ -303,6 +342,7 @@ SELECT p1.f1, p2.f1, p1.f1 - p2.f1 FROM POINT_TBL p1, POINT_TBL p2;
  (-10,0)           | (-5,-12)          | (-5,12)
  (-10,0)           | (1e-300,-1e-300)  | (-10,1e-300)
  (-10,0)           | (1e+300,Infinity) | (-1e+300,-Infinity)
+ (-10,0)           | (Infinity,1e+300) | (-Infinity,-1e+300)
  (-10,0)           | (NaN,NaN)         | (NaN,NaN)
  (-10,0)           | (10,10)           | (-20,-10)
  (-3,4)            | (0,0)             | (-3,4)
@@ -312,6 +352,7 @@ SELECT p1.f1, p2.f1, p1.f1 - p2.f1 FROM POINT_TBL p1, POINT_TBL p2;
  (-3,4)            | (-5,-12)          | (2,16)
  (-3,4)            | (1e-300,-1e-300)  | (-3,4)
  (-3,4)            | (1e+300,Infinity) | (-1e+300,-Infinity)
+ (-3,4)            | (Infinity,1e+300) | (-Infinity,-1e+300)
  (-3,4)            | (NaN,NaN)         | (NaN,NaN)
  (-3,4)            | (10,10)           | (-13,-6)
  (5.1,34.5)        | (0,0)             | (5.1,34.5)
@@ -321,6 +362,7 @@ SELECT p1.f1, p2.f1, p1.f1 - p2.f1 FROM POINT_TBL p1, POINT_TBL p2;
  (5.1,34.5)        | (-5,-12)          | (10.1,46.5)
  (5.1,34.5)        | (1e-300,-1e-300)  | (5.1,34.5)
  (5.1,34.5)        | (1e+300,Infinity) | (-1e+300,-Infinity)
+ (5.1,34.5)        | (Infinity,1e+300) | (-Infinity,-1e+300)
  (5.1,34.5)        | (NaN,NaN)         | (NaN,NaN)
  (5.1,34.5)        | (10,10)           | (-4.9,24.5)
  (-5,-12)          | (0,0)             | (-5,-12)
@@ -330,6 +372,7 @@ SELECT p1.f1, p2.f1, p1.f1 - p2.f1 FROM POINT_TBL p1, POINT_TBL p2;
  (-5,-12)          | (-5,-12)          | (0,0)
  (-5,-12)          | (1e-300,-1e-300)  | (-5,-12)
  (-5,-12)          | (1e+300,Infinity) | (-1e+300,-Infinity)
+ (-5,-12)          | (Infinity,1e+300) | (-Infinity,-1e+300)
  (-5,-12)          | (NaN,NaN)         | (NaN,NaN)
  (-5,-12)          | (10,10)           | (-15,-22)
  (1e-300,-1e-300)  | (0,0)             | (1e-300,-1e-300)
@@ -339,6 +382,7 @@ SELECT p1.f1, p2.f1, p1.f1 - p2.f1 FROM POINT_TBL p1, POINT_TBL p2;
  (1e-300,-1e-300)  | (-5,-12)          | (5,12)
  (1e-300,-1e-300)  | (1e-300,-1e-300)  | (0,0)
  (1e-300,-1e-300)  | (1e+300,Infinity) | (-1e+300,-Infinity)
+ (1e-300,-1e-300)  | (Infinity,1e+300) | (-Infinity,-1e+300)
  (1e-300,-1e-300)  | (NaN,NaN)         | (NaN,NaN)
  (1e-300,-1e-300)  | (10,10)           | (-10,-10)
  (1e+300,Infinity) | (0,0)             | (1e+300,Infinity)
@@ -348,8 +392,19 @@ SELECT p1.f1, p2.f1, p1.f1 - p2.f1 FROM POINT_TBL p1, POINT_TBL p2;
  (1e+300,Infinity) | (-5,-12)          | (1e+300,Infinity)
  (1e+300,Infinity) | (1e-300,-1e-300)  | (1e+300,Infinity)
  (1e+300,Infinity) | (1e+300,Infinity) | (0,NaN)
+ (1e+300,Infinity) | (Infinity,1e+300) | (-Infinity,Infinity)
  (1e+300,Infinity) | (NaN,NaN)         | (NaN,NaN)
  (1e+300,Infinity) | (10,10)           | (1e+300,Infinity)
+ (Infinity,1e+300) | (0,0)             | (Infinity,1e+300)
+ (Infinity,1e+300) | (-10,0)           | (Infinity,1e+300)
+ (Infinity,1e+300) | (-3,4)            | (Infinity,1e+300)
+ (Infinity,1e+300) | (5.1,34.5)        | (Infinity,1e+300)
+ (Infinity,1e+300) | (-5,-12)          | (Infinity,1e+300)
+ (Infinity,1e+300) | (1e-300,-1e-300)  | (Infinity,1e+300)
+ (Infinity,1e+300) | (1e+300,Infinity) | (Infinity,-Infinity)
+ (Infinity,1e+300) | (Infinity,1e+300) | (NaN,0)
+ (Infinity,1e+300) | (NaN,NaN)         | (NaN,NaN)
+ (Infinity,1e+300) | (10,10)           | (Infinity,1e+300)
  (NaN,NaN)         | (0,0)             | (NaN,NaN)
  (NaN,NaN)         | (-10,0)           | (NaN,NaN)
  (NaN,NaN)         | (-3,4)            | (NaN,NaN)
@@ -357,6 +412,7 @@ SELECT p1.f1, p2.f1, p1.f1 - p2.f1 FROM POINT_TBL p1, POINT_TBL p2;
  (NaN,NaN)         | (-5,-12)          | (NaN,NaN)
  (NaN,NaN)         | (1e-300,-1e-300)  | (NaN,NaN)
  (NaN,NaN)         | (1e+300,Infinity) | (NaN,NaN)
+ (NaN,NaN)         | (Infinity,1e+300) | (NaN,NaN)
  (NaN,NaN)         | (NaN,NaN)         | (NaN,NaN)
  (NaN,NaN)         | (10,10)           | (NaN,NaN)
  (10,10)           | (0,0)             | (10,10)
@@ -366,9 +422,10 @@ SELECT p1.f1, p2.f1, p1.f1 - p2.f1 FROM POINT_TBL p1, POINT_TBL p2;
  (10,10)           | (-5,-12)          | (15,22)
  (10,10)           | (1e-300,-1e-300)  | (10,10)
  (10,10)           | (1e+300,Infinity) | (-1e+300,-Infinity)
+ (10,10)           | (Infinity,1e+300) | (-Infinity,-1e+300)
  (10,10)           | (NaN,NaN)         | (NaN,NaN)
  (10,10)           | (10,10)           | (0,0)
-(81 rows)
+(100 rows)

 -- Multiply with point
 SELECT p1.f1, p2.f1, p1.f1 * p2.f1 FROM POINT_TBL p1, POINT_TBL p2 WHERE p1.f1[0] BETWEEN 1 AND 1000;
@@ -388,11 +445,13 @@ SELECT p1.f1, p2.f1, p1.f1 * p2.f1 FROM POINT_TBL p1, POINT_TBL p2 WHERE p1.f1[0
  (10,10)    | (1e-300,-1e-300)  | (2e-299,0)
  (5.1,34.5) | (1e+300,Infinity) | (-Infinity,Infinity)
  (10,10)    | (1e+300,Infinity) | (-Infinity,Infinity)
+ (5.1,34.5) | (Infinity,1e+300) | (Infinity,Infinity)
+ (10,10)    | (Infinity,1e+300) | (Infinity,Infinity)
  (5.1,34.5) | (NaN,NaN)         | (NaN,NaN)
  (10,10)    | (NaN,NaN)         | (NaN,NaN)
  (5.1,34.5) | (10,10)           | (-294,396)
  (10,10)    | (10,10)           | (0,200)
-(18 rows)
+(20 rows)

 -- Underflow error
 SELECT p1.f1, p2.f1, p1.f1 * p2.f1 FROM POINT_TBL p1, POINT_TBL p2 WHERE p1.f1[0] < 1;
@@ -415,11 +474,13 @@ SELECT p1.f1, p2.f1, p1.f1 / p2.f1 FROM POINT_TBL p1, POINT_TBL p2 WHERE p2.f1[0
  (1e-300,-1e-300)  | (10,10)    | (0,-1e-301)
  (1e+300,Infinity) | (5.1,34.5) | (Infinity,Infinity)
  (1e+300,Infinity) | (10,10)    | (Infinity,Infinity)
+ (Infinity,1e+300) | (5.1,34.5) | (Infinity,-Infinity)
+ (Infinity,1e+300) | (10,10)    | (Infinity,-Infinity)
  (NaN,NaN)         | (5.1,34.5) | (NaN,NaN)
  (NaN,NaN)         | (10,10)    | (NaN,NaN)
  (10,10)           | (5.1,34.5) | (0.325588278822,-0.241724631247)
  (10,10)           | (10,10)    | (1,0)
-(18 rows)
+(20 rows)

 -- Overflow error
 SELECT p1.f1, p2.f1, p1.f1 / p2.f1 FROM POINT_TBL p1, POINT_TBL p2 WHERE p2.f1[0] > 1000;
@@ -501,6 +562,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) | {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
+ (Infinity,1e+300) | {1,0,5}                               |                NaN |                NaN
+ (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) | {3,NaN,5}                             |                NaN |                NaN
+ (Infinity,1e+300) | {NaN,NaN,NaN}                         |                NaN |                NaN
+ (Infinity,1e+300) | {0,-1,3}                              |                NaN |                NaN
+ (Infinity,1e+300) | {-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
@@ -521,7 +592,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)           | {NaN,NaN,NaN}                         |                NaN |                NaN
  (10,10)           | {0,-1,3}                              |                  7 |                  7
  (10,10)           | {-1,0,3}                              |                  7 |                  7
-(90 rows)
+(100 rows)

 -- Distance to line segment
 SELECT p.f1, l.s, p.f1 <-> l.s AS dist_ps, l.s <-> p.f1 AS dist_sp FROM POINT_TBL p, LSEG_TBL l;
@@ -583,6 +654,14 @@ 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) | [(-10,2),(-10,3)]             |           Infinity |           Infinity
  (1e+300,Infinity) | [(0,-20),(30,-20)]            |           Infinity |           Infinity
  (1e+300,Infinity) | [(NaN,1),(NaN,90)]            |           Infinity |           Infinity
+ (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
+ (Infinity,1e+300) | [(-1000000,200),(300000,-40)] |           Infinity |           Infinity
+ (Infinity,1e+300) | [(11,22),(33,44)]             |           Infinity |           Infinity
+ (Infinity,1e+300) | [(-10,2),(-10,3)]             |           Infinity |           Infinity
+ (Infinity,1e+300) | [(0,-20),(30,-20)]            |           Infinity |           Infinity
+ (Infinity,1e+300) | [(NaN,1),(NaN,90)]            |                NaN |                NaN
  (NaN,NaN)         | [(1,2),(3,4)]                 |                NaN |                NaN
  (NaN,NaN)         | [(0,0),(6,6)]                 |                NaN |                NaN
  (NaN,NaN)         | [(10,-10),(-3,-4)]            |                NaN |                NaN
@@ -599,7 +678,7 @@ SELECT p.f1, l.s, p.f1 <-> l.s AS dist_ps, l.s <-> p.f1 AS dist_sp FROM POINT_TB
  (10,10)           | [(-10,2),(-10,3)]             |      21.1896201004 |      21.1896201004
  (10,10)           | [(0,-20),(30,-20)]            |                 30 |                 30
  (10,10)           | [(NaN,1),(NaN,90)]            |                NaN |                NaN
-(72 rows)
+(80 rows)

 -- Distance to box
 SELECT p.f1, b.f1, p.f1 <-> b.f1 AS dist_pb, b.f1 <-> p.f1 AS dist_bp FROM POINT_TBL p, BOX_TBL b;
@@ -640,6 +719,11 @@ SELECT p.f1, b.f1, p.f1 <-> b.f1 AS dist_pb, b.f1 <-> p.f1 AS dist_bp FROM POINT
  (1e+300,Infinity) | (-2,2),(-8,-10)     |           Infinity |           Infinity
  (1e+300,Infinity) | (2.5,3.5),(2.5,2.5) |           Infinity |           Infinity
  (1e+300,Infinity) | (3,3),(3,3)         |           Infinity |           Infinity
+ (Infinity,1e+300) | (2,2),(0,0)         |           Infinity |           Infinity
+ (Infinity,1e+300) | (3,3),(1,1)         |           Infinity |           Infinity
+ (Infinity,1e+300) | (-2,2),(-8,-10)     |           Infinity |           Infinity
+ (Infinity,1e+300) | (2.5,3.5),(2.5,2.5) |           Infinity |           Infinity
+ (Infinity,1e+300) | (3,3),(3,3)         |           Infinity |           Infinity
  (NaN,NaN)         | (2,2),(0,0)         |                NaN |                NaN
  (NaN,NaN)         | (3,3),(1,1)         |                NaN |                NaN
  (NaN,NaN)         | (-2,2),(-8,-10)     |                NaN |                NaN
@@ -650,7 +734,7 @@ SELECT p.f1, b.f1, p.f1 <-> b.f1 AS dist_pb, b.f1 <-> p.f1 AS dist_bp FROM POINT
  (10,10)           | (-2,2),(-8,-10)     |      14.4222051019 |      14.4222051019
  (10,10)           | (2.5,3.5),(2.5,2.5) |      9.92471662064 |      9.92471662064
  (10,10)           | (3,3),(3,3)         |      9.89949493661 |      9.89949493661
-(45 rows)
+(50 rows)

 -- Distance to path
 SELECT p.f1, p1.f1, p.f1 <-> p1.f1 AS dist_ppath, p1.f1 <-> p.f1 AS dist_pathp FROM POINT_TBL p, PATH_TBL p1;
@@ -719,6 +803,15 @@ SELECT p.f1, p1.f1, p.f1 <-> p1.f1 AS dist_ppath, p1.f1 <-> p.f1 AS dist_pathp F
  (1e+300,Infinity) | ((10,20))                 |           Infinity |           Infinity
  (1e+300,Infinity) | [(11,12),(13,14)]         |           Infinity |           Infinity
  (1e+300,Infinity) | ((11,12),(13,14))         |           Infinity |           Infinity
+ (Infinity,1e+300) | [(1,2),(3,4)]             |           Infinity |           Infinity
+ (Infinity,1e+300) | ((1,2),(3,4))             |           Infinity |           Infinity
+ (Infinity,1e+300) | [(0,0),(3,0),(4,5),(1,6)] |           Infinity |           Infinity
+ (Infinity,1e+300) | ((1,2),(3,4))             |           Infinity |           Infinity
+ (Infinity,1e+300) | ((1,2),(3,4))             |           Infinity |           Infinity
+ (Infinity,1e+300) | [(1,2),(3,4)]             |           Infinity |           Infinity
+ (Infinity,1e+300) | ((10,20))                 |           Infinity |           Infinity
+ (Infinity,1e+300) | [(11,12),(13,14)]         |           Infinity |           Infinity
+ (Infinity,1e+300) | ((11,12),(13,14))         |           Infinity |           Infinity
  (NaN,NaN)         | [(1,2),(3,4)]             |                NaN |                NaN
  (NaN,NaN)         | ((1,2),(3,4))             |                NaN |                NaN
  (NaN,NaN)         | [(0,0),(3,0),(4,5),(1,6)] |                NaN |                NaN
@@ -737,7 +830,7 @@ SELECT p.f1, p1.f1, p.f1 <-> p1.f1 AS dist_ppath, p1.f1 <-> p.f1 AS dist_pathp F
  (10,10)           | ((10,20))                 |                 10 |                 10
  (10,10)           | [(11,12),(13,14)]         |       2.2360679775 |       2.2360679775
  (10,10)           | ((11,12),(13,14))         |       2.2360679775 |       2.2360679775
-(81 rows)
+(90 rows)

 -- Distance to polygon
 SELECT p.f1, p1.f1, p.f1 <-> p1.f1 AS dist_ppoly, p1.f1 <-> p.f1 AS dist_polyp FROM POINT_TBL p, POLYGON_TBL p1;
@@ -792,6 +885,13 @@ SELECT p.f1, p1.f1, p.f1 <-> p1.f1 AS dist_ppoly, p1.f1 <-> p.f1 AS dist_polyp F
  (1e+300,Infinity) | ((1,2),(7,8),(5,6),(3,-4)) |      Infinity |      Infinity
  (1e+300,Infinity) | ((0,0))                    |      Infinity |      Infinity
  (1e+300,Infinity) | ((0,1),(0,1))              |      Infinity |      Infinity
+ (Infinity,1e+300) | ((2,0),(2,4),(0,0))        |      Infinity |      Infinity
+ (Infinity,1e+300) | ((3,1),(3,3),(1,0))        |      Infinity |      Infinity
+ (Infinity,1e+300) | ((1,2),(3,4),(5,6),(7,8))  |      Infinity |      Infinity
+ (Infinity,1e+300) | ((7,8),(5,6),(3,4),(1,2))  |      Infinity |      Infinity
+ (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
@@ -806,7 +906,7 @@ SELECT p.f1, p1.f1, p.f1 <-> p1.f1 AS dist_ppoly, p1.f1 <-> p.f1 AS dist_polyp F
  (10,10)           | ((1,2),(7,8),(5,6),(3,-4)) | 3.60555127546 | 3.60555127546
  (10,10)           | ((0,0))                    | 14.1421356237 | 14.1421356237
  (10,10)           | ((0,1),(0,1))              | 13.4536240471 | 13.4536240471
-(63 rows)
+(70 rows)

 -- Closest point to line
 SELECT p.f1, l.s, p.f1 ## l.s FROM POINT_TBL p, LINE_TBL l;
@@ -882,6 +982,16 @@ SELECT p.f1, l.s, p.f1 ## l.s FROM POINT_TBL p, LINE_TBL l;
  (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}                              |
+ (Infinity,1e+300) | {1,0,5}                               |
+ (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) | {3,NaN,5}                             |
+ (Infinity,1e+300) | {NaN,NaN,NaN}                         |
+ (Infinity,1e+300) | {0,-1,3}                              |
+ (Infinity,1e+300) | {-1,0,3}                              |
  (NaN,NaN)         | {0,-1,5}                              |
  (NaN,NaN)         | {1,0,5}                               |
  (NaN,NaN)         | {0,3,0}                               |
@@ -902,7 +1012,7 @@ SELECT p.f1, l.s, p.f1 ## l.s FROM POINT_TBL p, LINE_TBL l;
  (10,10)           | {NaN,NaN,NaN}                         |
  (10,10)           | {0,-1,3}                              | (10,3)
  (10,10)           | {-1,0,3}                              | (3,10)
-(90 rows)
+(100 rows)

 -- Closest point to line segment
 SELECT p.f1, l.s, p.f1 ## l.s FROM POINT_TBL p, LSEG_TBL l;
@@ -964,6 +1074,14 @@ SELECT p.f1, l.s, p.f1 ## l.s FROM POINT_TBL p, LSEG_TBL l;
  (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)
+ (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)
+ (Infinity,1e+300) | [(-1000000,200),(300000,-40)] | (300000,-40)
+ (Infinity,1e+300) | [(11,22),(33,44)]             | (33,44)
+ (Infinity,1e+300) | [(-10,2),(-10,3)]             | (-10,3)
+ (Infinity,1e+300) | [(0,-20),(30,-20)]            | (30,-20)
+ (Infinity,1e+300) | [(NaN,1),(NaN,90)]            |
  (NaN,NaN)         | [(1,2),(3,4)]                 |
  (NaN,NaN)         | [(0,0),(6,6)]                 |
  (NaN,NaN)         | [(10,-10),(-3,-4)]            |
@@ -980,7 +1098,7 @@ SELECT p.f1, l.s, p.f1 ## l.s FROM POINT_TBL p, LSEG_TBL l;
  (10,10)           | [(-10,2),(-10,3)]             | (-10,3)
  (10,10)           | [(0,-20),(30,-20)]            | (10,-20)
  (10,10)           | [(NaN,1),(NaN,90)]            |
-(72 rows)
+(80 rows)

 -- Closest point to box
 SELECT p.f1, b.f1, p.f1 ## b.f1 FROM POINT_TBL p, BOX_TBL b;
@@ -1021,6 +1139,11 @@ SELECT p.f1, b.f1, p.f1 ## b.f1 FROM POINT_TBL p, BOX_TBL b;
  (1e+300,Infinity) | (-2,2),(-8,-10)     | (-8,2)
  (1e+300,Infinity) | (2.5,3.5),(2.5,2.5) | (2.5,3.5)
  (1e+300,Infinity) | (3,3),(3,3)         | (3,3)
+ (Infinity,1e+300) | (2,2),(0,0)         | (0,2)
+ (Infinity,1e+300) | (3,3),(1,1)         | (1,3)
+ (Infinity,1e+300) | (-2,2),(-8,-10)     | (-8,2)
+ (Infinity,1e+300) | (2.5,3.5),(2.5,2.5) | (2.5,3.5)
+ (Infinity,1e+300) | (3,3),(3,3)         | (3,3)
  (NaN,NaN)         | (2,2),(0,0)         |
  (NaN,NaN)         | (3,3),(1,1)         |
  (NaN,NaN)         | (-2,2),(-8,-10)     |
@@ -1031,7 +1154,7 @@ SELECT p.f1, b.f1, p.f1 ## b.f1 FROM POINT_TBL p, BOX_TBL b;
  (10,10)           | (-2,2),(-8,-10)     | (-2,2)
  (10,10)           | (2.5,3.5),(2.5,2.5) | (2.5,3.5)
  (10,10)           | (3,3),(3,3)         | (3,3)
-(45 rows)
+(50 rows)

 -- On line
 SELECT p.f1, l.s FROM POINT_TBL p, LINE_TBL l WHERE p.f1 <@ l.s;
@@ -2347,6 +2470,11 @@ SELECT '' AS twentyfour, b.f1 + p.f1 AS translation
             | (1e+300,Infinity),(1e+300,Infinity)
             | (1e+300,Infinity),(1e+300,Infinity)
             | (1e+300,Infinity),(1e+300,Infinity)
+            | (Infinity,1e+300),(Infinity,1e+300)
+            | (Infinity,1e+300),(Infinity,1e+300)
+            | (Infinity,1e+300),(Infinity,1e+300)
+            | (Infinity,1e+300),(Infinity,1e+300)
+            | (Infinity,1e+300),(Infinity,1e+300)
             | (NaN,NaN),(NaN,NaN)
             | (NaN,NaN),(NaN,NaN)
             | (NaN,NaN),(NaN,NaN)
@@ -2357,7 +2485,7 @@ SELECT '' AS twentyfour, b.f1 + p.f1 AS translation
             | (8,12),(2,0)
             | (12.5,13.5),(12.5,12.5)
             | (13,13),(13,13)
-(45 rows)
+(50 rows)

 SELECT '' AS twentyfour, b.f1 - p.f1 AS translation
    FROM BOX_TBL b, POINT_TBL p;
@@ -2398,6 +2526,11 @@ SELECT '' AS twentyfour, b.f1 - p.f1 AS translation
             | (-1e+300,-Infinity),(-1e+300,-Infinity)
             | (-1e+300,-Infinity),(-1e+300,-Infinity)
             | (-1e+300,-Infinity),(-1e+300,-Infinity)
+            | (-Infinity,-1e+300),(-Infinity,-1e+300)
+            | (-Infinity,-1e+300),(-Infinity,-1e+300)
+            | (-Infinity,-1e+300),(-Infinity,-1e+300)
+            | (-Infinity,-1e+300),(-Infinity,-1e+300)
+            | (-Infinity,-1e+300),(-Infinity,-1e+300)
             | (NaN,NaN),(NaN,NaN)
             | (NaN,NaN),(NaN,NaN)
             | (NaN,NaN),(NaN,NaN)
@@ -2408,7 +2541,7 @@ SELECT '' AS twentyfour, b.f1 - p.f1 AS translation
             | (-12,-8),(-18,-20)
             | (-7.5,-6.5),(-7.5,-7.5)
             | (-7,-7),(-7,-7)
-(45 rows)
+(50 rows)

 -- Multiply with point
 SELECT b.f1, p.f1, b.f1 * p.f1 FROM BOX_TBL b, POINT_TBL p WHERE p.f1[0] BETWEEN 1 AND 1000;
@@ -2431,16 +2564,21 @@ SELECT b.f1, p.f1, b.f1 * p.f1 FROM BOX_TBL b, POINT_TBL p WHERE p.f1[0] > 1000;
          f1          |        f1         |                  ?column?
 ---------------------+-------------------+--------------------------------------------
  (2,2),(0,0)         | (1e+300,Infinity) | (NaN,NaN),(-Infinity,Infinity)
+ (2,2),(0,0)         | (Infinity,1e+300) | (NaN,NaN),(Infinity,Infinity)
  (2,2),(0,0)         | (NaN,NaN)         | (NaN,NaN),(NaN,NaN)
  (3,3),(1,1)         | (1e+300,Infinity) | (-Infinity,Infinity),(-Infinity,Infinity)
+ (3,3),(1,1)         | (Infinity,1e+300) | (Infinity,Infinity),(Infinity,Infinity)
  (3,3),(1,1)         | (NaN,NaN)         | (NaN,NaN),(NaN,NaN)
  (-2,2),(-8,-10)     | (1e+300,Infinity) | (Infinity,-Infinity),(-Infinity,-Infinity)
+ (-2,2),(-8,-10)     | (Infinity,1e+300) | (-Infinity,Infinity),(-Infinity,-Infinity)
  (-2,2),(-8,-10)     | (NaN,NaN)         | (NaN,NaN),(NaN,NaN)
  (2.5,3.5),(2.5,2.5) | (1e+300,Infinity) | (-Infinity,Infinity),(-Infinity,Infinity)
+ (2.5,3.5),(2.5,2.5) | (Infinity,1e+300) | (Infinity,Infinity),(Infinity,Infinity)
  (2.5,3.5),(2.5,2.5) | (NaN,NaN)         | (NaN,NaN),(NaN,NaN)
  (3,3),(3,3)         | (1e+300,Infinity) | (-Infinity,Infinity),(-Infinity,Infinity)
+ (3,3),(3,3)         | (Infinity,1e+300) | (Infinity,Infinity),(Infinity,Infinity)
  (3,3),(3,3)         | (NaN,NaN)         | (NaN,NaN),(NaN,NaN)
-(10 rows)
+(15 rows)

 -- Divide by point
 SELECT b.f1, p.f1, b.f1 / p.f1 FROM BOX_TBL b, POINT_TBL p WHERE p.f1[0] BETWEEN 1 AND 1000;
@@ -2470,9 +2608,10 @@ SELECT f1::box
  (-5,-12),(-5,-12)
  (1e-300,-1e-300),(1e-300,-1e-300)
  (1e+300,Infinity),(1e+300,Infinity)
+ (Infinity,1e+300),(Infinity,1e+300)
  (NaN,NaN),(NaN,NaN)
  (10,10),(10,10)
-(9 rows)
+(10 rows)

 SELECT bound_box(a.f1, b.f1)
     FROM BOX_TBL a, BOX_TBL b;
@@ -3102,6 +3241,15 @@ SELECT p.f1, p1.f1, p.f1 + p1.f1 FROM PATH_TBL p, POINT_TBL p1;
  ((10,20))                 | (1e+300,Infinity) | ((1e+300,Infinity))
  [(11,12),(13,14)]         | (1e+300,Infinity) | [(1e+300,Infinity),(1e+300,Infinity)]
  ((11,12),(13,14))         | (1e+300,Infinity) | ((1e+300,Infinity),(1e+300,Infinity))
+ [(1,2),(3,4)]             | (Infinity,1e+300) | [(Infinity,1e+300),(Infinity,1e+300)]
+ ((1,2),(3,4))             | (Infinity,1e+300) | ((Infinity,1e+300),(Infinity,1e+300))
+ [(0,0),(3,0),(4,5),(1,6)] | (Infinity,1e+300) |
[(Infinity,1e+300),(Infinity,1e+300),(Infinity,1e+300),(Infinity,1e+300)]
+ ((1,2),(3,4))             | (Infinity,1e+300) | ((Infinity,1e+300),(Infinity,1e+300))
+ ((1,2),(3,4))             | (Infinity,1e+300) | ((Infinity,1e+300),(Infinity,1e+300))
+ [(1,2),(3,4)]             | (Infinity,1e+300) | [(Infinity,1e+300),(Infinity,1e+300)]
+ ((10,20))                 | (Infinity,1e+300) | ((Infinity,1e+300))
+ [(11,12),(13,14)]         | (Infinity,1e+300) | [(Infinity,1e+300),(Infinity,1e+300)]
+ ((11,12),(13,14))         | (Infinity,1e+300) | ((Infinity,1e+300),(Infinity,1e+300))
  [(1,2),(3,4)]             | (NaN,NaN)         | [(NaN,NaN),(NaN,NaN)]
  ((1,2),(3,4))             | (NaN,NaN)         | ((NaN,NaN),(NaN,NaN))
  [(0,0),(3,0),(4,5),(1,6)] | (NaN,NaN)         | [(NaN,NaN),(NaN,NaN),(NaN,NaN),(NaN,NaN)]
@@ -3120,7 +3268,7 @@ SELECT p.f1, p1.f1, p.f1 + p1.f1 FROM PATH_TBL p, POINT_TBL p1;
  ((10,20))                 | (10,10)           | ((20,30))
  [(11,12),(13,14)]         | (10,10)           | [(21,22),(23,24)]
  ((11,12),(13,14))         | (10,10)           | ((21,22),(23,24))
-(81 rows)
+(90 rows)

 -- Subtract point
 SELECT p.f1, p1.f1, p.f1 - p1.f1 FROM PATH_TBL p, POINT_TBL p1;
@@ -3189,6 +3337,15 @@ SELECT p.f1, p1.f1, p.f1 - p1.f1 FROM PATH_TBL p, POINT_TBL p1;
  ((10,20))                 | (1e+300,Infinity) | ((-1e+300,-Infinity))
  [(11,12),(13,14)]         | (1e+300,Infinity) | [(-1e+300,-Infinity),(-1e+300,-Infinity)]
  ((11,12),(13,14))         | (1e+300,Infinity) | ((-1e+300,-Infinity),(-1e+300,-Infinity))
+ [(1,2),(3,4)]             | (Infinity,1e+300) | [(-Infinity,-1e+300),(-Infinity,-1e+300)]
+ ((1,2),(3,4))             | (Infinity,1e+300) | ((-Infinity,-1e+300),(-Infinity,-1e+300))
+ [(0,0),(3,0),(4,5),(1,6)] | (Infinity,1e+300) |
[(-Infinity,-1e+300),(-Infinity,-1e+300),(-Infinity,-1e+300),(-Infinity,-1e+300)]
+ ((1,2),(3,4))             | (Infinity,1e+300) | ((-Infinity,-1e+300),(-Infinity,-1e+300))
+ ((1,2),(3,4))             | (Infinity,1e+300) | ((-Infinity,-1e+300),(-Infinity,-1e+300))
+ [(1,2),(3,4)]             | (Infinity,1e+300) | [(-Infinity,-1e+300),(-Infinity,-1e+300)]
+ ((10,20))                 | (Infinity,1e+300) | ((-Infinity,-1e+300))
+ [(11,12),(13,14)]         | (Infinity,1e+300) | [(-Infinity,-1e+300),(-Infinity,-1e+300)]
+ ((11,12),(13,14))         | (Infinity,1e+300) | ((-Infinity,-1e+300),(-Infinity,-1e+300))
  [(1,2),(3,4)]             | (NaN,NaN)         | [(NaN,NaN),(NaN,NaN)]
  ((1,2),(3,4))             | (NaN,NaN)         | ((NaN,NaN),(NaN,NaN))
  [(0,0),(3,0),(4,5),(1,6)] | (NaN,NaN)         | [(NaN,NaN),(NaN,NaN),(NaN,NaN),(NaN,NaN)]
@@ -3207,7 +3364,7 @@ SELECT p.f1, p1.f1, p.f1 - p1.f1 FROM PATH_TBL p, POINT_TBL p1;
  ((10,20))                 | (10,10)           | ((0,10))
  [(11,12),(13,14)]         | (10,10)           | [(1,2),(3,4)]
  ((11,12),(13,14))         | (10,10)           | ((1,2),(3,4))
-(81 rows)
+(90 rows)

 -- Multiply with point
 SELECT p.f1, p1.f1, p.f1 * p1.f1 FROM PATH_TBL p, POINT_TBL p1;
@@ -3276,6 +3433,15 @@ SELECT p.f1, p1.f1, p.f1 * p1.f1 FROM PATH_TBL p, POINT_TBL p1;
  ((10,20))                 | (1e+300,Infinity) | ((-Infinity,Infinity))
  [(11,12),(13,14)]         | (1e+300,Infinity) | [(-Infinity,Infinity),(-Infinity,Infinity)]
  ((11,12),(13,14))         | (1e+300,Infinity) | ((-Infinity,Infinity),(-Infinity,Infinity))
+ [(1,2),(3,4)]             | (Infinity,1e+300) | [(Infinity,Infinity),(Infinity,Infinity)]
+ ((1,2),(3,4))             | (Infinity,1e+300) | ((Infinity,Infinity),(Infinity,Infinity))
+ [(0,0),(3,0),(4,5),(1,6)] | (Infinity,1e+300) | [(NaN,NaN),(Infinity,NaN),(Infinity,Infinity),(Infinity,Infinity)]
+ ((1,2),(3,4))             | (Infinity,1e+300) | ((Infinity,Infinity),(Infinity,Infinity))
+ ((1,2),(3,4))             | (Infinity,1e+300) | ((Infinity,Infinity),(Infinity,Infinity))
+ [(1,2),(3,4)]             | (Infinity,1e+300) | [(Infinity,Infinity),(Infinity,Infinity)]
+ ((10,20))                 | (Infinity,1e+300) | ((Infinity,Infinity))
+ [(11,12),(13,14)]         | (Infinity,1e+300) | [(Infinity,Infinity),(Infinity,Infinity)]
+ ((11,12),(13,14))         | (Infinity,1e+300) | ((Infinity,Infinity),(Infinity,Infinity))
  [(1,2),(3,4)]             | (NaN,NaN)         | [(NaN,NaN),(NaN,NaN)]
  ((1,2),(3,4))             | (NaN,NaN)         | ((NaN,NaN),(NaN,NaN))
  [(0,0),(3,0),(4,5),(1,6)] | (NaN,NaN)         | [(NaN,NaN),(NaN,NaN),(NaN,NaN),(NaN,NaN)]
@@ -3294,7 +3460,7 @@ SELECT p.f1, p1.f1, p.f1 * p1.f1 FROM PATH_TBL p, POINT_TBL p1;
  ((10,20))                 | (10,10)           | ((-100,300))
  [(11,12),(13,14)]         | (10,10)           | [(-10,230),(-10,270)]
  ((11,12),(13,14))         | (10,10)           | ((-10,230),(-10,270))
-(81 rows)
+(90 rows)

 -- Divide by point
 SELECT p.f1, p1.f1, p.f1 / p1.f1 FROM PATH_TBL p, POINT_TBL p1 WHERE p1.f1[0] BETWEEN 1 AND 1000;
@@ -3467,6 +3633,13 @@ SELECT '' AS twentyfour, p.f1, poly.f1, poly.f1 @> p.f1 AS contains
             | (1e+300,Infinity) | ((1,2),(7,8),(5,6),(3,-4)) | f
             | (1e+300,Infinity) | ((0,0))                    | f
             | (1e+300,Infinity) | ((0,1),(0,1))              | f
+            | (Infinity,1e+300) | ((2,0),(2,4),(0,0))        | f
+            | (Infinity,1e+300) | ((3,1),(3,3),(1,0))        | f
+            | (Infinity,1e+300) | ((1,2),(3,4),(5,6),(7,8))  | f
+            | (Infinity,1e+300) | ((7,8),(5,6),(3,4),(1,2))  | f
+            | (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
@@ -3481,7 +3654,7 @@ SELECT '' AS twentyfour, p.f1, poly.f1, poly.f1 @> p.f1 AS contains
             | (10,10)           | ((1,2),(7,8),(5,6),(3,-4)) | f
             | (10,10)           | ((0,0))                    | f
             | (10,10)           | ((0,1),(0,1))              | f
-(63 rows)
+(70 rows)

 SELECT '' AS twentyfour, p.f1, poly.f1, p.f1 <@ poly.f1 AS contained
    FROM POLYGON_TBL poly, POINT_TBL p;
@@ -3536,6 +3709,13 @@ SELECT '' AS twentyfour, p.f1, poly.f1, p.f1 <@ poly.f1 AS contained
             | (1e+300,Infinity) | ((1,2),(7,8),(5,6),(3,-4)) | f
             | (1e+300,Infinity) | ((0,0))                    | f
             | (1e+300,Infinity) | ((0,1),(0,1))              | f
+            | (Infinity,1e+300) | ((2,0),(2,4),(0,0))        | f
+            | (Infinity,1e+300) | ((3,1),(3,3),(1,0))        | f
+            | (Infinity,1e+300) | ((1,2),(3,4),(5,6),(7,8))  | f
+            | (Infinity,1e+300) | ((7,8),(5,6),(3,4),(1,2))  | f
+            | (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
@@ -3550,7 +3730,7 @@ SELECT '' AS twentyfour, p.f1, poly.f1, p.f1 <@ poly.f1 AS contained
             | (10,10)           | ((1,2),(7,8),(5,6),(3,-4)) | f
             | (10,10)           | ((0,0))                    | f
             | (10,10)           | ((0,1),(0,1))              | f
-(63 rows)
+(70 rows)

 SELECT '' AS four, npoints(f1) AS npoints, f1 AS polygon
    FROM POLYGON_TBL;
@@ -3929,9 +4109,10 @@ SELECT '' AS six, circle(f1, 50.0)
      | <(-5,-12),50>
      | <(1e-300,-1e-300),50>
      | <(1e+300,Infinity),50>
+     | <(Infinity,1e+300),50>
      | <(NaN,NaN),50>
      | <(10,10),50>
-(9 rows)
+(10 rows)

 SELECT '' AS four, circle(f1)
    FROM BOX_TBL;
@@ -3993,12 +4174,19 @@ SELECT '' AS twentyfour, c1.f1 AS circle, p1.f1 AS point, (p1.f1 <-> c1.f1) AS d
             | <(100,200),10> | (-10,0)           |  218.25424421
             | <(100,200),10> | (-5,-12)          | 226.577682802
             | <(3,5),0>      | (1e+300,Infinity) |      Infinity
+            | <(3,5),0>      | (Infinity,1e+300) |      Infinity
             | <(1,2),3>      | (1e+300,Infinity) |      Infinity
             | <(5,1),3>      | (1e+300,Infinity) |      Infinity
+            | <(5,1),3>      | (Infinity,1e+300) |      Infinity
+            | <(1,2),3>      | (Infinity,1e+300) |      Infinity
             | <(1,3),5>      | (1e+300,Infinity) |      Infinity
+            | <(1,3),5>      | (Infinity,1e+300) |      Infinity
             | <(100,200),10> | (1e+300,Infinity) |      Infinity
+            | <(100,200),10> | (Infinity,1e+300) |      Infinity
             | <(1,2),100>    | (1e+300,Infinity) |      Infinity
+            | <(1,2),100>    | (Infinity,1e+300) |      Infinity
             | <(100,1),115>  | (1e+300,Infinity) |      Infinity
+            | <(100,1),115>  | (Infinity,1e+300) |      Infinity
             | <(3,5),0>      | (NaN,NaN)         |           NaN
             | <(1,2),3>      | (NaN,NaN)         |           NaN
             | <(5,1),3>      | (NaN,NaN)         |           NaN
@@ -4014,8 +4202,9 @@ SELECT '' AS twentyfour, c1.f1 AS circle, p1.f1 AS point, (p1.f1 <-> c1.f1) AS d
             | <(3,5),NaN>    | (5.1,34.5)        |           NaN
             | <(3,5),NaN>    | (10,10)           |           NaN
             | <(3,5),NaN>    | (1e+300,Infinity) |           NaN
+            | <(3,5),NaN>    | (Infinity,1e+300) |           NaN
             | <(3,5),NaN>    | (NaN,NaN)         |           NaN
-(53 rows)
+(61 rows)

 -- To polygon
 SELECT f1, f1::polygon FROM CIRCLE_TBL WHERE f1 >= '<(0,0),1>';
@@ -4626,6 +4815,14 @@ SELECT c.f1, p.f1, c.f1 + p.f1 FROM CIRCLE_TBL c, POINT_TBL p;
  <(100,1),115>  | (1e+300,Infinity) | <(1e+300,Infinity),115>
  <(3,5),0>      | (1e+300,Infinity) | <(1e+300,Infinity),0>
  <(3,5),NaN>    | (1e+300,Infinity) | <(1e+300,Infinity),NaN>
+ <(5,1),3>      | (Infinity,1e+300) | <(Infinity,1e+300),3>
+ <(1,2),100>    | (Infinity,1e+300) | <(Infinity,1e+300),100>
+ <(1,3),5>      | (Infinity,1e+300) | <(Infinity,1e+300),5>
+ <(1,2),3>      | (Infinity,1e+300) | <(Infinity,1e+300),3>
+ <(100,200),10> | (Infinity,1e+300) | <(Infinity,1e+300),10>
+ <(100,1),115>  | (Infinity,1e+300) | <(Infinity,1e+300),115>
+ <(3,5),0>      | (Infinity,1e+300) | <(Infinity,1e+300),0>
+ <(3,5),NaN>    | (Infinity,1e+300) | <(Infinity,1e+300),NaN>
  <(5,1),3>      | (NaN,NaN)         | <(NaN,NaN),3>
  <(1,2),100>    | (NaN,NaN)         | <(NaN,NaN),100>
  <(1,3),5>      | (NaN,NaN)         | <(NaN,NaN),5>
@@ -4642,7 +4839,7 @@ SELECT c.f1, p.f1, c.f1 + p.f1 FROM CIRCLE_TBL c, POINT_TBL p;
  <(100,1),115>  | (10,10)           | <(110,11),115>
  <(3,5),0>      | (10,10)           | <(13,15),0>
  <(3,5),NaN>    | (10,10)           | <(13,15),NaN>
-(72 rows)
+(80 rows)

 -- Subtract point
 SELECT c.f1, p.f1, c.f1 - p.f1 FROM CIRCLE_TBL c, POINT_TBL p;
@@ -4704,6 +4901,14 @@ SELECT c.f1, p.f1, c.f1 - p.f1 FROM CIRCLE_TBL c, POINT_TBL p;
  <(100,1),115>  | (1e+300,Infinity) | <(-1e+300,-Infinity),115>
  <(3,5),0>      | (1e+300,Infinity) | <(-1e+300,-Infinity),0>
  <(3,5),NaN>    | (1e+300,Infinity) | <(-1e+300,-Infinity),NaN>
+ <(5,1),3>      | (Infinity,1e+300) | <(-Infinity,-1e+300),3>
+ <(1,2),100>    | (Infinity,1e+300) | <(-Infinity,-1e+300),100>
+ <(1,3),5>      | (Infinity,1e+300) | <(-Infinity,-1e+300),5>
+ <(1,2),3>      | (Infinity,1e+300) | <(-Infinity,-1e+300),3>
+ <(100,200),10> | (Infinity,1e+300) | <(-Infinity,-1e+300),10>
+ <(100,1),115>  | (Infinity,1e+300) | <(-Infinity,-1e+300),115>
+ <(3,5),0>      | (Infinity,1e+300) | <(-Infinity,-1e+300),0>
+ <(3,5),NaN>    | (Infinity,1e+300) | <(-Infinity,-1e+300),NaN>
  <(5,1),3>      | (NaN,NaN)         | <(NaN,NaN),3>
  <(1,2),100>    | (NaN,NaN)         | <(NaN,NaN),100>
  <(1,3),5>      | (NaN,NaN)         | <(NaN,NaN),5>
@@ -4720,7 +4925,7 @@ SELECT c.f1, p.f1, c.f1 - p.f1 FROM CIRCLE_TBL c, POINT_TBL p;
  <(100,1),115>  | (10,10)           | <(90,-9),115>
  <(3,5),0>      | (10,10)           | <(-7,-5),0>
  <(3,5),NaN>    | (10,10)           | <(-7,-5),NaN>
-(72 rows)
+(80 rows)

 -- Multiply with point
 SELECT c.f1, p.f1, c.f1 * p.f1 FROM CIRCLE_TBL c, POINT_TBL p;
@@ -4782,6 +4987,14 @@ SELECT c.f1, p.f1, c.f1 * p.f1 FROM CIRCLE_TBL c, POINT_TBL p;
  <(100,1),115>  | (1e+300,Infinity) | <(-Infinity,Infinity),Infinity>
  <(3,5),0>      | (1e+300,Infinity) | <(-Infinity,Infinity),NaN>
  <(3,5),NaN>    | (1e+300,Infinity) | <(-Infinity,Infinity),NaN>
+ <(5,1),3>      | (Infinity,1e+300) | <(Infinity,Infinity),Infinity>
+ <(1,2),100>    | (Infinity,1e+300) | <(Infinity,Infinity),Infinity>
+ <(1,3),5>      | (Infinity,1e+300) | <(Infinity,Infinity),Infinity>
+ <(1,2),3>      | (Infinity,1e+300) | <(Infinity,Infinity),Infinity>
+ <(100,200),10> | (Infinity,1e+300) | <(Infinity,Infinity),Infinity>
+ <(100,1),115>  | (Infinity,1e+300) | <(Infinity,Infinity),Infinity>
+ <(3,5),0>      | (Infinity,1e+300) | <(Infinity,Infinity),NaN>
+ <(3,5),NaN>    | (Infinity,1e+300) | <(Infinity,Infinity),NaN>
  <(5,1),3>      | (NaN,NaN)         | <(NaN,NaN),NaN>
  <(1,2),100>    | (NaN,NaN)         | <(NaN,NaN),NaN>
  <(1,3),5>      | (NaN,NaN)         | <(NaN,NaN),NaN>
@@ -4798,7 +5011,7 @@ SELECT c.f1, p.f1, c.f1 * p.f1 FROM CIRCLE_TBL c, POINT_TBL p;
  <(100,1),115>  | (10,10)           | <(990,1010),1626.34559673>
  <(3,5),0>      | (10,10)           | <(-20,80),0>
  <(3,5),NaN>    | (10,10)           | <(-20,80),NaN>
-(72 rows)
+(80 rows)

 -- Divide by point
 SELECT c.f1, p.f1, c.f1 / p.f1 FROM CIRCLE_TBL c, POINT_TBL p WHERE p.f1[0] BETWEEN 1 AND 1000;
diff --git a/src/test/regress/expected/point.out b/src/test/regress/expected/point.out
index 15e3b83b37..77e250fc3e 100644
--- a/src/test/regress/expected/point.out
+++ b/src/test/regress/expected/point.out
@@ -11,6 +11,7 @@ INSERT INTO POINT_TBL(f1) VALUES ('(5.1, 34.5)');
 INSERT INTO POINT_TBL(f1) VALUES ('(-5.0,-12.0)');
 INSERT INTO POINT_TBL(f1) VALUES ('(1e-300,-1e-300)');    -- To underflow
 INSERT INTO POINT_TBL(f1) VALUES ('(1e+300,Inf)');        -- To overflow
+INSERT INTO POINT_TBL(f1) VALUES ('(Inf,1e+300)');        -- Transposed
 INSERT INTO POINT_TBL(f1) VALUES (' ( Nan , NaN ) ');
 -- bad format points
 INSERT INTO POINT_TBL(f1) VALUES ('asdfasdf');
@@ -44,9 +45,10 @@ SELECT '' AS six, * FROM POINT_TBL;
      | (-5,-12)
      | (1e-300,-1e-300)
      | (1e+300,Infinity)
+     | (Infinity,1e+300)
      | (NaN,NaN)
      | (10,10)
-(9 rows)
+(10 rows)

 -- left of
 SELECT '' AS three, p.* FROM POINT_TBL p WHERE p.f1 << '(0.0, 0.0)';
@@ -115,8 +117,9 @@ SELECT '' AS three, p.* FROM POINT_TBL p
        | (-5,-12)
        | (1e-300,-1e-300)
        | (1e+300,Infinity)
+       | (Infinity,1e+300)
        | (NaN,NaN)
-(6 rows)
+(7 rows)

 SELECT '' AS two, p.* FROM POINT_TBL p
    WHERE p.f1 <@ path '[(0,0),(-10,0),(-10,10)]';
@@ -136,8 +139,9 @@ SELECT '' AS three, p.* FROM POINT_TBL p
        | (-5,-12)
        | (1e-300,-1e-300)
        | (1e+300,Infinity)
+       | (Infinity,1e+300)
        | (NaN,NaN)
-(6 rows)
+(7 rows)

 SELECT '' AS six, p.f1, p.f1 <-> point '(0,0)' AS dist
    FROM POINT_TBL p
@@ -152,8 +156,9 @@ SELECT '' AS six, p.f1, p.f1 <-> point '(0,0)' AS dist
      | (10,10)           |      14.142135623731
      | (5.1,34.5)        |     34.8749193547455
      | (1e+300,Infinity) |             Infinity
+     | (Infinity,1e+300) |             Infinity
      | (NaN,NaN)         |                  NaN
-(9 rows)
+(10 rows)

 SELECT '' AS thirtysix, p1.f1 AS point1, p2.f1 AS point2, p1.f1 <-> p2.f1 AS dist
    FROM POINT_TBL p1, POINT_TBL p2
@@ -210,12 +215,19 @@ SELECT '' AS thirtysix, p1.f1 AS point1, p2.f1 AS point2, p1.f1 <-> p2.f1 AS dis
            | (-5,-12)          | (5.1,34.5)        |     47.5842410888311
            | (5.1,34.5)        | (-5,-12)          |     47.5842410888311
            | (-10,0)           | (1e+300,Infinity) |             Infinity
+           | (-10,0)           | (Infinity,1e+300) |             Infinity
            | (-5,-12)          | (1e+300,Infinity) |             Infinity
+           | (-5,-12)          | (Infinity,1e+300) |             Infinity
            | (-3,4)            | (1e+300,Infinity) |             Infinity
+           | (-3,4)            | (Infinity,1e+300) |             Infinity
            | (0,0)             | (1e+300,Infinity) |             Infinity
+           | (0,0)             | (Infinity,1e+300) |             Infinity
            | (1e-300,-1e-300)  | (1e+300,Infinity) |             Infinity
+           | (1e-300,-1e-300)  | (Infinity,1e+300) |             Infinity
            | (5.1,34.5)        | (1e+300,Infinity) |             Infinity
+           | (5.1,34.5)        | (Infinity,1e+300) |             Infinity
            | (10,10)           | (1e+300,Infinity) |             Infinity
+           | (10,10)           | (Infinity,1e+300) |             Infinity
            | (1e+300,Infinity) | (-10,0)           |             Infinity
            | (1e+300,Infinity) | (-5,-12)          |             Infinity
            | (1e+300,Infinity) | (-3,4)            |             Infinity
@@ -223,6 +235,15 @@ SELECT '' AS thirtysix, p1.f1 AS point1, p2.f1 AS point2, p1.f1 <-> p2.f1 AS dis
            | (1e+300,Infinity) | (1e-300,-1e-300)  |             Infinity
            | (1e+300,Infinity) | (5.1,34.5)        |             Infinity
            | (1e+300,Infinity) | (10,10)           |             Infinity
+           | (1e+300,Infinity) | (Infinity,1e+300) |             Infinity
+           | (Infinity,1e+300) | (-10,0)           |             Infinity
+           | (Infinity,1e+300) | (-5,-12)          |             Infinity
+           | (Infinity,1e+300) | (-3,4)            |             Infinity
+           | (Infinity,1e+300) | (0,0)             |             Infinity
+           | (Infinity,1e+300) | (1e-300,-1e-300)  |             Infinity
+           | (Infinity,1e+300) | (5.1,34.5)        |             Infinity
+           | (Infinity,1e+300) | (10,10)           |             Infinity
+           | (Infinity,1e+300) | (1e+300,Infinity) |             Infinity
            | (-10,0)           | (NaN,NaN)         |                  NaN
            | (-5,-12)          | (NaN,NaN)         |                  NaN
            | (-3,4)            | (NaN,NaN)         |                  NaN
@@ -232,6 +253,8 @@ SELECT '' AS thirtysix, p1.f1 AS point1, p2.f1 AS point2, p1.f1 <-> p2.f1 AS dis
            | (10,10)           | (NaN,NaN)         |                  NaN
            | (1e+300,Infinity) | (1e+300,Infinity) |                  NaN
            | (1e+300,Infinity) | (NaN,NaN)         |                  NaN
+           | (Infinity,1e+300) | (Infinity,1e+300) |                  NaN
+           | (Infinity,1e+300) | (NaN,NaN)         |                  NaN
            | (NaN,NaN)         | (-10,0)           |                  NaN
            | (NaN,NaN)         | (-5,-12)          |                  NaN
            | (NaN,NaN)         | (-3,4)            |                  NaN
@@ -240,8 +263,9 @@ SELECT '' AS thirtysix, p1.f1 AS point1, p2.f1 AS point2, p1.f1 <-> p2.f1 AS dis
            | (NaN,NaN)         | (5.1,34.5)        |                  NaN
            | (NaN,NaN)         | (10,10)           |                  NaN
            | (NaN,NaN)         | (1e+300,Infinity) |                  NaN
+           | (NaN,NaN)         | (Infinity,1e+300) |                  NaN
            | (NaN,NaN)         | (NaN,NaN)         |                  NaN
-(81 rows)
+(100 rows)

 SELECT '' AS thirty, p1.f1 AS point1, p2.f1 AS point2
    FROM POINT_TBL p1, POINT_TBL p2
@@ -253,6 +277,7 @@ SELECT '' AS thirty, p1.f1 AS point1, p2.f1 AS point2
         | (0,0)             | (5.1,34.5)
         | (0,0)             | (-5,-12)
         | (0,0)             | (1e+300,Infinity)
+        | (0,0)             | (Infinity,1e+300)
         | (0,0)             | (NaN,NaN)
         | (0,0)             | (10,10)
         | (-10,0)           | (0,0)
@@ -261,6 +286,7 @@ SELECT '' AS thirty, p1.f1 AS point1, p2.f1 AS point2
         | (-10,0)           | (-5,-12)
         | (-10,0)           | (1e-300,-1e-300)
         | (-10,0)           | (1e+300,Infinity)
+        | (-10,0)           | (Infinity,1e+300)
         | (-10,0)           | (NaN,NaN)
         | (-10,0)           | (10,10)
         | (-3,4)            | (0,0)
@@ -269,6 +295,7 @@ SELECT '' AS thirty, p1.f1 AS point1, p2.f1 AS point2
         | (-3,4)            | (-5,-12)
         | (-3,4)            | (1e-300,-1e-300)
         | (-3,4)            | (1e+300,Infinity)
+        | (-3,4)            | (Infinity,1e+300)
         | (-3,4)            | (NaN,NaN)
         | (-3,4)            | (10,10)
         | (5.1,34.5)        | (0,0)
@@ -277,6 +304,7 @@ SELECT '' AS thirty, p1.f1 AS point1, p2.f1 AS point2
         | (5.1,34.5)        | (-5,-12)
         | (5.1,34.5)        | (1e-300,-1e-300)
         | (5.1,34.5)        | (1e+300,Infinity)
+        | (5.1,34.5)        | (Infinity,1e+300)
         | (5.1,34.5)        | (NaN,NaN)
         | (5.1,34.5)        | (10,10)
         | (-5,-12)          | (0,0)
@@ -285,6 +313,7 @@ SELECT '' AS thirty, p1.f1 AS point1, p2.f1 AS point2
         | (-5,-12)          | (5.1,34.5)
         | (-5,-12)          | (1e-300,-1e-300)
         | (-5,-12)          | (1e+300,Infinity)
+        | (-5,-12)          | (Infinity,1e+300)
         | (-5,-12)          | (NaN,NaN)
         | (-5,-12)          | (10,10)
         | (1e-300,-1e-300)  | (-10,0)
@@ -292,6 +321,7 @@ SELECT '' AS thirty, p1.f1 AS point1, p2.f1 AS point2
         | (1e-300,-1e-300)  | (5.1,34.5)
         | (1e-300,-1e-300)  | (-5,-12)
         | (1e-300,-1e-300)  | (1e+300,Infinity)
+        | (1e-300,-1e-300)  | (Infinity,1e+300)
         | (1e-300,-1e-300)  | (NaN,NaN)
         | (1e-300,-1e-300)  | (10,10)
         | (1e+300,Infinity) | (0,0)
@@ -301,8 +331,19 @@ SELECT '' AS thirty, p1.f1 AS point1, p2.f1 AS point2
         | (1e+300,Infinity) | (-5,-12)
         | (1e+300,Infinity) | (1e-300,-1e-300)
         | (1e+300,Infinity) | (1e+300,Infinity)
+        | (1e+300,Infinity) | (Infinity,1e+300)
         | (1e+300,Infinity) | (NaN,NaN)
         | (1e+300,Infinity) | (10,10)
+        | (Infinity,1e+300) | (0,0)
+        | (Infinity,1e+300) | (-10,0)
+        | (Infinity,1e+300) | (-3,4)
+        | (Infinity,1e+300) | (5.1,34.5)
+        | (Infinity,1e+300) | (-5,-12)
+        | (Infinity,1e+300) | (1e-300,-1e-300)
+        | (Infinity,1e+300) | (1e+300,Infinity)
+        | (Infinity,1e+300) | (Infinity,1e+300)
+        | (Infinity,1e+300) | (NaN,NaN)
+        | (Infinity,1e+300) | (10,10)
         | (NaN,NaN)         | (0,0)
         | (NaN,NaN)         | (-10,0)
         | (NaN,NaN)         | (-3,4)
@@ -310,6 +351,7 @@ SELECT '' AS thirty, p1.f1 AS point1, p2.f1 AS point2
         | (NaN,NaN)         | (-5,-12)
         | (NaN,NaN)         | (1e-300,-1e-300)
         | (NaN,NaN)         | (1e+300,Infinity)
+        | (NaN,NaN)         | (Infinity,1e+300)
         | (NaN,NaN)         | (NaN,NaN)
         | (NaN,NaN)         | (10,10)
         | (10,10)           | (0,0)
@@ -319,57 +361,67 @@ SELECT '' AS thirty, p1.f1 AS point1, p2.f1 AS point2
         | (10,10)           | (-5,-12)
         | (10,10)           | (1e-300,-1e-300)
         | (10,10)           | (1e+300,Infinity)
+        | (10,10)           | (Infinity,1e+300)
         | (10,10)           | (NaN,NaN)
-(72 rows)
+(91 rows)

 -- put distance result into output to allow sorting with GEQ optimizer - tgl 97/05/10
 SELECT '' AS fifteen, p1.f1 AS point1, p2.f1 AS point2, (p1.f1 <-> p2.f1) AS distance
    FROM POINT_TBL p1, POINT_TBL p2
    WHERE (p1.f1 <-> p2.f1) > 3 and p1.f1 << p2.f1
    ORDER BY distance, p1.f1[0], p2.f1[0];
- fifteen |      point1      |      point2       |     distance
----------+------------------+-------------------+------------------
-         | (-3,4)           | (0,0)             |                5
-         | (-3,4)           | (1e-300,-1e-300)  |                5
-         | (-10,0)          | (-3,4)            | 8.06225774829855
-         | (-10,0)          | (0,0)             |               10
-         | (-10,0)          | (1e-300,-1e-300)  |               10
-         | (-10,0)          | (-5,-12)          |               13
-         | (-5,-12)         | (0,0)             |               13
-         | (-5,-12)         | (1e-300,-1e-300)  |               13
-         | (0,0)            | (10,10)           |  14.142135623731
-         | (1e-300,-1e-300) | (10,10)           |  14.142135623731
-         | (-3,4)           | (10,10)           | 14.3178210632764
-         | (-5,-12)         | (-3,4)            | 16.1245154965971
-         | (-10,0)          | (10,10)           | 22.3606797749979
-         | (5.1,34.5)       | (10,10)           | 24.9851956166046
-         | (-5,-12)         | (10,10)           | 26.6270539113887
-         | (-3,4)           | (5.1,34.5)        | 31.5572495632937
-         | (0,0)            | (5.1,34.5)        | 34.8749193547455
-         | (1e-300,-1e-300) | (5.1,34.5)        | 34.8749193547455
-         | (-10,0)          | (5.1,34.5)        | 37.6597928831267
-         | (-5,-12)         | (5.1,34.5)        | 47.5842410888311
-         | (-10,0)          | (1e+300,Infinity) |         Infinity
-         | (-5,-12)         | (1e+300,Infinity) |         Infinity
-         | (-3,4)           | (1e+300,Infinity) |         Infinity
-         | (0,0)            | (1e+300,Infinity) |         Infinity
-         | (1e-300,-1e-300) | (1e+300,Infinity) |         Infinity
-         | (5.1,34.5)       | (1e+300,Infinity) |         Infinity
-         | (10,10)          | (1e+300,Infinity) |         Infinity
-(27 rows)
+ fifteen |      point1       |      point2       |     distance
+---------+-------------------+-------------------+------------------
+         | (-3,4)            | (0,0)             |                5
+         | (-3,4)            | (1e-300,-1e-300)  |                5
+         | (-10,0)           | (-3,4)            | 8.06225774829855
+         | (-10,0)           | (0,0)             |               10
+         | (-10,0)           | (1e-300,-1e-300)  |               10
+         | (-10,0)           | (-5,-12)          |               13
+         | (-5,-12)          | (0,0)             |               13
+         | (-5,-12)          | (1e-300,-1e-300)  |               13
+         | (0,0)             | (10,10)           |  14.142135623731
+         | (1e-300,-1e-300)  | (10,10)           |  14.142135623731
+         | (-3,4)            | (10,10)           | 14.3178210632764
+         | (-5,-12)          | (-3,4)            | 16.1245154965971
+         | (-10,0)           | (10,10)           | 22.3606797749979
+         | (5.1,34.5)        | (10,10)           | 24.9851956166046
+         | (-5,-12)          | (10,10)           | 26.6270539113887
+         | (-3,4)            | (5.1,34.5)        | 31.5572495632937
+         | (0,0)             | (5.1,34.5)        | 34.8749193547455
+         | (1e-300,-1e-300)  | (5.1,34.5)        | 34.8749193547455
+         | (-10,0)           | (5.1,34.5)        | 37.6597928831267
+         | (-5,-12)          | (5.1,34.5)        | 47.5842410888311
+         | (-10,0)           | (1e+300,Infinity) |         Infinity
+         | (-10,0)           | (Infinity,1e+300) |         Infinity
+         | (-5,-12)          | (1e+300,Infinity) |         Infinity
+         | (-5,-12)          | (Infinity,1e+300) |         Infinity
+         | (-3,4)            | (1e+300,Infinity) |         Infinity
+         | (-3,4)            | (Infinity,1e+300) |         Infinity
+         | (0,0)             | (1e+300,Infinity) |         Infinity
+         | (0,0)             | (Infinity,1e+300) |         Infinity
+         | (1e-300,-1e-300)  | (1e+300,Infinity) |         Infinity
+         | (1e-300,-1e-300)  | (Infinity,1e+300) |         Infinity
+         | (5.1,34.5)        | (1e+300,Infinity) |         Infinity
+         | (5.1,34.5)        | (Infinity,1e+300) |         Infinity
+         | (10,10)           | (1e+300,Infinity) |         Infinity
+         | (10,10)           | (Infinity,1e+300) |         Infinity
+         | (1e+300,Infinity) | (Infinity,1e+300) |         Infinity
+(35 rows)

 -- put distance result into output to allow sorting with GEQ optimizer - tgl 97/05/10
 SELECT '' AS three, p1.f1 AS point1, p2.f1 AS point2, (p1.f1 <-> p2.f1) AS distance
    FROM POINT_TBL p1, POINT_TBL p2
    WHERE (p1.f1 <-> p2.f1) > 3 and p1.f1 << p2.f1 and p1.f1 >^ p2.f1
    ORDER BY distance;
- three |   point1   |      point2      |     distance
--------+------------+------------------+------------------
-       | (-3,4)     | (0,0)            |                5
-       | (-3,4)     | (1e-300,-1e-300) |                5
-       | (-10,0)    | (-5,-12)         |               13
-       | (5.1,34.5) | (10,10)          | 24.9851956166046
-(4 rows)
+ three |      point1       |      point2       |     distance
+-------+-------------------+-------------------+------------------
+       | (-3,4)            | (0,0)             |                5
+       | (-3,4)            | (1e-300,-1e-300)  |                5
+       | (-10,0)           | (-5,-12)          |               13
+       | (5.1,34.5)        | (10,10)           | 24.9851956166046
+       | (1e+300,Infinity) | (Infinity,1e+300) |         Infinity
+(5 rows)

 -- Test that GiST indexes provide same behavior as sequential scan
 CREATE TEMP TABLE point_gist_tbl(f1 point);
diff --git a/src/test/regress/sql/point.sql b/src/test/regress/sql/point.sql
index 7f8504dbd1..6a1ca12d5c 100644
--- a/src/test/regress/sql/point.sql
+++ b/src/test/regress/sql/point.sql
@@ -21,6 +21,8 @@ INSERT INTO POINT_TBL(f1) VALUES ('(1e-300,-1e-300)');    -- To underflow

 INSERT INTO POINT_TBL(f1) VALUES ('(1e+300,Inf)');        -- To overflow

+INSERT INTO POINT_TBL(f1) VALUES ('(Inf,1e+300)');        -- Transposed
+
 INSERT INTO POINT_TBL(f1) VALUES (' ( Nan , NaN ) ');

 -- bad format points
diff --git a/src/backend/utils/adt/geo_ops.c b/src/backend/utils/adt/geo_ops.c
index a7db783958..fc6493a0d7 100644
--- a/src/backend/utils/adt/geo_ops.c
+++ b/src/backend/utils/adt/geo_ops.c
@@ -2707,9 +2707,14 @@ lseg_interpt_line(Point *result, LSEG *lseg, LINE *line)
  *-------------------------------------------------------------------*/

 /*
- * If *result is not NULL, it is set to the intersection point of a
- * perpendicular of the line through the point.  Returns the distance
- * of those two points.
+ * Determine the closest point on the given line to the given point.
+ * If result is not NULL, *result is set to the coordinates of that point.
+ * In any case, returns the distance from the point to the line.
+ * Returns NaN for any ill-defined value.
+ *
+ * NOTE: in some cases the distance is well defined (i.e., infinity)
+ * even though the specific closest point is not.  Hence, if you care
+ * about whether the point is well-defined, check its coordinates for NaNs.
  */
 static float8
 line_closept_point(Point *result, LINE *line, Point *point)
@@ -2717,17 +2722,30 @@ line_closept_point(Point *result, LINE *line, Point *point)
     Point        closept;
     LINE        tmp;

+    /*
+     * 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.
+     */
+    if (unlikely(isnan(float8_pl(float8_pl(float8_mul(line->A, point->x),
+                                           float8_mul(line->B, point->y)),
+                                 line->C))))
+    {
+        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
-     * should always find it, but that can fail in the presence of NaN
-     * coordinates, and perhaps even from simple roundoff issues.
+     * should always find it, but perhaps roundoff issues could prevent that.
      */
     line_construct(&tmp, point, line_invsl(line));
     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 +2764,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);
diff --git a/src/test/regress/expected/geometry.out b/src/test/regress/expected/geometry.out
index 81202a4c33..8499300b53 100644
--- a/src/test/regress/expected/geometry.out
+++ b/src/test/regress/expected/geometry.out
@@ -975,9 +975,9 @@ SELECT p.f1, l.s, p.f1 ## l.s FROM POINT_TBL p, LINE_TBL l;
  (1e+300,Infinity) | {0,-1,5}                              | (1e+300,5)
  (1e+300,Infinity) | {1,0,5}                               |
  (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}                              |
+ (1e+300,Infinity) | {-0.4,-1,-6}                          |
+ (1e+300,Infinity) | {-0.000184615384615,-1,15.3846153846} |
  (1e+300,Infinity) | {3,NaN,5}                             |
  (1e+300,Infinity) | {NaN,NaN,NaN}                         |
  (1e+300,Infinity) | {0,-1,3}                              | (1e+300,3)

pgsql-hackers by date:

Previous
From: Robert Haas
Date:
Subject: Re: xid wraparound danger due to INDEX_CLEANUP false
Next
From: Heikki Linnakangas
Date:
Subject: Re: Refactor pg_rewind code and make it work against a standby