I spent some time looking this over, and have a few thoughts: 1. I think it's useful to split the test changes into two patches, as I've done below: first, just add the additional row in point_tbl and let the fallout from that happen, and then in the second patch make the code changes. This way, it's much clearer what the actual behavioral changes are. Some of them don't look right, either. For instance, in the very first hunk in geometry.out, we have this:
- (Infinity,1e+300) | {1,0,5} | NaN | NaN + (Infinity,1e+300) | {1,0,5} | Infinity | Infinity which seems right, and also this: - (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) | {1,-1,0} | NaN | NaN + (1e+300,Infinity) | {-0.4,-1,-6} | NaN | NaN + (1e+300,Infinity) | {-0.000184615384615,-1,15.3846153846} | NaN | NaN which does not. Why aren't these distances infinite as well? 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. 2. Rather than coding around undesirable behavior of float8_min, it seems like it's better to add a primitive to float.h that does what you want, ie "NaN if either input is NaN, else the smaller input". This is more readable, and possibly more efficient (depending on whether the compiler is smart enough to optimize away redundant isnan checks). I did that in the attached. 3. Looking for other calls of float8_min, I wonder why you did not touch the bounding-box calculations in box_interpt_lseg() or boxes_bound_box(). 4. The line changes feel a bit weird, like there's no clear idea of what a "valid" or "invalid" line is. For instance the first hunk in line_construct(): + /* Avoid creating a valid line from an invalid point */ + if (unlikely(isnan(pt->y))) + result->C = get_float8_nan(); Why's it appropriate to set C and only C to NaN? 5. But actually there's a bigger issue with that particular hunk. This code branch is dealing with "draw a vertical line through this point", so why should we care what the point's y coordinate is --- that is, why is this particular change appropriate at all? The usual rule as I understand it is that if a function's result is determined by some of its arguments independently of what another argument's value is, then it doesn't matter if that one is NaN, you can still return the same result. 6. I'm a bit uncomfortable with the use of "bool isnan" in a couple of places. I think it's confusing to use that alongside the isnan() macro. Moreover, it's at least possible that some platforms implement isnan() in a way that would break this usage. The C spec specifically says that isnan() is a macro not a function ... but it doesn't commit to it being a macro-with-arguments. I think "anynan" or something like that would be a better choice of name. [ a bit later... ] Indeed, I get a compile failure on gaur: geo_ops.c: In function 'lseg_closept_lseg': geo_ops.c:2906:17: error: called object 'isnan' is not a function geo_ops.c:2906:32: error: called object 'isnan' is not a function geo_ops.c:2916:16: error: called object 'isnan' is not a function geo_ops.c:2924:16: error: called object 'isnan' is not a function geo_ops.c: In function 'box_closept_point': geo_ops.c:2989:16: error: called object 'isnan' is not a function geo_ops.c:2992:16: error: called object 'isnan' is not a function geo_ops.c:3004:16: error: called object 'isnan' is not a function geo_ops.c:3014:16: error: called object 'isnan' is not a function make: *** [geo_ops.o] Error 1 So that scenario isn't hypothetical. Please rename the variables. regards, tom lane
diff --git a/src/test/regress/expected/create_index.out b/src/test/regress/expected/create_index.out index 93a8736a3f..76679bae8d 100644 --- a/src/test/regress/expected/create_index.out +++ b/src/test/regress/expected/create_index.out @@ -157,7 +157,7 @@ SELECT count(*) FROM point_tbl p WHERE p.f1 << '(0.0, 0.0)'; SELECT count(*) FROM point_tbl p WHERE p.f1 >> '(0.0, 0.0)'; count ------- - 3 + 4 (1 row) SELECT count(*) FROM point_tbl p WHERE p.f1 <^ '(0.0, 0.0)'; @@ -169,7 +169,7 @@ SELECT count(*) FROM point_tbl p WHERE p.f1 <^ '(0.0, 0.0)'; SELECT count(*) FROM point_tbl p WHERE p.f1 >^ '(0.0, 0.0)'; count ------- - 4 + 5 (1 row) SELECT count(*) FROM point_tbl p WHERE p.f1 ~= '(-5, -12)'; @@ -188,10 +188,11 @@ SELECT * FROM point_tbl ORDER BY f1 <-> '0,1'; (10,10) (-5,-12) (5.1,34.5) + (Infinity,1e+300) (1e+300,Infinity) (NaN,NaN) -(10 rows) +(11 rows) SELECT * FROM point_tbl WHERE f1 IS NULL; f1 @@ -202,16 +203,17 @@ SELECT * FROM point_tbl WHERE f1 IS NULL; SELECT * FROM point_tbl WHERE f1 IS NOT NULL ORDER BY f1 <-> '0,1'; f1 ------------------- - (1e-300,-1e-300) (0,0) + (1e-300,-1e-300) (-3,4) (-10,0) (10,10) (-5,-12) (5.1,34.5) (1e+300,Infinity) + (Infinity,1e+300) (NaN,NaN) -(9 rows) +(10 rows) SELECT * FROM point_tbl WHERE f1 <@ '(-10,-10),(10,10)':: box ORDER BY f1 <-> '0,1'; f1 @@ -464,7 +466,7 @@ SELECT count(*) FROM point_tbl p WHERE p.f1 >> '(0.0, 0.0)'; SELECT count(*) FROM point_tbl p WHERE p.f1 >> '(0.0, 0.0)'; count ------- - 3 + 4 (1 row) EXPLAIN (COSTS OFF) @@ -494,7 +496,7 @@ SELECT count(*) FROM point_tbl p WHERE p.f1 >^ '(0.0, 0.0)'; SELECT count(*) FROM point_tbl p WHERE p.f1 >^ '(0.0, 0.0)'; count ------- - 4 + 5 (1 row) EXPLAIN (COSTS OFF) @@ -530,10 +532,11 @@ SELECT * FROM point_tbl ORDER BY f1 <-> '0,1'; (10,10) (-5,-12) (5.1,34.5) + (Infinity,1e+300) (1e+300,Infinity) (NaN,NaN) -(10 rows) +(11 rows) EXPLAIN (COSTS OFF) SELECT * FROM point_tbl WHERE f1 IS NULL; @@ -568,9 +571,10 @@ SELECT * FROM point_tbl WHERE f1 IS NOT NULL ORDER BY f1 <-> '0,1'; (10,10) (-5,-12) (5.1,34.5) + (Infinity,1e+300) (1e+300,Infinity) (NaN,NaN) -(9 rows) +(10 rows) EXPLAIN (COSTS OFF) SELECT * FROM point_tbl WHERE f1 <@ '(-10,-10),(10,10)':: box ORDER BY f1 <-> '0,1'; diff --git a/src/test/regress/expected/geometry.out b/src/test/regress/expected/geometry.out index 5b9d37030f..81202a4c33 100644 --- a/src/test/regress/expected/geometry.out +++ b/src/test/regress/expected/geometry.out @@ -120,6 +120,7 @@ SELECT p1.f1, p2.f1, slope(p1.f1, p2.f1) FROM POINT_TBL p1, POINT_TBL p2; (0,0) | (-5,-12) | 2.4 (0,0) | (1e-300,-1e-300) | 1.79769313486e+308 (0,0) | (1e+300,Infinity) | Infinity + (0,0) | (Infinity,1e+300) | 0 (0,0) | (NaN,NaN) | NaN (0,0) | (10,10) | 1 (-10,0) | (0,0) | 0 @@ -129,6 +130,7 @@ SELECT p1.f1, p2.f1, slope(p1.f1, p2.f1) FROM POINT_TBL p1, POINT_TBL p2; (-10,0) | (-5,-12) | -2.4 (-10,0) | (1e-300,-1e-300) | 0 (-10,0) | (1e+300,Infinity) | Infinity + (-10,0) | (Infinity,1e+300) | 0 (-10,0) | (NaN,NaN) | NaN (-10,0) | (10,10) | 0.5 (-3,4) | (0,0) | -1.33333333333 @@ -138,6 +140,7 @@ SELECT p1.f1, p2.f1, slope(p1.f1, p2.f1) FROM POINT_TBL p1, POINT_TBL p2; (-3,4) | (-5,-12) | 8 (-3,4) | (1e-300,-1e-300) | -1.33333333333 (-3,4) | (1e+300,Infinity) | Infinity + (-3,4) | (Infinity,1e+300) | 0 (-3,4) | (NaN,NaN) | NaN (-3,4) | (10,10) | 0.461538461538 (5.1,34.5) | (0,0) | 6.76470588235 @@ -147,6 +150,7 @@ SELECT p1.f1, p2.f1, slope(p1.f1, p2.f1) FROM POINT_TBL p1, POINT_TBL p2; (5.1,34.5) | (-5,-12) | 4.60396039604 (5.1,34.5) | (1e-300,-1e-300) | 6.76470588235 (5.1,34.5) | (1e+300,Infinity) | Infinity + (5.1,34.5) | (Infinity,1e+300) | 0 (5.1,34.5) | (NaN,NaN) | NaN (5.1,34.5) | (10,10) | -5 (-5,-12) | (0,0) | 2.4 @@ -156,6 +160,7 @@ SELECT p1.f1, p2.f1, slope(p1.f1, p2.f1) FROM POINT_TBL p1, POINT_TBL p2; (-5,-12) | (-5,-12) | 1.79769313486e+308 (-5,-12) | (1e-300,-1e-300) | 2.4 (-5,-12) | (1e+300,Infinity) | Infinity + (-5,-12) | (Infinity,1e+300) | 0 (-5,-12) | (NaN,NaN) | NaN (-5,-12) | (10,10) | 1.46666666667 (1e-300,-1e-300) | (0,0) | 1.79769313486e+308 @@ -165,6 +170,7 @@ SELECT p1.f1, p2.f1, slope(p1.f1, p2.f1) FROM POINT_TBL p1, POINT_TBL p2; (1e-300,-1e-300) | (-5,-12) | 2.4 (1e-300,-1e-300) | (1e-300,-1e-300) | 1.79769313486e+308 (1e-300,-1e-300) | (1e+300,Infinity) | Infinity + (1e-300,-1e-300) | (Infinity,1e+300) | 0 (1e-300,-1e-300) | (NaN,NaN) | NaN (1e-300,-1e-300) | (10,10) | 1 (1e+300,Infinity) | (0,0) | Infinity @@ -174,8 +180,19 @@ SELECT p1.f1, p2.f1, slope(p1.f1, p2.f1) FROM POINT_TBL p1, POINT_TBL p2; (1e+300,Infinity) | (-5,-12) | Infinity (1e+300,Infinity) | (1e-300,-1e-300) | Infinity (1e+300,Infinity) | (1e+300,Infinity) | 1.79769313486e+308 + (1e+300,Infinity) | (Infinity,1e+300) | NaN (1e+300,Infinity) | (NaN,NaN) | NaN (1e+300,Infinity) | (10,10) | Infinity + (Infinity,1e+300) | (0,0) | 0 + (Infinity,1e+300) | (-10,0) | 0 + (Infinity,1e+300) | (-3,4) | 0 + (Infinity,1e+300) | (5.1,34.5) | 0 + (Infinity,1e+300) | (-5,-12) | 0 + (Infinity,1e+300) | (1e-300,-1e-300) | 0 + (Infinity,1e+300) | (1e+300,Infinity) | NaN + (Infinity,1e+300) | (Infinity,1e+300) | 0 + (Infinity,1e+300) | (NaN,NaN) | NaN + (Infinity,1e+300) | (10,10) | 0 (NaN,NaN) | (0,0) | NaN (NaN,NaN) | (-10,0) | NaN (NaN,NaN) | (-3,4) | NaN @@ -183,6 +200,7 @@ SELECT p1.f1, p2.f1, slope(p1.f1, p2.f1) FROM POINT_TBL p1, POINT_TBL p2; (NaN,NaN) | (-5,-12) | NaN (NaN,NaN) | (1e-300,-1e-300) | NaN (NaN,NaN) | (1e+300,Infinity) | NaN + (NaN,NaN) | (Infinity,1e+300) | NaN (NaN,NaN) | (NaN,NaN) | NaN (NaN,NaN) | (10,10) | NaN (10,10) | (0,0) | 1 @@ -192,14 +210,15 @@ SELECT p1.f1, p2.f1, slope(p1.f1, p2.f1) FROM POINT_TBL p1, POINT_TBL p2; (10,10) | (-5,-12) | 1.46666666667 (10,10) | (1e-300,-1e-300) | 1 (10,10) | (1e+300,Infinity) | Infinity + (10,10) | (Infinity,1e+300) | 0 (10,10) | (NaN,NaN) | NaN (10,10) | (10,10) | 1.79769313486e+308 -(81 rows) +(100 rows) -- Add point SELECT p1.f1, p2.f1, p1.f1 + p2.f1 FROM POINT_TBL p1, POINT_TBL p2; - f1 | f1 | ?column? --------------------+-------------------+------------------- + f1 | f1 | ?column? +-------------------+-------------------+--------------------- (0,0) | (0,0) | (0,0) (0,0) | (-10,0) | (-10,0) (0,0) | (-3,4) | (-3,4) @@ -207,6 +226,7 @@ SELECT p1.f1, p2.f1, p1.f1 + p2.f1 FROM POINT_TBL p1, POINT_TBL p2; (0,0) | (-5,-12) | (-5,-12) (0,0) | (1e-300,-1e-300) | (1e-300,-1e-300) (0,0) | (1e+300,Infinity) | (1e+300,Infinity) + (0,0) | (Infinity,1e+300) | (Infinity,1e+300) (0,0) | (NaN,NaN) | (NaN,NaN) (0,0) | (10,10) | (10,10) (-10,0) | (0,0) | (-10,0) @@ -216,6 +236,7 @@ SELECT p1.f1, p2.f1, p1.f1 + p2.f1 FROM POINT_TBL p1, POINT_TBL p2; (-10,0) | (-5,-12) | (-15,-12) (-10,0) | (1e-300,-1e-300) | (-10,-1e-300) (-10,0) | (1e+300,Infinity) | (1e+300,Infinity) + (-10,0) | (Infinity,1e+300) | (Infinity,1e+300) (-10,0) | (NaN,NaN) | (NaN,NaN) (-10,0) | (10,10) | (0,10) (-3,4) | (0,0) | (-3,4) @@ -225,6 +246,7 @@ SELECT p1.f1, p2.f1, p1.f1 + p2.f1 FROM POINT_TBL p1, POINT_TBL p2; (-3,4) | (-5,-12) | (-8,-8) (-3,4) | (1e-300,-1e-300) | (-3,4) (-3,4) | (1e+300,Infinity) | (1e+300,Infinity) + (-3,4) | (Infinity,1e+300) | (Infinity,1e+300) (-3,4) | (NaN,NaN) | (NaN,NaN) (-3,4) | (10,10) | (7,14) (5.1,34.5) | (0,0) | (5.1,34.5) @@ -234,6 +256,7 @@ SELECT p1.f1, p2.f1, p1.f1 + p2.f1 FROM POINT_TBL p1, POINT_TBL p2; (5.1,34.5) | (-5,-12) | (0.1,22.5) (5.1,34.5) | (1e-300,-1e-300) | (5.1,34.5) (5.1,34.5) | (1e+300,Infinity) | (1e+300,Infinity) + (5.1,34.5) | (Infinity,1e+300) | (Infinity,1e+300) (5.1,34.5) | (NaN,NaN) | (NaN,NaN) (5.1,34.5) | (10,10) | (15.1,44.5) (-5,-12) | (0,0) | (-5,-12) @@ -243,6 +266,7 @@ SELECT p1.f1, p2.f1, p1.f1 + p2.f1 FROM POINT_TBL p1, POINT_TBL p2; (-5,-12) | (-5,-12) | (-10,-24) (-5,-12) | (1e-300,-1e-300) | (-5,-12) (-5,-12) | (1e+300,Infinity) | (1e+300,Infinity) + (-5,-12) | (Infinity,1e+300) | (Infinity,1e+300) (-5,-12) | (NaN,NaN) | (NaN,NaN) (-5,-12) | (10,10) | (5,-2) (1e-300,-1e-300) | (0,0) | (1e-300,-1e-300) @@ -252,6 +276,7 @@ SELECT p1.f1, p2.f1, p1.f1 + p2.f1 FROM POINT_TBL p1, POINT_TBL p2; (1e-300,-1e-300) | (-5,-12) | (-5,-12) (1e-300,-1e-300) | (1e-300,-1e-300) | (2e-300,-2e-300) (1e-300,-1e-300) | (1e+300,Infinity) | (1e+300,Infinity) + (1e-300,-1e-300) | (Infinity,1e+300) | (Infinity,1e+300) (1e-300,-1e-300) | (NaN,NaN) | (NaN,NaN) (1e-300,-1e-300) | (10,10) | (10,10) (1e+300,Infinity) | (0,0) | (1e+300,Infinity) @@ -261,8 +286,19 @@ SELECT p1.f1, p2.f1, p1.f1 + p2.f1 FROM POINT_TBL p1, POINT_TBL p2; (1e+300,Infinity) | (-5,-12) | (1e+300,Infinity) (1e+300,Infinity) | (1e-300,-1e-300) | (1e+300,Infinity) (1e+300,Infinity) | (1e+300,Infinity) | (2e+300,Infinity) + (1e+300,Infinity) | (Infinity,1e+300) | (Infinity,Infinity) (1e+300,Infinity) | (NaN,NaN) | (NaN,NaN) (1e+300,Infinity) | (10,10) | (1e+300,Infinity) + (Infinity,1e+300) | (0,0) | (Infinity,1e+300) + (Infinity,1e+300) | (-10,0) | (Infinity,1e+300) + (Infinity,1e+300) | (-3,4) | (Infinity,1e+300) + (Infinity,1e+300) | (5.1,34.5) | (Infinity,1e+300) + (Infinity,1e+300) | (-5,-12) | (Infinity,1e+300) + (Infinity,1e+300) | (1e-300,-1e-300) | (Infinity,1e+300) + (Infinity,1e+300) | (1e+300,Infinity) | (Infinity,Infinity) + (Infinity,1e+300) | (Infinity,1e+300) | (Infinity,2e+300) + (Infinity,1e+300) | (NaN,NaN) | (NaN,NaN) + (Infinity,1e+300) | (10,10) | (Infinity,1e+300) (NaN,NaN) | (0,0) | (NaN,NaN) (NaN,NaN) | (-10,0) | (NaN,NaN) (NaN,NaN) | (-3,4) | (NaN,NaN) @@ -270,6 +306,7 @@ SELECT p1.f1, p2.f1, p1.f1 + p2.f1 FROM POINT_TBL p1, POINT_TBL p2; (NaN,NaN) | (-5,-12) | (NaN,NaN) (NaN,NaN) | (1e-300,-1e-300) | (NaN,NaN) (NaN,NaN) | (1e+300,Infinity) | (NaN,NaN) + (NaN,NaN) | (Infinity,1e+300) | (NaN,NaN) (NaN,NaN) | (NaN,NaN) | (NaN,NaN) (NaN,NaN) | (10,10) | (NaN,NaN) (10,10) | (0,0) | (10,10) @@ -279,14 +316,15 @@ SELECT p1.f1, p2.f1, p1.f1 + p2.f1 FROM POINT_TBL p1, POINT_TBL p2; (10,10) | (-5,-12) | (5,-2) (10,10) | (1e-300,-1e-300) | (10,10) (10,10) | (1e+300,Infinity) | (1e+300,Infinity) + (10,10) | (Infinity,1e+300) | (Infinity,1e+300) (10,10) | (NaN,NaN) | (NaN,NaN) (10,10) | (10,10) | (20,20) -(81 rows) +(100 rows) -- Subtract point SELECT p1.f1, p2.f1, p1.f1 - p2.f1 FROM POINT_TBL p1, POINT_TBL p2; - f1 | f1 | ?column? --------------------+-------------------+--------------------- + f1 | f1 | ?column? +-------------------+-------------------+---------------------- (0,0) | (0,0) | (0,0) (0,0) | (-10,0) | (10,0) (0,0) | (-3,4) | (3,-4) @@ -294,6 +332,7 @@ SELECT p1.f1, p2.f1, p1.f1 - p2.f1 FROM POINT_TBL p1, POINT_TBL p2; (0,0) | (-5,-12) | (5,12) (0,0) | (1e-300,-1e-300) | (-1e-300,1e-300) (0,0) | (1e+300,Infinity) | (-1e+300,-Infinity) + (0,0) | (Infinity,1e+300) | (-Infinity,-1e+300) (0,0) | (NaN,NaN) | (NaN,NaN) (0,0) | (10,10) | (-10,-10) (-10,0) | (0,0) | (-10,0) @@ -303,6 +342,7 @@ SELECT p1.f1, p2.f1, p1.f1 - p2.f1 FROM POINT_TBL p1, POINT_TBL p2; (-10,0) | (-5,-12) | (-5,12) (-10,0) | (1e-300,-1e-300) | (-10,1e-300) (-10,0) | (1e+300,Infinity) | (-1e+300,-Infinity) + (-10,0) | (Infinity,1e+300) | (-Infinity,-1e+300) (-10,0) | (NaN,NaN) | (NaN,NaN) (-10,0) | (10,10) | (-20,-10) (-3,4) | (0,0) | (-3,4) @@ -312,6 +352,7 @@ SELECT p1.f1, p2.f1, p1.f1 - p2.f1 FROM POINT_TBL p1, POINT_TBL p2; (-3,4) | (-5,-12) | (2,16) (-3,4) | (1e-300,-1e-300) | (-3,4) (-3,4) | (1e+300,Infinity) | (-1e+300,-Infinity) + (-3,4) | (Infinity,1e+300) | (-Infinity,-1e+300) (-3,4) | (NaN,NaN) | (NaN,NaN) (-3,4) | (10,10) | (-13,-6) (5.1,34.5) | (0,0) | (5.1,34.5) @@ -321,6 +362,7 @@ SELECT p1.f1, p2.f1, p1.f1 - p2.f1 FROM POINT_TBL p1, POINT_TBL p2; (5.1,34.5) | (-5,-12) | (10.1,46.5) (5.1,34.5) | (1e-300,-1e-300) | (5.1,34.5) (5.1,34.5) | (1e+300,Infinity) | (-1e+300,-Infinity) + (5.1,34.5) | (Infinity,1e+300) | (-Infinity,-1e+300) (5.1,34.5) | (NaN,NaN) | (NaN,NaN) (5.1,34.5) | (10,10) | (-4.9,24.5) (-5,-12) | (0,0) | (-5,-12) @@ -330,6 +372,7 @@ SELECT p1.f1, p2.f1, p1.f1 - p2.f1 FROM POINT_TBL p1, POINT_TBL p2; (-5,-12) | (-5,-12) | (0,0) (-5,-12) | (1e-300,-1e-300) | (-5,-12) (-5,-12) | (1e+300,Infinity) | (-1e+300,-Infinity) + (-5,-12) | (Infinity,1e+300) | (-Infinity,-1e+300) (-5,-12) | (NaN,NaN) | (NaN,NaN) (-5,-12) | (10,10) | (-15,-22) (1e-300,-1e-300) | (0,0) | (1e-300,-1e-300) @@ -339,6 +382,7 @@ SELECT p1.f1, p2.f1, p1.f1 - p2.f1 FROM POINT_TBL p1, POINT_TBL p2; (1e-300,-1e-300) | (-5,-12) | (5,12) (1e-300,-1e-300) | (1e-300,-1e-300) | (0,0) (1e-300,-1e-300) | (1e+300,Infinity) | (-1e+300,-Infinity) + (1e-300,-1e-300) | (Infinity,1e+300) | (-Infinity,-1e+300) (1e-300,-1e-300) | (NaN,NaN) | (NaN,NaN) (1e-300,-1e-300) | (10,10) | (-10,-10) (1e+300,Infinity) | (0,0) | (1e+300,Infinity) @@ -348,8 +392,19 @@ SELECT p1.f1, p2.f1, p1.f1 - p2.f1 FROM POINT_TBL p1, POINT_TBL p2; (1e+300,Infinity) | (-5,-12) | (1e+300,Infinity) (1e+300,Infinity) | (1e-300,-1e-300) | (1e+300,Infinity) (1e+300,Infinity) | (1e+300,Infinity) | (0,NaN) + (1e+300,Infinity) | (Infinity,1e+300) | (-Infinity,Infinity) (1e+300,Infinity) | (NaN,NaN) | (NaN,NaN) (1e+300,Infinity) | (10,10) | (1e+300,Infinity) + (Infinity,1e+300) | (0,0) | (Infinity,1e+300) + (Infinity,1e+300) | (-10,0) | (Infinity,1e+300) + (Infinity,1e+300) | (-3,4) | (Infinity,1e+300) + (Infinity,1e+300) | (5.1,34.5) | (Infinity,1e+300) + (Infinity,1e+300) | (-5,-12) | (Infinity,1e+300) + (Infinity,1e+300) | (1e-300,-1e-300) | (Infinity,1e+300) + (Infinity,1e+300) | (1e+300,Infinity) | (Infinity,-Infinity) + (Infinity,1e+300) | (Infinity,1e+300) | (NaN,0) + (Infinity,1e+300) | (NaN,NaN) | (NaN,NaN) + (Infinity,1e+300) | (10,10) | (Infinity,1e+300) (NaN,NaN) | (0,0) | (NaN,NaN) (NaN,NaN) | (-10,0) | (NaN,NaN) (NaN,NaN) | (-3,4) | (NaN,NaN) @@ -357,6 +412,7 @@ SELECT p1.f1, p2.f1, p1.f1 - p2.f1 FROM POINT_TBL p1, POINT_TBL p2; (NaN,NaN) | (-5,-12) | (NaN,NaN) (NaN,NaN) | (1e-300,-1e-300) | (NaN,NaN) (NaN,NaN) | (1e+300,Infinity) | (NaN,NaN) + (NaN,NaN) | (Infinity,1e+300) | (NaN,NaN) (NaN,NaN) | (NaN,NaN) | (NaN,NaN) (NaN,NaN) | (10,10) | (NaN,NaN) (10,10) | (0,0) | (10,10) @@ -366,9 +422,10 @@ SELECT p1.f1, p2.f1, p1.f1 - p2.f1 FROM POINT_TBL p1, POINT_TBL p2; (10,10) | (-5,-12) | (15,22) (10,10) | (1e-300,-1e-300) | (10,10) (10,10) | (1e+300,Infinity) | (-1e+300,-Infinity) + (10,10) | (Infinity,1e+300) | (-Infinity,-1e+300) (10,10) | (NaN,NaN) | (NaN,NaN) (10,10) | (10,10) | (0,0) -(81 rows) +(100 rows) -- Multiply with point SELECT p1.f1, p2.f1, p1.f1 * p2.f1 FROM POINT_TBL p1, POINT_TBL p2 WHERE p1.f1[0] BETWEEN 1 AND 1000; @@ -388,11 +445,13 @@ SELECT p1.f1, p2.f1, p1.f1 * p2.f1 FROM POINT_TBL p1, POINT_TBL p2 WHERE p1.f1[0 (10,10) | (1e-300,-1e-300) | (2e-299,0) (5.1,34.5) | (1e+300,Infinity) | (-Infinity,Infinity) (10,10) | (1e+300,Infinity) | (-Infinity,Infinity) + (5.1,34.5) | (Infinity,1e+300) | (Infinity,Infinity) + (10,10) | (Infinity,1e+300) | (Infinity,Infinity) (5.1,34.5) | (NaN,NaN) | (NaN,NaN) (10,10) | (NaN,NaN) | (NaN,NaN) (5.1,34.5) | (10,10) | (-294,396) (10,10) | (10,10) | (0,200) -(18 rows) +(20 rows) -- Underflow error SELECT p1.f1, p2.f1, p1.f1 * p2.f1 FROM POINT_TBL p1, POINT_TBL p2 WHERE p1.f1[0] < 1; @@ -415,11 +474,13 @@ SELECT p1.f1, p2.f1, p1.f1 / p2.f1 FROM POINT_TBL p1, POINT_TBL p2 WHERE p2.f1[0 (1e-300,-1e-300) | (10,10) | (0,-1e-301) (1e+300,Infinity) | (5.1,34.5) | (Infinity,Infinity) (1e+300,Infinity) | (10,10) | (Infinity,Infinity) + (Infinity,1e+300) | (5.1,34.5) | (Infinity,-Infinity) + (Infinity,1e+300) | (10,10) | (Infinity,-Infinity) (NaN,NaN) | (5.1,34.5) | (NaN,NaN) (NaN,NaN) | (10,10) | (NaN,NaN) (10,10) | (5.1,34.5) | (0.325588278822,-0.241724631247) (10,10) | (10,10) | (1,0) -(18 rows) +(20 rows) -- Overflow error SELECT p1.f1, p2.f1, p1.f1 / p2.f1 FROM POINT_TBL p1, POINT_TBL p2 WHERE p2.f1[0] > 1000; @@ -501,6 +562,16 @@ SELECT p.f1, l.s, p.f1 <-> l.s AS dist_pl, l.s <-> p.f1 AS dist_lp FROM POINT_TB (1e+300,Infinity) | {NaN,NaN,NaN} | NaN | NaN (1e+300,Infinity) | {0,-1,3} | Infinity | Infinity (1e+300,Infinity) | {-1,0,3} | NaN | NaN + (Infinity,1e+300) | {0,-1,5} | NaN | NaN + (Infinity,1e+300) | {1,0,5} | NaN | NaN + (Infinity,1e+300) | {0,3,0} | NaN | NaN + (Infinity,1e+300) | {1,-1,0} | NaN | NaN + (Infinity,1e+300) | {-0.4,-1,-6} | NaN | NaN + (Infinity,1e+300) | {-0.000184615384615,-1,15.3846153846} | NaN | NaN + (Infinity,1e+300) | {3,NaN,5} | NaN | NaN + (Infinity,1e+300) | {NaN,NaN,NaN} | NaN | NaN + (Infinity,1e+300) | {0,-1,3} | NaN | NaN + (Infinity,1e+300) | {-1,0,3} | NaN | NaN (NaN,NaN) | {0,-1,5} | NaN | NaN (NaN,NaN) | {1,0,5} | NaN | NaN (NaN,NaN) | {0,3,0} | NaN | NaN @@ -521,7 +592,7 @@ SELECT p.f1, l.s, p.f1 <-> l.s AS dist_pl, l.s <-> p.f1 AS dist_lp FROM POINT_TB (10,10) | {NaN,NaN,NaN} | NaN | NaN (10,10) | {0,-1,3} | 7 | 7 (10,10) | {-1,0,3} | 7 | 7 -(90 rows) +(100 rows) -- Distance to line segment SELECT p.f1, l.s, p.f1 <-> l.s AS dist_ps, l.s <-> p.f1 AS dist_sp FROM POINT_TBL p, LSEG_TBL l; @@ -583,6 +654,14 @@ SELECT p.f1, l.s, p.f1 <-> l.s AS dist_ps, l.s <-> p.f1 AS dist_sp FROM POINT_TB (1e+300,Infinity) | [(-10,2),(-10,3)] | Infinity | Infinity (1e+300,Infinity) | [(0,-20),(30,-20)] | Infinity | Infinity (1e+300,Infinity) | [(NaN,1),(NaN,90)] | Infinity | Infinity + (Infinity,1e+300) | [(1,2),(3,4)] | Infinity | Infinity + (Infinity,1e+300) | [(0,0),(6,6)] | Infinity | Infinity + (Infinity,1e+300) | [(10,-10),(-3,-4)] | Infinity | Infinity + (Infinity,1e+300) | [(-1000000,200),(300000,-40)] | Infinity | Infinity + (Infinity,1e+300) | [(11,22),(33,44)] | Infinity | Infinity + (Infinity,1e+300) | [(-10,2),(-10,3)] | Infinity | Infinity + (Infinity,1e+300) | [(0,-20),(30,-20)] | Infinity | Infinity + (Infinity,1e+300) | [(NaN,1),(NaN,90)] | NaN | NaN (NaN,NaN) | [(1,2),(3,4)] | NaN | NaN (NaN,NaN) | [(0,0),(6,6)] | NaN | NaN (NaN,NaN) | [(10,-10),(-3,-4)] | NaN | NaN @@ -599,7 +678,7 @@ SELECT p.f1, l.s, p.f1 <-> l.s AS dist_ps, l.s <-> p.f1 AS dist_sp FROM POINT_TB (10,10) | [(-10,2),(-10,3)] | 21.1896201004 | 21.1896201004 (10,10) | [(0,-20),(30,-20)] | 30 | 30 (10,10) | [(NaN,1),(NaN,90)] | NaN | NaN -(72 rows) +(80 rows) -- Distance to box SELECT p.f1, b.f1, p.f1 <-> b.f1 AS dist_pb, b.f1 <-> p.f1 AS dist_bp FROM POINT_TBL p, BOX_TBL b; @@ -640,6 +719,11 @@ SELECT p.f1, b.f1, p.f1 <-> b.f1 AS dist_pb, b.f1 <-> p.f1 AS dist_bp FROM POINT (1e+300,Infinity) | (-2,2),(-8,-10) | Infinity | Infinity (1e+300,Infinity) | (2.5,3.5),(2.5,2.5) | Infinity | Infinity (1e+300,Infinity) | (3,3),(3,3) | Infinity | Infinity + (Infinity,1e+300) | (2,2),(0,0) | Infinity | Infinity + (Infinity,1e+300) | (3,3),(1,1) | Infinity | Infinity + (Infinity,1e+300) | (-2,2),(-8,-10) | Infinity | Infinity + (Infinity,1e+300) | (2.5,3.5),(2.5,2.5) | Infinity | Infinity + (Infinity,1e+300) | (3,3),(3,3) | Infinity | Infinity (NaN,NaN) | (2,2),(0,0) | NaN | NaN (NaN,NaN) | (3,3),(1,1) | NaN | NaN (NaN,NaN) | (-2,2),(-8,-10) | NaN | NaN @@ -650,7 +734,7 @@ SELECT p.f1, b.f1, p.f1 <-> b.f1 AS dist_pb, b.f1 <-> p.f1 AS dist_bp FROM POINT (10,10) | (-2,2),(-8,-10) | 14.4222051019 | 14.4222051019 (10,10) | (2.5,3.5),(2.5,2.5) | 9.92471662064 | 9.92471662064 (10,10) | (3,3),(3,3) | 9.89949493661 | 9.89949493661 -(45 rows) +(50 rows) -- Distance to path SELECT p.f1, p1.f1, p.f1 <-> p1.f1 AS dist_ppath, p1.f1 <-> p.f1 AS dist_pathp FROM POINT_TBL p, PATH_TBL p1; @@ -719,6 +803,15 @@ SELECT p.f1, p1.f1, p.f1 <-> p1.f1 AS dist_ppath, p1.f1 <-> p.f1 AS dist_pathp F (1e+300,Infinity) | ((10,20)) | Infinity | Infinity (1e+300,Infinity) | [(11,12),(13,14)] | Infinity | Infinity (1e+300,Infinity) | ((11,12),(13,14)) | Infinity | Infinity + (Infinity,1e+300) | [(1,2),(3,4)] | Infinity | Infinity + (Infinity,1e+300) | ((1,2),(3,4)) | Infinity | Infinity + (Infinity,1e+300) | [(0,0),(3,0),(4,5),(1,6)] | Infinity | Infinity + (Infinity,1e+300) | ((1,2),(3,4)) | Infinity | Infinity + (Infinity,1e+300) | ((1,2),(3,4)) | Infinity | Infinity + (Infinity,1e+300) | [(1,2),(3,4)] | Infinity | Infinity + (Infinity,1e+300) | ((10,20)) | Infinity | Infinity + (Infinity,1e+300) | [(11,12),(13,14)] | Infinity | Infinity + (Infinity,1e+300) | ((11,12),(13,14)) | Infinity | Infinity (NaN,NaN) | [(1,2),(3,4)] | NaN | NaN (NaN,NaN) | ((1,2),(3,4)) | NaN | NaN (NaN,NaN) | [(0,0),(3,0),(4,5),(1,6)] | NaN | NaN @@ -737,7 +830,7 @@ SELECT p.f1, p1.f1, p.f1 <-> p1.f1 AS dist_ppath, p1.f1 <-> p.f1 AS dist_pathp F (10,10) | ((10,20)) | 10 | 10 (10,10) | [(11,12),(13,14)] | 2.2360679775 | 2.2360679775 (10,10) | ((11,12),(13,14)) | 2.2360679775 | 2.2360679775 -(81 rows) +(90 rows) -- Distance to polygon SELECT p.f1, p1.f1, p.f1 <-> p1.f1 AS dist_ppoly, p1.f1 <-> p.f1 AS dist_polyp FROM POINT_TBL p, POLYGON_TBL p1; @@ -792,6 +885,13 @@ SELECT p.f1, p1.f1, p.f1 <-> p1.f1 AS dist_ppoly, p1.f1 <-> p.f1 AS dist_polyp F (1e+300,Infinity) | ((1,2),(7,8),(5,6),(3,-4)) | Infinity | Infinity (1e+300,Infinity) | ((0,0)) | Infinity | Infinity (1e+300,Infinity) | ((0,1),(0,1)) | Infinity | Infinity + (Infinity,1e+300) | ((2,0),(2,4),(0,0)) | Infinity | Infinity + (Infinity,1e+300) | ((3,1),(3,3),(1,0)) | Infinity | Infinity + (Infinity,1e+300) | ((1,2),(3,4),(5,6),(7,8)) | Infinity | Infinity + (Infinity,1e+300) | ((7,8),(5,6),(3,4),(1,2)) | Infinity | Infinity + (Infinity,1e+300) | ((1,2),(7,8),(5,6),(3,-4)) | Infinity | Infinity + (Infinity,1e+300) | ((0,0)) | Infinity | Infinity + (Infinity,1e+300) | ((0,1),(0,1)) | Infinity | Infinity (NaN,NaN) | ((2,0),(2,4),(0,0)) | 0 | 0 (NaN,NaN) | ((3,1),(3,3),(1,0)) | 0 | 0 (NaN,NaN) | ((1,2),(3,4),(5,6),(7,8)) | 0 | 0 @@ -806,7 +906,7 @@ SELECT p.f1, p1.f1, p.f1 <-> p1.f1 AS dist_ppoly, p1.f1 <-> p.f1 AS dist_polyp F (10,10) | ((1,2),(7,8),(5,6),(3,-4)) | 3.60555127546 | 3.60555127546 (10,10) | ((0,0)) | 14.1421356237 | 14.1421356237 (10,10) | ((0,1),(0,1)) | 13.4536240471 | 13.4536240471 -(63 rows) +(70 rows) -- Closest point to line SELECT p.f1, l.s, p.f1 ## l.s FROM POINT_TBL p, LINE_TBL l; @@ -882,6 +982,16 @@ SELECT p.f1, l.s, p.f1 ## l.s FROM POINT_TBL p, LINE_TBL l; (1e+300,Infinity) | {NaN,NaN,NaN} | (1e+300,Infinity) | {0,-1,3} | (1e+300,3) (1e+300,Infinity) | {-1,0,3} | + (Infinity,1e+300) | {0,-1,5} | + (Infinity,1e+300) | {1,0,5} | + (Infinity,1e+300) | {0,3,0} | + (Infinity,1e+300) | {1,-1,0} | + (Infinity,1e+300) | {-0.4,-1,-6} | + (Infinity,1e+300) | {-0.000184615384615,-1,15.3846153846} | + (Infinity,1e+300) | {3,NaN,5} | + (Infinity,1e+300) | {NaN,NaN,NaN} | + (Infinity,1e+300) | {0,-1,3} | + (Infinity,1e+300) | {-1,0,3} | (NaN,NaN) | {0,-1,5} | (NaN,NaN) | {1,0,5} | (NaN,NaN) | {0,3,0} | @@ -902,7 +1012,7 @@ SELECT p.f1, l.s, p.f1 ## l.s FROM POINT_TBL p, LINE_TBL l; (10,10) | {NaN,NaN,NaN} | (10,10) | {0,-1,3} | (10,3) (10,10) | {-1,0,3} | (3,10) -(90 rows) +(100 rows) -- Closest point to line segment SELECT p.f1, l.s, p.f1 ## l.s FROM POINT_TBL p, LSEG_TBL l; @@ -964,6 +1074,14 @@ SELECT p.f1, l.s, p.f1 ## l.s FROM POINT_TBL p, LSEG_TBL l; (1e+300,Infinity) | [(-10,2),(-10,3)] | (-10,3) (1e+300,Infinity) | [(0,-20),(30,-20)] | (30,-20) (1e+300,Infinity) | [(NaN,1),(NaN,90)] | (NaN,90) + (Infinity,1e+300) | [(1,2),(3,4)] | (3,4) + (Infinity,1e+300) | [(0,0),(6,6)] | (6,6) + (Infinity,1e+300) | [(10,-10),(-3,-4)] | (-3,-4) + (Infinity,1e+300) | [(-1000000,200),(300000,-40)] | (300000,-40) + (Infinity,1e+300) | [(11,22),(33,44)] | (33,44) + (Infinity,1e+300) | [(-10,2),(-10,3)] | (-10,3) + (Infinity,1e+300) | [(0,-20),(30,-20)] | (30,-20) + (Infinity,1e+300) | [(NaN,1),(NaN,90)] | (NaN,NaN) | [(1,2),(3,4)] | (NaN,NaN) | [(0,0),(6,6)] | (NaN,NaN) | [(10,-10),(-3,-4)] | @@ -980,7 +1098,7 @@ SELECT p.f1, l.s, p.f1 ## l.s FROM POINT_TBL p, LSEG_TBL l; (10,10) | [(-10,2),(-10,3)] | (-10,3) (10,10) | [(0,-20),(30,-20)] | (10,-20) (10,10) | [(NaN,1),(NaN,90)] | -(72 rows) +(80 rows) -- Closest point to box SELECT p.f1, b.f1, p.f1 ## b.f1 FROM POINT_TBL p, BOX_TBL b; @@ -1021,6 +1139,11 @@ SELECT p.f1, b.f1, p.f1 ## b.f1 FROM POINT_TBL p, BOX_TBL b; (1e+300,Infinity) | (-2,2),(-8,-10) | (-8,2) (1e+300,Infinity) | (2.5,3.5),(2.5,2.5) | (2.5,3.5) (1e+300,Infinity) | (3,3),(3,3) | (3,3) + (Infinity,1e+300) | (2,2),(0,0) | (0,2) + (Infinity,1e+300) | (3,3),(1,1) | (1,3) + (Infinity,1e+300) | (-2,2),(-8,-10) | (-8,2) + (Infinity,1e+300) | (2.5,3.5),(2.5,2.5) | (2.5,3.5) + (Infinity,1e+300) | (3,3),(3,3) | (3,3) (NaN,NaN) | (2,2),(0,0) | (NaN,NaN) | (3,3),(1,1) | (NaN,NaN) | (-2,2),(-8,-10) | @@ -1031,7 +1154,7 @@ SELECT p.f1, b.f1, p.f1 ## b.f1 FROM POINT_TBL p, BOX_TBL b; (10,10) | (-2,2),(-8,-10) | (-2,2) (10,10) | (2.5,3.5),(2.5,2.5) | (2.5,3.5) (10,10) | (3,3),(3,3) | (3,3) -(45 rows) +(50 rows) -- On line SELECT p.f1, l.s FROM POINT_TBL p, LINE_TBL l WHERE p.f1 <@ l.s; @@ -2347,6 +2470,11 @@ SELECT '' AS twentyfour, b.f1 + p.f1 AS translation | (1e+300,Infinity),(1e+300,Infinity) | (1e+300,Infinity),(1e+300,Infinity) | (1e+300,Infinity),(1e+300,Infinity) + | (Infinity,1e+300),(Infinity,1e+300) + | (Infinity,1e+300),(Infinity,1e+300) + | (Infinity,1e+300),(Infinity,1e+300) + | (Infinity,1e+300),(Infinity,1e+300) + | (Infinity,1e+300),(Infinity,1e+300) | (NaN,NaN),(NaN,NaN) | (NaN,NaN),(NaN,NaN) | (NaN,NaN),(NaN,NaN) @@ -2357,7 +2485,7 @@ SELECT '' AS twentyfour, b.f1 + p.f1 AS translation | (8,12),(2,0) | (12.5,13.5),(12.5,12.5) | (13,13),(13,13) -(45 rows) +(50 rows) SELECT '' AS twentyfour, b.f1 - p.f1 AS translation FROM BOX_TBL b, POINT_TBL p; @@ -2398,6 +2526,11 @@ SELECT '' AS twentyfour, b.f1 - p.f1 AS translation | (-1e+300,-Infinity),(-1e+300,-Infinity) | (-1e+300,-Infinity),(-1e+300,-Infinity) | (-1e+300,-Infinity),(-1e+300,-Infinity) + | (-Infinity,-1e+300),(-Infinity,-1e+300) + | (-Infinity,-1e+300),(-Infinity,-1e+300) + | (-Infinity,-1e+300),(-Infinity,-1e+300) + | (-Infinity,-1e+300),(-Infinity,-1e+300) + | (-Infinity,-1e+300),(-Infinity,-1e+300) | (NaN,NaN),(NaN,NaN) | (NaN,NaN),(NaN,NaN) | (NaN,NaN),(NaN,NaN) @@ -2408,7 +2541,7 @@ SELECT '' AS twentyfour, b.f1 - p.f1 AS translation | (-12,-8),(-18,-20) | (-7.5,-6.5),(-7.5,-7.5) | (-7,-7),(-7,-7) -(45 rows) +(50 rows) -- Multiply with point SELECT b.f1, p.f1, b.f1 * p.f1 FROM BOX_TBL b, POINT_TBL p WHERE p.f1[0] BETWEEN 1 AND 1000; @@ -2431,16 +2564,21 @@ SELECT b.f1, p.f1, b.f1 * p.f1 FROM BOX_TBL b, POINT_TBL p WHERE p.f1[0] > 1000; f1 | f1 | ?column? ---------------------+-------------------+-------------------------------------------- (2,2),(0,0) | (1e+300,Infinity) | (NaN,NaN),(-Infinity,Infinity) + (2,2),(0,0) | (Infinity,1e+300) | (NaN,NaN),(Infinity,Infinity) (2,2),(0,0) | (NaN,NaN) | (NaN,NaN),(NaN,NaN) (3,3),(1,1) | (1e+300,Infinity) | (-Infinity,Infinity),(-Infinity,Infinity) + (3,3),(1,1) | (Infinity,1e+300) | (Infinity,Infinity),(Infinity,Infinity) (3,3),(1,1) | (NaN,NaN) | (NaN,NaN),(NaN,NaN) (-2,2),(-8,-10) | (1e+300,Infinity) | (Infinity,-Infinity),(-Infinity,-Infinity) + (-2,2),(-8,-10) | (Infinity,1e+300) | (-Infinity,Infinity),(-Infinity,-Infinity) (-2,2),(-8,-10) | (NaN,NaN) | (NaN,NaN),(NaN,NaN) (2.5,3.5),(2.5,2.5) | (1e+300,Infinity) | (-Infinity,Infinity),(-Infinity,Infinity) + (2.5,3.5),(2.5,2.5) | (Infinity,1e+300) | (Infinity,Infinity),(Infinity,Infinity) (2.5,3.5),(2.5,2.5) | (NaN,NaN) | (NaN,NaN),(NaN,NaN) (3,3),(3,3) | (1e+300,Infinity) | (-Infinity,Infinity),(-Infinity,Infinity) + (3,3),(3,3) | (Infinity,1e+300) | (Infinity,Infinity),(Infinity,Infinity) (3,3),(3,3) | (NaN,NaN) | (NaN,NaN),(NaN,NaN) -(10 rows) +(15 rows) -- Divide by point SELECT b.f1, p.f1, b.f1 / p.f1 FROM BOX_TBL b, POINT_TBL p WHERE p.f1[0] BETWEEN 1 AND 1000; @@ -2470,9 +2608,10 @@ SELECT f1::box (-5,-12),(-5,-12) (1e-300,-1e-300),(1e-300,-1e-300) (1e+300,Infinity),(1e+300,Infinity) + (Infinity,1e+300),(Infinity,1e+300) (NaN,NaN),(NaN,NaN) (10,10),(10,10) -(9 rows) +(10 rows) SELECT bound_box(a.f1, b.f1) FROM BOX_TBL a, BOX_TBL b; @@ -3102,6 +3241,15 @@ SELECT p.f1, p1.f1, p.f1 + p1.f1 FROM PATH_TBL p, POINT_TBL p1; ((10,20)) | (1e+300,Infinity) | ((1e+300,Infinity)) [(11,12),(13,14)] | (1e+300,Infinity) | [(1e+300,Infinity),(1e+300,Infinity)] ((11,12),(13,14)) | (1e+300,Infinity) | ((1e+300,Infinity),(1e+300,Infinity)) + [(1,2),(3,4)] | (Infinity,1e+300) | [(Infinity,1e+300),(Infinity,1e+300)] + ((1,2),(3,4)) | (Infinity,1e+300) | ((Infinity,1e+300),(Infinity,1e+300)) + [(0,0),(3,0),(4,5),(1,6)] | (Infinity,1e+300) | [(Infinity,1e+300),(Infinity,1e+300),(Infinity,1e+300),(Infinity,1e+300)] + ((1,2),(3,4)) | (Infinity,1e+300) | ((Infinity,1e+300),(Infinity,1e+300)) + ((1,2),(3,4)) | (Infinity,1e+300) | ((Infinity,1e+300),(Infinity,1e+300)) + [(1,2),(3,4)] | (Infinity,1e+300) | [(Infinity,1e+300),(Infinity,1e+300)] + ((10,20)) | (Infinity,1e+300) | ((Infinity,1e+300)) + [(11,12),(13,14)] | (Infinity,1e+300) | [(Infinity,1e+300),(Infinity,1e+300)] + ((11,12),(13,14)) | (Infinity,1e+300) | ((Infinity,1e+300),(Infinity,1e+300)) [(1,2),(3,4)] | (NaN,NaN) | [(NaN,NaN),(NaN,NaN)] ((1,2),(3,4)) | (NaN,NaN) | ((NaN,NaN),(NaN,NaN)) [(0,0),(3,0),(4,5),(1,6)] | (NaN,NaN) | [(NaN,NaN),(NaN,NaN),(NaN,NaN),(NaN,NaN)] @@ -3120,7 +3268,7 @@ SELECT p.f1, p1.f1, p.f1 + p1.f1 FROM PATH_TBL p, POINT_TBL p1; ((10,20)) | (10,10) | ((20,30)) [(11,12),(13,14)] | (10,10) | [(21,22),(23,24)] ((11,12),(13,14)) | (10,10) | ((21,22),(23,24)) -(81 rows) +(90 rows) -- Subtract point SELECT p.f1, p1.f1, p.f1 - p1.f1 FROM PATH_TBL p, POINT_TBL p1; @@ -3189,6 +3337,15 @@ SELECT p.f1, p1.f1, p.f1 - p1.f1 FROM PATH_TBL p, POINT_TBL p1; ((10,20)) | (1e+300,Infinity) | ((-1e+300,-Infinity)) [(11,12),(13,14)] | (1e+300,Infinity) | [(-1e+300,-Infinity),(-1e+300,-Infinity)] ((11,12),(13,14)) | (1e+300,Infinity) | ((-1e+300,-Infinity),(-1e+300,-Infinity)) + [(1,2),(3,4)] | (Infinity,1e+300) | [(-Infinity,-1e+300),(-Infinity,-1e+300)] + ((1,2),(3,4)) | (Infinity,1e+300) | ((-Infinity,-1e+300),(-Infinity,-1e+300)) + [(0,0),(3,0),(4,5),(1,6)] | (Infinity,1e+300) | [(-Infinity,-1e+300),(-Infinity,-1e+300),(-Infinity,-1e+300),(-Infinity,-1e+300)] + ((1,2),(3,4)) | (Infinity,1e+300) | ((-Infinity,-1e+300),(-Infinity,-1e+300)) + ((1,2),(3,4)) | (Infinity,1e+300) | ((-Infinity,-1e+300),(-Infinity,-1e+300)) + [(1,2),(3,4)] | (Infinity,1e+300) | [(-Infinity,-1e+300),(-Infinity,-1e+300)] + ((10,20)) | (Infinity,1e+300) | ((-Infinity,-1e+300)) + [(11,12),(13,14)] | (Infinity,1e+300) | [(-Infinity,-1e+300),(-Infinity,-1e+300)] + ((11,12),(13,14)) | (Infinity,1e+300) | ((-Infinity,-1e+300),(-Infinity,-1e+300)) [(1,2),(3,4)] | (NaN,NaN) | [(NaN,NaN),(NaN,NaN)] ((1,2),(3,4)) | (NaN,NaN) | ((NaN,NaN),(NaN,NaN)) [(0,0),(3,0),(4,5),(1,6)] | (NaN,NaN) | [(NaN,NaN),(NaN,NaN),(NaN,NaN),(NaN,NaN)] @@ -3207,7 +3364,7 @@ SELECT p.f1, p1.f1, p.f1 - p1.f1 FROM PATH_TBL p, POINT_TBL p1; ((10,20)) | (10,10) | ((0,10)) [(11,12),(13,14)] | (10,10) | [(1,2),(3,4)] ((11,12),(13,14)) | (10,10) | ((1,2),(3,4)) -(81 rows) +(90 rows) -- Multiply with point SELECT p.f1, p1.f1, p.f1 * p1.f1 FROM PATH_TBL p, POINT_TBL p1; @@ -3276,6 +3433,15 @@ SELECT p.f1, p1.f1, p.f1 * p1.f1 FROM PATH_TBL p, POINT_TBL p1; ((10,20)) | (1e+300,Infinity) | ((-Infinity,Infinity)) [(11,12),(13,14)] | (1e+300,Infinity) | [(-Infinity,Infinity),(-Infinity,Infinity)] ((11,12),(13,14)) | (1e+300,Infinity) | ((-Infinity,Infinity),(-Infinity,Infinity)) + [(1,2),(3,4)] | (Infinity,1e+300) | [(Infinity,Infinity),(Infinity,Infinity)] + ((1,2),(3,4)) | (Infinity,1e+300) | ((Infinity,Infinity),(Infinity,Infinity)) + [(0,0),(3,0),(4,5),(1,6)] | (Infinity,1e+300) | [(NaN,NaN),(Infinity,NaN),(Infinity,Infinity),(Infinity,Infinity)] + ((1,2),(3,4)) | (Infinity,1e+300) | ((Infinity,Infinity),(Infinity,Infinity)) + ((1,2),(3,4)) | (Infinity,1e+300) | ((Infinity,Infinity),(Infinity,Infinity)) + [(1,2),(3,4)] | (Infinity,1e+300) | [(Infinity,Infinity),(Infinity,Infinity)] + ((10,20)) | (Infinity,1e+300) | ((Infinity,Infinity)) + [(11,12),(13,14)] | (Infinity,1e+300) | [(Infinity,Infinity),(Infinity,Infinity)] + ((11,12),(13,14)) | (Infinity,1e+300) | ((Infinity,Infinity),(Infinity,Infinity)) [(1,2),(3,4)] | (NaN,NaN) | [(NaN,NaN),(NaN,NaN)] ((1,2),(3,4)) | (NaN,NaN) | ((NaN,NaN),(NaN,NaN)) [(0,0),(3,0),(4,5),(1,6)] | (NaN,NaN) | [(NaN,NaN),(NaN,NaN),(NaN,NaN),(NaN,NaN)] @@ -3294,7 +3460,7 @@ SELECT p.f1, p1.f1, p.f1 * p1.f1 FROM PATH_TBL p, POINT_TBL p1; ((10,20)) | (10,10) | ((-100,300)) [(11,12),(13,14)] | (10,10) | [(-10,230),(-10,270)] ((11,12),(13,14)) | (10,10) | ((-10,230),(-10,270)) -(81 rows) +(90 rows) -- Divide by point SELECT p.f1, p1.f1, p.f1 / p1.f1 FROM PATH_TBL p, POINT_TBL p1 WHERE p1.f1[0] BETWEEN 1 AND 1000; @@ -3467,6 +3633,13 @@ SELECT '' AS twentyfour, p.f1, poly.f1, poly.f1 @> p.f1 AS contains | (1e+300,Infinity) | ((1,2),(7,8),(5,6),(3,-4)) | f | (1e+300,Infinity) | ((0,0)) | f | (1e+300,Infinity) | ((0,1),(0,1)) | f + | (Infinity,1e+300) | ((2,0),(2,4),(0,0)) | f + | (Infinity,1e+300) | ((3,1),(3,3),(1,0)) | f + | (Infinity,1e+300) | ((1,2),(3,4),(5,6),(7,8)) | f + | (Infinity,1e+300) | ((7,8),(5,6),(3,4),(1,2)) | f + | (Infinity,1e+300) | ((1,2),(7,8),(5,6),(3,-4)) | f + | (Infinity,1e+300) | ((0,0)) | f + | (Infinity,1e+300) | ((0,1),(0,1)) | f | (NaN,NaN) | ((2,0),(2,4),(0,0)) | t | (NaN,NaN) | ((3,1),(3,3),(1,0)) | t | (NaN,NaN) | ((1,2),(3,4),(5,6),(7,8)) | t @@ -3481,7 +3654,7 @@ SELECT '' AS twentyfour, p.f1, poly.f1, poly.f1 @> p.f1 AS contains | (10,10) | ((1,2),(7,8),(5,6),(3,-4)) | f | (10,10) | ((0,0)) | f | (10,10) | ((0,1),(0,1)) | f -(63 rows) +(70 rows) SELECT '' AS twentyfour, p.f1, poly.f1, p.f1 <@ poly.f1 AS contained FROM POLYGON_TBL poly, POINT_TBL p; @@ -3536,6 +3709,13 @@ SELECT '' AS twentyfour, p.f1, poly.f1, p.f1 <@ poly.f1 AS contained | (1e+300,Infinity) | ((1,2),(7,8),(5,6),(3,-4)) | f | (1e+300,Infinity) | ((0,0)) | f | (1e+300,Infinity) | ((0,1),(0,1)) | f + | (Infinity,1e+300) | ((2,0),(2,4),(0,0)) | f + | (Infinity,1e+300) | ((3,1),(3,3),(1,0)) | f + | (Infinity,1e+300) | ((1,2),(3,4),(5,6),(7,8)) | f + | (Infinity,1e+300) | ((7,8),(5,6),(3,4),(1,2)) | f + | (Infinity,1e+300) | ((1,2),(7,8),(5,6),(3,-4)) | f + | (Infinity,1e+300) | ((0,0)) | f + | (Infinity,1e+300) | ((0,1),(0,1)) | f | (NaN,NaN) | ((2,0),(2,4),(0,0)) | t | (NaN,NaN) | ((3,1),(3,3),(1,0)) | t | (NaN,NaN) | ((1,2),(3,4),(5,6),(7,8)) | t @@ -3550,7 +3730,7 @@ SELECT '' AS twentyfour, p.f1, poly.f1, p.f1 <@ poly.f1 AS contained | (10,10) | ((1,2),(7,8),(5,6),(3,-4)) | f | (10,10) | ((0,0)) | f | (10,10) | ((0,1),(0,1)) | f -(63 rows) +(70 rows) SELECT '' AS four, npoints(f1) AS npoints, f1 AS polygon FROM POLYGON_TBL; @@ -3929,9 +4109,10 @@ SELECT '' AS six, circle(f1, 50.0) | <(-5,-12),50> | <(1e-300,-1e-300),50> | <(1e+300,Infinity),50> + | <(Infinity,1e+300),50> | <(NaN,NaN),50> | <(10,10),50> -(9 rows) +(10 rows) SELECT '' AS four, circle(f1) FROM BOX_TBL; @@ -3993,12 +4174,19 @@ SELECT '' AS twentyfour, c1.f1 AS circle, p1.f1 AS point, (p1.f1 <-> c1.f1) AS d | <(100,200),10> | (-10,0) | 218.25424421 | <(100,200),10> | (-5,-12) | 226.577682802 | <(3,5),0> | (1e+300,Infinity) | Infinity + | <(3,5),0> | (Infinity,1e+300) | Infinity | <(1,2),3> | (1e+300,Infinity) | Infinity | <(5,1),3> | (1e+300,Infinity) | Infinity + | <(5,1),3> | (Infinity,1e+300) | Infinity + | <(1,2),3> | (Infinity,1e+300) | Infinity | <(1,3),5> | (1e+300,Infinity) | Infinity + | <(1,3),5> | (Infinity,1e+300) | Infinity | <(100,200),10> | (1e+300,Infinity) | Infinity + | <(100,200),10> | (Infinity,1e+300) | Infinity | <(1,2),100> | (1e+300,Infinity) | Infinity + | <(1,2),100> | (Infinity,1e+300) | Infinity | <(100,1),115> | (1e+300,Infinity) | Infinity + | <(100,1),115> | (Infinity,1e+300) | Infinity | <(3,5),0> | (NaN,NaN) | NaN | <(1,2),3> | (NaN,NaN) | NaN | <(5,1),3> | (NaN,NaN) | NaN @@ -4014,8 +4202,9 @@ SELECT '' AS twentyfour, c1.f1 AS circle, p1.f1 AS point, (p1.f1 <-> c1.f1) AS d | <(3,5),NaN> | (5.1,34.5) | NaN | <(3,5),NaN> | (10,10) | NaN | <(3,5),NaN> | (1e+300,Infinity) | NaN + | <(3,5),NaN> | (Infinity,1e+300) | NaN | <(3,5),NaN> | (NaN,NaN) | NaN -(53 rows) +(61 rows) -- To polygon SELECT f1, f1::polygon FROM CIRCLE_TBL WHERE f1 >= '<(0,0),1>'; @@ -4626,6 +4815,14 @@ SELECT c.f1, p.f1, c.f1 + p.f1 FROM CIRCLE_TBL c, POINT_TBL p; <(100,1),115> | (1e+300,Infinity) | <(1e+300,Infinity),115> <(3,5),0> | (1e+300,Infinity) | <(1e+300,Infinity),0> <(3,5),NaN> | (1e+300,Infinity) | <(1e+300,Infinity),NaN> + <(5,1),3> | (Infinity,1e+300) | <(Infinity,1e+300),3> + <(1,2),100> | (Infinity,1e+300) | <(Infinity,1e+300),100> + <(1,3),5> | (Infinity,1e+300) | <(Infinity,1e+300),5> + <(1,2),3> | (Infinity,1e+300) | <(Infinity,1e+300),3> + <(100,200),10> | (Infinity,1e+300) | <(Infinity,1e+300),10> + <(100,1),115> | (Infinity,1e+300) | <(Infinity,1e+300),115> + <(3,5),0> | (Infinity,1e+300) | <(Infinity,1e+300),0> + <(3,5),NaN> | (Infinity,1e+300) | <(Infinity,1e+300),NaN> <(5,1),3> | (NaN,NaN) | <(NaN,NaN),3> <(1,2),100> | (NaN,NaN) | <(NaN,NaN),100> <(1,3),5> | (NaN,NaN) | <(NaN,NaN),5> @@ -4642,7 +4839,7 @@ SELECT c.f1, p.f1, c.f1 + p.f1 FROM CIRCLE_TBL c, POINT_TBL p; <(100,1),115> | (10,10) | <(110,11),115> <(3,5),0> | (10,10) | <(13,15),0> <(3,5),NaN> | (10,10) | <(13,15),NaN> -(72 rows) +(80 rows) -- Subtract point SELECT c.f1, p.f1, c.f1 - p.f1 FROM CIRCLE_TBL c, POINT_TBL p; @@ -4704,6 +4901,14 @@ SELECT c.f1, p.f1, c.f1 - p.f1 FROM CIRCLE_TBL c, POINT_TBL p; <(100,1),115> | (1e+300,Infinity) | <(-1e+300,-Infinity),115> <(3,5),0> | (1e+300,Infinity) | <(-1e+300,-Infinity),0> <(3,5),NaN> | (1e+300,Infinity) | <(-1e+300,-Infinity),NaN> + <(5,1),3> | (Infinity,1e+300) | <(-Infinity,-1e+300),3> + <(1,2),100> | (Infinity,1e+300) | <(-Infinity,-1e+300),100> + <(1,3),5> | (Infinity,1e+300) | <(-Infinity,-1e+300),5> + <(1,2),3> | (Infinity,1e+300) | <(-Infinity,-1e+300),3> + <(100,200),10> | (Infinity,1e+300) | <(-Infinity,-1e+300),10> + <(100,1),115> | (Infinity,1e+300) | <(-Infinity,-1e+300),115> + <(3,5),0> | (Infinity,1e+300) | <(-Infinity,-1e+300),0> + <(3,5),NaN> | (Infinity,1e+300) | <(-Infinity,-1e+300),NaN> <(5,1),3> | (NaN,NaN) | <(NaN,NaN),3> <(1,2),100> | (NaN,NaN) | <(NaN,NaN),100> <(1,3),5> | (NaN,NaN) | <(NaN,NaN),5> @@ -4720,7 +4925,7 @@ SELECT c.f1, p.f1, c.f1 - p.f1 FROM CIRCLE_TBL c, POINT_TBL p; <(100,1),115> | (10,10) | <(90,-9),115> <(3,5),0> | (10,10) | <(-7,-5),0> <(3,5),NaN> | (10,10) | <(-7,-5),NaN> -(72 rows) +(80 rows) -- Multiply with point SELECT c.f1, p.f1, c.f1 * p.f1 FROM CIRCLE_TBL c, POINT_TBL p; @@ -4782,6 +4987,14 @@ SELECT c.f1, p.f1, c.f1 * p.f1 FROM CIRCLE_TBL c, POINT_TBL p; <(100,1),115> | (1e+300,Infinity) | <(-Infinity,Infinity),Infinity> <(3,5),0> | (1e+300,Infinity) | <(-Infinity,Infinity),NaN> <(3,5),NaN> | (1e+300,Infinity) | <(-Infinity,Infinity),NaN> + <(5,1),3> | (Infinity,1e+300) | <(Infinity,Infinity),Infinity> + <(1,2),100> | (Infinity,1e+300) | <(Infinity,Infinity),Infinity> + <(1,3),5> | (Infinity,1e+300) | <(Infinity,Infinity),Infinity> + <(1,2),3> | (Infinity,1e+300) | <(Infinity,Infinity),Infinity> + <(100,200),10> | (Infinity,1e+300) | <(Infinity,Infinity),Infinity> + <(100,1),115> | (Infinity,1e+300) | <(Infinity,Infinity),Infinity> + <(3,5),0> | (Infinity,1e+300) | <(Infinity,Infinity),NaN> + <(3,5),NaN> | (Infinity,1e+300) | <(Infinity,Infinity),NaN> <(5,1),3> | (NaN,NaN) | <(NaN,NaN),NaN> <(1,2),100> | (NaN,NaN) | <(NaN,NaN),NaN> <(1,3),5> | (NaN,NaN) | <(NaN,NaN),NaN> @@ -4798,7 +5011,7 @@ SELECT c.f1, p.f1, c.f1 * p.f1 FROM CIRCLE_TBL c, POINT_TBL p; <(100,1),115> | (10,10) | <(990,1010),1626.34559673> <(3,5),0> | (10,10) | <(-20,80),0> <(3,5),NaN> | (10,10) | <(-20,80),NaN> -(72 rows) +(80 rows) -- Divide by point SELECT c.f1, p.f1, c.f1 / p.f1 FROM CIRCLE_TBL c, POINT_TBL p WHERE p.f1[0] BETWEEN 1 AND 1000; diff --git a/src/test/regress/expected/point.out b/src/test/regress/expected/point.out index 15e3b83b37..77e250fc3e 100644 --- a/src/test/regress/expected/point.out +++ b/src/test/regress/expected/point.out @@ -11,6 +11,7 @@ INSERT INTO POINT_TBL(f1) VALUES ('(5.1, 34.5)'); INSERT INTO POINT_TBL(f1) VALUES ('(-5.0,-12.0)'); INSERT INTO POINT_TBL(f1) VALUES ('(1e-300,-1e-300)'); -- To underflow INSERT INTO POINT_TBL(f1) VALUES ('(1e+300,Inf)'); -- To overflow +INSERT INTO POINT_TBL(f1) VALUES ('(Inf,1e+300)'); -- Transposed INSERT INTO POINT_TBL(f1) VALUES (' ( Nan , NaN ) '); -- bad format points INSERT INTO POINT_TBL(f1) VALUES ('asdfasdf'); @@ -44,9 +45,10 @@ SELECT '' AS six, * FROM POINT_TBL; | (-5,-12) | (1e-300,-1e-300) | (1e+300,Infinity) + | (Infinity,1e+300) | (NaN,NaN) | (10,10) -(9 rows) +(10 rows) -- left of SELECT '' AS three, p.* FROM POINT_TBL p WHERE p.f1 << '(0.0, 0.0)'; @@ -115,8 +117,9 @@ SELECT '' AS three, p.* FROM POINT_TBL p | (-5,-12) | (1e-300,-1e-300) | (1e+300,Infinity) + | (Infinity,1e+300) | (NaN,NaN) -(6 rows) +(7 rows) SELECT '' AS two, p.* FROM POINT_TBL p WHERE p.f1 <@ path '[(0,0),(-10,0),(-10,10)]'; @@ -136,8 +139,9 @@ SELECT '' AS three, p.* FROM POINT_TBL p | (-5,-12) | (1e-300,-1e-300) | (1e+300,Infinity) + | (Infinity,1e+300) | (NaN,NaN) -(6 rows) +(7 rows) SELECT '' AS six, p.f1, p.f1 <-> point '(0,0)' AS dist FROM POINT_TBL p @@ -152,8 +156,9 @@ SELECT '' AS six, p.f1, p.f1 <-> point '(0,0)' AS dist | (10,10) | 14.142135623731 | (5.1,34.5) | 34.8749193547455 | (1e+300,Infinity) | Infinity + | (Infinity,1e+300) | Infinity | (NaN,NaN) | NaN -(9 rows) +(10 rows) SELECT '' AS thirtysix, p1.f1 AS point1, p2.f1 AS point2, p1.f1 <-> p2.f1 AS dist FROM POINT_TBL p1, POINT_TBL p2 @@ -210,12 +215,19 @@ SELECT '' AS thirtysix, p1.f1 AS point1, p2.f1 AS point2, p1.f1 <-> p2.f1 AS dis | (-5,-12) | (5.1,34.5) | 47.5842410888311 | (5.1,34.5) | (-5,-12) | 47.5842410888311 | (-10,0) | (1e+300,Infinity) | Infinity + | (-10,0) | (Infinity,1e+300) | Infinity | (-5,-12) | (1e+300,Infinity) | Infinity + | (-5,-12) | (Infinity,1e+300) | Infinity | (-3,4) | (1e+300,Infinity) | Infinity + | (-3,4) | (Infinity,1e+300) | Infinity | (0,0) | (1e+300,Infinity) | Infinity + | (0,0) | (Infinity,1e+300) | Infinity | (1e-300,-1e-300) | (1e+300,Infinity) | Infinity + | (1e-300,-1e-300) | (Infinity,1e+300) | Infinity | (5.1,34.5) | (1e+300,Infinity) | Infinity + | (5.1,34.5) | (Infinity,1e+300) | Infinity | (10,10) | (1e+300,Infinity) | Infinity + | (10,10) | (Infinity,1e+300) | Infinity | (1e+300,Infinity) | (-10,0) | Infinity | (1e+300,Infinity) | (-5,-12) | Infinity | (1e+300,Infinity) | (-3,4) | Infinity @@ -223,6 +235,15 @@ SELECT '' AS thirtysix, p1.f1 AS point1, p2.f1 AS point2, p1.f1 <-> p2.f1 AS dis | (1e+300,Infinity) | (1e-300,-1e-300) | Infinity | (1e+300,Infinity) | (5.1,34.5) | Infinity | (1e+300,Infinity) | (10,10) | Infinity + | (1e+300,Infinity) | (Infinity,1e+300) | Infinity + | (Infinity,1e+300) | (-10,0) | Infinity + | (Infinity,1e+300) | (-5,-12) | Infinity + | (Infinity,1e+300) | (-3,4) | Infinity + | (Infinity,1e+300) | (0,0) | Infinity + | (Infinity,1e+300) | (1e-300,-1e-300) | Infinity + | (Infinity,1e+300) | (5.1,34.5) | Infinity + | (Infinity,1e+300) | (10,10) | Infinity + | (Infinity,1e+300) | (1e+300,Infinity) | Infinity | (-10,0) | (NaN,NaN) | NaN | (-5,-12) | (NaN,NaN) | NaN | (-3,4) | (NaN,NaN) | NaN @@ -232,6 +253,8 @@ SELECT '' AS thirtysix, p1.f1 AS point1, p2.f1 AS point2, p1.f1 <-> p2.f1 AS dis | (10,10) | (NaN,NaN) | NaN | (1e+300,Infinity) | (1e+300,Infinity) | NaN | (1e+300,Infinity) | (NaN,NaN) | NaN + | (Infinity,1e+300) | (Infinity,1e+300) | NaN + | (Infinity,1e+300) | (NaN,NaN) | NaN | (NaN,NaN) | (-10,0) | NaN | (NaN,NaN) | (-5,-12) | NaN | (NaN,NaN) | (-3,4) | NaN @@ -240,8 +263,9 @@ SELECT '' AS thirtysix, p1.f1 AS point1, p2.f1 AS point2, p1.f1 <-> p2.f1 AS dis | (NaN,NaN) | (5.1,34.5) | NaN | (NaN,NaN) | (10,10) | NaN | (NaN,NaN) | (1e+300,Infinity) | NaN + | (NaN,NaN) | (Infinity,1e+300) | NaN | (NaN,NaN) | (NaN,NaN) | NaN -(81 rows) +(100 rows) SELECT '' AS thirty, p1.f1 AS point1, p2.f1 AS point2 FROM POINT_TBL p1, POINT_TBL p2 @@ -253,6 +277,7 @@ SELECT '' AS thirty, p1.f1 AS point1, p2.f1 AS point2 | (0,0) | (5.1,34.5) | (0,0) | (-5,-12) | (0,0) | (1e+300,Infinity) + | (0,0) | (Infinity,1e+300) | (0,0) | (NaN,NaN) | (0,0) | (10,10) | (-10,0) | (0,0) @@ -261,6 +286,7 @@ SELECT '' AS thirty, p1.f1 AS point1, p2.f1 AS point2 | (-10,0) | (-5,-12) | (-10,0) | (1e-300,-1e-300) | (-10,0) | (1e+300,Infinity) + | (-10,0) | (Infinity,1e+300) | (-10,0) | (NaN,NaN) | (-10,0) | (10,10) | (-3,4) | (0,0) @@ -269,6 +295,7 @@ SELECT '' AS thirty, p1.f1 AS point1, p2.f1 AS point2 | (-3,4) | (-5,-12) | (-3,4) | (1e-300,-1e-300) | (-3,4) | (1e+300,Infinity) + | (-3,4) | (Infinity,1e+300) | (-3,4) | (NaN,NaN) | (-3,4) | (10,10) | (5.1,34.5) | (0,0) @@ -277,6 +304,7 @@ SELECT '' AS thirty, p1.f1 AS point1, p2.f1 AS point2 | (5.1,34.5) | (-5,-12) | (5.1,34.5) | (1e-300,-1e-300) | (5.1,34.5) | (1e+300,Infinity) + | (5.1,34.5) | (Infinity,1e+300) | (5.1,34.5) | (NaN,NaN) | (5.1,34.5) | (10,10) | (-5,-12) | (0,0) @@ -285,6 +313,7 @@ SELECT '' AS thirty, p1.f1 AS point1, p2.f1 AS point2 | (-5,-12) | (5.1,34.5) | (-5,-12) | (1e-300,-1e-300) | (-5,-12) | (1e+300,Infinity) + | (-5,-12) | (Infinity,1e+300) | (-5,-12) | (NaN,NaN) | (-5,-12) | (10,10) | (1e-300,-1e-300) | (-10,0) @@ -292,6 +321,7 @@ SELECT '' AS thirty, p1.f1 AS point1, p2.f1 AS point2 | (1e-300,-1e-300) | (5.1,34.5) | (1e-300,-1e-300) | (-5,-12) | (1e-300,-1e-300) | (1e+300,Infinity) + | (1e-300,-1e-300) | (Infinity,1e+300) | (1e-300,-1e-300) | (NaN,NaN) | (1e-300,-1e-300) | (10,10) | (1e+300,Infinity) | (0,0) @@ -301,8 +331,19 @@ SELECT '' AS thirty, p1.f1 AS point1, p2.f1 AS point2 | (1e+300,Infinity) | (-5,-12) | (1e+300,Infinity) | (1e-300,-1e-300) | (1e+300,Infinity) | (1e+300,Infinity) + | (1e+300,Infinity) | (Infinity,1e+300) | (1e+300,Infinity) | (NaN,NaN) | (1e+300,Infinity) | (10,10) + | (Infinity,1e+300) | (0,0) + | (Infinity,1e+300) | (-10,0) + | (Infinity,1e+300) | (-3,4) + | (Infinity,1e+300) | (5.1,34.5) + | (Infinity,1e+300) | (-5,-12) + | (Infinity,1e+300) | (1e-300,-1e-300) + | (Infinity,1e+300) | (1e+300,Infinity) + | (Infinity,1e+300) | (Infinity,1e+300) + | (Infinity,1e+300) | (NaN,NaN) + | (Infinity,1e+300) | (10,10) | (NaN,NaN) | (0,0) | (NaN,NaN) | (-10,0) | (NaN,NaN) | (-3,4) @@ -310,6 +351,7 @@ SELECT '' AS thirty, p1.f1 AS point1, p2.f1 AS point2 | (NaN,NaN) | (-5,-12) | (NaN,NaN) | (1e-300,-1e-300) | (NaN,NaN) | (1e+300,Infinity) + | (NaN,NaN) | (Infinity,1e+300) | (NaN,NaN) | (NaN,NaN) | (NaN,NaN) | (10,10) | (10,10) | (0,0) @@ -319,57 +361,67 @@ SELECT '' AS thirty, p1.f1 AS point1, p2.f1 AS point2 | (10,10) | (-5,-12) | (10,10) | (1e-300,-1e-300) | (10,10) | (1e+300,Infinity) + | (10,10) | (Infinity,1e+300) | (10,10) | (NaN,NaN) -(72 rows) +(91 rows) -- put distance result into output to allow sorting with GEQ optimizer - tgl 97/05/10 SELECT '' AS fifteen, p1.f1 AS point1, p2.f1 AS point2, (p1.f1 <-> p2.f1) AS distance FROM POINT_TBL p1, POINT_TBL p2 WHERE (p1.f1 <-> p2.f1) > 3 and p1.f1 << p2.f1 ORDER BY distance, p1.f1[0], p2.f1[0]; - fifteen | point1 | point2 | distance ----------+------------------+-------------------+------------------ - | (-3,4) | (0,0) | 5 - | (-3,4) | (1e-300,-1e-300) | 5 - | (-10,0) | (-3,4) | 8.06225774829855 - | (-10,0) | (0,0) | 10 - | (-10,0) | (1e-300,-1e-300) | 10 - | (-10,0) | (-5,-12) | 13 - | (-5,-12) | (0,0) | 13 - | (-5,-12) | (1e-300,-1e-300) | 13 - | (0,0) | (10,10) | 14.142135623731 - | (1e-300,-1e-300) | (10,10) | 14.142135623731 - | (-3,4) | (10,10) | 14.3178210632764 - | (-5,-12) | (-3,4) | 16.1245154965971 - | (-10,0) | (10,10) | 22.3606797749979 - | (5.1,34.5) | (10,10) | 24.9851956166046 - | (-5,-12) | (10,10) | 26.6270539113887 - | (-3,4) | (5.1,34.5) | 31.5572495632937 - | (0,0) | (5.1,34.5) | 34.8749193547455 - | (1e-300,-1e-300) | (5.1,34.5) | 34.8749193547455 - | (-10,0) | (5.1,34.5) | 37.6597928831267 - | (-5,-12) | (5.1,34.5) | 47.5842410888311 - | (-10,0) | (1e+300,Infinity) | Infinity - | (-5,-12) | (1e+300,Infinity) | Infinity - | (-3,4) | (1e+300,Infinity) | Infinity - | (0,0) | (1e+300,Infinity) | Infinity - | (1e-300,-1e-300) | (1e+300,Infinity) | Infinity - | (5.1,34.5) | (1e+300,Infinity) | Infinity - | (10,10) | (1e+300,Infinity) | Infinity -(27 rows) + fifteen | point1 | point2 | distance +---------+-------------------+-------------------+------------------ + | (-3,4) | (0,0) | 5 + | (-3,4) | (1e-300,-1e-300) | 5 + | (-10,0) | (-3,4) | 8.06225774829855 + | (-10,0) | (0,0) | 10 + | (-10,0) | (1e-300,-1e-300) | 10 + | (-10,0) | (-5,-12) | 13 + | (-5,-12) | (0,0) | 13 + | (-5,-12) | (1e-300,-1e-300) | 13 + | (0,0) | (10,10) | 14.142135623731 + | (1e-300,-1e-300) | (10,10) | 14.142135623731 + | (-3,4) | (10,10) | 14.3178210632764 + | (-5,-12) | (-3,4) | 16.1245154965971 + | (-10,0) | (10,10) | 22.3606797749979 + | (5.1,34.5) | (10,10) | 24.9851956166046 + | (-5,-12) | (10,10) | 26.6270539113887 + | (-3,4) | (5.1,34.5) | 31.5572495632937 + | (0,0) | (5.1,34.5) | 34.8749193547455 + | (1e-300,-1e-300) | (5.1,34.5) | 34.8749193547455 + | (-10,0) | (5.1,34.5) | 37.6597928831267 + | (-5,-12) | (5.1,34.5) | 47.5842410888311 + | (-10,0) | (1e+300,Infinity) | Infinity + | (-10,0) | (Infinity,1e+300) | Infinity + | (-5,-12) | (1e+300,Infinity) | Infinity + | (-5,-12) | (Infinity,1e+300) | Infinity + | (-3,4) | (1e+300,Infinity) | Infinity + | (-3,4) | (Infinity,1e+300) | Infinity + | (0,0) | (1e+300,Infinity) | Infinity + | (0,0) | (Infinity,1e+300) | Infinity + | (1e-300,-1e-300) | (1e+300,Infinity) | Infinity + | (1e-300,-1e-300) | (Infinity,1e+300) | Infinity + | (5.1,34.5) | (1e+300,Infinity) | Infinity + | (5.1,34.5) | (Infinity,1e+300) | Infinity + | (10,10) | (1e+300,Infinity) | Infinity + | (10,10) | (Infinity,1e+300) | Infinity + | (1e+300,Infinity) | (Infinity,1e+300) | Infinity +(35 rows) -- put distance result into output to allow sorting with GEQ optimizer - tgl 97/05/10 SELECT '' AS three, p1.f1 AS point1, p2.f1 AS point2, (p1.f1 <-> p2.f1) AS distance FROM POINT_TBL p1, POINT_TBL p2 WHERE (p1.f1 <-> p2.f1) > 3 and p1.f1 << p2.f1 and p1.f1 >^ p2.f1 ORDER BY distance; - three | point1 | point2 | distance --------+------------+------------------+------------------ - | (-3,4) | (0,0) | 5 - | (-3,4) | (1e-300,-1e-300) | 5 - | (-10,0) | (-5,-12) | 13 - | (5.1,34.5) | (10,10) | 24.9851956166046 -(4 rows) + three | point1 | point2 | distance +-------+-------------------+-------------------+------------------ + | (-3,4) | (0,0) | 5 + | (-3,4) | (1e-300,-1e-300) | 5 + | (-10,0) | (-5,-12) | 13 + | (5.1,34.5) | (10,10) | 24.9851956166046 + | (1e+300,Infinity) | (Infinity,1e+300) | Infinity +(5 rows) -- Test that GiST indexes provide same behavior as sequential scan CREATE TEMP TABLE point_gist_tbl(f1 point); diff --git a/src/test/regress/sql/point.sql b/src/test/regress/sql/point.sql index 7f8504dbd1..6a1ca12d5c 100644 --- a/src/test/regress/sql/point.sql +++ b/src/test/regress/sql/point.sql @@ -21,6 +21,8 @@ INSERT INTO POINT_TBL(f1) VALUES ('(1e-300,-1e-300)'); -- To underflow INSERT INTO POINT_TBL(f1) VALUES ('(1e+300,Inf)'); -- To overflow +INSERT INTO POINT_TBL(f1) VALUES ('(Inf,1e+300)'); -- Transposed + INSERT INTO POINT_TBL(f1) VALUES (' ( Nan , NaN ) '); -- bad format points
diff --git a/doc/src/sgml/func.sgml b/doc/src/sgml/func.sgml index 2783985b55..78f943b960 100644 --- a/doc/src/sgml/func.sgml +++ b/doc/src/sgml/func.sgml @@ -10890,6 +10890,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..99d149c948 100644 --- a/src/backend/utils/adt/geo_ops.c +++ b/src/backend/utils/adt/geo_ops.c @@ -904,9 +904,9 @@ box_intersect(PG_FUNCTION_ARGS) result = (BOX *) palloc(sizeof(BOX)); - result->high.x = float8_min(box1->high.x, box2->high.x); + result->high.x = float8_min_nan(box1->high.x, box2->high.x); result->low.x = float8_max(box1->low.x, box2->low.x); - result->high.y = float8_min(box1->high.y, box2->high.y); + result->high.y = float8_min_nan(box1->high.y, box2->high.y); result->low.y = float8_max(box1->low.y, box2->low.y); PG_RETURN_BOX_P(result); @@ -1061,6 +1061,21 @@ 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 (unlikely(isnan(pt->y))) + result->C = get_float8_nan(); + } + 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 (unlikely(isnan(pt->x))) + result->C = get_float8_nan(); } else { @@ -1084,6 +1099,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 +1120,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 +1143,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 +1164,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 +1172,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 +1218,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 +1242,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 +1267,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; @@ -1291,14 +1343,21 @@ line_interpt_line(Point *result, LINE *l1, LINE *l2) } 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_mul(l2->A, x), l2->C), l2->B); } else return false; @@ -1628,8 +1687,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 +1696,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 +1787,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 +2044,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 +2068,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 +2494,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 +2730,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 +2761,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; /* @@ -2803,6 +2891,7 @@ lseg_closept_lseg(Point *result, LSEG *on_lseg, LSEG *to_lseg) Point point; float8 dist, d; + bool isnan = false; /* First, we handle the case when the line segments are intersecting. */ if (lseg_interpt_lseg(result, on_lseg, to_lseg)) @@ -2814,6 +2903,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]); + isnan |= (isnan(dist) || isnan(d)); if (float8_lt(d, dist)) { dist = d; @@ -2823,6 +2913,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]); + isnan |= isnan(d); if (float8_lt(d, dist)) { dist = d; @@ -2830,6 +2921,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]); + isnan |= isnan(d); if (float8_lt(d, dist)) { dist = d; @@ -2837,6 +2929,12 @@ lseg_closept_lseg(Point *result, LSEG *on_lseg, LSEG *to_lseg) *result = on_lseg->p[1]; } + if (unlikely(isnan)) + { + if (result != NULL) + result->x = result->y = get_float8_nan(); + return get_float8_nan(); + } return dist; } @@ -2873,6 +2971,7 @@ box_closept_point(Point *result, BOX *box, Point *pt) Point point, closept; LSEG lseg; + bool isnan = false; if (box_contain_point(box, pt)) { @@ -2887,9 +2986,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); - + isnan |= isnan(dist); statlseg_construct(&lseg, &box->high, &point); d = lseg_closept_point(&closept, &lseg, pt); + isnan |= isnan(d); if (float8_lt(d, dist)) { dist = d; @@ -2901,6 +3001,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); + isnan |= isnan(d); if (float8_lt(d, dist)) { dist = d; @@ -2910,6 +3011,7 @@ box_closept_point(Point *result, BOX *box, Point *pt) statlseg_construct(&lseg, &box->high, &point); d = lseg_closept_point(&closept, &lseg, pt); + isnan |= isnan(d); if (float8_lt(d, dist)) { dist = d; @@ -2917,6 +3019,13 @@ box_closept_point(Point *result, BOX *box, Point *pt) *result = closept; } + if (unlikely(isnan)) + { + if (result != NULL) + result->x = result->y = get_float8_nan(); + return get_float8_nan(); + } + return dist; } @@ -2988,6 +3097,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 +3120,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]; @@ -3436,6 +3554,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 +4035,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 +5479,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 +5492,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 +5654,12 @@ pg_hypot(float8 x, float8 y) result; /* Handle INF and NaN properly */ - if (isinf(x) || isinf(y)) - return get_float8_infinity(); - - if (isnan(x) || isnan(y)) + if (unlikely(isnan(x) || isnan(y))) return get_float8_nan(); + if (unlikely(isinf(x) || isinf(y))) + return get_float8_infinity(); + /* 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..20acb0b0b4 100644 --- a/src/test/regress/expected/geometry.out +++ b/src/test/regress/expected/geometry.out @@ -555,15 +555,15 @@ 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) | {0,-1,5} | Infinity | Infinity (1e+300,Infinity) | {1,0,5} | NaN | NaN (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 - (1e+300,Infinity) | {-0.000184615384615,-1,15.3846153846} | Infinity | Infinity + (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) | {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) | {1,0,5} | Infinity | Infinity (Infinity,1e+300) | {0,3,0} | NaN | NaN (Infinity,1e+300) | {1,-1,0} | NaN | NaN (Infinity,1e+300) | {-0.4,-1,-6} | NaN | NaN @@ -571,7 +571,7 @@ SELECT p.f1, l.s, p.f1 <-> l.s AS dist_pl, l.s <-> p.f1 AS dist_lp FROM POINT_TB (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) | {-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 @@ -653,14 +653,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) | [(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 (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) | [(0,-20),(30,-20)] | NaN | NaN (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 @@ -719,9 +719,9 @@ 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,2),(0,0) | NaN | NaN + (Infinity,1e+300) | (3,3),(1,1) | NaN | NaN + (Infinity,1e+300) | (-2,2),(-8,-10) | NaN | NaN (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 @@ -805,7 +805,7 @@ SELECT p.f1, p1.f1, p.f1 <-> p1.f1 AS dist_ppath, p1.f1 <-> p.f1 AS dist_pathp F (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) | [(0,0),(3,0),(4,5),(1,6)] | NaN | NaN (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 @@ -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 @@ -975,15 +975,15 @@ SELECT p.f1, l.s, p.f1 ## l.s FROM POINT_TBL p, LINE_TBL l; (1e+300,Infinity) | {0,-1,5} | (1e+300,5) (1e+300,Infinity) | {1,0,5} | (1e+300,Infinity) | {0,3,0} | (1e+300,0) - (1e+300,Infinity) | {1,-1,0} | (Infinity,NaN) - (1e+300,Infinity) | {-0.4,-1,-6} | (-Infinity,NaN) - (1e+300,Infinity) | {-0.000184615384615,-1,15.3846153846} | (-Infinity,NaN) + (1e+300,Infinity) | {1,-1,0} | + (1e+300,Infinity) | {-0.4,-1,-6} | + (1e+300,Infinity) | {-0.000184615384615,-1,15.3846153846} | (1e+300,Infinity) | {3,NaN,5} | (1e+300,Infinity) | {NaN,NaN,NaN} | (1e+300,Infinity) | {0,-1,3} | (1e+300,3) (1e+300,Infinity) | {-1,0,3} | (Infinity,1e+300) | {0,-1,5} | - (Infinity,1e+300) | {1,0,5} | + (Infinity,1e+300) | {1,0,5} | (-5,1e+300) (Infinity,1e+300) | {0,3,0} | (Infinity,1e+300) | {1,-1,0} | (Infinity,1e+300) | {-0.4,-1,-6} | @@ -991,7 +991,7 @@ SELECT p.f1, l.s, p.f1 ## l.s FROM POINT_TBL p, LINE_TBL l; (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) | {-1,0,3} | (3,1e+300) (NaN,NaN) | {0,-1,5} | (NaN,NaN) | {1,0,5} | (NaN,NaN) | {0,3,0} | @@ -1073,14 +1073,14 @@ 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) (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) | [(0,-20),(30,-20)] | (Infinity,1e+300) | [(NaN,1),(NaN,90)] | (NaN,NaN) | [(1,2),(3,4)] | (NaN,NaN) | [(0,0),(6,6)] | @@ -1139,9 +1139,9 @@ 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,2),(0,0) | + (Infinity,1e+300) | (3,3),(1,1) | + (Infinity,1e+300) | (-2,2),(-8,-10) | (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) | @@ -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; @@ -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} | (-5,NaN) + {1,0,5} | {NaN,NaN,NaN} | (-5,NaN) {1,0,5} | {0,-1,3} | (-5,3) {1,0,5} | {-1,0,3} | {0,3,0} | {0,-1,5} | @@ -1586,8 +1545,8 @@ 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} | (3,NaN) + {-1,0,3} | {NaN,NaN,NaN} | (3,NaN) {-1,0,3} | {0,-1,3} | (3,3) {-1,0,3} | {-1,0,3} | (100 rows) @@ -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