Re: Strange behavior with polygon and NaN - Mailing list pgsql-hackers
From | Kyotaro Horiguchi |
---|---|
Subject | Re: Strange behavior with polygon and NaN |
Date | |
Msg-id | 20201116.151636.571392156451834232.horikyota.ntt@gmail.com Whole thread Raw |
In response to | Re: Strange behavior with polygon and NaN (Tom Lane <tgl@sss.pgh.pa.us>) |
Responses |
Re: Strange behavior with polygon and NaN
|
List | pgsql-hackers |
At Fri, 13 Nov 2020 11:26:21 -0500, Tom Lane <tgl@sss.pgh.pa.us> wrote in > Kyotaro Horiguchi <horikyota.ntt@gmail.com> writes: > > At Tue, 10 Nov 2020 14:30:08 -0500, Tom Lane <tgl@sss.pgh.pa.us> wrote in > >> For instance, {1,-1,0} is the line "x = y". We could argue about > >> whether it'd be sensible to return zero for the distance between that > >> and the point (inf,inf), but surely any point with one inf and one > >> finite coordinate must be an infinite distance away from that line. > >> There's nothing ill-defined about that situation. > > > Mmm... (swinging my arms to mimic lines..) > > dist(x = y, (1e300, Inf)) looks indeterminant to me.. > > Well, what you're showing is that we get an internal overflow, > essentially, on the way to calculating the result. Which is true, > so it's sort of accidental that we got a sensible result before. > Nonetheless, we *did* get a sensible result, so producing NaN > instead seems like a regression. Independently from the discussion, the following was wrong. > 2. calculate the cross point. > corsspoint({-1, -1, Inf}, {1,-1,0}) => (Inf, NaN) The Corss point must be on the line 2, that is, x equas to y. If we avoid using x to calcualte y, the result gets right. But that doesn't "fix" the result. > We might need to introduce special-case handling to protect the > low-level calculations from ever seeing NaN or Inf in their inputs. > Getting the right answer to "just fall out" of those calculations > might be an unreasonable hope. However, as far as we we calculate the distance between the point and the foot of the perpendicular line from the point to the line, (inf - inf) is inevitable and we cannot avoid that "wrong" result. > For example, for a line with positive slope (A and B of opposite > signs), I think that the right answer for points (Inf,Inf) and > (-Inf,-Inf) should be NaN, on much the same grounds that Inf > minus Inf is NaN not zero. But all other points involving any Inf > coordinates are clearly an infinite distance away from that line. After some checking I noticed that the calculation with the well-known formula was wrong. > The formula for the distance((x0,y0) - (ax + by + c = 0)) is > > |ax0 + by0 + c|/sqrt(a^2 + b^2) > > where a = -1, b = -1, c = Inf, x0 = 1e300, y0 = Inf, a = -1, b = -1, c = "0", x0=1e300, y0=Inf results in Inf. Sorry for the mistake. So, we can recalculate the result using the formula if get NaN based on the perpendicular foot. The reason I left the existing calculation is the consistency between the returned perpendicular foot and the distance value, and for the reduced complexity in the major code path. 1. So the attached yeilds "Inf" in that cases. 2. Independently from the point, I noticed that the y-coord of the perpendicular foot is miscalculated as NaN instead of Inf for the cases that are discussed here. (line_interpt_line) 3. I fixed line_construct to construct (NaN, NaN, NaN) if the input containsNaNs. 4. Renamed the variable "isnan" to "anynan" in lseg_closept_lseg() and box_closept_point(). 5. (not in the past comments) line_interpt() needs to check if any of the coordinates is NaN since line_interpt_line() is defined to return such a result. A. I'm not sure how to treat addtion/subtruct/multiply between points. But thinking that operations as vector calculation returning such values are valid. So I left them as it is. -- Add point SELECT p1.f1, p2.f1, p1.f1 + p2.f1 FROM POINT_TBL p1, POINT_TBL p2; (NaN,NaN) | (0,0) | (NaN,NaN) B. @@ lseg (center) returns NaN-containing results. I'm not sure this is regarded whether as a vector calculation or as a geometric operation. If it is the former we don't fix it and otherwise we should reutrn NULL for such input. =# select @@ lseg('[(NaN,1),(NaN,90)]'); ?column? ------------ (NaN,45.5) (1 row) == Changes in the result ============ 1 and 2 above cause visible diffence in some results at the least significant digit in mantissa, but that difference doesn't matter. > - (-3,4) | {-0.000184615384615,-1,15.3846153846} | 11.3851690368 | 11.3851690368 > + (-3,4) | {-0.000184615384615,-1,15.3846153846} | 11.3851690367 | 11.3851690367 1 restored the previous results. > - (1e+300,Infinity) | {1,-1,0} | NaN | NaN > - (1e+300,Infinity) | {-0.4,-1,-6} | NaN | NaN > - (1e+300,Infinity) | {-0.000184615384615,-1,15.3846153846} | NaN | 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 > > > - (Infinity,1e+300) | [(0,-20),(30,-20)] | NaN | NaN > + (Infinity,1e+300) | [(0,-20),(30,-20)] | Infinity | Infinity > - (Infinity,1e+300) | [(0,0),(3,0),(4,5),(1,6)] | NaN | NaN > + (Infinity,1e+300) | [(0,0),(3,0),(4,5),(1,6)] | Infinity | Infinity Looks fine. > -- Closest point to line > SELECT p.f1, l.s, p.f1 ## l.s FROM POINT_TBL p, LINE_TBL l; > - (1e+300,Infinity) | {1,-1,0} | > - (1e+300,Infinity) | {-0.4,-1,-6} | > - (1e+300,Infinity) | {-0.000184615384615,-1,15.3846153846} | > + (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) > > -- 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; > - (Infinity,1e+300) | [(0,-20),(30,-20)] | > + (Infinity,1e+300) | [(0,-20),(30,-20)] | (30,-20) > > -- Intersection point with line > SELECT l1.s, l2.s, l1.s # l2.s FROM LINE_TBL l1, LINE_TBL l2; > - {-0.000184615384615,-1,15.3846153846} | {0,3,0} | (83333.3333333,-1.7763568394e-15) > + {-0.000184615384615,-1,15.3846153846} | {0,3,0} | (83333.3333333,0) These are fixed by 2. > -- Distance to line > SELECT p.f1, l.s, p.f1 <-> l.s AS dist_pl, l.s <-> p.f1 AS dist_lp FROM POINT_TBL p, LINE_TBL l; > (1e+300,Infinity) | {-1,0,3} | NaN | NaN This should be 1e+300, not NaN, but 1 nor 2 doesn't fix this. The reasonis line->B(0) * point->y(Infinity) results in NaN. But from the meaning of the this sexpression, it should be 0. I made line_closept_point() to do that but I found a similar issue in line_interpt_line(). > -- Closest point to line > SELECT p.f1, l.s, p.f1 ## l.s FROM POINT_TBL p, LINE_TBL l; > (1e+300,Infinity) | {1,0,5} | (NaN,Infinity) So, what is needed here is we have special multiplication function that supercedes 0*Inf = NaN rule by "0"*Inf = 0. I introduced that function as float8_coef_mul(). The reason that the function is in geo_ops.c is that it is geo_ops specific and using ZPzere(), which is not used in float.h. By using the function the results are fixed as: > -- Distance to line > SELECT p.f1, l.s, p.f1 <-> l.s AS dist_pl, l.s <-> p.f1 AS dist_lp FROM POINT_TBL p, LINE_TBL l; > (1e+300,Infinity) | {-1,0,3} | 1e+300 | 1e+300 > (Infinity,1e+300) | {0,-1,5} | 1e+300 | 1e+300 > > -- Closest point to line > SELECT p.f1, l.s, p.f1 ## l.s FROM POINT_TBL p, LINE_TBL l; > (1e+300,Infinity) | {1,0,5} | (-5,Infinity) regards. -- Kyotaro Horiguchi NTT Open Source Software Center From d6b6041f25ca8c3f4c77d5822d1dd7ac47ddaccf Mon Sep 17 00:00:00 2001 From: Kyotaro Horiguchi <horikyoga.ntt@gmail.com> Date: Fri, 13 Nov 2020 13:31:00 +0900 Subject: [PATCH v4 1/2] add morepoint tests --- src/test/regress/expected/create_index.out | 22 +- src/test/regress/expected/geometry.out | 275 ++++++++++++++++++--- src/test/regress/expected/point.out | 138 +++++++---- src/test/regress/sql/point.sql | 2 + 4 files changed, 354 insertions(+), 83 deletions(-) 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 -- 2.18.4 From 9d11d6781e02ab6d06db2854d1eb963b5b72f943 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 v4 2/2] fix geometric nan handling --- doc/src/sgml/func.sgml | 17 + src/backend/utils/adt/geo_ops.c | 300 +++++++++++-- src/include/utils/float.h | 22 + src/test/regress/expected/create_index.out | 2 +- src/test/regress/expected/geometry.out | 463 ++++++++++----------- 5 files changed, 511 insertions(+), 293 deletions(-) diff --git a/doc/src/sgml/func.sgml b/doc/src/sgml/func.sgml index 7c7d177c02..9ecb0bdfcc 100644 --- a/doc/src/sgml/func.sgml +++ b/doc/src/sgml/func.sgml @@ -10896,6 +10896,23 @@ CREATE TYPE rainbow AS ENUM ('red', 'orange', 'yellow', 'green', 'blue', 'purple </para> </caution> + <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 a7db783958..eaf4528b30 100644 --- a/src/backend/utils/adt/geo_ops.c +++ b/src/backend/utils/adt/geo_ops.c @@ -159,6 +159,38 @@ static char *path_encode(enum path_delim path_delim, int npts, Point *pt); #define LDELIM_L '{' #define RDELIM_L '}' +/* + * Float multiplication, but "0"*Inf is calculated as 0, not NaN, only when + * val1 is FPzero(). val1 is assued to be one of the coefficients of a line, + * specifically A or B. if both is true, val2 is treaded the same way as val1. + */ +static inline float8 +float8_coef_mul(const float8 val1, const float8 val2, bool both) +{ + float8 result; + + if (FPzero(val1)) + { + if (isnan(val2)) + return get_float8_nan(); + return 0.0; + } + + if (both && FPzero(val2)) + { + if (isnan(val1)) + return get_float8_nan(); + return 0.0; + } + + result = val1 * val2; + if (unlikely(isinf(result)) && !isinf(val1) && !isinf(val2)) + float_overflow_error(); + if (unlikely(result == 0.0) && val1 != 0.0 && val2 != 0.0) + float_underflow_error(); + + return result; +} /* * Geometric data types are composed of points. @@ -904,9 +936,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,8 +1093,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 + else if (m == 0.0) + { + /* use "mx - y + yinter = 0" */ + 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 if (!isnan(m)) { /* use "mx - y + yinter = 0" */ result->A = m; @@ -1071,7 +1118,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() @@ -1084,6 +1136,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), @@ -1104,8 +1157,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 @@ -1123,14 +1180,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)); @@ -1141,7 +1201,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 @@ -1149,7 +1209,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)); } @@ -1195,9 +1255,19 @@ 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 DBL_MAX; + } return float8_div(line->A, -line->B); } @@ -1209,9 +1279,19 @@ 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 DBL_MAX; + } 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); } @@ -1224,14 +1304,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 was 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; @@ -1253,8 +1342,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); } @@ -1283,22 +1377,39 @@ line_interpt_line(Point *result, LINE *l1, LINE *l2) if (FPeq(l2->A, float8_mul(l1->A, float8_div(l2->B, l1->B)))) return false; - x = float8_div(float8_mi(float8_mul(l1->B, l2->C), - 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); + x = float8_div(float8_mi(float8_coef_mul(l1->B, l2->C, false), + float8_coef_mul(l2->B, l1->C, false)), + float8_mi(float8_coef_mul(l1->A, l2->B, true), + float8_coef_mul(l2->A, l1->B, true))); + /* + * 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_coef_mul(l1->A, l2->C, false), + float8_coef_mul(l2->A, l1->C, false)), + float8_mi(float8_coef_mul(l2->A, l1->B, true), + float8_coef_mul(l1->A, l2->B, true))); } else if (!FPzero(l2->B)) { - if (FPeq(l1->A, float8_mul(l2->A, float8_div(l1->B, l2->B)))) - return false; + /* + * We know that l1->B is zero, which means l1 is vertical. 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); - x = float8_div(float8_mi(float8_mul(l2->B, l1->C), - float8_mul(l1->B, l2->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); + /* + * 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_coef_mul(l2->A, x, false), l2->C), + l2->B); } else return false; @@ -1628,8 +1739,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; @@ -1637,8 +1748,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); @@ -1728,6 +1839,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; @@ -1980,9 +2096,17 @@ 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 DBL_MAX; + } 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)); } @@ -1996,9 +2120,17 @@ 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 DBL_MAX; + } return float8_div(float8_mi(pt1->x, pt2->x), float8_mi(pt2->y, pt1->y)); } @@ -2414,6 +2546,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; @@ -2645,6 +2782,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; @@ -2674,7 +2813,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; /* @@ -2716,6 +2856,7 @@ line_closept_point(Point *result, LINE *line, Point *point) { Point closept; LINE tmp; + float8 distance; /* * We drop a perpendicular to find the intersection point. Ordinarily we @@ -2734,7 +2875,36 @@ line_closept_point(Point *result, LINE *line, Point *point) if (result != NULL) *result = closept; - return point_dt(&closept, point); + distance = point_dt(&closept, point); + + if (likely(!isnan(distance))) + return point_dt(&closept, point); + + /* + * We may have Inf's in the two points that results in NaN wrongly. Try + * re-calculate the distance not using the corsspoint. + * + * | a*x0 + b*y0 + c | / sqrt(a^2 + b^2) + * + * We could avoid that calcualtion in the cases where that is apparently + * useless, but we don't bother checking that since the chances we get here + * are relatively rare. + */ + + /* + * But in some further special cases where A = 0 or B = 0, x and y + * correspondingly is completely irrelevant but that terms may yeild + * unwanted result. Avoid such results to be resulted by removing the + * ignorable terms in the expression in those cases. So use + * float8_coef_mul() instead of float8_mul(). + */ + + return float8_div(fabs(float8_pl( + float8_pl( + float8_coef_mul(line->A, point->x, false), + float8_coef_mul(line->B, point->y, false)), + line->C)), + HYPOT(line->A, line->B)); } Datum @@ -2803,6 +2973,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)) @@ -2814,6 +2985,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; @@ -2823,6 +2995,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; @@ -2830,6 +3003,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; @@ -2837,6 +3011,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; } @@ -2873,6 +3053,7 @@ box_closept_point(Point *result, BOX *box, Point *pt) Point point, closept; LSEG lseg; + bool anynan = false; if (box_contain_point(box, pt)) { @@ -2887,9 +3068,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; @@ -2901,6 +3083,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; @@ -2910,6 +3093,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; @@ -2917,6 +3101,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; } @@ -2988,6 +3179,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) @@ -3010,6 +3202,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]; @@ -3135,9 +3335,10 @@ 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)); + return FPzero(float8_pl( + float8_pl(float8_coef_mul(line->A, point->x, false), + float8_coef_mul(line->B, point->y, false)), + line->C)); } Datum @@ -3436,6 +3637,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)) @@ -3911,6 +4118,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; @@ -5350,6 +5562,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 */ @@ -5359,6 +5575,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; @@ -5517,12 +5737,12 @@ pg_hypot(float8 x, float8 y) result; /* Handle INF and NaN properly */ - if (isinf(x) || isinf(y)) + if (unlikely(isnan(x) || isnan(y))) + return get_float8_nan(); + + if (unlikely(isinf(x) || isinf(y))) return get_float8_infinity(); - if (isnan(x) || isnan(y)) - return get_float8_nan(); - /* Else, drop any minus signs */ x = fabs(x); y = fabs(y); 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 76679bae8d..581bf414f2 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 81202a4c33..634e7e2dc7 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,17 +561,17 @@ 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 - (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 + (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} | 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) | {-1,0,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 (NaN,NaN) | {0,3,0} | 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 @@ -973,25 +973,25 @@ 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} | - (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} | + (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,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) | {-1,0,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} | (NaN,NaN) | {0,3,0} | @@ -1073,7 +1073,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) @@ -1183,12 +1183,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 @@ -1276,8 +1271,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 @@ -1286,8 +1281,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 @@ -1296,8 +1291,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 @@ -1306,8 +1301,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 @@ -1316,8 +1311,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 @@ -1326,38 +1321,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 @@ -1366,8 +1361,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) @@ -1385,31 +1380,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} @@ -1417,8 +1404,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} @@ -1426,46 +1411,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; @@ -1488,16 +1447,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) @@ -1506,8 +1465,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} | @@ -1516,8 +1475,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) @@ -1526,8 +1485,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) @@ -1536,48 +1495,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) @@ -1586,16 +1545,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) @@ -1615,7 +1574,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)] | @@ -1974,88 +1933,88 @@ SELECT l1.s, l2.s FROM LSEG_TBL l1, LSEG_TBL l2 WHERE l1.s ?-| l2.s; -- Distance to line SELECT l.s, l1.s, l.s <-> l1.s AS dist_sl, l1.s <-> l.s AS dist_ls FROM LSEG_TBL l, LINE_TBL l1; - s | s | dist_sl | dist_ls --------------------------------+---------------------------------------+----------------+---------------- - [(1,2),(3,4)] | {0,-1,5} | 1 | 1 - [(0,0),(6,6)] | {0,-1,5} | 0 | 0 - [(10,-10),(-3,-4)] | {0,-1,5} | 9 | 9 - [(-1000000,200),(300000,-40)] | {0,-1,5} | 0 | 0 - [(11,22),(33,44)] | {0,-1,5} | 17 | 17 - [(-10,2),(-10,3)] | {0,-1,5} | 2 | 2 - [(0,-20),(30,-20)] | {0,-1,5} | 25 | 25 - [(NaN,1),(NaN,90)] | {0,-1,5} | NaN | NaN - [(1,2),(3,4)] | {1,0,5} | 6 | 6 - [(0,0),(6,6)] | {1,0,5} | 5 | 5 - [(10,-10),(-3,-4)] | {1,0,5} | 2 | 2 - [(-1000000,200),(300000,-40)] | {1,0,5} | 0 | 0 - [(11,22),(33,44)] | {1,0,5} | 16 | 16 - [(-10,2),(-10,3)] | {1,0,5} | 5 | 5 - [(0,-20),(30,-20)] | {1,0,5} | 5 | 5 - [(NaN,1),(NaN,90)] | {1,0,5} | NaN | NaN - [(1,2),(3,4)] | {0,3,0} | 2 | 2 - [(0,0),(6,6)] | {0,3,0} | 0 | 0 - [(10,-10),(-3,-4)] | {0,3,0} | 4 | 4 - [(-1000000,200),(300000,-40)] | {0,3,0} | 0 | 0 - [(11,22),(33,44)] | {0,3,0} | 22 | 22 - [(-10,2),(-10,3)] | {0,3,0} | 2 | 2 - [(0,-20),(30,-20)] | {0,3,0} | 20 | 20 - [(NaN,1),(NaN,90)] | {0,3,0} | NaN | NaN - [(1,2),(3,4)] | {1,-1,0} | 0.707106781187 | 0.707106781187 - [(0,0),(6,6)] | {1,-1,0} | 0 | 0 - [(10,-10),(-3,-4)] | {1,-1,0} | 0.707106781187 | 0.707106781187 - [(-1000000,200),(300000,-40)] | {1,-1,0} | 0 | 0 - [(11,22),(33,44)] | {1,-1,0} | 7.77817459305 | 7.77817459305 - [(-10,2),(-10,3)] | {1,-1,0} | 8.48528137424 | 8.48528137424 - [(0,-20),(30,-20)] | {1,-1,0} | 14.1421356237 | 14.1421356237 - [(NaN,1),(NaN,90)] | {1,-1,0} | NaN | NaN - [(1,2),(3,4)] | {-0.4,-1,-6} | 7.79920420344 | 7.79920420344 - [(0,0),(6,6)] | {-0.4,-1,-6} | 5.57086014531 | 5.57086014531 - [(10,-10),(-3,-4)] | {-0.4,-1,-6} | 0 | 0 - [(-1000000,200),(300000,-40)] | {-0.4,-1,-6} | 0 | 0 - [(11,22),(33,44)] | {-0.4,-1,-6} | 30.0826447847 | 30.0826447847 - [(-10,2),(-10,3)] | {-0.4,-1,-6} | 3.71390676354 | 3.71390676354 - [(0,-20),(30,-20)] | {-0.4,-1,-6} | 1.85695338177 | 1.85695338177 - [(NaN,1),(NaN,90)] | {-0.4,-1,-6} | NaN | NaN - [(1,2),(3,4)] | {-0.000184615384615,-1,15.3846153846} | 11.3840613445 | 11.3840613445 - [(0,0),(6,6)] | {-0.000184615384615,-1,15.3846153846} | 9.3835075324 | 9.3835075324 - [(10,-10),(-3,-4)] | {-0.000184615384615,-1,15.3846153846} | 19.3851689004 | 19.3851689004 - [(-1000000,200),(300000,-40)] | {-0.000184615384615,-1,15.3846153846} | 0 | 0 - [(11,22),(33,44)] | {-0.000184615384615,-1,15.3846153846} | 6.61741527185 | 6.61741527185 - [(-10,2),(-10,3)] | {-0.000184615384615,-1,15.3846153846} | 12.3864613274 | 12.3864613274 - [(0,-20),(30,-20)] | {-0.000184615384615,-1,15.3846153846} | 35.3790763202 | 35.3790763202 - [(NaN,1),(NaN,90)] | {-0.000184615384615,-1,15.3846153846} | NaN | NaN - [(1,2),(3,4)] | {3,NaN,5} | NaN | NaN - [(0,0),(6,6)] | {3,NaN,5} | NaN | NaN - [(10,-10),(-3,-4)] | {3,NaN,5} | NaN | NaN - [(-1000000,200),(300000,-40)] | {3,NaN,5} | NaN | NaN - [(11,22),(33,44)] | {3,NaN,5} | NaN | NaN - [(-10,2),(-10,3)] | {3,NaN,5} | NaN | NaN - [(0,-20),(30,-20)] | {3,NaN,5} | NaN | NaN - [(NaN,1),(NaN,90)] | {3,NaN,5} | NaN | NaN - [(1,2),(3,4)] | {NaN,NaN,NaN} | NaN | NaN - [(0,0),(6,6)] | {NaN,NaN,NaN} | NaN | NaN - [(10,-10),(-3,-4)] | {NaN,NaN,NaN} | NaN | NaN - [(-1000000,200),(300000,-40)] | {NaN,NaN,NaN} | NaN | NaN - [(11,22),(33,44)] | {NaN,NaN,NaN} | NaN | NaN - [(-10,2),(-10,3)] | {NaN,NaN,NaN} | NaN | NaN - [(0,-20),(30,-20)] | {NaN,NaN,NaN} | NaN | NaN - [(NaN,1),(NaN,90)] | {NaN,NaN,NaN} | NaN | NaN - [(1,2),(3,4)] | {0,-1,3} | 0 | 0 - [(0,0),(6,6)] | {0,-1,3} | 0 | 0 - [(10,-10),(-3,-4)] | {0,-1,3} | 7 | 7 - [(-1000000,200),(300000,-40)] | {0,-1,3} | 0 | 0 - [(11,22),(33,44)] | {0,-1,3} | 19 | 19 - [(-10,2),(-10,3)] | {0,-1,3} | 0 | 0 - [(0,-20),(30,-20)] | {0,-1,3} | 23 | 23 - [(NaN,1),(NaN,90)] | {0,-1,3} | NaN | NaN - [(1,2),(3,4)] | {-1,0,3} | 0 | 0 - [(0,0),(6,6)] | {-1,0,3} | 0 | 0 - [(10,-10),(-3,-4)] | {-1,0,3} | 0 | 0 - [(-1000000,200),(300000,-40)] | {-1,0,3} | 0 | 0 - [(11,22),(33,44)] | {-1,0,3} | 8 | 8 - [(-10,2),(-10,3)] | {-1,0,3} | 13 | 13 - [(0,-20),(30,-20)] | {-1,0,3} | 0 | 0 - [(NaN,1),(NaN,90)] | {-1,0,3} | NaN | NaN + s | s | dist_sl | dist_ls +-------------------------------+---------------------------------------+------------------+------------------ + [(1,2),(3,4)] | {0,-1,5} | 1 | 1 + [(0,0),(6,6)] | {0,-1,5} | 0 | 0 + [(10,-10),(-3,-4)] | {0,-1,5} | 9 | 9 + [(-1000000,200),(300000,-40)] | {0,-1,5} | 0 | 0 + [(11,22),(33,44)] | {0,-1,5} | 17 | 17 + [(-10,2),(-10,3)] | {0,-1,5} | 2 | 2 + [(0,-20),(30,-20)] | {0,-1,5} | 25 | 25 + [(NaN,1),(NaN,90)] | {0,-1,5} | NaN | NaN + [(1,2),(3,4)] | {1,0,5} | 6 | 6 + [(0,0),(6,6)] | {1,0,5} | 5 | 5 + [(10,-10),(-3,-4)] | {1,0,5} | 2 | 2 + [(-1000000,200),(300000,-40)] | {1,0,5} | 0 | 0 + [(11,22),(33,44)] | {1,0,5} | 16 | 16 + [(-10,2),(-10,3)] | {1,0,5} | 5 | 5 + [(0,-20),(30,-20)] | {1,0,5} | 5 | 5 + [(NaN,1),(NaN,90)] | {1,0,5} | NaN | NaN + [(1,2),(3,4)] | {0,3,0} | 2 | 2 + [(0,0),(6,6)] | {0,3,0} | 0 | 0 + [(10,-10),(-3,-4)] | {0,3,0} | 4 | 4 + [(-1000000,200),(300000,-40)] | {0,3,0} | 0 | 0 + [(11,22),(33,44)] | {0,3,0} | 22 | 22 + [(-10,2),(-10,3)] | {0,3,0} | 2 | 2 + [(0,-20),(30,-20)] | {0,3,0} | 20 | 20 + [(NaN,1),(NaN,90)] | {0,3,0} | NaN | NaN + [(1,2),(3,4)] | {1,-1,0} | 0.707106781187 | 0.707106781187 + [(0,0),(6,6)] | {1,-1,0} | 0 | 0 + [(10,-10),(-3,-4)] | {1,-1,0} | 0.707106781187 | 0.707106781187 + [(-1000000,200),(300000,-40)] | {1,-1,0} | 0 | 0 + [(11,22),(33,44)] | {1,-1,0} | 7.77817459305 | 7.77817459305 + [(-10,2),(-10,3)] | {1,-1,0} | 8.48528137424 | 8.48528137424 + [(0,-20),(30,-20)] | {1,-1,0} | 14.1421356237 | 14.1421356237 + [(NaN,1),(NaN,90)] | {1,-1,0} | NaN | NaN + [(1,2),(3,4)] | {-0.4,-1,-6} | 7.79920420344 | 7.79920420344 + [(0,0),(6,6)] | {-0.4,-1,-6} | 5.57086014531 | 5.57086014531 + [(10,-10),(-3,-4)] | {-0.4,-1,-6} | 0 | 0 + [(-1000000,200),(300000,-40)] | {-0.4,-1,-6} | 0 | 0 + [(11,22),(33,44)] | {-0.4,-1,-6} | 30.0826447847 | 30.0826447847 + [(-10,2),(-10,3)] | {-0.4,-1,-6} | 3.71390676354 | 3.71390676354 + [(0,-20),(30,-20)] | {-0.4,-1,-6} | 1.85695338177 | 1.85695338177 + [(NaN,1),(NaN,90)] | {-0.4,-1,-6} | NaN | NaN + [(1,2),(3,4)] | {-0.000184615384615,-1,15.3846153846} | 11.3840613445 | 11.3840613445 + [(0,0),(6,6)] | {-0.000184615384615,-1,15.3846153846} | 9.3835075324 | 9.3835075324 + [(10,-10),(-3,-4)] | {-0.000184615384615,-1,15.3846153846} | 19.3851689004 | 19.3851689004 + [(-1000000,200),(300000,-40)] | {-0.000184615384615,-1,15.3846153846} | 7.1054273576e-15 | 7.1054273576e-15 + [(11,22),(33,44)] | {-0.000184615384615,-1,15.3846153846} | 6.61741527185 | 6.61741527185 + [(-10,2),(-10,3)] | {-0.000184615384615,-1,15.3846153846} | 12.3864613274 | 12.3864613274 + [(0,-20),(30,-20)] | {-0.000184615384615,-1,15.3846153846} | 35.3790763202 | 35.3790763202 + [(NaN,1),(NaN,90)] | {-0.000184615384615,-1,15.3846153846} | NaN | NaN + [(1,2),(3,4)] | {3,NaN,5} | NaN | NaN + [(0,0),(6,6)] | {3,NaN,5} | NaN | NaN + [(10,-10),(-3,-4)] | {3,NaN,5} | NaN | NaN + [(-1000000,200),(300000,-40)] | {3,NaN,5} | NaN | NaN + [(11,22),(33,44)] | {3,NaN,5} | NaN | NaN + [(-10,2),(-10,3)] | {3,NaN,5} | NaN | NaN + [(0,-20),(30,-20)] | {3,NaN,5} | NaN | NaN + [(NaN,1),(NaN,90)] | {3,NaN,5} | NaN | NaN + [(1,2),(3,4)] | {NaN,NaN,NaN} | NaN | NaN + [(0,0),(6,6)] | {NaN,NaN,NaN} | NaN | NaN + [(10,-10),(-3,-4)] | {NaN,NaN,NaN} | NaN | NaN + [(-1000000,200),(300000,-40)] | {NaN,NaN,NaN} | NaN | NaN + [(11,22),(33,44)] | {NaN,NaN,NaN} | NaN | NaN + [(-10,2),(-10,3)] | {NaN,NaN,NaN} | NaN | NaN + [(0,-20),(30,-20)] | {NaN,NaN,NaN} | NaN | NaN + [(NaN,1),(NaN,90)] | {NaN,NaN,NaN} | NaN | NaN + [(1,2),(3,4)] | {0,-1,3} | 0 | 0 + [(0,0),(6,6)] | {0,-1,3} | 0 | 0 + [(10,-10),(-3,-4)] | {0,-1,3} | 7 | 7 + [(-1000000,200),(300000,-40)] | {0,-1,3} | 0 | 0 + [(11,22),(33,44)] | {0,-1,3} | 19 | 19 + [(-10,2),(-10,3)] | {0,-1,3} | 0 | 0 + [(0,-20),(30,-20)] | {0,-1,3} | 23 | 23 + [(NaN,1),(NaN,90)] | {0,-1,3} | NaN | NaN + [(1,2),(3,4)] | {-1,0,3} | 0 | 0 + [(0,0),(6,6)] | {-1,0,3} | 0 | 0 + [(10,-10),(-3,-4)] | {-1,0,3} | 0 | 0 + [(-1000000,200),(300000,-40)] | {-1,0,3} | 0 | 0 + [(11,22),(33,44)] | {-1,0,3} | 8 | 8 + [(-10,2),(-10,3)] | {-1,0,3} | 13 | 13 + [(0,-20),(30,-20)] | {-1,0,3} | 0 | 0 + [(NaN,1),(NaN,90)] | {-1,0,3} | NaN | NaN (80 rows) -- Distance to line segment @@ -3640,13 +3599,13 @@ SELECT '' AS twentyfour, 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 @@ -3716,13 +3675,13 @@ SELECT '' AS twentyfour, 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.18.4
pgsql-hackers by date: