From ba50fcb28c115c91324354bd9ec91aa557801a1f Mon Sep 17 00:00:00 2001 From: stepan-neretin7 Date: Thu, 20 Jul 2023 16:51:37 +0700 Subject: [PATCH 01/87] Return value from function, which should return angle must be float, not pointer --- Makefile | 2 +- expected/euler.out | 138 ++++++++++++++++++++++++++++++++++++++++ expected/init.out | 2 +- pg_sphere--1.2.3.sql.in | 2 + pg_sphere.control | 2 +- sql/euler.sql | 46 ++++++++++++++ src/euler.c | 7 +- 7 files changed, 192 insertions(+), 7 deletions(-) create mode 100644 pg_sphere--1.2.3.sql.in diff --git a/Makefile b/Makefile index 95c9bbb..d9e90d7 100644 --- a/Makefile +++ b/Makefile @@ -1,4 +1,4 @@ -PGSPHERE_VERSION = 1.2.2 +PGSPHERE_VERSION = 1.2.3 EXTENSION = pg_sphere RELEASE_SQL = $(EXTENSION)--$(PGSPHERE_VERSION).sql USE_PGXS = 1 diff --git a/expected/euler.out b/expected/euler.out index 9ea179d..e48f9ad 100644 --- a/expected/euler.out +++ b/expected/euler.out @@ -17,3 +17,141 @@ SELECT strans '-40d,0d,40d,ZZZ' <> '-40d,0d,40d,XXX' ; f (1 row) +SELECT strans ( 20.0*pi()/180.0, -270.0*pi()/180.0, 70.5*pi()/180.0, 'XZY' ); + strans +--------------------------------------- + 0.34906585, 1.5707963, 1.2304571, XZY +(1 row) + +SELECT theta( strans ( 20.0*pi()/180.0, -270.0*pi()/180.0, 70.5*pi()/180.0, 'XZY' ) ); + theta +--------------- + 1.57079632679 +(1 row) + +SELECT psi( strans ( 20.0*pi()/180.0, -270.0*pi()/180.0, 70.5*pi()/180.0, 'XZY' ) ); + psi +--------------- + 1.23045712266 +(1 row) + +SELECT phi( strans ( 20.0*pi()/180.0, -270.0*pi()/180.0, 70.5*pi()/180.0, 'XZY' ) ); + phi +---------------- + 0.349065850399 +(1 row) + +SELECT theta( strans( '20d, 30d, 40d, XZY' ) ); + theta +---------------- + 0.523598775598 +(1 row) + +SELECT psi( strans( '20d, 30d, 40d, XZY' ) ); + psi +---------------- + 0.698131700798 +(1 row) + +SELECT phi( strans( '20d, 30d, 40d, XZY' ) ); + phi +---------------- + 0.349065850399 +(1 row) + +SELECT strans( '2d 20m, 10d, 0' ); + strans +--------------------------------- + 0.040724349, 0.17453293, 0, ZXZ +(1 row) + +SELECT theta( strans( '2d 20m, 10d, 0' ) ); + theta +---------------- + 0.174532925199 +(1 row) + +SELECT psi( strans( '2d 20m, 10d, 0' ) ); + psi +----- + 0 +(1 row) + +SELECT phi( strans( '2d 20m, 10d, 0' ) ); + phi +----------------- + 0.0407243492132 +(1 row) + +SELECT strans ( '10d, 90d, 270d, ZXZ' ); + strans +-------------------------------------- + 0.17453293, 1.5707963, 4.712389, ZXZ +(1 row) + +SELECT theta( strans ( '10d, 90d, 270d, ZXZ' ) ); + theta +--------------- + 1.57079632679 +(1 row) + +SELECT psi( strans ( '10d, 90d, 270d, ZXZ' ) ); + psi +--------------- + 4.71238898038 +(1 row) + +SELECT phi( strans ( '10d, 90d, 270d, ZXZ' ) ); + phi +---------------- + 0.174532925199 +(1 row) + +SELECT - strans ( '20d, 50d, 80d, XYZ' ); + ?column? +-------------------------------------- + 4.8869219, 5.4105207, 5.9341195, ZYX +(1 row) + +SELECT theta( - strans ( '20d, 50d, 80d, XYZ' ) ); + theta +----------------- + -0.872664625997 +(1 row) + +SELECT psi( - strans ( '20d, 50d, 80d, XYZ' ) ); + psi +----------------- + -0.349065850399 +(1 row) + +SELECT phi( - strans ( '20d, 50d, 80d, XYZ' ) ); + phi +--------------- + -1.3962634016 +(1 row) + +SELECT strans( '90d, 60d, 30d' ); + strans +--------------------------------------- + 1.5707963, 1.0471976, 0.52359878, ZXZ +(1 row) + +SELECT theta( strans( '90d, 60d, 30d' ) ); + theta +-------------- + 1.0471975512 +(1 row) + +SELECT psi( strans( '90d, 60d, 30d' ) ); + psi +---------------- + 0.523598775598 +(1 row) + +SELECT phi( strans( '90d, 60d, 30d' ) ); + phi +--------------- + 1.57079632679 +(1 row) + diff --git a/expected/init.out b/expected/init.out index 5bce07c..519c140 100644 --- a/expected/init.out +++ b/expected/init.out @@ -6,6 +6,6 @@ CREATE EXTENSION pg_sphere; select pg_sphere_version(); pg_sphere_version ------------------- - 1.2.2 + 1.2.3 (1 row) diff --git a/pg_sphere--1.2.3.sql.in b/pg_sphere--1.2.3.sql.in new file mode 100644 index 0000000..b83d02a --- /dev/null +++ b/pg_sphere--1.2.3.sql.in @@ -0,0 +1,2 @@ +-- complain if this script is run via psql +\echo Use "CREATE EXTENSION pg_sphere" to load this file. \quit diff --git a/pg_sphere.control b/pg_sphere.control index a995012..bebbe02 100644 --- a/pg_sphere.control +++ b/pg_sphere.control @@ -1,5 +1,5 @@ # pg_sphere extension comment = 'spherical objects with useful functions, operators and index support' -default_version = '1.2.2' +default_version = '1.2.3' module_pathname = '$libdir/pg_sphere' relocatable = true diff --git a/sql/euler.sql b/sql/euler.sql index c60bf02..6fabaf9 100644 --- a/sql/euler.sql +++ b/sql/euler.sql @@ -1,5 +1,6 @@ \set ECHO none SELECT set_sphere_output_precision(8); +SET extra_float_digits TO -3; \set ECHO all -- checking Euler transformation operators @@ -7,3 +8,48 @@ SELECT set_sphere_output_precision(8); SELECT strans '-10d,0d,10d,ZZZ' = '-10d,0d,10d,XXX' ; SELECT strans '-40d,0d,40d,ZZZ' <> '-40d,0d,40d,XXX' ; +SELECT strans ( 20.0*pi()/180.0, -270.0*pi()/180.0, 70.5*pi()/180.0, 'XZY' ); + +SELECT theta( strans ( 20.0*pi()/180.0, -270.0*pi()/180.0, 70.5*pi()/180.0, 'XZY' ) ); + +SELECT psi( strans ( 20.0*pi()/180.0, -270.0*pi()/180.0, 70.5*pi()/180.0, 'XZY' ) ); + +SELECT phi( strans ( 20.0*pi()/180.0, -270.0*pi()/180.0, 70.5*pi()/180.0, 'XZY' ) ); + +SELECT theta( strans( '20d, 30d, 40d, XZY' ) ); + +SELECT psi( strans( '20d, 30d, 40d, XZY' ) ); + +SELECT phi( strans( '20d, 30d, 40d, XZY' ) ); + +SELECT strans( '2d 20m, 10d, 0' ); + +SELECT theta( strans( '2d 20m, 10d, 0' ) ); + +SELECT psi( strans( '2d 20m, 10d, 0' ) ); + +SELECT phi( strans( '2d 20m, 10d, 0' ) ); + +SELECT strans ( '10d, 90d, 270d, ZXZ' ); + +SELECT theta( strans ( '10d, 90d, 270d, ZXZ' ) ); + +SELECT psi( strans ( '10d, 90d, 270d, ZXZ' ) ); + +SELECT phi( strans ( '10d, 90d, 270d, ZXZ' ) ); + +SELECT - strans ( '20d, 50d, 80d, XYZ' ); + +SELECT theta( - strans ( '20d, 50d, 80d, XYZ' ) ); + +SELECT psi( - strans ( '20d, 50d, 80d, XYZ' ) ); + +SELECT phi( - strans ( '20d, 50d, 80d, XYZ' ) ); + +SELECT strans( '90d, 60d, 30d' ); + +SELECT theta( strans( '90d, 60d, 30d' ) ); + +SELECT psi( strans( '90d, 60d, 30d' ) ); + +SELECT phi( strans( '90d, 60d, 30d' ) ); diff --git a/src/euler.c b/src/euler.c index b071635..a45f7b3 100644 --- a/src/euler.c +++ b/src/euler.c @@ -203,15 +203,14 @@ spheretrans_phi(PG_FUNCTION_ARGS) { SEuler *se = (SEuler *) PG_GETARG_POINTER(0); - PG_RETURN_POINTER(&se->phi); + PG_RETURN_FLOAT8(se->phi); } Datum spheretrans_theta(PG_FUNCTION_ARGS) { SEuler *se = (SEuler *) PG_GETARG_POINTER(0); - - PG_RETURN_POINTER(&se->theta); + PG_RETURN_FLOAT8(se->theta); } Datum @@ -219,7 +218,7 @@ spheretrans_psi(PG_FUNCTION_ARGS) { SEuler *se = (SEuler *) PG_GETARG_POINTER(0); - PG_RETURN_POINTER(&se->psi); + PG_RETURN_FLOAT8(se->psi); } Datum From bc591b8b1383ff8acaf413f12b933689fac4bd94 Mon Sep 17 00:00:00 2001 From: stepan-neretin7 Date: Mon, 24 Jul 2023 13:37:03 +0700 Subject: [PATCH 02/87] Create Upgrade script --- Makefile | 6 +++++- pg_sphere--1.2.1.sql.in | 2 -- pg_sphere--1.2.2.sql.in | 2 -- upgrade_scripts/pg_sphere--1.2.2--1.2.3.sql.in | 1 + 4 files changed, 6 insertions(+), 5 deletions(-) delete mode 100644 pg_sphere--1.2.1.sql.in delete mode 100644 pg_sphere--1.2.2.sql.in create mode 100644 upgrade_scripts/pg_sphere--1.2.2--1.2.3.sql.in diff --git a/Makefile b/Makefile index d9e90d7..dca3b7d 100644 --- a/Makefile +++ b/Makefile @@ -26,7 +26,8 @@ DATA_built = $(RELEASE_SQL) \ pg_sphere--1.1.5beta2gavo--1.1.5beta4gavo.sql \ pg_sphere--1.1.5beta4gavo--1.2.0.sql \ pg_sphere--1.2.0--1.2.1.sql \ - pg_sphere--1.2.1--1.2.2.sql + pg_sphere--1.2.1--1.2.2.sql \ + pg_sphere--1.2.2--1.2.3.sql DOCS = README.pg_sphere COPYRIGHT.pg_sphere REGRESS = init tables points euler circle line ellipse poly path box index \ @@ -256,6 +257,9 @@ pg_sphere--1.2.1--1.2.2.sql: cat upgrade_scripts/$@.in > $@ endif +pg_sphere--1.2.2--1.2.3.sql: + cat upgrade_scripts/$@.in > $@ + # end of local stuff src/sscan.o : src/sparse.c diff --git a/pg_sphere--1.2.1.sql.in b/pg_sphere--1.2.1.sql.in deleted file mode 100644 index b83d02a..0000000 --- a/pg_sphere--1.2.1.sql.in +++ /dev/null @@ -1,2 +0,0 @@ --- complain if this script is run via psql -\echo Use "CREATE EXTENSION pg_sphere" to load this file. \quit diff --git a/pg_sphere--1.2.2.sql.in b/pg_sphere--1.2.2.sql.in deleted file mode 100644 index b83d02a..0000000 --- a/pg_sphere--1.2.2.sql.in +++ /dev/null @@ -1,2 +0,0 @@ --- complain if this script is run via psql -\echo Use "CREATE EXTENSION pg_sphere" to load this file. \quit diff --git a/upgrade_scripts/pg_sphere--1.2.2--1.2.3.sql.in b/upgrade_scripts/pg_sphere--1.2.2--1.2.3.sql.in new file mode 100644 index 0000000..8ea3baa --- /dev/null +++ b/upgrade_scripts/pg_sphere--1.2.2--1.2.3.sql.in @@ -0,0 +1 @@ +-- Nothing to upgrade in the schema From 118fe52b13cb13a170593830d4d769270cc016c2 Mon Sep 17 00:00:00 2001 From: stepan-neretin7 Date: Mon, 31 Jul 2023 17:22:11 +0700 Subject: [PATCH 03/87] [ISSUE #22] Created spoint_deg, scircle_deg functions. --- Makefile | 6 ++- expected/circle.out | 16 +++++++ expected/init_test.out.in | 22 ++++----- expected/init_test_healpix.out.in | 4 +- expected/points.out | 18 +++++++ expected/poly.out | 22 +++++++++ pgs_circle.sql.in | 8 ++++ pgs_point.sql.in | 9 ++++ pgs_polygon.sql.in | 12 +++++ pgs_types.sql.in | 1 - sql/circle.sql | 8 ++++ sql/points.sql | 6 +++ sql/poly.sql | 10 ++++ src/circle.c | 20 +++++++- src/circle.h | 5 ++ src/pgs_util.h | 5 ++ src/point.c | 28 +++++++++-- src/point.h | 10 ++++ src/polygon.c | 47 +++++++++++++++++++ src/polygon.h | 5 ++ .../pg_sphere--1.2.3--1.3.0.sql.in | 29 ++++++++++++ 21 files changed, 271 insertions(+), 20 deletions(-) create mode 100644 upgrade_scripts/pg_sphere--1.2.3--1.3.0.sql.in diff --git a/Makefile b/Makefile index dca3b7d..4e0f826 100644 --- a/Makefile +++ b/Makefile @@ -27,7 +27,8 @@ DATA_built = $(RELEASE_SQL) \ pg_sphere--1.1.5beta4gavo--1.2.0.sql \ pg_sphere--1.2.0--1.2.1.sql \ pg_sphere--1.2.1--1.2.2.sql \ - pg_sphere--1.2.2--1.2.3.sql + pg_sphere--1.2.2--1.2.3.sql \ + pg_sphere--1.2.3--1.3.0.sql DOCS = README.pg_sphere COPYRIGHT.pg_sphere REGRESS = init tables points euler circle line ellipse poly path box index \ @@ -260,6 +261,9 @@ endif pg_sphere--1.2.2--1.2.3.sql: cat upgrade_scripts/$@.in > $@ +pg_sphere--1.2.3--1.3.0.sql: + cat upgrade_scripts/$@.in > $@ + # end of local stuff src/sscan.o : src/sparse.c diff --git a/expected/circle.out b/expected/circle.out index 60a0159..02e5334 100644 --- a/expected/circle.out +++ b/expected/circle.out @@ -5,6 +5,22 @@ (1 row) -- Input/Output --- +SELECT scircle_deg(spoint(10,10), 90); + scircle_deg +------------------------------------------ + <(0.57522204 , -0.57522204) , 1.5707963> +(1 row) + +SELECT scircle_deg(spoint(10,10), 91); +ERROR: radius must not be greater than 90 degrees or less than 0 +SELECT scircle_deg(spoint(0,0), 0); + scircle_deg +--------------- + <(0 , 0) , 0> +(1 row) + +SELECT scircle_deg(spoint(10,10), -1); +ERROR: radius must not be greater than 90 degrees or less than 0 SELECT set_sphere_output( 'RAD' ); set_sphere_output ------------------- diff --git a/expected/init_test.out.in b/expected/init_test.out.in index 129283c..4b0671c 100644 --- a/expected/init_test.out.in +++ b/expected/init_test.out.in @@ -18,18 +18,18 @@ psql:pg_sphere.test.sql:108: NOTICE: argument type sellipse is only a shell psql:pg_sphere.test.sql:126: NOTICE: type "spoly" is not yet defined DETAIL: Creating a shell type definition. psql:pg_sphere.test.sql:133: NOTICE: argument type spoly is only a shell -psql:pg_sphere.test.sql:152: NOTICE: type "spath" is not yet defined +psql:pg_sphere.test.sql:151: NOTICE: type "spath" is not yet defined DETAIL: Creating a shell type definition. -psql:pg_sphere.test.sql:159: NOTICE: argument type spath is only a shell -psql:pg_sphere.test.sql:178: NOTICE: type "sbox" is not yet defined +psql:pg_sphere.test.sql:158: NOTICE: argument type spath is only a shell +psql:pg_sphere.test.sql:177: NOTICE: type "sbox" is not yet defined DETAIL: Creating a shell type definition. -psql:pg_sphere.test.sql:185: NOTICE: argument type sbox is only a shell -psql:pg_sphere.test.sql:8540: NOTICE: type "spherekey" is not yet defined +psql:pg_sphere.test.sql:184: NOTICE: argument type sbox is only a shell +psql:pg_sphere.test.sql:8568: NOTICE: type "spherekey" is not yet defined DETAIL: Creating a shell type definition. -psql:pg_sphere.test.sql:8547: NOTICE: argument type spherekey is only a shell -psql:pg_sphere.test.sql:8561: NOTICE: type "pointkey" is not yet defined +psql:pg_sphere.test.sql:8575: NOTICE: argument type spherekey is only a shell +psql:pg_sphere.test.sql:8589: NOTICE: type "pointkey" is not yet defined DETAIL: Creating a shell type definition. -psql:pg_sphere.test.sql:8568: NOTICE: argument type pointkey is only a shell -psql:pg_sphere.test.sql:8574: NOTICE: argument type pointkey is only a shell -psql:pg_sphere.test.sql:8580: NOTICE: argument type pointkey is only a shell -psql:pg_sphere.test.sql:8586: NOTICE: argument type pointkey is only a shell +psql:pg_sphere.test.sql:8596: NOTICE: argument type pointkey is only a shell +psql:pg_sphere.test.sql:8602: NOTICE: argument type pointkey is only a shell +psql:pg_sphere.test.sql:8608: NOTICE: argument type pointkey is only a shell +psql:pg_sphere.test.sql:8614: NOTICE: argument type pointkey is only a shell diff --git a/expected/init_test_healpix.out.in b/expected/init_test_healpix.out.in index 330dc68..7e725f8 100644 --- a/expected/init_test_healpix.out.in +++ b/expected/init_test_healpix.out.in @@ -1,2 +1,2 @@ -psql:pg_sphere.test.sql:9153: NOTICE: return type smoc is only a shell -psql:pg_sphere.test.sql:9159: NOTICE: argument type smoc is only a shell +psql:pg_sphere.test.sql:9181: NOTICE: return type smoc is only a shell +psql:pg_sphere.test.sql:9187: NOTICE: argument type smoc is only a shell diff --git a/expected/points.out b/expected/points.out index 84375e6..6fb3c17 100644 --- a/expected/points.out +++ b/expected/points.out @@ -239,6 +239,24 @@ SELECT spoint(0.0109083078249646 , -0.000727220521664407); (0.625d , -0.041666667d) (1 row) +SELECT spoint_deg(57.2958, 57.2958); + spoint_deg +----------------------- + (57.2958d , 57.2958d) +(1 row) + +SELECT spoint_deg(0, 0); + spoint_deg +------------ + (0d , 0d) +(1 row) + +SELECT spoint_deg(114.5916, 0); + spoint_deg +------------------ + (114.5916d , 0d) +(1 row) + SELECT set_sphere_output( 'RAD' ); set_sphere_output ------------------- diff --git a/expected/poly.out b/expected/poly.out index 201b9be..a705483 100644 --- a/expected/poly.out +++ b/expected/poly.out @@ -318,11 +318,33 @@ SELECT spoly '{(10d,0d),(10d,1d),(15d,0d)}'; {(10d , 0d),(10d , 1d),(15d , 0d)} (1 row) +SELECT spoly_deg(ARRAY[1.0, 2.0, 3.0, 4.0, 5.0, 6.0]); + spoly_deg +--------------------------------- + {(1d , 2d),(3d , 4d),(5d , 6d)} +(1 row) + +SELECT spoly_deg(ARRAY[10.0, 0.0, 10.0, 1.0, 15.0, 0.0]); + spoly_deg +------------------------------------ + {(10d , 0d),(10d , 1d),(15d , 0d)} +(1 row) + -- incorrect input ----- SELECT spoly '{(10d,0d),(10d,1d)}'; ERROR: spherepoly_in: more than two points needed LINE 1: SELECT spoly '{(10d,0d),(10d,1d)}'; ^ +SELECT spoly_deg(ARRAY[1.0, 2.0, 3.0, 4.0, 5.0]); +ERROR: spherepoly_deg: invalid number of arguments (must be even and >= 6) +SELECT spoly_deg(ARRAY[]::float8[]); +ERROR: spherepoly_deg: invalid number of arguments (must be even and >= 6) +SELECT spoly_deg(NULL::float8[]); + spoly_deg +----------- + +(1 row) + --- self-crossing input ----- SELECT spoly '{(0d,0d),(10d,10d),(0d,10d),(10d,0d)}'; ERROR: spherepoly_from_array: a line segment overlaps or polygon too large diff --git a/pgs_circle.sql.in b/pgs_circle.sql.in index e0c110d..9e386dd 100644 --- a/pgs_circle.sql.in +++ b/pgs_circle.sql.in @@ -32,6 +32,14 @@ CREATE FUNCTION scircle(spoint, float8) COMMENT ON FUNCTION scircle(spoint, float8) IS 'spherical circle with spherical point as center and float8 as radius in radians'; +CREATE FUNCTION scircle_deg(spoint, float8) + RETURNS scircle + AS 'MODULE_PATHNAME' , 'spherecircle_by_center_deg' + LANGUAGE 'c' + IMMUTABLE STRICT PARALLEL SAFE; + +COMMENT ON FUNCTION scircle_deg(spoint, float8) IS + 'spherical circle with spherical point as center and float8 as radius in degrees'; -- -- Casting point as circle diff --git a/pgs_point.sql.in b/pgs_point.sql.in index a9afb84..908707e 100644 --- a/pgs_point.sql.in +++ b/pgs_point.sql.in @@ -15,6 +15,12 @@ CREATE FUNCTION spoint(FLOAT8, FLOAT8) LANGUAGE 'c' IMMUTABLE STRICT PARALLEL SAFE; +CREATE FUNCTION spoint_deg(FLOAT8, FLOAT8) + RETURNS spoint + AS 'MODULE_PATHNAME', 'spherepoint_from_long_lat_deg' + LANGUAGE 'c' + IMMUTABLE STRICT PARALLEL SAFE; + CREATE FUNCTION set_sphere_output_precision(INT4) RETURNS CSTRING AS 'MODULE_PATHNAME', 'set_sphere_output_precision' @@ -28,6 +34,9 @@ CREATE FUNCTION set_sphere_output(CSTRING) COMMENT ON FUNCTION spoint(FLOAT8, FLOAT8) IS 'returns a spherical point from longitude (arg1), latitude (arg2)'; +COMMENT ON FUNCTION spoint_deg(FLOAT8, FLOAT8) IS + 'returns a spherical point from longitude (arg1, in degrees), latitude (arg2, in degrees)'; + CREATE FUNCTION long(spoint) RETURNS FLOAT8 AS 'MODULE_PATHNAME', 'spherepoint_long' diff --git a/pgs_polygon.sql.in b/pgs_polygon.sql.in index 701c860..df5a614 100644 --- a/pgs_polygon.sql.in +++ b/pgs_polygon.sql.in @@ -928,6 +928,18 @@ CREATE FUNCTION spoly_add_point_aggr (spoly, spoint) COMMENT ON FUNCTION spoly_add_point_aggr (spoly, spoint) IS 'adds a spherical point to spherical polygon. Do not use it standalone!'; +CREATE FUNCTION spoly_deg(float8[]) + RETURNS spoly + AS 'MODULE_PATHNAME', 'spherepoly_deg' + LANGUAGE 'c' + IMMUTABLE STRICT; + +COMMENT ON FUNCTION spoly_deg(float8[]) IS + ' Create spoly from array of points. + Two consecutive numbers among those present + refer to the same occurrence and cover its + latitude and longitude, respectively.'; + CREATE FUNCTION spoly_add_points_fin_aggr (spoly) RETURNS spoly AS 'MODULE_PATHNAME', 'spherepoly_add_points_finalize' diff --git a/pgs_types.sql.in b/pgs_types.sql.in index e0ff8f3..4bede83 100644 --- a/pgs_types.sql.in +++ b/pgs_types.sql.in @@ -132,7 +132,6 @@ CREATE FUNCTION spoly_out(spoly) LANGUAGE 'c' IMMUTABLE STRICT; - CREATE TYPE spoly ( internallength = VARIABLE, input = spoly_in, diff --git a/sql/circle.sql b/sql/circle.sql index 5fbbc91..0a57cab 100644 --- a/sql/circle.sql +++ b/sql/circle.sql @@ -5,6 +5,14 @@ SET extra_float_digits = 0; -- Input/Output --- +SELECT scircle_deg(spoint(10,10), 90); + +SELECT scircle_deg(spoint(10,10), 91); + +SELECT scircle_deg(spoint(0,0), 0); + +SELECT scircle_deg(spoint(10,10), -1); + SELECT set_sphere_output( 'RAD' ); SELECT '< (1h 2m 30s , +1d 2m 30s), 1.0d >'::scircle; diff --git a/sql/points.sql b/sql/points.sql index a2d53a6..5e63260 100644 --- a/sql/points.sql +++ b/sql/points.sql @@ -86,6 +86,12 @@ SELECT '(0.0109083078249646 , -0.000727220521664407)'::spoint; SELECT spoint(0.0109083078249646 , -0.000727220521664407); +SELECT spoint_deg(57.2958, 57.2958); + +SELECT spoint_deg(0, 0); + +SELECT spoint_deg(114.5916, 0); + SELECT set_sphere_output( 'RAD' ); SELECT spoint(7.28318530717958623 , 0.00); diff --git a/sql/poly.sql b/sql/poly.sql index 4168024..52cedd7 100644 --- a/sql/poly.sql +++ b/sql/poly.sql @@ -78,10 +78,20 @@ SELECT spoly '{(359d,0d),(359d,1d),(4d,0d)}'; SELECT spoly '{(10d,0d),(10d,1d),(15d,0d)}'; +SELECT spoly_deg(ARRAY[1.0, 2.0, 3.0, 4.0, 5.0, 6.0]); + +SELECT spoly_deg(ARRAY[10.0, 0.0, 10.0, 1.0, 15.0, 0.0]); + -- incorrect input ----- SELECT spoly '{(10d,0d),(10d,1d)}'; +SELECT spoly_deg(ARRAY[1.0, 2.0, 3.0, 4.0, 5.0]); + +SELECT spoly_deg(ARRAY[]::float8[]); + +SELECT spoly_deg(NULL::float8[]); + --- self-crossing input ----- SELECT spoly '{(0d,0d),(10d,10d),(0d,10d),(10d,0d)}'; diff --git a/src/circle.c b/src/circle.c index f2b2992..e28fe0c 100644 --- a/src/circle.c +++ b/src/circle.c @@ -1,4 +1,5 @@ #include "circle.h" +#include "pgs_util.h" /* Circle functions */ @@ -22,6 +23,7 @@ PG_FUNCTION_INFO_V1(spherecircle_center); PG_FUNCTION_INFO_V1(spherecircle_radius); PG_FUNCTION_INFO_V1(spherepoint_to_circle); PG_FUNCTION_INFO_V1(spherecircle_by_center); +PG_FUNCTION_INFO_V1(spherecircle_by_center_deg); PG_FUNCTION_INFO_V1(spherecircle_area); PG_FUNCTION_INFO_V1(spherecircle_circ); PG_FUNCTION_INFO_V1(spheretrans_circle); @@ -79,7 +81,7 @@ spherecircle_in(PG_FUNCTION_ARGS) { pfree(c); c = NULL; - elog(ERROR, "spherecircle_in: radius must be not greater than 90 degrees"); + elog(ERROR, "spherecircle_in: radius must not be greater than 90 degrees or less than 0"); } else if (FPeq(c->radius, PIH)) { @@ -361,7 +363,7 @@ spherecircle_by_center(PG_FUNCTION_ARGS) if (FPgt(rad, PIH) || FPlt(rad, 0.0)) { - elog(ERROR, "radius must be not greater than 90 degrees or less than 0"); + elog(ERROR, "radius must not be greater than 90 degrees or less than 0"); PG_RETURN_NULL(); } c = (SCIRCLE *) palloc(sizeof(SCIRCLE)); @@ -370,6 +372,20 @@ spherecircle_by_center(PG_FUNCTION_ARGS) PG_RETURN_POINTER(c); } +Datum +spherecircle_by_center_deg(PG_FUNCTION_ARGS) +{ + Datum res; + SPoint *p = (SPoint *) PG_GETARG_POINTER(0); + const float8 rad = deg_to_rad(PG_GETARG_FLOAT8(1)); + res = DirectFunctionCall2( + spherecircle_by_center, + PointerGetDatum(p), + Float8GetDatum(rad) + ); + PG_RETURN_DATUM(res); +} + Datum spherecircle_area(PG_FUNCTION_ARGS) { diff --git a/src/circle.h b/src/circle.h index 8ac5175..b8aa520 100644 --- a/src/circle.h +++ b/src/circle.h @@ -132,6 +132,11 @@ Datum spherepoint_to_circle(PG_FUNCTION_ARGS); */ Datum spherecircle_by_center(PG_FUNCTION_ARGS); +/* + * Creates a circle from center and radius(in degrees). + */ +Datum spherecircle_by_center_deg(PG_FUNCTION_ARGS); + /* * Calculates the area of a circle in square radians. */ diff --git a/src/pgs_util.h b/src/pgs_util.h index ad9763b..b79170b 100644 --- a/src/pgs_util.h +++ b/src/pgs_util.h @@ -26,4 +26,9 @@ conv_theta(double x) return y; } +static inline double deg_to_rad(double in) +{ + return in * PI / 180; +} + #endif diff --git a/src/point.c b/src/point.c index 5132835..c68ee71 100644 --- a/src/point.c +++ b/src/point.c @@ -1,9 +1,11 @@ #include "point.h" +#include "pgs_util.h" /* This file contains definitions for spherical point functions. */ PG_FUNCTION_INFO_V1(spherepoint_in); PG_FUNCTION_INFO_V1(spherepoint_from_long_lat); +PG_FUNCTION_INFO_V1(spherepoint_from_long_lat_deg); PG_FUNCTION_INFO_V1(spherepoint_distance); PG_FUNCTION_INFO_V1(spherepoint_long); PG_FUNCTION_INFO_V1(spherepoint_lat); @@ -141,18 +143,38 @@ spherepoint_in(PG_FUNCTION_ARGS) PG_RETURN_POINTER(sp); } +void create_spherepoint_from_long_lat(SPoint *p, float8 lng, float8 lat) +{ + p->lat = lat; + p->lng = lng; + spoint_check(p); +} Datum spherepoint_from_long_lat(PG_FUNCTION_ARGS) { SPoint *p = (SPoint *) palloc(sizeof(SPoint)); - p->lng = PG_GETARG_FLOAT8(0); - p->lat = PG_GETARG_FLOAT8(1); - spoint_check(p); + const float8 lng = PG_GETARG_FLOAT8(0); + const float8 lat = PG_GETARG_FLOAT8(1); + create_spherepoint_from_long_lat(p, lng, lat); PG_RETURN_POINTER(p); } +Datum +spherepoint_from_long_lat_deg(PG_FUNCTION_ARGS) +{ + Datum res; + const float8 lng = deg_to_rad(PG_GETARG_FLOAT8(0)); + const float8 lat = deg_to_rad(PG_GETARG_FLOAT8(1)); + res = DirectFunctionCall2( + spherepoint_from_long_lat, + Float8GetDatum(lng), + Float8GetDatum(lat) + ); + PG_RETURN_DATUM(res); +} + static double norm2(double a, double b) { diff --git a/src/point.h b/src/point.h index 76c2202..89197d0 100644 --- a/src/point.h +++ b/src/point.h @@ -45,11 +45,21 @@ void spoint_vector3d(Vector3D *v, const SPoint *p); */ Datum spherepoint_in(PG_FUNCTION_ARGS); +/* + * Create spherical point from lat, lng and store to first argument(pointer) + */ +void create_spherepoint_from_long_lat(SPoint *p, float8 lng, float8 lat); + /* * Create a spherical point from longitude and latitude both in radians. */ Datum spherepoint_from_long_lat(PG_FUNCTION_ARGS); +/* + * Create a spherical point from longitude and latitude both in degrees. + */ +Datum spherepoint_from_long_lat_deg(PG_FUNCTION_ARGS); + /* * Calculate the distance between two spherical points. */ diff --git a/src/polygon.c b/src/polygon.c index 8ae3fe8..17f4841 100644 --- a/src/polygon.c +++ b/src/polygon.c @@ -1,9 +1,11 @@ #include "polygon.h" +#include "point.h" /* Polygon functions */ PG_FUNCTION_INFO_V1(spherepoly_in); +PG_FUNCTION_INFO_V1(spherepoly_deg); PG_FUNCTION_INFO_V1(spherepoly_equal); PG_FUNCTION_INFO_V1(spherepoly_equal_neg); PG_FUNCTION_INFO_V1(spherepoly_circ); @@ -850,6 +852,51 @@ spherepoly_in(PG_FUNCTION_ARGS) PG_RETURN_POINTER(poly); } +Datum +spherepoly_deg(PG_FUNCTION_ARGS) +{ + int i, + np; + ArrayType *float_vector = PG_GETARG_ARRAYTYPE_P(0); + float8 *array_data; + SPoint *points; + + np = ArrayGetNItems(ARR_NDIM(float_vector), ARR_DIMS(float_vector)); + + if (np < 6 || np % 2 != 0) + { + elog( + ERROR, + "spherepoly_deg: invalid number of arguments (must be even and >= 6)" + ); + PG_RETURN_NULL(); + } + + np /= 2; + + points = (SPoint *) palloc(np * sizeof(SPoint)); + if (points == NULL) + { + elog( + ERROR, + "spherepoly_deg: failed for allocate memory for points array" + ); + PG_RETURN_NULL(); + } + + array_data = (float8 *) ARR_DATA_PTR(float_vector); + + for (i = 0; i < np; i++) + { + create_spherepoint_from_long_lat( + &points[i], + deg_to_rad(array_data[2 * i]), + deg_to_rad(array_data[2 * i + 1]) + ); + } + PG_RETURN_POINTER(spherepoly_from_array(points, np)); +} + Datum spherepoly_equal(PG_FUNCTION_ARGS) { diff --git a/src/polygon.h b/src/polygon.h index 7f2aa80..eefd099 100644 --- a/src/polygon.h +++ b/src/polygon.h @@ -81,6 +81,11 @@ bool spoly_contains_point(const SPOLY *pg, const SPoint *sp); */ int8 poly_line_pos(const SPOLY *poly, const SLine *line); +/* + * Input of a spherical from sequence of pairconsecutive numbers(lng, lat). + */ +Datum spherepoly_deg(PG_FUNCTION_ARGS); + /* * Input of a spherical polygon. */ diff --git a/upgrade_scripts/pg_sphere--1.2.3--1.3.0.sql.in b/upgrade_scripts/pg_sphere--1.2.3--1.3.0.sql.in new file mode 100644 index 0000000..86cc233 --- /dev/null +++ b/upgrade_scripts/pg_sphere--1.2.3--1.3.0.sql.in @@ -0,0 +1,29 @@ +CREATE FUNCTION scircle_deg(spoint, float8) + RETURNS scircle + AS 'MODULE_PATHNAME' , 'spherecircle_by_center_deg' + LANGUAGE 'c' + IMMUTABLE STRICT PARALLEL SAFE; + +COMMENT ON FUNCTION scircle_deg(spoint, float8) IS + 'spherical circle with spherical point as center and float8 as radius in degrees'; + +CREATE FUNCTION spoint_deg(FLOAT8, FLOAT8) + RETURNS spoint + AS 'MODULE_PATHNAME', 'spherepoint_from_long_lat_deg' + LANGUAGE 'c' + IMMUTABLE STRICT PARALLEL SAFE; + +COMMENT ON FUNCTION spoint_deg(FLOAT8, FLOAT8) IS + 'returns a spherical point from longitude (arg1, in degrees), latitude (arg2, in degrees)'; + +CREATE FUNCTION spoly_deg(float8[]) + RETURNS spoly + AS 'MODULE_PATHNAME', 'spherepoly_deg' + LANGUAGE 'c' + IMMUTABLE STRICT; + +COMMENT ON FUNCTION spoly_deg(float8[]) IS + ' Create spoly from array of points. + Two consecutive numbers among those present + refer to the same occurrence and cover its + latitude and longitude, respectively.'; From 513e2d0e4845b4dd45660009773f0cc6e613f97a Mon Sep 17 00:00:00 2001 From: Vitaly Davydov Date: Fri, 4 Aug 2023 23:32:07 +0300 Subject: [PATCH 04/87] Updated the current version. --- Makefile | 2 +- expected/init.out | 2 +- pg_sphere--1.2.3.sql.in => pg_sphere--1.3.0.sql.in | 0 pg_sphere.control | 2 +- 4 files changed, 3 insertions(+), 3 deletions(-) rename pg_sphere--1.2.3.sql.in => pg_sphere--1.3.0.sql.in (100%) diff --git a/Makefile b/Makefile index 4e0f826..a954626 100644 --- a/Makefile +++ b/Makefile @@ -1,4 +1,4 @@ -PGSPHERE_VERSION = 1.2.3 +PGSPHERE_VERSION = 1.3.0 EXTENSION = pg_sphere RELEASE_SQL = $(EXTENSION)--$(PGSPHERE_VERSION).sql USE_PGXS = 1 diff --git a/expected/init.out b/expected/init.out index 519c140..fc47f40 100644 --- a/expected/init.out +++ b/expected/init.out @@ -6,6 +6,6 @@ CREATE EXTENSION pg_sphere; select pg_sphere_version(); pg_sphere_version ------------------- - 1.2.3 + 1.3.0 (1 row) diff --git a/pg_sphere--1.2.3.sql.in b/pg_sphere--1.3.0.sql.in similarity index 100% rename from pg_sphere--1.2.3.sql.in rename to pg_sphere--1.3.0.sql.in diff --git a/pg_sphere.control b/pg_sphere.control index bebbe02..412cd57 100644 --- a/pg_sphere.control +++ b/pg_sphere.control @@ -1,5 +1,5 @@ # pg_sphere extension comment = 'spherical objects with useful functions, operators and index support' -default_version = '1.2.3' +default_version = '1.3.0' module_pathname = '$libdir/pg_sphere' relocatable = true From cbf89a8300710c35f3dfda4794a80ff597a111f4 Mon Sep 17 00:00:00 2001 From: stepan-neretin7 Date: Sat, 5 Aug 2023 05:01:21 +0700 Subject: [PATCH 05/87] [ISSUE #42] Fix compiler warning --- src/process_moc.cpp | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/src/process_moc.cpp b/src/process_moc.cpp index b2ba137..4a9e342 100644 --- a/src/process_moc.cpp +++ b/src/process_moc.cpp @@ -621,31 +621,31 @@ create_moc_release_context(void* moc_in_context, Smoc* moc, for (size_t k = 1; k < depth; ++k) { rnode_iter z(moc_data, m.layout[k].level_end); - rnode_iter n(moc_data, m.layout[k + 1].level_end); + rnode_iter b(moc_data, m.layout[k + 1].level_end); rnode_iter last_z; rnode_iter z_end = rend; for ( ; z != z_end; ++z) { if (z.page_ready()) { - n.set(make_node(z.index(), (*z).start)); - last_rend = n; - rend = ++n; + b.set(make_node(z.index(), (*z).start)); + last_rend = b; + rend = ++b; } last_z = z; } if (!last_z.page_ready()) { - n.set(make_node(last_z.index(), (*last_z).start)); - last_rend = n; - rend = ++n; + b.set(make_node(last_z.index(), (*last_z).start)); + last_rend = b; + rend = ++b; } } // The level-end section must be put relative to the actual beginning // of the root node to prevent confusing redunancies. int32 tree_begin = last_rend.index() - depth * MOC_INDEX_ALIGN; - + // fill out level-end section int32* level_ends = data_as(detoasted_offset(moc, tree_begin)); moc->depth = depth; From 5e7111ef27fa95d998465c7b3a5bb0c47e8b9ad2 Mon Sep 17 00:00:00 2001 From: ggnmstr Date: Sat, 29 Jul 2023 15:32:23 +0700 Subject: [PATCH 06/87] Fix sline_sline_pos, add tests for degenerate polygons --- expected/poly.out | 9 +++++++++ sql/poly.sql | 6 ++++++ src/line.c | 18 +++++++++--------- 3 files changed, 24 insertions(+), 9 deletions(-) diff --git a/expected/poly.out b/expected/poly.out index a705483..180e06f 100644 --- a/expected/poly.out +++ b/expected/poly.out @@ -350,6 +350,15 @@ SELECT spoly '{(0d,0d),(10d,10d),(0d,10d),(10d,0d)}'; ERROR: spherepoly_from_array: a line segment overlaps or polygon too large LINE 1: SELECT spoly '{(0d,0d),(10d,10d),(0d,10d),(10d,0d)}'; ^ +--- degenerate polygons ----- +SELECT spoly '{(0d,1d),(0d,2d),(0d,3d)}'; +ERROR: spherepoly_from_array: a line segment overlaps or polygon too large +LINE 1: SELECT spoly '{(0d,1d),(0d,2d),(0d,3d)}'; + ^ +SELECT spoly '{(1d,0d),(2d,0d),(3d,0d)}'; +ERROR: spherepoly_from_array: a line segment overlaps or polygon too large +LINE 1: SELECT spoly '{(1d,0d),(2d,0d),(3d,0d)}'; + ^ --- functions SELECT npoints( spoly '{(10d,0d),(10d,1d),(15d,0d)}'); npoints diff --git a/sql/poly.sql b/sql/poly.sql index 52cedd7..bdfbef8 100644 --- a/sql/poly.sql +++ b/sql/poly.sql @@ -96,6 +96,12 @@ SELECT spoly_deg(NULL::float8[]); SELECT spoly '{(0d,0d),(10d,10d),(0d,10d),(10d,0d)}'; +--- degenerate polygons ----- + +SELECT spoly '{(0d,1d),(0d,2d),(0d,3d)}'; + +SELECT spoly '{(1d,0d),(2d,0d),(3d,0d)}'; + --- functions SELECT npoints( spoly '{(10d,0d),(10d,1d),(15d,0d)}'); diff --git a/src/line.c b/src/line.c index 315adfb..b8d1195 100644 --- a/src/line.c +++ b/src/line.c @@ -494,15 +494,6 @@ sline_sline_pos(const SLine *l1, const SLine *l2) vector3d_spoint(&p[2], &v[1][0]); vector3d_spoint(&p[3], &v[1][1]); - /* check connected lines */ - if (FPgt(il2->length, 0.0) && (vector3d_eq(&v[0][0], &v[1][0]) || - vector3d_eq(&v[0][0], &v[1][1]) || - vector3d_eq(&v[0][1], &v[1][0]) || - vector3d_eq(&v[0][1], &v[1][1]))) - { - return PGS_LINE_CONNECT; - } - /* Check, sl2 is at equator */ if (FPzero(p[2].lat) && FPzero(p[3].lat)) { @@ -527,6 +518,15 @@ sline_sline_pos(const SLine *l1, const SLine *l2) return PGS_LINE_AVOID; } + /* check connected lines */ + if (FPgt(il2->length, 0.0) && (vector3d_eq(&v[0][0], &v[1][0]) || + vector3d_eq(&v[0][0], &v[1][1]) || + vector3d_eq(&v[0][1], &v[1][0]) || + vector3d_eq(&v[0][1], &v[1][1]))) + { + return PGS_LINE_CONNECT; + } + /* Now sl2 is not at equator */ if (FPle(il2->length, seg_length)) From cd82a4d963402510aacf7523c4f0d902a0bd7ccc Mon Sep 17 00:00:00 2001 From: Vitaly Davydov Date: Fri, 4 Aug 2023 12:29:35 +0300 Subject: [PATCH 07/87] Added simple description of versioning. --- README.pg_sphere | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) diff --git a/README.pg_sphere b/README.pg_sphere index 6d36fef..8a85c39 100644 --- a/README.pg_sphere +++ b/README.pg_sphere @@ -13,7 +13,21 @@ This is an R-Tree implementation using GiST for spherical objects like spherical points and spherical circles with useful functions and operators. NOTICE: - This version will work only with PostgreSQL version 9.6 and above. + This version will work only with PostgreSQL version 10 and above. + +VERSIONING: + +Stable versions are marked with tags containing version numbers in the GitHub +repository at https://github.com/postgrespro/pgsphere/. Each stable version +contains upgrade scripts for updating an existing installation to the latest +version using the ALTER EXTENSION UPDATE TO command. + +The master branch is intended for development purposes and may contain +intermediate changes. The current version in the master branch and its +functionality are subject to change. + +Note: The master branch should not be used in production because the upgrade +scripts and the current version number may be changed. INSTALLATION: From d88c0597e18afee1dc6dd990ccfce6379c69ba2d Mon Sep 17 00:00:00 2001 From: stepan-neretin7 Date: Mon, 24 Jul 2023 10:22:23 +0700 Subject: [PATCH 08/87] [ISSUE #16] Implemented a function and tests to extract vertices from spoly by index --- doc/functions.sgm | 89 ++++++++++++++++++- expected/init_test.out.in | 14 +-- expected/init_test_healpix.out.in | 4 +- expected/path.out | 25 ++++++ expected/poly.out | 30 +++++++ pgs_path.sql.in | 8 ++ pgs_polygon.sql.in | 18 ++++ sql/path.sql | 6 ++ sql/poly.sql | 7 ++ src/path.c | 27 ++++++ src/path.h | 5 ++ src/point.c | 12 +++ src/point.h | 2 + src/polygon.c | 53 +++++++++++ src/polygon.h | 10 +++ .../pg_sphere--1.2.3--1.3.0.sql.in | 27 ++++++ 16 files changed, 326 insertions(+), 11 deletions(-) diff --git a/doc/functions.sgm b/doc/functions.sgm index 30118bf..5cdc3aa 100644 --- a/doc/functions.sgm +++ b/doc/functions.sgm @@ -463,7 +463,7 @@ Positions at a path - pgSphere provides two functions to + pgSphere provides three functions to get points at a path. @@ -477,6 +477,10 @@ spath path float8 f + + spath_as_array + spath path + The first function returns the i-th @@ -495,6 +499,36 @@ + + + + + Codestin Search App + + SELECT spoint( spath '{(0, 0),(1, 1)}', 1 );]]> + + + + + + SELECT spoint( spath '{(0, 0),(1, 1)}', 2 );]]> + + + + + + + + Codestin Search App + + SELECT spath_as_array( spath '{(0, 0),(1, 1)}');]]> + + + @@ -532,7 +566,58 @@ - + + Codestin Search App + + pgSphere provides two functions to + get points at a path. + + + + spoint + spoly path + int4 i + + + spoly_as_array + spath path + + + + Codestin Search App + + SELECT spoint( spoly '{(0,0),(1,0),(1,1)}', 1 );]]> + + + + + + SELECT spoint( spoly '{(0,0),(1,0),(1,1)}', 2 );]]> + + + + + + SELECT spoint( spoly '{(0,0),(1,0),(1,1)}', 3 );]]> + + + + + + + + Codestin Search App + + SELECT spoly_as_array( spoly '{(0,0),(1,0),(1,1)}' );]]> + + + + + + + diff --git a/expected/init_test.out.in b/expected/init_test.out.in index 4b0671c..1276622 100644 --- a/expected/init_test.out.in +++ b/expected/init_test.out.in @@ -24,12 +24,12 @@ psql:pg_sphere.test.sql:158: NOTICE: argument type spath is only a shell psql:pg_sphere.test.sql:177: NOTICE: type "sbox" is not yet defined DETAIL: Creating a shell type definition. psql:pg_sphere.test.sql:184: NOTICE: argument type sbox is only a shell -psql:pg_sphere.test.sql:8568: NOTICE: type "spherekey" is not yet defined +psql:pg_sphere.test.sql:8594: NOTICE: type "spherekey" is not yet defined DETAIL: Creating a shell type definition. -psql:pg_sphere.test.sql:8575: NOTICE: argument type spherekey is only a shell -psql:pg_sphere.test.sql:8589: NOTICE: type "pointkey" is not yet defined +psql:pg_sphere.test.sql:8601: NOTICE: argument type spherekey is only a shell +psql:pg_sphere.test.sql:8615: NOTICE: type "pointkey" is not yet defined DETAIL: Creating a shell type definition. -psql:pg_sphere.test.sql:8596: NOTICE: argument type pointkey is only a shell -psql:pg_sphere.test.sql:8602: NOTICE: argument type pointkey is only a shell -psql:pg_sphere.test.sql:8608: NOTICE: argument type pointkey is only a shell -psql:pg_sphere.test.sql:8614: NOTICE: argument type pointkey is only a shell +psql:pg_sphere.test.sql:8622: NOTICE: argument type pointkey is only a shell +psql:pg_sphere.test.sql:8628: NOTICE: argument type pointkey is only a shell +psql:pg_sphere.test.sql:8634: NOTICE: argument type pointkey is only a shell +psql:pg_sphere.test.sql:8640: NOTICE: argument type pointkey is only a shell diff --git a/expected/init_test_healpix.out.in b/expected/init_test_healpix.out.in index 7e725f8..147d4f9 100644 --- a/expected/init_test_healpix.out.in +++ b/expected/init_test_healpix.out.in @@ -1,2 +1,2 @@ -psql:pg_sphere.test.sql:9181: NOTICE: return type smoc is only a shell -psql:pg_sphere.test.sql:9187: NOTICE: argument type smoc is only a shell +psql:pg_sphere.test.sql:9207: NOTICE: return type smoc is only a shell +psql:pg_sphere.test.sql:9213: NOTICE: argument type smoc is only a shell diff --git a/expected/path.out b/expected/path.out index 1734d8c..9f62534 100644 --- a/expected/path.out +++ b/expected/path.out @@ -468,3 +468,28 @@ SELECT spoint(p,2) FROM spheretmp6 WHERE id=2; (1d , -5d) (1 row) +SELECT set_sphere_output( 'RAD' ); + set_sphere_output +------------------- + SET RAD +(1 row) + +-- get n-th point and array representation path points tests +SELECT spoint( spath '{(0, 0),(1, 1)}', 1 ); + spoint +--------- + (0 , 0) +(1 row) + +SELECT spoint( spath '{(0, 0),(1, 1)}', 2 ); + spoint +--------- + (1 , 1) +(1 row) + +SELECT spath_as_array( spath '{(0, 0),(1, 1)}'); + spath_as_array +----------------------- + {"(0 , 0)","(1 , 1)"} +(1 row) + diff --git a/expected/poly.out b/expected/poly.out index a705483..bf7bc0b 100644 --- a/expected/poly.out +++ b/expected/poly.out @@ -1760,3 +1760,33 @@ SELECT npoints( spoly '{ 4 (1 row) +SELECT set_sphere_output( 'RAD' ); + set_sphere_output +------------------- + SET RAD +(1 row) + +SELECT spoint( spoly '{(0,0),(1,0),(1,1)}', 1 ); + spoint +--------- + (0 , 0) +(1 row) + +SELECT spoint( spoly '{(0,0),(1,0),(1,1)}', 2 ); + spoint +--------- + (1 , 0) +(1 row) + +SELECT spoint( spoly '{(0,0),(1,0),(1,1)}', 3 ); + spoint +--------- + (1 , 1) +(1 row) + +SELECT spoly_as_array( spoly '{(0,0),(1,0),(1,1)}' ); + spoly_as_array +--------------------------------- + {"(0 , 0)","(1 , 0)","(1 , 1)"} +(1 row) + diff --git a/pgs_path.sql.in b/pgs_path.sql.in index 94f3222..58268d4 100644 --- a/pgs_path.sql.in +++ b/pgs_path.sql.in @@ -34,6 +34,14 @@ CREATE FUNCTION spoint(spath, float8) COMMENT ON FUNCTION spoint(spath, float8) IS 'returns n-th point of spherical path using linear interpolation'; +CREATE FUNCTION spath_as_array(spath) + RETURNS spoint[] + AS 'MODULE_PATHNAME', 'spherepath_get_array' + LANGUAGE 'c' + IMMUTABLE STRICT PARALLEL SAFE; + +COMMENT ON FUNCTION spath_as_array(spath) IS + 'returns spath as array of points'; -- ****************************** -- diff --git a/pgs_polygon.sql.in b/pgs_polygon.sql.in index df5a614..5db17c6 100644 --- a/pgs_polygon.sql.in +++ b/pgs_polygon.sql.in @@ -11,6 +11,24 @@ CREATE FUNCTION npoints(spoly) COMMENT ON FUNCTION npoints(spoly) IS 'returns number of points of spherical polygon'; +CREATE FUNCTION spoint(spoly, int4) + RETURNS spoint + AS 'MODULE_PATHNAME', 'spherepoly_get_point' + LANGUAGE 'c' + IMMUTABLE STRICT PARALLEL SAFE; + +COMMENT ON FUNCTION spoint(spoly, int4) IS + 'returns n-th point of spherical polygon'; + +CREATE FUNCTION spoly_as_array(spoly) + RETURNS spoint[] + AS 'MODULE_PATHNAME', 'spherepoly_get_array' + LANGUAGE 'c' + IMMUTABLE STRICT PARALLEL SAFE; + +COMMENT ON FUNCTION spoly_as_array(spoly) IS + 'returns spoly as array of points'; + CREATE FUNCTION area(spoly) RETURNS FLOAT8 AS 'MODULE_PATHNAME', 'spherepoly_area' diff --git a/sql/path.sql b/sql/path.sql index fef5c1f..85fb3ff 100644 --- a/sql/path.sql +++ b/sql/path.sql @@ -104,3 +104,9 @@ SELECT set_sphere_output( 'DEG' ); -- test stored data SELECT spoint(p,2) FROM spheretmp6 WHERE id=2; +SELECT set_sphere_output( 'RAD' ); + +-- get n-th point and array representation path points tests +SELECT spoint( spath '{(0, 0),(1, 1)}', 1 ); +SELECT spoint( spath '{(0, 0),(1, 1)}', 2 ); +SELECT spath_as_array( spath '{(0, 0),(1, 1)}'); diff --git a/sql/poly.sql b/sql/poly.sql index 52cedd7..9d7b600 100644 --- a/sql/poly.sql +++ b/sql/poly.sql @@ -603,3 +603,10 @@ SELECT npoints( spoly '{ (1.5121581120647 , -1.93925472462553e-05), (1.51214841579108 , -1.93925472462553e-05) }'); + +SELECT set_sphere_output( 'RAD' ); + +SELECT spoint( spoly '{(0,0),(1,0),(1,1)}', 1 ); +SELECT spoint( spoly '{(0,0),(1,0),(1,1)}', 2 ); +SELECT spoint( spoly '{(0,0),(1,0),(1,1)}', 3 ); +SELECT spoly_as_array( spoly '{(0,0),(1,0),(1,1)}' ); diff --git a/src/path.c b/src/path.c index b72a753..f6d9495 100644 --- a/src/path.c +++ b/src/path.c @@ -1,4 +1,6 @@ #include "path.h" +#include "point.h" +#include /* * Path functions @@ -50,6 +52,7 @@ PG_FUNCTION_INFO_V1(spheretrans_path); PG_FUNCTION_INFO_V1(spheretrans_path_inverse); PG_FUNCTION_INFO_V1(spherepath_add_point); PG_FUNCTION_INFO_V1(spherepath_add_points_finalize); +PG_FUNCTION_INFO_V1(spherepath_get_array); /* @@ -555,6 +558,30 @@ spherepath_get_point(PG_FUNCTION_ARGS) PG_RETURN_NULL(); } +Datum +spherepath_get_array(PG_FUNCTION_ARGS) +{ + SPATH *path = PG_GETARG_SPATH(0); + Datum *datum_arr = (Datum *) palloc(sizeof(Datum) * path->npts); + ArrayType *res; + SPoint *p = (SPoint *) palloc(sizeof(SPoint) * path->npts); + + for (size_t i = 0; i < path->npts; i++) + { + if (!spath_get_point(&p[i], path, i)) + { + pfree(p); + pfree(datum_arr); + PG_RETURN_NULL(); + } + datum_arr[i] = PointerGetDatum(&p[i]); + } + + res = construct_array(datum_arr, path->npts, get_spoint_type_oid(), sizeof(SPoint), false, 'd'); + + PG_RETURN_ARRAYTYPE_P(res); +} + Datum spherepath_point(PG_FUNCTION_ARGS) { diff --git a/src/path.h b/src/path.h index 1d0fc35..29c687b 100644 --- a/src/path.h +++ b/src/path.h @@ -71,6 +71,11 @@ Datum spherepath_in(PG_FUNCTION_ARGS); */ Datum spherepath_get_point(PG_FUNCTION_ARGS); +/* + * Returns spath as array of points + */ +Datum spherepath_get_array(PG_FUNCTION_ARGS); + /* * This function interpolates between points of path. Returns the * n-th point of a path where n is a float. diff --git a/src/point.c b/src/point.c index c68ee71..0cbfa00 100644 --- a/src/point.c +++ b/src/point.c @@ -1,5 +1,6 @@ #include "point.h" #include "pgs_util.h" +#include /* This file contains definitions for spherical point functions. */ @@ -15,6 +16,17 @@ PG_FUNCTION_INFO_V1(spherepoint_z); PG_FUNCTION_INFO_V1(spherepoint_xyz); PG_FUNCTION_INFO_V1(spherepoint_equal); +static Oid point_id = InvalidOid; + +Oid get_spoint_type_oid(void) +{ + if (point_id == InvalidOid) + { + point_id = TypenameGetTypid("spoint"); + } + return point_id; +} + bool spoint_eq(const SPoint *p1, const SPoint *p2) { diff --git a/src/point.h b/src/point.h index 89197d0..9269cf7 100644 --- a/src/point.h +++ b/src/point.h @@ -15,6 +15,8 @@ typedef struct float8 lat; /* latitude value in radians */ } SPoint; +Oid get_spoint_type_oid(void); + /* * Calculate the distance between two spherical points in radians. */ diff --git a/src/polygon.c b/src/polygon.c index 17f4841..54eb2a6 100644 --- a/src/polygon.c +++ b/src/polygon.c @@ -11,6 +11,8 @@ PG_FUNCTION_INFO_V1(spherepoly_equal_neg); PG_FUNCTION_INFO_V1(spherepoly_circ); PG_FUNCTION_INFO_V1(spherepoly_npts); PG_FUNCTION_INFO_V1(spherepoly_area); +PG_FUNCTION_INFO_V1(spherepoly_get_point); +PG_FUNCTION_INFO_V1(spherepoly_get_array); PG_FUNCTION_INFO_V1(spherepoly_cont_point); PG_FUNCTION_INFO_V1(spherepoly_cont_point_neg); PG_FUNCTION_INFO_V1(spherepoly_cont_point_com); @@ -556,6 +558,57 @@ spoly_segment(SLine *sl, const SPOLY *poly, int32 i) } } +static bool +spoly_get_point(SPoint *sp, const SPOLY *poly, int32 i) +{ + if (i >= 0 && i < poly->npts) + { + memcpy((void *) sp, (void *) &poly->p[i], sizeof(SPoint)); + return true; + } + return false; +} + +Datum +spherepoly_get_point(PG_FUNCTION_ARGS) +{ + int32 i; + SPOLY *poly = PG_GETARG_SPOLY(0); + SPoint *sp = (SPoint *) palloc(sizeof(SPoint)); + + i = PG_GETARG_INT32(1); + if (spoly_get_point(sp, poly, i - 1)) + { + PG_RETURN_POINTER(sp); + } + pfree(sp); + PG_RETURN_NULL(); +} + +Datum +spherepoly_get_array(PG_FUNCTION_ARGS) +{ + SPOLY *poly = PG_GETARG_SPOLY(0); + Datum *datum_arr = (Datum *) palloc(sizeof(Datum) * poly->npts); + ArrayType *res; + SPoint *p = (SPoint *) palloc(sizeof(SPoint) * poly->npts); + + for (int i = 0; i < poly->npts; i++) + { + if (!spoly_get_point(&p[i], poly, i)) + { + pfree(p); + pfree(datum_arr); + PG_RETURN_NULL(); + } + datum_arr[i] = PointerGetDatum(&p[i]); + } + + res = construct_array(datum_arr, poly->npts, get_spoint_type_oid(), sizeof(SPoint), false, 'd'); + + PG_RETURN_ARRAYTYPE_P(res); +} + /* * Checks whether a polygon contains a point. * diff --git a/src/polygon.h b/src/polygon.h index eefd099..c7daf13 100644 --- a/src/polygon.h +++ b/src/polygon.h @@ -72,6 +72,11 @@ bool spoly_segment(SLine *sl, const SPOLY *poly, int32 i); */ bool spoly_contains_point(const SPOLY *pg, const SPoint *sp); +/* + * Returns the n-th point of a spoly. + */ +Datum spherepoly_get_point(PG_FUNCTION_ARGS); + /* * Returns the relationship between a polygon and a line as * PGS_LINE_POLY_REL int8 value. @@ -348,4 +353,9 @@ Datum spherepoly_add_point(PG_FUNCTION_ARGS); */ Datum spherepoly_add_points_finalize(PG_FUNCTION_ARGS); +/* + * Returns spoly as array of points + */ +Datum spherepoly_get_array(PG_FUNCTION_ARGS); + #endif diff --git a/upgrade_scripts/pg_sphere--1.2.3--1.3.0.sql.in b/upgrade_scripts/pg_sphere--1.2.3--1.3.0.sql.in index 86cc233..3791852 100644 --- a/upgrade_scripts/pg_sphere--1.2.3--1.3.0.sql.in +++ b/upgrade_scripts/pg_sphere--1.2.3--1.3.0.sql.in @@ -27,3 +27,30 @@ COMMENT ON FUNCTION spoly_deg(float8[]) IS Two consecutive numbers among those present refer to the same occurrence and cover its latitude and longitude, respectively.'; + +CREATE FUNCTION spath_as_array(spath) + RETURNS spoint[] + AS 'MODULE_PATHNAME', 'spherepath_get_array' + LANGUAGE 'c' + IMMUTABLE STRICT PARALLEL SAFE; + +COMMENT ON FUNCTION spath_as_array(spath) IS + 'returns spath as array of points'; + +CREATE FUNCTION spoint(spoly, int4) + RETURNS spoint + AS 'MODULE_PATHNAME', 'spherepoly_get_point' + LANGUAGE 'c' + IMMUTABLE STRICT PARALLEL SAFE; + +COMMENT ON FUNCTION spoint(spoly, int4) IS + 'returns n-th point of spherical polygon'; + +CREATE FUNCTION spoly_as_array(spoly) + RETURNS spoint[] + AS 'MODULE_PATHNAME', 'spherepoly_get_array' + LANGUAGE 'c' + IMMUTABLE STRICT PARALLEL SAFE; + +COMMENT ON FUNCTION spoly_as_array(spoly) IS + 'returns spoly as array of points'; From 23ff77ef2e67bce357a15e2d952ac026c3219d91 Mon Sep 17 00:00:00 2001 From: 3Davydov Date: Fri, 4 Aug 2023 03:51:02 +0700 Subject: [PATCH 09/87] Created some tests for contains and overlap operations to check DE-9IM compliance --- Makefile | 5 +- expected/contains.out | 233 ++++++++++ expected/overlaps.out | 1017 +++++++++++++++++++++++++++++++++++++++++ sql/contains.sql | 123 +++++ sql/overlaps.sql | 484 ++++++++++++++++++++ 5 files changed, 1860 insertions(+), 2 deletions(-) create mode 100644 expected/contains.out create mode 100644 expected/overlaps.out create mode 100644 sql/contains.sql create mode 100644 sql/overlaps.sql diff --git a/Makefile b/Makefile index dca3b7d..5bd53f7 100644 --- a/Makefile +++ b/Makefile @@ -31,7 +31,8 @@ DATA_built = $(RELEASE_SQL) \ DOCS = README.pg_sphere COPYRIGHT.pg_sphere REGRESS = init tables points euler circle line ellipse poly path box index \ - contains_ops contains_ops_compat bounding_box_gist gnomo epochprop + contains_ops contains_ops_compat bounding_box_gist gnomo epochprop \ + contains overlaps ifneq ($(USE_HEALPIX),0) REGRESS += healpix moc mocautocast @@ -41,7 +42,7 @@ REGRESS_9_5 = index_9.5 # experimental for spoint3 TESTS = init_test tables points euler circle line ellipse poly path box \ index contains_ops contains_ops_compat bounding_box_gist gnomo \ - epochprop + epochprop contains overlaps ifneq ($(USE_HEALPIX),0) TESTS += healpix moc mocautocast diff --git a/expected/contains.out b/expected/contains.out new file mode 100644 index 0000000..e86fcad --- /dev/null +++ b/expected/contains.out @@ -0,0 +1,233 @@ +/* +This set of tests is designed to verify the compliance of the contain operation with the DE-9IM model +*/ +-- sline vs spoint +-- the point lies far beyond the line +select 'sline ~ spoint', 'f' as expected, sline(spoint'(270d,10d)', spoint'(270d,30d)') ~ spoint'(0d, 50d)' as actual; + ?column? | expected | actual +----------------+----------+-------- + sline ~ spoint | f | f +(1 row) + +-- the point lies in the boundary of line +select 'sline ~ spoint', 'f' as expected, sline(spoint'(270d,10d)', spoint'(270d,30d)') ~ spoint'(270d, 10d)' as actual; + ?column? | expected | actual +----------------+----------+-------- + sline ~ spoint | f | t +(1 row) + +-- the point lies in the interior of line +select 'sline ~ spoint', 't' as expected, sline(spoint'(270d,10d)', spoint'(270d,30d)') ~ spoint'(270d, 20d)' as actual; + ?column? | expected | actual +----------------+----------+-------- + sline ~ spoint | t | t +(1 row) + +-- the point and line that degenerated into the point coincide +select 'sline ~ spoint', 't' as expected, sline(spoint'(270d,10d)', spoint'(270d,10d)') ~ spoint'(270d, 10d)' as actual; + ?column? | expected | actual +----------------+----------+-------- + sline ~ spoint | t | t +(1 row) + +-- the point and line that degenerated into the point do not coincide +select 'sline ~ spoint', 'f' as expected, sline(spoint'(270d,10d)', spoint'(270d,10d)') ~ spoint'(270d, 20d)' as actual; + ?column? | expected | actual +----------------+----------+-------- + sline ~ spoint | f | f +(1 row) + +-- spoint vs scircle +-- the point lies far beyond the circle +select 'spoint @ scircle', 'f' as expected, spoint'(0d,0d)' @ scircle'<(0d,90d),50d>' as actual; + ?column? | expected | actual +------------------+----------+-------- + spoint @ scircle | f | f +(1 row) + +-- the point lies in the boundary of circle +select 'spoint @ scircle', 'f' as expected, spoint'(0d,80d)' @ scircle'<(0d,90d),10d>' as actual; + ?column? | expected | actual +------------------+----------+-------- + spoint @ scircle | f | t +(1 row) + +-- the point lies in the interior of circle +select 'spoint @ scircle', 't' as expected, spoint'(0d,80d)' @ scircle'<(0d,90d),50d>' as actual; + ?column? | expected | actual +------------------+----------+-------- + spoint @ scircle | t | t +(1 row) + +-- the point and circle that degenerated into the point coincide +select 'spoint @ scircle', 't' as expected, spoint'(0d,90d)' @ scircle'<(0d,90d),0d>' as actual; + ?column? | expected | actual +------------------+----------+-------- + spoint @ scircle | t | t +(1 row) + +-- the point and circle that degenerated into the point do not coincide +select 'spoint @ scircle', 'f' as expected, spoint'(0d,50d)' @ scircle'<(0d,90d),0d>' as actual; + ?column? | expected | actual +------------------+----------+-------- + spoint @ scircle | f | f +(1 row) + +-- sellipse vs spoint +-- the point lies far beyond the ellipse +select 'sellipse ~ spoint', 'f' as expected, sellipse'<{ 30d , 20d }, (0d , 90d) , 0d>' ~ spoint'(0d, 0d)' as actual; + ?column? | expected | actual +-------------------+----------+-------- + sellipse ~ spoint | f | f +(1 row) + +-- the point lies in the boundary of ellipse +select 'sellipse ~ spoint', 'f' as expected, sellipse'<{ 30d , 20d }, (0d , 90d) , 0d>' ~ spoint'(0d, 70d)' as actual; + ?column? | expected | actual +-------------------+----------+-------- + sellipse ~ spoint | f | t +(1 row) + +-- the point lies in the interior of ellipse +select 'sellipse ~ spoint', 't' as expected, sellipse'<{ 30d , 20d }, (0d , 90d) , 0d>' ~ spoint'(90d, 65d)' as actual; + ?column? | expected | actual +-------------------+----------+-------- + sellipse ~ spoint | t | t +(1 row) + +-- the point lies in the boundary of ellipse that degenerated into the line +select 'sellipse ~ spoint', 't' as expected, sellipse'<{ 10d , 0d }, (0d , 0d) , 0d>' ~ spoint'(10d, 0d)' as actual; + ?column? | expected | actual +-------------------+----------+-------- + sellipse ~ spoint | t | t +(1 row) + +-- the point lies in the interior of ellipse that degenerated into the line +select 'sellipse ~ spoint', 't' as expected, sellipse'<{ 10d , 0d }, (0d , 0d) , 0d>' ~ spoint'(0d, 0d)' as actual; + ?column? | expected | actual +-------------------+----------+-------- + sellipse ~ spoint | t | t +(1 row) + +-- the point and ellipse that degenerated into the point coincide +select 'sellipse ~ spoint', 't' as expected, sellipse'<{ 0d , 0d }, (0d , 90d) , 0d>' ~ spoint'(0d, 90d)' as actual; + ?column? | expected | actual +-------------------+----------+-------- + sellipse ~ spoint | t | t +(1 row) + +-- the point and ellipse that degenerated into the point do not coincide +select 'sellipse ~ spoint', 'f' as expected, sellipse'<{ 0d , 0d }, (0d , 90d) , 0d>' ~ spoint'(0d, 91d)' as actual; + ?column? | expected | actual +-------------------+----------+-------- + sellipse ~ spoint | f | f +(1 row) + +-- spath vs spoint +-- the point lies far beyond the opened path +select 'spath ~ spoint', 'f' as expected, spath'{ (-10d, 0d),(10d,0d),(45d,15d),(80d,30d) }' ~ spoint'(0d, 90d)' as actual; + ?column? | expected | actual +----------------+----------+-------- + spath ~ spoint | f | f +(1 row) + +-- the point lies in the boundary of opened path +select 'spath ~ spoint', 'f' as expected, spath'{ (-10d, 0d),(10d,0d),(45d,15d),(80d,30d) }' ~ spoint'(-10d, 0d)' as actual; + ?column? | expected | actual +----------------+----------+-------- + spath ~ spoint | f | t +(1 row) + +-- the point lies in the boundary of unsimple opened path +select 'spath ~ spoint', 'f' as expected, spath'{ (-10d, 0d),(10d,0d),(45d,15d),(80d,30d),(-5d, 0d) }' ~ spoint'(-5d, 0d)' as actual; + ?column? | expected | actual +----------------+----------+-------- + spath ~ spoint | f | t +(1 row) + +-- the point lies in the interior of opened path +select 'spath ~ spoint', 't' as expected, spath'{ (-10d, 0d),(10d,0d),(45d,15d),(80d,30d) }' ~ spoint'(9d, 0d)' as actual; + ?column? | expected | actual +----------------+----------+-------- + spath ~ spoint | t | t +(1 row) + +-- the point lies in the interior of closed path +select 'spath ~ spoint', 't' as expected, spath'{ (-10d, 0d),(10d,0d),(45d,15d),(80d,30d),(-10d, 0d) }' ~ spoint'(-10d, 0d)' as actual; + ?column? | expected | actual +----------------+----------+-------- + spath ~ spoint | t | t +(1 row) + +-- spoly vs spoint +-- the point lies far beyond the polygon +select 'spoly ~ spoint', 'f' as expected, spoly'{ (0d,0d), (10d,0d), (20d,20d) }' ~ spoint'(0d, 90d)' as actual; + ?column? | expected | actual +----------------+----------+-------- + spoly ~ spoint | f | f +(1 row) + +-- the point lies in the boundary of polygon +select 'spoly ~ spoint', 'f' as expected, spoly'{ (0d,0d), (10d,0d), (20d,20d) }' ~ spoint'(5d, 0d)' as actual; + ?column? | expected | actual +----------------+----------+-------- + spoly ~ spoint | f | t +(1 row) + +-- the point lies in the boundary of polygon +select 'spoly ~ spoint', 'f' as expected, spoly'{ (0d,0d), (10d,0d), (20d,20d) }' ~ spoint'(20d, 20d)' as actual; + ?column? | expected | actual +----------------+----------+-------- + spoly ~ spoint | f | t +(1 row) + +-- the point lies in the interior of polygon +select 'spoly ~ spoint', 't' as expected, spoly'{ (0d,0d), (10d,0d), (20d,20d) }' ~ spoint'(5d, 5d)' as actual; + ?column? | expected | actual +----------------+----------+-------- + spoly ~ spoint | t | t +(1 row) + +-- sbox vs spoint +-- the point lies far beyond the box +select 'sbox ~ spoint', 'f' as expected, sbox'( (0d,0d), (20d,10d) )' ~ spoint'(0d, 90d)' as actual; + ?column? | expected | actual +---------------+----------+-------- + sbox ~ spoint | f | f +(1 row) + +-- the point lies in the boundary of box +select 'sbox ~ spoint', 'f' as expected, sbox'( (0d,0d), (20d,10d) )' ~ spoint'(0d, 5d)' as actual; + ?column? | expected | actual +---------------+----------+-------- + sbox ~ spoint | f | t +(1 row) + +-- the point lies in the boundary of box +select 'sbox ~ spoint', 'f' as expected, sbox'( (0d,0d), (20d,10d) )' ~ spoint'(0d, 0d)' as actual; + ?column? | expected | actual +---------------+----------+-------- + sbox ~ spoint | f | t +(1 row) + +-- the point lies in the interior of box +select 'sbox ~ spoint', 't' as expected, sbox'( (0d,0d), (20d,10d) )' ~ spoint'(5d, 5d)' as actual; + ?column? | expected | actual +---------------+----------+-------- + sbox ~ spoint | t | t +(1 row) + +-- the point and box that degenerated into the point coincide +select 'sbox ~ spoint', 't' as expected, sbox'( (0d,0d), (0d,0d) )' ~ spoint'(0d, 0d)' as actual; + ?column? | expected | actual +---------------+----------+-------- + sbox ~ spoint | t | t +(1 row) + +-- the point and box that degenerated into the point do not coincide +select 'sbox ~ spoint', 'f' as expected, sbox'( (0d,0d), (0d,0d) )' ~ spoint'(0d, 1d)' as actual; + ?column? | expected | actual +---------------+----------+-------- + sbox ~ spoint | f | f +(1 row) + diff --git a/expected/overlaps.out b/expected/overlaps.out new file mode 100644 index 0000000..5a7625f --- /dev/null +++ b/expected/overlaps.out @@ -0,0 +1,1017 @@ +/* +This set of tests is designed to verify the compliance of the overlap operation with the DE-9IM model +*/ +-- sline vs sline +-- the lines have no common points +select 'sline && sline', 'f' as expected, sline( spoint'(0d,0d)', spoint'(10d,0d)') && sline( spoint'(20d,0d)', spoint'(30d,0d)') as actual; + ?column? | expected | actual +----------------+----------+-------- + sline && sline | f | f +(1 row) + +-- the point of intersection of the lines is the boundary for both +select 'sline && sline', 'f' as expected, sline( spoint'(0d,0d)', spoint'(10d,0d)') && sline( spoint'(10d,0d)', spoint'(20d,0d)') as actual; + ?column? | expected | actual +----------------+----------+-------- + sline && sline | f | t +(1 row) + +-- one line intersects the other at the boundary point of the latter +select 'sline && sline', 'f' as expected, sline( spoint'(0d,0d)', spoint'(10d,0d)') && sline( spoint'(0d,90d)', spoint'(0d,-10d)') as actual; + ?column? | expected | actual +----------------+----------+-------- + sline && sline | f | t +(1 row) + +-- the interiors of the lines intersect at one point +select 'sline && sline', 'f' as expected, sline( spoint'(-10d,0d)', spoint'(10d,0d)') && sline( spoint'(0d,90d)', spoint'(0d,-10d)') as actual; + ?column? | expected | actual +----------------+----------+-------- + sline && sline | f | t +(1 row) + +-- the lines match +select 'sline && sline', 'f' as expected, sline( spoint'(0d,0d)', spoint'(10d,0d)') && sline( spoint'(0d,0d)', spoint'(10d,0d)') as actual; + ?column? | expected | actual +----------------+----------+-------- + sline && sline | f | t +(1 row) + +-- one line lies completely in the other and they have an intersection at the boundary point +select 'sline && sline', 'f' as expected, sline( spoint'(0d,0d)', spoint'(10d,0d)') && sline( spoint'(0d,0d)', spoint'(5d,0d)') as actual; + ?column? | expected | actual +----------------+----------+-------- + sline && sline | f | t +(1 row) + +-- one line lies completely in the other and they have no intersection at the boundary point +select 'sline && sline', 'f' as expected, sline( spoint'(0d,0d)', spoint'(10d,0d)') && sline( spoint'(2d,0d)', spoint'(5d,0d)') as actual; + ?column? | expected | actual +----------------+----------+-------- + sline && sline | f | t +(1 row) + +-- one line partially lies in the other +select 'sline && sline', 't' as expected, sline( spoint'(0d,0d)', spoint'(10d,0d)') && sline( spoint'(5d,0d)', spoint'(20d,0d)') as actual; + ?column? | expected | actual +----------------+----------+-------- + sline && sline | t | t +(1 row) + +-- the line degenerated into the point lies on the boundary of another +select 'sline && sline', 'f' as expected, sline( spoint'(0d,0d)', spoint'(10d,0d)') && sline( spoint'(0d,0d)', spoint'(0d,0d)') as actual; + ?column? | expected | actual +----------------+----------+-------- + sline && sline | f | t +(1 row) + +-- the line degenerated into the point lies in the interior of another +select 'sline && sline', 'f' as expected, sline( spoint'(0d,0d)', spoint'(10d,0d)') && sline( spoint'(5d,0d)', spoint'(5d,0d)') as actual; + ?column? | expected | actual +----------------+----------+-------- + sline && sline | f | t +(1 row) + +-- both lines are degenerated into the point and coincide +select 'sline && sline', 'f' as expected, sline( spoint'(0d,0d)', spoint'(0d,0d)') && sline( spoint'(0d,0d)', spoint'(0d,0d)') as actual; + ?column? | expected | actual +----------------+----------+-------- + sline && sline | f | t +(1 row) + +-- both lines are degenerated into the point and do not coincide, but lie close to each other +select 'sline && sline', 'f' as expected, sline( spoint'(0d,0d)', spoint'(0d,0d)') && sline( spoint'(1d,0d)', spoint'(1d,0d)') as actual; + ?column? | expected | actual +----------------+----------+-------- + sline && sline | f | f +(1 row) + +-- scircle vs scircle +-- the circles have no common points +select 'scircle && scircle', 'f' as expected, scircle'<(0d , 0d) , 20d>' && scircle'<(30d , 0d) , 5d>' as actual; + ?column? | expected | actual +--------------------+----------+-------- + scircle && scircle | f | f +(1 row) + +-- the point of intersection of the circles is the boundary for both +select 'scircle && scircle', 'f' as expected, scircle'<(-10d , 0d) , 10d>' && scircle'<(10d , 0d) , 10d>' as actual; + ?column? | expected | actual +--------------------+----------+-------- + scircle && scircle | f | t +(1 row) + +-- the circles match +select 'scircle && scircle', 'f' as expected, scircle'<(-10d , 0d) , 10d>' && scircle'<(-10d , 0d) , 10d>' as actual; + ?column? | expected | actual +--------------------+----------+-------- + scircle && scircle | f | t +(1 row) + +-- one circle lies completely in the other and they have an intersection at the boundary point +select 'scircle && scircle', 'f' as expected, scircle'<(0d , 0d) , 20d>' && scircle'<(-10d , 0d) , 10d>' as actual; + ?column? | expected | actual +--------------------+----------+-------- + scircle && scircle | f | t +(1 row) + +-- one circle lies completely in the other and they have no intersection at the boundary point +select 'scircle && scircle', 'f' as expected, scircle'<(0d , 0d) , 20d>' && scircle'<(0d , 0d) , 5d>' as actual; + ?column? | expected | actual +--------------------+----------+-------- + scircle && scircle | f | t +(1 row) + +-- one circle partially lies in the other +select 'scircle && scircle', 't' as expected, scircle'<(0d , 0d) , 20d>' && scircle'<(10d , 0d) , 20d>' as actual; + ?column? | expected | actual +--------------------+----------+-------- + scircle && scircle | t | t +(1 row) + +-- the circle degenerated into the point lies on the boundary of another +select 'scircle && scircle', 'f' as expected, scircle'<(0d , 0d) , 20d>' && scircle'<(20d , 0d) , 0d>' as actual; + ?column? | expected | actual +--------------------+----------+-------- + scircle && scircle | f | t +(1 row) + +-- the circle degenerated into the point lies in the interior of another +select 'scircle && scircle', 'f' as expected, scircle'<(0d , 0d) , 20d>' && scircle'<(0d , 0d) , 0d>' as actual; + ?column? | expected | actual +--------------------+----------+-------- + scircle && scircle | f | t +(1 row) + +-- both circles are degenerated into the point and coincide +select 'scircle && scircle', 'f' as expected, scircle'<(0d , 0d) , 0d>' && scircle'<(0d , 0d) , 0d>' as actual; + ?column? | expected | actual +--------------------+----------+-------- + scircle && scircle | f | t +(1 row) + +-- both circles are degenerated into the point and do not coincide, but lie close to each other +select 'scircle && scircle', 'f' as expected, scircle'<(1d , 0d) , 0d>' && scircle'<(0d , 0d) , 0d>' as actual; + ?column? | expected | actual +--------------------+----------+-------- + scircle && scircle | f | f +(1 row) + +-- sellipse vs sellipse +-- the ellipses have no common points +select 'sellipse && sellipse', 'f' as expected, sellipse'<{ 45d , 20d }, (-45d , 0d) , 0d>' && sellipse'<{ 45d , 20d }, (50 , 0d) , 0d>' as actual; + ?column? | expected | actual +----------------------+----------+-------- + sellipse && sellipse | f | t +(1 row) + +-- the point of intersection of the ellipses is the boundary for both +select 'sellipse && sellipse', 'f' as expected, sellipse'<{ 45d , 20d }, (-45d , 0d) , 0d>' && sellipse'<{ 45d , 20d }, (45d , 0d) , 0d>' as actual; + ?column? | expected | actual +----------------------+----------+-------- + sellipse && sellipse | f | f +(1 row) + +-- the ellipses match +select 'sellipse && sellipse', 'f' as expected, sellipse'<{ 45d , 20d }, (-45d , 0d) , 0d>' && sellipse'<{ 45d , 20d }, (-45d , 0d) , 0d>' as actual; + ?column? | expected | actual +----------------------+----------+-------- + sellipse && sellipse | f | t +(1 row) + +-- one ellipse lies completely in the other and they have an intersection at the boundary point +select 'sellipse && sellipse', 'f' as expected, sellipse'<{ 40d , 30d }, (0d , 0d) , 0d>' && sellipse'<{ 20d , 5d }, (-20d , 0d) , 0d>' as actual; + ?column? | expected | actual +----------------------+----------+-------- + sellipse && sellipse | f | t +(1 row) + +-- one ellipse lies completely in the other and they have no intersection at the boundary point +select 'sellipse && sellipse', 'f' as expected, sellipse'<{ 40d , 30d }, (0d , 0d) , 0d>' && sellipse'<{ 10d , 5d }, (-20d , 0d) , 0d>' as actual; + ?column? | expected | actual +----------------------+----------+-------- + sellipse && sellipse | f | t +(1 row) + +-- one ellipse partially lies in the other +select 'sellipse && sellipse', 't' as expected, sellipse'<{ 45d , 30d }, (0d , 0d) , 0d>' && sellipse'<{ 20d , 5d }, (30d , 0d) , 0d>' as actual; + ?column? | expected | actual +----------------------+----------+-------- + sellipse && sellipse | t | t +(1 row) + +-- the ellipse degenerated into the line lies completely in the interior of another (non-degenerate) ellipse +select 'sellipse && sellipse', 'f' as expected, sellipse'<{ 40d , 30d }, (0d , 0d) , 0d>' && sellipse'<{ 10d , 0d }, (10d , 0d) , 0d>' as actual; + ?column? | expected | actual +----------------------+----------+-------- + sellipse && sellipse | f | t +(1 row) + +-- the ellipse degenerated into the line partially lies in the interior of another (non-degenerate) ellipse +select 'sellipse && sellipse', 'f' as expected, sellipse'<{ 40d , 30d }, (0d , 0d) , 0d>' && sellipse'<{ 20d , 0d }, (30d , 0d) , 0d>' as actual; + ?column? | expected | actual +----------------------+----------+-------- + sellipse && sellipse | f | t +(1 row) + +-- the ellipse degenerated into the point lies on the boundary of another +select 'sellipse && sellipse', 'f' as expected, sellipse'<{ 40d , 30d }, (0d , 0d) , 0d>' && sellipse'<{ 0d , 0d }, (30d , 0d) , 0d>' as actual; + ?column? | expected | actual +----------------------+----------+-------- + sellipse && sellipse | f | t +(1 row) + +-- the ellipse degenerated into the point lies in the interior of another +select 'sellipse && sellipse', 'f' as expected, sellipse'<{ 40d , 30d }, (0d , 0d) , 0d>' && sellipse'<{ 0d , 0d }, (40d , 0d) , 0d>' as actual; + ?column? | expected | actual +----------------------+----------+-------- + sellipse && sellipse | f | t +(1 row) + +-- both ellipses are degenerated into the point and coincide +select 'sellipse && sellipse', 'f' as expected, sellipse'<{ 0d , 0d }, (0d , 0d) , 0d>' && sellipse'<{ 0d , 0d }, (0d , 0d) , 0d>' as actual; + ?column? | expected | actual +----------------------+----------+-------- + sellipse && sellipse | f | t +(1 row) + +-- both ellipses are degenerated into the point and do not coincide, but lie close to each other +select 'sellipse && sellipse', 'f' as expected, sellipse'<{ 0d , 0d }, (0d , 0d) , 0d>' && sellipse'<{ 0d , 0d }, (1d , 0d) , 0d>' as actual; + ?column? | expected | actual +----------------------+----------+-------- + sellipse && sellipse | f | f +(1 row) + +-- sellipse vs scircle +-- the ellipse and circle have no common points +select 'sellipse && scircle', 'f' as expected, sellipse'<{ 20d , 10d }, (0d , 0d) , 0d>' && scircle'<(30d , 0d) , 5d>' as actual; + ?column? | expected | actual +---------------------+----------+-------- + sellipse && scircle | f | f +(1 row) + +-- the point of intersection of the ellipse and circle is the boundary for both +select 'sellipse && scircle', 'f' as expected, sellipse'<{ 20d , 10d }, (0d , 0d) , 0d>' && scircle'<(30d , 0d) , 10d>' as actual; + ?column? | expected | actual +---------------------+----------+-------- + sellipse && scircle | f | f +(1 row) + +-- the ellipse and circle match +select 'sellipse && scircle', 'f' as expected, sellipse'<{ 10d , 10d }, (30d , 0d) , 0d>' && scircle'<(30d , 0d) , 10d>' as actual; + ?column? | expected | actual +---------------------+----------+-------- + sellipse && scircle | f | t +(1 row) + +-- the ellipse lies completely in the circle and they have an intersection at the boundary point +select 'sellipse && scircle', 'f' as expected, sellipse'<{ 20d , 10d }, (0d , 0d) , 0d>' && scircle'<(20d , 0d) , 40d>' as actual; + ?column? | expected | actual +---------------------+----------+-------- + sellipse && scircle | f | t +(1 row) + +-- the ellipse lies completely in the circle and they have no intersection at the boundary point +select 'sellipse && scircle', 'f' as expected, sellipse'<{ 20d , 10d }, (20d , 0d) , 0d>' && scircle'<(20d , 0d) , 40d>' as actual; + ?column? | expected | actual +---------------------+----------+-------- + sellipse && scircle | f | t +(1 row) + +-- the circle lies completely in the ellipse +select 'sellipse && scircle', 'f' as expected, sellipse'<{ 20d , 10d }, (0d , 0d) , 0d>' && scircle'<(0d , 0d) , 5d>' as actual; + ?column? | expected | actual +---------------------+----------+-------- + sellipse && scircle | f | t +(1 row) + +-- the circle partially lies in the ellipse +select 'sellipse && scircle', 't' as expected, sellipse'<{ 20d , 10d }, (0d , 0d) , 0d>' && scircle'<(20d , 0d) , 15d>' as actual; + ?column? | expected | actual +---------------------+----------+-------- + sellipse && scircle | t | t +(1 row) + +-- the ellipse degenerated into the line lies completely in the interior of circle +select 'sellipse && scircle', 'f' as expected, sellipse'<{ 20d , 0d }, (0d , 0d) , 0d>' && scircle'<(0d , 0d) , 20d>' as actual; + ?column? | expected | actual +---------------------+----------+-------- + sellipse && scircle | f | t +(1 row) + +-- the ellipse degenerated into the line partially lies in the interior of circle +select 'sellipse && scircle', 'f' as expected, sellipse'<{ 20d , 0d }, (10d , 0d) , 0d>' && scircle'<(0d , 0d) , 20d>' as actual; + ?column? | expected | actual +---------------------+----------+-------- + sellipse && scircle | f | t +(1 row) + +-- the ellipse degenerated into the point lies on the boundary of circle +select 'sellipse && scircle', 'f' as expected, sellipse'<{ 0d , 0d }, (10d , 0d) , 0d>' && scircle'<(0d , 0d) , 10d>' as actual; + ?column? | expected | actual +---------------------+----------+-------- + sellipse && scircle | f | t +(1 row) + +-- the ellipse degenerated into the point lies in the interior of circle +select 'sellipse && scircle', 'f' as expected, sellipse'<{ 0d , 0d }, (5d , 0d) , 0d>' && scircle'<(0d , 0d) , 10d>' as actual; + ?column? | expected | actual +---------------------+----------+-------- + sellipse && scircle | f | t +(1 row) + +-- the ellipse and circle are degenerated into the point and coincide +select 'sellipse && scircle', 'f' as expected, sellipse'<{ 0d , 0d }, (0d , 0d) , 0d>' && scircle'<(0d , 0d) , 0d>' as actual; + ?column? | expected | actual +---------------------+----------+-------- + sellipse && scircle | f | t +(1 row) + +-- the ellipses are degenerated into the point and do not coincide, but lie close to each other +select 'sellipse && scircle', 'f' as expected, sellipse'<{ 0d , 0d }, (0d , 0d) , 0d>' && scircle'<(1d , 0d) , 0d>' as actual; + ?column? | expected | actual +---------------------+----------+-------- + sellipse && scircle | f | f +(1 row) + +-- spath vs spath +-- the opened paths have no common points +select 'spath && spath', 'f' as expected, spath'{ (-10d, 0d),(10d,0d),(45d,15d) }' && spath'{ (60d, 15d),(70d, 20d),(75d, 20d) }' as actual; + ?column? | expected | actual +----------------+----------+-------- + spath && spath | f | f +(1 row) + +-- the points of intersection of the opened paths is the boundary for both +select 'spath && spath', 'f' as expected, spath'{ (-10d, 0d),(10d, 0d),(45d, 15d) }' && spath'{ (-10d, 0d),(0d, 10d),(45d, 15d) }' as actual; + ?column? | expected | actual +----------------+----------+-------- + spath && spath | f | t +(1 row) + +-- one opened path intersects the other at the boundary point of the latter +select 'spath && spath', 'f' as expected, spath'{ (-10d, 0d),(10d, 0d),(45d, 15d) }' && spath'{ (-20d, -10d),(-10d, 0d),(0d, 10d),(45d, 15d),(60d, 15d) }' as actual; + ?column? | expected | actual +----------------+----------+-------- + spath && spath | f | t +(1 row) + +-- the interiors of the opened paths intersect at one point +select 'spath && spath', 'f' as expected, spath'{ (-10d, 0d),(10d, 0d),(45d, 15d) }' && spath'{ (0d, 10d),(0d, -10d),(10d, -10d) }' as actual; + ?column? | expected | actual +----------------+----------+-------- + spath && spath | f | t +(1 row) + +-- the interiors of the opened paths intersect at two points +select 'spath && spath', 'f' as expected, spath'{ (-10d, 0d),(10d, 0d),(45d, 15d) }' && spath'{ (0d, 10d),(0d, -10d),(5d, 0d) }' as actual; + ?column? | expected | actual +----------------+----------+-------- + spath && spath | f | t +(1 row) + +-- the opened paths match +select 'spath && spath', 'f' as expected, spath'{ (-10d, 0d),(10d, 0d),(45d, 15d) }' && spath'{ (-10d, 0d),(10d, 0d),(45d, 15d) }' as actual; + ?column? | expected | actual +----------------+----------+-------- + spath && spath | f | t +(1 row) + +-- the closed paths match +select 'spath && spath', 'f' as expected, spath'{ (-10d, 0d),(10d, 0d),(45d, 15d),(-10d, 0d) }' && spath'{ (-10d, 0d),(10d, 0d),(45d, 15d),(-10d, 0d) }' as actual; + ?column? | expected | actual +----------------+----------+-------- + spath && spath | f | t +(1 row) + +-- one opened path lies completely in the other and they have an intersection at the boundary point +select 'spath && spath', 'f' as expected, spath'{ (-10d, 0d),(10d, 0d),(45d, 15d),(60d, 15d),(70d, 20d) }' && spath'{ (-10d, 0d),(10d, 0d),(45d, 15d) }' as actual; + ?column? | expected | actual +----------------+----------+-------- + spath && spath | f | t +(1 row) + +-- one opened path lies completely in the other and they have no intersection at the boundary point +select 'spath && spath', 'f' as expected, spath'{ (-10d, 0d),(10d, 0d),(45d, 15d),(60d, 15d),(70d, 20d) }' && spath'{ (10d, 0d),(45d, 15d),(60d, 15d) }' as actual; + ?column? | expected | actual +----------------+----------+-------- + spath && spath | f | t +(1 row) + +-- one opened path partially lies in the other +select 'spath && spath', 't' as expected, spath'{ (-10d, 0d),(10d, 0d),(45d, 15d) }' && spath'{ (45d, 15d),(60d, 15d),(70d, 20d) }' as actual; + ?column? | expected | actual +----------------+----------+-------- + spath && spath | t | t +(1 row) + +-- one closed path partially lies in the other +select 'spath && spath', 't' as expected, spath'{ (-10d, 0d),(10d, 0d),(45d, 15d),(-10d, 0d) }' && spath'{ (45d, 15d),(60d, 15d),(70d, 20d),(45d, 15d) }' as actual; + ?column? | expected | actual +----------------+----------+-------- + spath && spath | t | t +(1 row) + +-- the opened path partially lies in the closed path +select 'spath && spath', 't' as expected, spath'{ (-10d, 0d),(10d, 0d),(45d, 15d),(-10d, 0d) }' && spath'{ (45d, 15d),(60d, 15d),(70d, 20d) }' as actual; + ?column? | expected | actual +----------------+----------+-------- + spath && spath | t | t +(1 row) + +-- spath vs sline +-- the opened path and line have no common points +select 'spath && sline', 'f' as expected, spath'{ (-10d, 0d),(10d, 0d),(45d, 15d) }' && sline( spoint'(20d, 0d)', spoint'(30d, 0d)') as actual; + ?column? | expected | actual +----------------+----------+-------- + spath && sline | f | f +(1 row) + +-- the points of intersection of the opened path and line is the boundary for both +select 'spath && sline', 'f' as expected, spath'{ (-10d, 0d),(10d, 0d),(45d, 15d) }' && sline( spoint'(-10d, 0d)', spoint'(45d, 15d)') as actual; + ?column? | expected | actual +----------------+----------+-------- + spath && sline | f | t +(1 row) + +-- the interiors of the opened path and line intersect at one point +select 'spath && sline', 'f' as expected, spath'{ (-10d, 0d),(10d, 0d),(45d, 15d) }' && sline( spoint'(0d, 10d)', spoint'(0d, -10d)') as actual; + ?column? | expected | actual +----------------+----------+-------- + spath && sline | f | t +(1 row) + +-- the path and line match +select 'spath && sline', 'f' as expected, spath'{ (0d, 10d),(0d, -10d) }' && sline( spoint'(0d, 10d)', spoint'(0d, -10d)') as actual; + ?column? | expected | actual +----------------+----------+-------- + spath && sline | f | t +(1 row) + +-- the line lies completely in the opened path and they have an intersection at the boundary point +select 'spath && sline', 'f' as expected, spath'{ (-10d, 0d),(10d, 0d),(45d, 15d),(60d, 20d) }' && sline( spoint'(-10d, 0d)', spoint'(10d, 0d)') as actual; + ?column? | expected | actual +----------------+----------+-------- + spath && sline | f | t +(1 row) + +-- the line lies completely in the opened path and they have no intersection at the boundary point +select 'spath && sline', 'f' as expected, spath'{ (-10d, 0d),(10d, 0d),(45d, 15d),(60d, 20d) }' && sline( spoint'(10d, 0d)', spoint'(45d, 15d)') as actual; + ?column? | expected | actual +----------------+----------+-------- + spath && sline | f | t +(1 row) + +-- the line partially lies in the open path +select 'spath && sline', 't' as expected, spath'{ (-10d, 0d),(10d, 0d),(45d, 15d) }' && sline( spoint'(5d, 0d)', spoint'(20d, 0d)') as actual; + ?column? | expected | actual +----------------+----------+-------- + spath && sline | t | t +(1 row) + +-- the line degenerated into the point lies in the boundary of open path +select 'spath && sline', 'f' as expected, spath'{ (-10d, 0d),(10d, 0d),(45d, 15d) }' && sline( spoint'(-10d, 0d)', spoint'(-10d, 0d)') as actual; + ?column? | expected | actual +----------------+----------+-------- + spath && sline | f | t +(1 row) + +-- the line degenerated into the point lies in the interior of open path +select 'spath && sline', 'f' as expected, spath'{ (-10d, 0d),(10d, 0d),(45d, 15d) }' && sline( spoint'(0d, 0d)', spoint'(0d, 0d)') as actual; + ?column? | expected | actual +----------------+----------+-------- + spath && sline | f | t +(1 row) + +-- spoly vs spoly +-- the polygons have no common points +select 'spoly && spoly', 'f' as expected, spoly'{ (0d, 0d),(-10d, 0d),(0d, 10d) }' && spoly'{ (10d, 0d),(20d, 0d),(10d, 10d) }' as actual; + ?column? | expected | actual +----------------+----------+-------- + spoly && spoly | f | f +(1 row) + +-- the point of intersection of the polygons is the boundary for both +select 'spoly && spoly', 'f' as expected, spoly'{ (0d, 0d),(-10d, 0d),(0d, 10d) }' && spoly'{ (10d, 0d),(20d, 0d),(0d, 10d) }' as actual; + ?column? | expected | actual +----------------+----------+-------- + spoly && spoly | f | t +(1 row) + +-- the interiors of the polygons intersect at one line +select 'spoly && spoly', 'f' as expected, spoly'{ (0d, 0d),(-10d, 0d),(0d, 10d) }' && spoly'{ (0d, 0d),(20d, 0d),(0d, 10d) }' as actual; + ?column? | expected | actual +----------------+----------+-------- + spoly && spoly | f | t +(1 row) + +-- the polygons matches +select 'spoly && spoly', 'f' as expected, spoly'{ (0d, 0d),(-10d, 0d),(0d, 10d) }' && spoly'{ (0d, 0d),(-10d, 0d),(0d, 10d) }' as actual; + ?column? | expected | actual +----------------+----------+-------- + spoly && spoly | f | t +(1 row) + +-- one polygon lies completely in the other and they have an intersection at the boundary line +select 'spoly && spoly', 'f' as expected, spoly'{ (0d, 0d),(20d, 0d),(20d, 20d),(0d, 20d) }' && spoly'{ (0d, 0d),(20d, 0d),(0d, 20d) }' as actual; + ?column? | expected | actual +----------------+----------+-------- + spoly && spoly | f | t +(1 row) + +-- one polygon lies completely in the other and they have no intersection at the boundary line or point +select 'spoly && spoly', 'f' as expected, spoly'{ (0d, 0d),(20d, 0d),(20d, 20d),(0d, 20d) }' && spoly'{ (5d, 5d),(15d, 5d),(15d, 15d),(5d,15d) }' as actual; + ?column? | expected | actual +----------------+----------+-------- + spoly && spoly | f | t +(1 row) + +-- one polygon partially lies in the other +select 'spoly && spoly', 't' as expected, spoly'{ (0d, 0d),(-10d, 0d),(0d, 10d) }' && spoly'{ (5d, 5d),(30d, 5d),(30d, 15d),(5d,15d) }' as actual; + ?column? | expected | actual +----------------+----------+-------- + spoly && spoly | t | f +(1 row) + +-- spoly vs scircle +-- the polygon and circle have no common points +select 'spoly && scircle', 'f' as expected, spoly'{ (0d, 0d),(10d, 0d),(0d, 10d) }' && scircle'<(0d , 90d) , 10d>' as actual; + ?column? | expected | actual +------------------+----------+-------- + spoly && scircle | f | f +(1 row) + +-- the point of intersection of the polygon and circle is the boundary for both +select 'spoly && scircle', 'f' as expected, spoly'{ (0d, 0d),(10d, 0d),(0d, 10d) }' && scircle'<(0d , 90d) , 80d>' as actual; + ?column? | expected | actual +------------------+----------+-------- + spoly && scircle | f | t +(1 row) + +-- the circle lies completely in the polygon and they have an intersection at the boundary point +select 'spoly && scircle', 'f' as expected, spoly'{ (0d, 0d),(10d, 0d),(0d, 10d) }' && scircle'<(5d , 1d) , 1d>' as actual; + ?column? | expected | actual +------------------+----------+-------- + spoly && scircle | f | t +(1 row) + +-- the circle lies completely in the polygon and they have no intersection at the boundary point +select 'spoly && scircle', 'f' as expected, spoly'{ (0d, 0d),(10d, 0d),(0d, 10d) }' && scircle'<(5d , 2d) , 1d>' as actual; + ?column? | expected | actual +------------------+----------+-------- + spoly && scircle | f | t +(1 row) + +-- the polygon lies completely in the circle +select 'spoly && scircle', 'f' as expected, spoly'{ (0d, 0d),(10d, 0d),(0d, 10d) }' && scircle'<(0d , 15d) , 20d>' as actual; + ?column? | expected | actual +------------------+----------+-------- + spoly && scircle | f | t +(1 row) + +-- the polygon partially lies in the circle +select 'spoly && scircle', 't' as expected, spoly'{ (0d, 0d),(10d, 0d),(0d, 10d) }' && scircle'<(0d , 5d) , 5d>' as actual; + ?column? | expected | actual +------------------+----------+-------- + spoly && scircle | t | t +(1 row) + +-- the circle degenerated into the point lies in the boundary of polygon +select 'spoly && scircle', 'f' as expected, spoly'{ (0d, 0d),(10d, 0d),(0d, 10d) }' && scircle'<(0d , 0d) , 0d>' as actual; + ?column? | expected | actual +------------------+----------+-------- + spoly && scircle | f | t +(1 row) + +-- the circle degenerated into the point lies in the interior of polygon +select 'spoly && scircle', 'f' as expected, spoly'{ (0d, 0d),(10d, 0d),(0d, 10d) }' && scircle'<(2d , 2d) , 0d>' as actual; + ?column? | expected | actual +------------------+----------+-------- + spoly && scircle | f | t +(1 row) + +-- spoly vs sellipse +-- the polygon and ellipse have no common points +select 'spoly && sellipse', 'f' as expected, spoly'{ (0d, 0d),(10d, 0d),(0d, 10d) }' && sellipse'<{ 30d , 20d }, (0d , 90d) , 0d>' as actual; + ?column? | expected | actual +-------------------+----------+-------- + spoly && sellipse | f | f +(1 row) + +-- the point of intersection of the polygon and ellipse is the boundary for both +select 'spoly && sellipse', 'f' as expected, spoly'{ (0d, 0d),(10d, 0d),(0d, 10d) }' && sellipse'<{ 80d , 20d }, (0d , 90d) , 90d>' as actual; + ?column? | expected | actual +-------------------+----------+-------- + spoly && sellipse | f | t +(1 row) + +-- the ellipse lies completely in the polygon and they have an intersection at the boundary points +select 'spoly && sellipse', 'f' as expected, spoly'{ (0d, 0d),(20d, 0d),(20d, 20d),(0d, 20d) }' && sellipse'<{ 10d , 5d }, (10d , 10d), 0d>' as actual; + ?column? | expected | actual +-------------------+----------+-------- + spoly && sellipse | f | t +(1 row) + +-- the ellipse lies completely in the polygon and they have no intersection at the boundary points +select 'spoly && sellipse', 'f' as expected, spoly'{ (0d, 0d),(20d, 0d),(20d, 20d),(0d, 20d) }' && sellipse'<{ 7d , 5d }, (10d , 10d), 0d>' as actual; + ?column? | expected | actual +-------------------+----------+-------- + spoly && sellipse | f | t +(1 row) + +-- the polygon lies completely in the ellipse and they have an intersection at the boundary points +select 'spoly && sellipse', 'f' as expected, spoly'{ (0d, 5d),(10d, 10d),(20d, 5d),(10d, 0d) }' && sellipse'<{ 10d , 5d }, (10d , 5d), 0d>' as actual; + ?column? | expected | actual +-------------------+----------+-------- + spoly && sellipse | f | t +(1 row) + +-- the polygon lies completely in the ellipse and they have no intersection at the boundary points +select 'spoly && sellipse', 'f' as expected, spoly'{ (1d, 5d),(10d, 9d),(19d, 5d),(10d, 1d) }' && sellipse'<{ 10d , 5d }, (10d , 10d), 0d>' as actual; + ?column? | expected | actual +-------------------+----------+-------- + spoly && sellipse | f | t +(1 row) + +-- the ellipse partially lies in the polygon +select 'spoly && sellipse', 't' as expected, spoly'{ (0d, 0d),(10d, 0d),(0d, 10d) }' && sellipse'<{ 10d , 2d }, (0d , 5d) , 0d>' as actual; + ?column? | expected | actual +-------------------+----------+-------- + spoly && sellipse | t | t +(1 row) + +-- the ellipse degenerated into the point lies in the boundary of polygon +select 'spoly && sellipse', 'f' as expected, spoly'{ (0d, 0d),(10d, 0d),(0d, 10d) }' && sellipse'<{ 0d , 0d }, (0d , 0d), 0d>' as actual; + ?column? | expected | actual +-------------------+----------+-------- + spoly && sellipse | f | t +(1 row) + +-- the ellipse degenerated into the point lies in the interior of polygon +select 'spoly && sellipse', 'f' as expected, spoly'{ (0d, 0d),(10d, 0d),(0d, 10d) }' && sellipse'<{ 0d , 0d }, (5d , 2d), 0d>' as actual; + ?column? | expected | actual +-------------------+----------+-------- + spoly && sellipse | f | t +(1 row) + +-- the ellipse degenerated into the line lies in the boundary of polygon +select 'spoly && sellipse', 'f' as expected, spoly'{ (0d, 0d),(10d, 0d),(0d, 10d) }' && sellipse'<{ 5d , 0d }, (5d , 0d), 0d>' as actual; + ?column? | expected | actual +-------------------+----------+-------- + spoly && sellipse | f | t +(1 row) + +-- the ellipse degenerated into the line lies in the interior of polygon +select 'spoly && sellipse', 'f' as expected, spoly'{ (0d, 0d),(10d, 0d),(0d, 10d) }' && sellipse'<{ 2d , 0d }, (1d , 4d), 90d>' as actual; + ?column? | expected | actual +-------------------+----------+-------- + spoly && sellipse | f | t +(1 row) + +-- the ellipse degenerated into the line partially lies in the interior of polygon +select 'spoly && sellipse', 'f' as expected, spoly'{ (0d, 0d),(10d, 0d),(0d, 10d) }' && sellipse'<{ 10d , 0d }, (1d , 4d), 0d>' as actual; + ?column? | expected | actual +-------------------+----------+-------- + spoly && sellipse | f | t +(1 row) + +-- sbox vs sbox +-- the boxes have no common points +select 'sbox && sbox', 'f' as expected, sbox'((0d , 0d), (20d , 20d))' && sbox'((30d , 30d), (50d , 50d))' as actual; + ?column? | expected | actual +--------------+----------+-------- + sbox && sbox | f | f +(1 row) + +-- the point of intersection of the boxes is the boundary for both +select 'sbox && sbox', 'f' as expected, sbox'((0d , 0d), (20d , 20d))' && sbox'((20d , 20d), (50d , 50d))' as actual; + ?column? | expected | actual +--------------+----------+-------- + sbox && sbox | f | t +(1 row) + +-- the boundaries of the boxes intersect at one line +select 'sbox && sbox', 'f' as expected, sbox'((0d , 0d), (20d , 20d))' && sbox'((20d , 0d), (50d , 20d))' as actual; + ?column? | expected | actual +--------------+----------+-------- + sbox && sbox | f | t +(1 row) + +-- the boxes matches +select 'sbox && sbox', 'f' as expected, sbox'((0d , 0d), (20d , 20d))' && sbox'((5d , 5d), (10d , 10d))' as actual; + ?column? | expected | actual +--------------+----------+-------- + sbox && sbox | f | t +(1 row) + +-- one box lies completely in the other and they have no intersection at the boundary line or point +select 'sbox && sbox', 'f' as expected, sbox'((0d , 0d), (20d , 20d))' && sbox'((5d , 5d), (10d , 10d))' as actual; + ?column? | expected | actual +--------------+----------+-------- + sbox && sbox | f | t +(1 row) + +-- one box partially lies in the other +select 'sbox && sbox', 't' as expected, sbox'((0d , 0d), (20d , 20d))' && sbox'((10d , 10d), (30d , 30d))' as actual; + ?column? | expected | actual +--------------+----------+-------- + sbox && sbox | t | t +(1 row) + +-- one box degenerated into the line lies in the boundary of other +select 'sbox && sbox', 'f' as expected, sbox'((0d , 0d), (20d , 20d))' && sbox'((0d , 0d), (20d , 0d))' as actual; + ?column? | expected | actual +--------------+----------+-------- + sbox && sbox | f | t +(1 row) + +-- one box degenerated into the line lies in the interior of other +select 'sbox && sbox', 'f' as expected, sbox'((0d , 0d), (20d , 20d))' && sbox'((5d , 5d), (10d , 5d))' as actual; + ?column? | expected | actual +--------------+----------+-------- + sbox && sbox | f | t +(1 row) + +-- one box degenerated into the point lies in the boundary of other +select 'sbox && sbox', 'f' as expected, sbox'((0d , 0d), (20d , 20d))' && sbox'((0d , 0d), (0d , 0d))' as actual; + ?column? | expected | actual +--------------+----------+-------- + sbox && sbox | f | t +(1 row) + +-- one box degenerated into the point lies in the interior of other +select 'sbox && sbox', 'f' as expected, sbox'((0d , 0d), (20d , 20d))' && sbox'((5d , 5d), (5d , 5d))' as actual; + ?column? | expected | actual +--------------+----------+-------- + sbox && sbox | f | t +(1 row) + +-- the boxes are degenerated into the point and coincide +select 'sbox && sbox', 'f' as expected, sbox'((0d , 0d), (0d , 0d))' && sbox'((0d , 0d), (0d , 0d))' as actual; + ?column? | expected | actual +--------------+----------+-------- + sbox && sbox | f | t +(1 row) + +-- the boxes are degenerated into the point and not coincide +select 'sbox && sbox', 'f' as expected, sbox'((0d , 0d), (0d , 0d))' && sbox'((10d , 10d), (10d , 10d))' as actual; + ?column? | expected | actual +--------------+----------+-------- + sbox && sbox | f | f +(1 row) + +-- sbox vs scircle +-- the box and circle have no common points +select 'sbox && scircle', 'f' as expected, sbox'((0d , 0d), (20d , 20d))' && scircle'<(0d , 90d) , 10d>' as actual; + ?column? | expected | actual +-----------------+----------+-------- + sbox && scircle | f | f +(1 row) + +-- the point of intersection of the box and circle is the boundary for both +select 'sbox && scircle', 'f' as expected, sbox'((0d , 0d), (20d , 20d))' && scircle'<(30d , 0d) , 10d>' as actual; + ?column? | expected | actual +-----------------+----------+-------- + sbox && scircle | f | t +(1 row) + +-- the circle lies completely in the box and they have an intersection at the boundary points +select 'sbox && scircle', 'f' as expected, sbox'((0d , 0d), (20d , 20d))' && scircle'<(10d , 10d) , 10d>' as actual; + ?column? | expected | actual +-----------------+----------+-------- + sbox && scircle | f | t +(1 row) + +-- the circle lies completely in the box and they have no intersection at the boundary points +select 'sbox && scircle', 'f' as expected, sbox'((0d , 0d), (20d , 20d))' && scircle'<(10d , 10d) , 5d>' as actual; + ?column? | expected | actual +-----------------+----------+-------- + sbox && scircle | f | t +(1 row) + +-- the box lies completely in the circle and they have an intersection at the boundary points +select 'sbox && scircle', 'f' as expected, sbox'((-4d , -3d), (3d , 4d))' && scircle'<(0d , 0d) , 5d>' as actual; + ?column? | expected | actual +-----------------+----------+-------- + sbox && scircle | f | t +(1 row) + +-- the box lies completely in the circle and they have no intersection at the boundary points +select 'sbox && scircle', 'f' as expected, sbox'((-4d , -3d), (3d , 4d))' && scircle'<(0d , 0d) , 10d>' as actual; + ?column? | expected | actual +-----------------+----------+-------- + sbox && scircle | f | t +(1 row) + +-- the box degenerated into the line intersects circle +select 'sbox && scircle', 'f' as expected, sbox'((-20d , 0d), (20d , 0d))' && scircle'<(0d , 0d) , 10d>' as actual; + ?column? | expected | actual +-----------------+----------+-------- + sbox && scircle | f | f +(1 row) + +-- the circle partially lies in the box +select 'sbox && scircle', 't' as expected, sbox'((0d , 0d), (20d , 20d))' && scircle'<(15d , 15d) , 10d>' as actual; + ?column? | expected | actual +-----------------+----------+-------- + sbox && scircle | t | t +(1 row) + +-- the circle degenerated into the point lies in the boundary of box +select 'sbox && scircle', 'f' as expected, sbox'((0d , 0d), (20d , 20d))' && scircle'<(0d , 10d) , 0d>' as actual; + ?column? | expected | actual +-----------------+----------+-------- + sbox && scircle | f | t +(1 row) + +-- the circle degenerated into the point lies in the interior of box +select 'sbox && scircle', 'f' as expected, sbox'((0d , 0d), (20d , 20d))' && scircle'<(10d , 10d) , 0d>' as actual; + ?column? | expected | actual +-----------------+----------+-------- + sbox && scircle | f | t +(1 row) + +-- the box degenerated into the point lies in the boundary of circle +select 'sbox && scircle', 'f' as expected, sbox'((0d , 0d), (0d , 0d))' && scircle'<(10d , 0d) , 10d>' as actual; + ?column? | expected | actual +-----------------+----------+-------- + sbox && scircle | f | f +(1 row) + +-- the box degenerated into the point lies in the interior of circle +select 'sbox && scircle', 'f' as expected, sbox'((0d , 0d), (0d , 0d))' && scircle'<(0d , 0d) , 10d>' as actual; + ?column? | expected | actual +-----------------+----------+-------- + sbox && scircle | f | f +(1 row) + +-- the box and circle are degenerated into the point and coincide +select 'sbox && scircle', 'f' as expected, sbox'((0d , 0d), (0d , 0d))' && scircle'<(0d , 0d) , 0d>' as actual; + ?column? | expected | actual +-----------------+----------+-------- + sbox && scircle | f | t +(1 row) + +-- the box and circle are degenerated into the point and not coincide +select 'sbox && scircle', 'f' as expected, sbox'((0d , 0d), (0d , 0d))' && scircle'<(5d , 5d) , 0d>' as actual; + ?column? | expected | actual +-----------------+----------+-------- + sbox && scircle | f | f +(1 row) + +-- sbox vs spoly +-- the box and polygon have no common points +select 'sbox && spoly', 'f' as expected, sbox'((0d , 0d), (20d , 20d))' && spoly'{ (30d, 0d),(40d, 0d),(30d, 20d) }' as actual; + ?column? | expected | actual +---------------+----------+-------- + sbox && spoly | f | f +(1 row) + +-- the point of intersection of the box and polygon is the boundary for both +select 'sbox && spoly', 'f' as expected, sbox'((0d , 0d), (20d , 20d))' && spoly'{ (30d, 0d),(40d, 0d),(30d, 20d) }' as actual; + ?column? | expected | actual +---------------+----------+-------- + sbox && spoly | f | f +(1 row) + +-- the boundaries of the boxes intersect at one line +select 'sbox && spoly', 'f' as expected, sbox'((0d , 0d), (20d , 20d))' && spoly'{ (20d, 0d),(30d, 0d),(20d, 20d) }' as actual; + ?column? | expected | actual +---------------+----------+-------- + sbox && spoly | f | t +(1 row) + +-- the box and circle matches +select 'sbox && spoly', 'f' as expected, sbox'((0d , 0d), (20d , 20d))' && spoly'{ (0d, 0d),(20d, 0d),(20d, 20d),(0d, 20d) }' as actual; + ?column? | expected | actual +---------------+----------+-------- + sbox && spoly | f | t +(1 row) + +-- the polygon lies completely in the box and they have an intersection at the boundary line +select 'sbox && spoly', 'f' as expected, sbox'((0d , 0d), (20d , 20d))' && spoly'{ (0d, 0d),(20d, 0d),(0d, 20d) }' as actual; + ?column? | expected | actual +---------------+----------+-------- + sbox && spoly | f | t +(1 row) + +-- the polygon lies completely in the box and they have no intersection at the boundary +select 'sbox && spoly', 'f' as expected, sbox'((0d , 0d), (20d , 20d))' && spoly'{ (1d, 1d),(11d, 1d),(1d, 19d) }' as actual; + ?column? | expected | actual +---------------+----------+-------- + sbox && spoly | f | t +(1 row) + +-- the box lies completely in the polygon and they have an intersection at the boundary line +select 'sbox && spoly', 'f' as expected, sbox'((0d , 0d), (10d , 10d))' && spoly'{ (0d, 0d),(20d, 0d),(0d, 20d) }' as actual; + ?column? | expected | actual +---------------+----------+-------- + sbox && spoly | f | t +(1 row) + +-- the box lies completely in the polygon and they have no intersection at the boundary +select 'sbox && spoly', 'f' as expected, sbox'((1d , 1d), (2d , 2d))' && spoly'{ (0d, 0d),(20d, 0d),(0d, 20d) }' as actual; + ?column? | expected | actual +---------------+----------+-------- + sbox && spoly | f | t +(1 row) + +-- the polygon partially lies in the box +select 'sbox && spoly', 't' as expected, sbox'((0d , 0d), (20d , 20d))' && spoly'{ (15d, 0d),(35d, 0d),(15d, 35d) }' as actual; + ?column? | expected | actual +---------------+----------+-------- + sbox && spoly | t | t +(1 row) + +-- the box degenerated into the line lies in the boundary of polygon +select 'sbox && spoly', 'f' as expected, sbox'((0d , 0d), (20d , 0d))' && spoly'{ (0d, 0d),(20d, 0d),(0d, 20d) }' as actual; + ?column? | expected | actual +---------------+----------+-------- + sbox && spoly | f | t +(1 row) + +-- the box degenerated into the line lies in the interior of polygon +select 'sbox && spoly', 'f' as expected, sbox'((0d , 5d), (10d , 5d))' && spoly'{ (0d, 0d),(20d, 0d),(0d, 20d) }' as actual; + ?column? | expected | actual +---------------+----------+-------- + sbox && spoly | f | t +(1 row) + +-- the box degenerated into the point lies in the boundary of polygon +select 'sbox && spoly', 'f' as expected, sbox'((0d , 0d), (0d , 0d))' && spoly'{ (0d, 0d),(20d, 0d),(0d, 20d) }' as actual; + ?column? | expected | actual +---------------+----------+-------- + sbox && spoly | f | t +(1 row) + +-- the box degenerated into the point lies in the interior of polygon +select 'sbox && spoly', 'f' as expected, sbox'((5d , 5d), (5d , 5d))' && spoly'{ (0d, 0d),(20d, 0d),(0d, 20d) }' as actual; + ?column? | expected | actual +---------------+----------+-------- + sbox && spoly | f | t +(1 row) + +-- sbox vs sellipse +-- the box and ellipse have no common points +select 'sbox && sellipse', 'f' as expected, sbox'((0d , 0d), (20d , 20d))' && sellipse'<{ 20d , 10d }, (0d, 90d) , 0d>' as actual; + ?column? | expected | actual +------------------+----------+-------- + sbox && sellipse | f | f +(1 row) + +-- the point of intersection of the box and ellipse is the boundary for both +select 'sbox && sellipse', 'f' as expected, sbox'((-10d , -10d), (10d , 10d))' && sellipse'<{ 80d , 10d }, (0d, 90d) , 90d>' as actual; + ?column? | expected | actual +------------------+----------+-------- + sbox && sellipse | f | f +(1 row) + +-- the ellipse lies completely in the box and they have an intersection at the boundary points +select 'sbox && sellipse', 'f' as expected, sbox'((0d , 0d), (20d , 20d))' && sellipse'<{ 10d , 5d }, (10d, 10d) , 0d>' as actual; + ?column? | expected | actual +------------------+----------+-------- + sbox && sellipse | f | t +(1 row) + +-- the ellipse lies completely in the box and they have no intersection at the boundary points +select 'sbox && sellipse', 'f' as expected, sbox'((0d , 0d), (20d , 20d))' && sellipse'<{ 9d , 5d }, (10d, 10d) , 0d>' as actual; + ?column? | expected | actual +------------------+----------+-------- + sbox && sellipse | f | t +(1 row) + +-- the box lies completely in the ellipse and they have no intersection at the boundary points +select 'sbox && sellipse', 'f' as expected, sbox'((-10d , -10d), (10d , 10d))' && sellipse'<{ 30d , 20d }, (0d, 0d) , 0d>' as actual; + ?column? | expected | actual +------------------+----------+-------- + sbox && sellipse | f | t +(1 row) + +-- the ellipse partially lies in the box +select 'sbox && sellipse', 't' as expected, sbox'((-10d , -10d), (10d , 10d))' && sellipse'<{ 10d , 5d }, (10d, 10d) , 90d>' as actual; + ?column? | expected | actual +------------------+----------+-------- + sbox && sellipse | t | t +(1 row) + +-- the box degenerated into the point lies in the boundary of ellipse +select 'sbox && sellipse', 'f' as expected, sbox'((30d , 0d), (30d , 0d))' && sellipse'<{ 30d , 20d }, (0d, 0d) , 0d>' as actual; + ?column? | expected | actual +------------------+----------+-------- + sbox && sellipse | f | t +(1 row) + +-- the box degenerated into the point lies in the interior of ellipse +select 'sbox && sellipse', 'f' as expected, sbox'((0d , 0d), (10d , 0d))' && sellipse'<{ 30d , 20d }, (0d, 0d) , 0d>' as actual; + ?column? | expected | actual +------------------+----------+-------- + sbox && sellipse | f | t +(1 row) + +-- the box and ellipse are degenerated into the point and coincide +select 'sbox && sellipse', 'f' as expected, sbox'((0d , 0d), (0d , 0d))' && sellipse'<{ 0d , 0d }, (0d, 0d) , 0d>' as actual; + ?column? | expected | actual +------------------+----------+-------- + sbox && sellipse | f | t +(1 row) + diff --git a/sql/contains.sql b/sql/contains.sql new file mode 100644 index 0000000..4e348cc --- /dev/null +++ b/sql/contains.sql @@ -0,0 +1,123 @@ +/* +This set of tests is designed to verify the compliance of the contain operation with the DE-9IM model +*/ + + +-- sline vs spoint + + +-- the point lies far beyond the line +select 'sline ~ spoint', 'f' as expected, sline(spoint'(270d,10d)', spoint'(270d,30d)') ~ spoint'(0d, 50d)' as actual; + +-- the point lies in the boundary of line +select 'sline ~ spoint', 'f' as expected, sline(spoint'(270d,10d)', spoint'(270d,30d)') ~ spoint'(270d, 10d)' as actual; + +-- the point lies in the interior of line +select 'sline ~ spoint', 't' as expected, sline(spoint'(270d,10d)', spoint'(270d,30d)') ~ spoint'(270d, 20d)' as actual; + +-- the point and line that degenerated into the point coincide +select 'sline ~ spoint', 't' as expected, sline(spoint'(270d,10d)', spoint'(270d,10d)') ~ spoint'(270d, 10d)' as actual; + +-- the point and line that degenerated into the point do not coincide +select 'sline ~ spoint', 'f' as expected, sline(spoint'(270d,10d)', spoint'(270d,10d)') ~ spoint'(270d, 20d)' as actual; + + +-- spoint vs scircle + + +-- the point lies far beyond the circle +select 'spoint @ scircle', 'f' as expected, spoint'(0d,0d)' @ scircle'<(0d,90d),50d>' as actual; + +-- the point lies in the boundary of circle +select 'spoint @ scircle', 'f' as expected, spoint'(0d,80d)' @ scircle'<(0d,90d),10d>' as actual; + +-- the point lies in the interior of circle +select 'spoint @ scircle', 't' as expected, spoint'(0d,80d)' @ scircle'<(0d,90d),50d>' as actual; + +-- the point and circle that degenerated into the point coincide +select 'spoint @ scircle', 't' as expected, spoint'(0d,90d)' @ scircle'<(0d,90d),0d>' as actual; + +-- the point and circle that degenerated into the point do not coincide +select 'spoint @ scircle', 'f' as expected, spoint'(0d,50d)' @ scircle'<(0d,90d),0d>' as actual; + + +-- sellipse vs spoint + + +-- the point lies far beyond the ellipse +select 'sellipse ~ spoint', 'f' as expected, sellipse'<{ 30d , 20d }, (0d , 90d) , 0d>' ~ spoint'(0d, 0d)' as actual; + +-- the point lies in the boundary of ellipse +select 'sellipse ~ spoint', 'f' as expected, sellipse'<{ 30d , 20d }, (0d , 90d) , 0d>' ~ spoint'(0d, 70d)' as actual; + +-- the point lies in the interior of ellipse +select 'sellipse ~ spoint', 't' as expected, sellipse'<{ 30d , 20d }, (0d , 90d) , 0d>' ~ spoint'(90d, 65d)' as actual; + +-- the point lies in the boundary of ellipse that degenerated into the line +select 'sellipse ~ spoint', 't' as expected, sellipse'<{ 10d , 0d }, (0d , 0d) , 0d>' ~ spoint'(10d, 0d)' as actual; + +-- the point lies in the interior of ellipse that degenerated into the line +select 'sellipse ~ spoint', 't' as expected, sellipse'<{ 10d , 0d }, (0d , 0d) , 0d>' ~ spoint'(0d, 0d)' as actual; + +-- the point and ellipse that degenerated into the point coincide +select 'sellipse ~ spoint', 't' as expected, sellipse'<{ 0d , 0d }, (0d , 90d) , 0d>' ~ spoint'(0d, 90d)' as actual; + +-- the point and ellipse that degenerated into the point do not coincide +select 'sellipse ~ spoint', 'f' as expected, sellipse'<{ 0d , 0d }, (0d , 90d) , 0d>' ~ spoint'(0d, 91d)' as actual; + + +-- spath vs spoint + + +-- the point lies far beyond the opened path +select 'spath ~ spoint', 'f' as expected, spath'{ (-10d, 0d),(10d,0d),(45d,15d),(80d,30d) }' ~ spoint'(0d, 90d)' as actual; + +-- the point lies in the boundary of opened path +select 'spath ~ spoint', 'f' as expected, spath'{ (-10d, 0d),(10d,0d),(45d,15d),(80d,30d) }' ~ spoint'(-10d, 0d)' as actual; + +-- the point lies in the boundary of unsimple opened path +select 'spath ~ spoint', 'f' as expected, spath'{ (-10d, 0d),(10d,0d),(45d,15d),(80d,30d),(-5d, 0d) }' ~ spoint'(-5d, 0d)' as actual; + +-- the point lies in the interior of opened path +select 'spath ~ spoint', 't' as expected, spath'{ (-10d, 0d),(10d,0d),(45d,15d),(80d,30d) }' ~ spoint'(9d, 0d)' as actual; + +-- the point lies in the interior of closed path +select 'spath ~ spoint', 't' as expected, spath'{ (-10d, 0d),(10d,0d),(45d,15d),(80d,30d),(-10d, 0d) }' ~ spoint'(-10d, 0d)' as actual; + + +-- spoly vs spoint + + +-- the point lies far beyond the polygon +select 'spoly ~ spoint', 'f' as expected, spoly'{ (0d,0d), (10d,0d), (20d,20d) }' ~ spoint'(0d, 90d)' as actual; + +-- the point lies in the boundary of polygon +select 'spoly ~ spoint', 'f' as expected, spoly'{ (0d,0d), (10d,0d), (20d,20d) }' ~ spoint'(5d, 0d)' as actual; + +-- the point lies in the boundary of polygon +select 'spoly ~ spoint', 'f' as expected, spoly'{ (0d,0d), (10d,0d), (20d,20d) }' ~ spoint'(20d, 20d)' as actual; + +-- the point lies in the interior of polygon +select 'spoly ~ spoint', 't' as expected, spoly'{ (0d,0d), (10d,0d), (20d,20d) }' ~ spoint'(5d, 5d)' as actual; + + +-- sbox vs spoint + + +-- the point lies far beyond the box +select 'sbox ~ spoint', 'f' as expected, sbox'( (0d,0d), (20d,10d) )' ~ spoint'(0d, 90d)' as actual; + +-- the point lies in the boundary of box +select 'sbox ~ spoint', 'f' as expected, sbox'( (0d,0d), (20d,10d) )' ~ spoint'(0d, 5d)' as actual; + +-- the point lies in the boundary of box +select 'sbox ~ spoint', 'f' as expected, sbox'( (0d,0d), (20d,10d) )' ~ spoint'(0d, 0d)' as actual; + +-- the point lies in the interior of box +select 'sbox ~ spoint', 't' as expected, sbox'( (0d,0d), (20d,10d) )' ~ spoint'(5d, 5d)' as actual; + +-- the point and box that degenerated into the point coincide +select 'sbox ~ spoint', 't' as expected, sbox'( (0d,0d), (0d,0d) )' ~ spoint'(0d, 0d)' as actual; + +-- the point and box that degenerated into the point do not coincide +select 'sbox ~ spoint', 'f' as expected, sbox'( (0d,0d), (0d,0d) )' ~ spoint'(0d, 1d)' as actual; diff --git a/sql/overlaps.sql b/sql/overlaps.sql new file mode 100644 index 0000000..82db270 --- /dev/null +++ b/sql/overlaps.sql @@ -0,0 +1,484 @@ +/* +This set of tests is designed to verify the compliance of the overlap operation with the DE-9IM model +*/ + + +-- sline vs sline + + +-- the lines have no common points +select 'sline && sline', 'f' as expected, sline( spoint'(0d,0d)', spoint'(10d,0d)') && sline( spoint'(20d,0d)', spoint'(30d,0d)') as actual; + +-- the point of intersection of the lines is the boundary for both +select 'sline && sline', 'f' as expected, sline( spoint'(0d,0d)', spoint'(10d,0d)') && sline( spoint'(10d,0d)', spoint'(20d,0d)') as actual; + +-- one line intersects the other at the boundary point of the latter +select 'sline && sline', 'f' as expected, sline( spoint'(0d,0d)', spoint'(10d,0d)') && sline( spoint'(0d,90d)', spoint'(0d,-10d)') as actual; + +-- the interiors of the lines intersect at one point +select 'sline && sline', 'f' as expected, sline( spoint'(-10d,0d)', spoint'(10d,0d)') && sline( spoint'(0d,90d)', spoint'(0d,-10d)') as actual; + +-- the lines match +select 'sline && sline', 'f' as expected, sline( spoint'(0d,0d)', spoint'(10d,0d)') && sline( spoint'(0d,0d)', spoint'(10d,0d)') as actual; + +-- one line lies completely in the other and they have an intersection at the boundary point +select 'sline && sline', 'f' as expected, sline( spoint'(0d,0d)', spoint'(10d,0d)') && sline( spoint'(0d,0d)', spoint'(5d,0d)') as actual; + +-- one line lies completely in the other and they have no intersection at the boundary point +select 'sline && sline', 'f' as expected, sline( spoint'(0d,0d)', spoint'(10d,0d)') && sline( spoint'(2d,0d)', spoint'(5d,0d)') as actual; + +-- one line partially lies in the other +select 'sline && sline', 't' as expected, sline( spoint'(0d,0d)', spoint'(10d,0d)') && sline( spoint'(5d,0d)', spoint'(20d,0d)') as actual; + +-- the line degenerated into the point lies on the boundary of another +select 'sline && sline', 'f' as expected, sline( spoint'(0d,0d)', spoint'(10d,0d)') && sline( spoint'(0d,0d)', spoint'(0d,0d)') as actual; + +-- the line degenerated into the point lies in the interior of another +select 'sline && sline', 'f' as expected, sline( spoint'(0d,0d)', spoint'(10d,0d)') && sline( spoint'(5d,0d)', spoint'(5d,0d)') as actual; + +-- both lines are degenerated into the point and coincide +select 'sline && sline', 'f' as expected, sline( spoint'(0d,0d)', spoint'(0d,0d)') && sline( spoint'(0d,0d)', spoint'(0d,0d)') as actual; + +-- both lines are degenerated into the point and do not coincide, but lie close to each other +select 'sline && sline', 'f' as expected, sline( spoint'(0d,0d)', spoint'(0d,0d)') && sline( spoint'(1d,0d)', spoint'(1d,0d)') as actual; + + +-- scircle vs scircle + + +-- the circles have no common points +select 'scircle && scircle', 'f' as expected, scircle'<(0d , 0d) , 20d>' && scircle'<(30d , 0d) , 5d>' as actual; + +-- the point of intersection of the circles is the boundary for both +select 'scircle && scircle', 'f' as expected, scircle'<(-10d , 0d) , 10d>' && scircle'<(10d , 0d) , 10d>' as actual; + +-- the circles match +select 'scircle && scircle', 'f' as expected, scircle'<(-10d , 0d) , 10d>' && scircle'<(-10d , 0d) , 10d>' as actual; + +-- one circle lies completely in the other and they have an intersection at the boundary point +select 'scircle && scircle', 'f' as expected, scircle'<(0d , 0d) , 20d>' && scircle'<(-10d , 0d) , 10d>' as actual; + +-- one circle lies completely in the other and they have no intersection at the boundary point +select 'scircle && scircle', 'f' as expected, scircle'<(0d , 0d) , 20d>' && scircle'<(0d , 0d) , 5d>' as actual; + +-- one circle partially lies in the other +select 'scircle && scircle', 't' as expected, scircle'<(0d , 0d) , 20d>' && scircle'<(10d , 0d) , 20d>' as actual; + +-- the circle degenerated into the point lies on the boundary of another +select 'scircle && scircle', 'f' as expected, scircle'<(0d , 0d) , 20d>' && scircle'<(20d , 0d) , 0d>' as actual; + +-- the circle degenerated into the point lies in the interior of another +select 'scircle && scircle', 'f' as expected, scircle'<(0d , 0d) , 20d>' && scircle'<(0d , 0d) , 0d>' as actual; + +-- both circles are degenerated into the point and coincide +select 'scircle && scircle', 'f' as expected, scircle'<(0d , 0d) , 0d>' && scircle'<(0d , 0d) , 0d>' as actual; + +-- both circles are degenerated into the point and do not coincide, but lie close to each other +select 'scircle && scircle', 'f' as expected, scircle'<(1d , 0d) , 0d>' && scircle'<(0d , 0d) , 0d>' as actual; + + +-- sellipse vs sellipse + + +-- the ellipses have no common points +select 'sellipse && sellipse', 'f' as expected, sellipse'<{ 45d , 20d }, (-45d , 0d) , 0d>' && sellipse'<{ 45d , 20d }, (50 , 0d) , 0d>' as actual; + +-- the point of intersection of the ellipses is the boundary for both +select 'sellipse && sellipse', 'f' as expected, sellipse'<{ 45d , 20d }, (-45d , 0d) , 0d>' && sellipse'<{ 45d , 20d }, (45d , 0d) , 0d>' as actual; + +-- the ellipses match +select 'sellipse && sellipse', 'f' as expected, sellipse'<{ 45d , 20d }, (-45d , 0d) , 0d>' && sellipse'<{ 45d , 20d }, (-45d , 0d) , 0d>' as actual; + +-- one ellipse lies completely in the other and they have an intersection at the boundary point +select 'sellipse && sellipse', 'f' as expected, sellipse'<{ 40d , 30d }, (0d , 0d) , 0d>' && sellipse'<{ 20d , 5d }, (-20d , 0d) , 0d>' as actual; + +-- one ellipse lies completely in the other and they have no intersection at the boundary point +select 'sellipse && sellipse', 'f' as expected, sellipse'<{ 40d , 30d }, (0d , 0d) , 0d>' && sellipse'<{ 10d , 5d }, (-20d , 0d) , 0d>' as actual; + +-- one ellipse partially lies in the other +select 'sellipse && sellipse', 't' as expected, sellipse'<{ 45d , 30d }, (0d , 0d) , 0d>' && sellipse'<{ 20d , 5d }, (30d , 0d) , 0d>' as actual; + +-- the ellipse degenerated into the line lies completely in the interior of another (non-degenerate) ellipse +select 'sellipse && sellipse', 'f' as expected, sellipse'<{ 40d , 30d }, (0d , 0d) , 0d>' && sellipse'<{ 10d , 0d }, (10d , 0d) , 0d>' as actual; + +-- the ellipse degenerated into the line partially lies in the interior of another (non-degenerate) ellipse +select 'sellipse && sellipse', 'f' as expected, sellipse'<{ 40d , 30d }, (0d , 0d) , 0d>' && sellipse'<{ 20d , 0d }, (30d , 0d) , 0d>' as actual; + +-- the ellipse degenerated into the point lies on the boundary of another +select 'sellipse && sellipse', 'f' as expected, sellipse'<{ 40d , 30d }, (0d , 0d) , 0d>' && sellipse'<{ 0d , 0d }, (30d , 0d) , 0d>' as actual; + +-- the ellipse degenerated into the point lies in the interior of another +select 'sellipse && sellipse', 'f' as expected, sellipse'<{ 40d , 30d }, (0d , 0d) , 0d>' && sellipse'<{ 0d , 0d }, (40d , 0d) , 0d>' as actual; + +-- both ellipses are degenerated into the point and coincide +select 'sellipse && sellipse', 'f' as expected, sellipse'<{ 0d , 0d }, (0d , 0d) , 0d>' && sellipse'<{ 0d , 0d }, (0d , 0d) , 0d>' as actual; + +-- both ellipses are degenerated into the point and do not coincide, but lie close to each other +select 'sellipse && sellipse', 'f' as expected, sellipse'<{ 0d , 0d }, (0d , 0d) , 0d>' && sellipse'<{ 0d , 0d }, (1d , 0d) , 0d>' as actual; + + +-- sellipse vs scircle + + +-- the ellipse and circle have no common points +select 'sellipse && scircle', 'f' as expected, sellipse'<{ 20d , 10d }, (0d , 0d) , 0d>' && scircle'<(30d , 0d) , 5d>' as actual; + +-- the point of intersection of the ellipse and circle is the boundary for both +select 'sellipse && scircle', 'f' as expected, sellipse'<{ 20d , 10d }, (0d , 0d) , 0d>' && scircle'<(30d , 0d) , 10d>' as actual; + +-- the ellipse and circle match +select 'sellipse && scircle', 'f' as expected, sellipse'<{ 10d , 10d }, (30d , 0d) , 0d>' && scircle'<(30d , 0d) , 10d>' as actual; + +-- the ellipse lies completely in the circle and they have an intersection at the boundary point +select 'sellipse && scircle', 'f' as expected, sellipse'<{ 20d , 10d }, (0d , 0d) , 0d>' && scircle'<(20d , 0d) , 40d>' as actual; + +-- the ellipse lies completely in the circle and they have no intersection at the boundary point +select 'sellipse && scircle', 'f' as expected, sellipse'<{ 20d , 10d }, (20d , 0d) , 0d>' && scircle'<(20d , 0d) , 40d>' as actual; + +-- the circle lies completely in the ellipse +select 'sellipse && scircle', 'f' as expected, sellipse'<{ 20d , 10d }, (0d , 0d) , 0d>' && scircle'<(0d , 0d) , 5d>' as actual; + +-- the circle partially lies in the ellipse +select 'sellipse && scircle', 't' as expected, sellipse'<{ 20d , 10d }, (0d , 0d) , 0d>' && scircle'<(20d , 0d) , 15d>' as actual; + +-- the ellipse degenerated into the line lies completely in the interior of circle +select 'sellipse && scircle', 'f' as expected, sellipse'<{ 20d , 0d }, (0d , 0d) , 0d>' && scircle'<(0d , 0d) , 20d>' as actual; + +-- the ellipse degenerated into the line partially lies in the interior of circle +select 'sellipse && scircle', 'f' as expected, sellipse'<{ 20d , 0d }, (10d , 0d) , 0d>' && scircle'<(0d , 0d) , 20d>' as actual; + +-- the ellipse degenerated into the point lies on the boundary of circle +select 'sellipse && scircle', 'f' as expected, sellipse'<{ 0d , 0d }, (10d , 0d) , 0d>' && scircle'<(0d , 0d) , 10d>' as actual; + +-- the ellipse degenerated into the point lies in the interior of circle +select 'sellipse && scircle', 'f' as expected, sellipse'<{ 0d , 0d }, (5d , 0d) , 0d>' && scircle'<(0d , 0d) , 10d>' as actual; + +-- the ellipse and circle are degenerated into the point and coincide +select 'sellipse && scircle', 'f' as expected, sellipse'<{ 0d , 0d }, (0d , 0d) , 0d>' && scircle'<(0d , 0d) , 0d>' as actual; + +-- the ellipses are degenerated into the point and do not coincide, but lie close to each other +select 'sellipse && scircle', 'f' as expected, sellipse'<{ 0d , 0d }, (0d , 0d) , 0d>' && scircle'<(1d , 0d) , 0d>' as actual; + + +-- spath vs spath + + +-- the opened paths have no common points +select 'spath && spath', 'f' as expected, spath'{ (-10d, 0d),(10d,0d),(45d,15d) }' && spath'{ (60d, 15d),(70d, 20d),(75d, 20d) }' as actual; + +-- the points of intersection of the opened paths is the boundary for both +select 'spath && spath', 'f' as expected, spath'{ (-10d, 0d),(10d, 0d),(45d, 15d) }' && spath'{ (-10d, 0d),(0d, 10d),(45d, 15d) }' as actual; + +-- one opened path intersects the other at the boundary point of the latter +select 'spath && spath', 'f' as expected, spath'{ (-10d, 0d),(10d, 0d),(45d, 15d) }' && spath'{ (-20d, -10d),(-10d, 0d),(0d, 10d),(45d, 15d),(60d, 15d) }' as actual; + +-- the interiors of the opened paths intersect at one point +select 'spath && spath', 'f' as expected, spath'{ (-10d, 0d),(10d, 0d),(45d, 15d) }' && spath'{ (0d, 10d),(0d, -10d),(10d, -10d) }' as actual; + +-- the interiors of the opened paths intersect at two points +select 'spath && spath', 'f' as expected, spath'{ (-10d, 0d),(10d, 0d),(45d, 15d) }' && spath'{ (0d, 10d),(0d, -10d),(5d, 0d) }' as actual; + +-- the opened paths match +select 'spath && spath', 'f' as expected, spath'{ (-10d, 0d),(10d, 0d),(45d, 15d) }' && spath'{ (-10d, 0d),(10d, 0d),(45d, 15d) }' as actual; + +-- the closed paths match +select 'spath && spath', 'f' as expected, spath'{ (-10d, 0d),(10d, 0d),(45d, 15d),(-10d, 0d) }' && spath'{ (-10d, 0d),(10d, 0d),(45d, 15d),(-10d, 0d) }' as actual; + +-- one opened path lies completely in the other and they have an intersection at the boundary point +select 'spath && spath', 'f' as expected, spath'{ (-10d, 0d),(10d, 0d),(45d, 15d),(60d, 15d),(70d, 20d) }' && spath'{ (-10d, 0d),(10d, 0d),(45d, 15d) }' as actual; + +-- one opened path lies completely in the other and they have no intersection at the boundary point +select 'spath && spath', 'f' as expected, spath'{ (-10d, 0d),(10d, 0d),(45d, 15d),(60d, 15d),(70d, 20d) }' && spath'{ (10d, 0d),(45d, 15d),(60d, 15d) }' as actual; + +-- one opened path partially lies in the other +select 'spath && spath', 't' as expected, spath'{ (-10d, 0d),(10d, 0d),(45d, 15d) }' && spath'{ (45d, 15d),(60d, 15d),(70d, 20d) }' as actual; + +-- one closed path partially lies in the other +select 'spath && spath', 't' as expected, spath'{ (-10d, 0d),(10d, 0d),(45d, 15d),(-10d, 0d) }' && spath'{ (45d, 15d),(60d, 15d),(70d, 20d),(45d, 15d) }' as actual; + +-- the opened path partially lies in the closed path +select 'spath && spath', 't' as expected, spath'{ (-10d, 0d),(10d, 0d),(45d, 15d),(-10d, 0d) }' && spath'{ (45d, 15d),(60d, 15d),(70d, 20d) }' as actual; + + +-- spath vs sline + + +-- the opened path and line have no common points +select 'spath && sline', 'f' as expected, spath'{ (-10d, 0d),(10d, 0d),(45d, 15d) }' && sline( spoint'(20d, 0d)', spoint'(30d, 0d)') as actual; + +-- the points of intersection of the opened path and line is the boundary for both +select 'spath && sline', 'f' as expected, spath'{ (-10d, 0d),(10d, 0d),(45d, 15d) }' && sline( spoint'(-10d, 0d)', spoint'(45d, 15d)') as actual; + +-- the interiors of the opened path and line intersect at one point +select 'spath && sline', 'f' as expected, spath'{ (-10d, 0d),(10d, 0d),(45d, 15d) }' && sline( spoint'(0d, 10d)', spoint'(0d, -10d)') as actual; + +-- the path and line match +select 'spath && sline', 'f' as expected, spath'{ (0d, 10d),(0d, -10d) }' && sline( spoint'(0d, 10d)', spoint'(0d, -10d)') as actual; + +-- the line lies completely in the opened path and they have an intersection at the boundary point +select 'spath && sline', 'f' as expected, spath'{ (-10d, 0d),(10d, 0d),(45d, 15d),(60d, 20d) }' && sline( spoint'(-10d, 0d)', spoint'(10d, 0d)') as actual; + +-- the line lies completely in the opened path and they have no intersection at the boundary point +select 'spath && sline', 'f' as expected, spath'{ (-10d, 0d),(10d, 0d),(45d, 15d),(60d, 20d) }' && sline( spoint'(10d, 0d)', spoint'(45d, 15d)') as actual; + +-- the line partially lies in the open path +select 'spath && sline', 't' as expected, spath'{ (-10d, 0d),(10d, 0d),(45d, 15d) }' && sline( spoint'(5d, 0d)', spoint'(20d, 0d)') as actual; + +-- the line degenerated into the point lies in the boundary of open path +select 'spath && sline', 'f' as expected, spath'{ (-10d, 0d),(10d, 0d),(45d, 15d) }' && sline( spoint'(-10d, 0d)', spoint'(-10d, 0d)') as actual; + +-- the line degenerated into the point lies in the interior of open path +select 'spath && sline', 'f' as expected, spath'{ (-10d, 0d),(10d, 0d),(45d, 15d) }' && sline( spoint'(0d, 0d)', spoint'(0d, 0d)') as actual; + + +-- spoly vs spoly + + +-- the polygons have no common points +select 'spoly && spoly', 'f' as expected, spoly'{ (0d, 0d),(-10d, 0d),(0d, 10d) }' && spoly'{ (10d, 0d),(20d, 0d),(10d, 10d) }' as actual; + +-- the point of intersection of the polygons is the boundary for both +select 'spoly && spoly', 'f' as expected, spoly'{ (0d, 0d),(-10d, 0d),(0d, 10d) }' && spoly'{ (10d, 0d),(20d, 0d),(0d, 10d) }' as actual; + +-- the interiors of the polygons intersect at one line +select 'spoly && spoly', 'f' as expected, spoly'{ (0d, 0d),(-10d, 0d),(0d, 10d) }' && spoly'{ (0d, 0d),(20d, 0d),(0d, 10d) }' as actual; + +-- the polygons matches +select 'spoly && spoly', 'f' as expected, spoly'{ (0d, 0d),(-10d, 0d),(0d, 10d) }' && spoly'{ (0d, 0d),(-10d, 0d),(0d, 10d) }' as actual; + +-- one polygon lies completely in the other and they have an intersection at the boundary line +select 'spoly && spoly', 'f' as expected, spoly'{ (0d, 0d),(20d, 0d),(20d, 20d),(0d, 20d) }' && spoly'{ (0d, 0d),(20d, 0d),(0d, 20d) }' as actual; + +-- one polygon lies completely in the other and they have no intersection at the boundary line or point +select 'spoly && spoly', 'f' as expected, spoly'{ (0d, 0d),(20d, 0d),(20d, 20d),(0d, 20d) }' && spoly'{ (5d, 5d),(15d, 5d),(15d, 15d),(5d,15d) }' as actual; + +-- one polygon partially lies in the other +select 'spoly && spoly', 't' as expected, spoly'{ (0d, 0d),(-10d, 0d),(0d, 10d) }' && spoly'{ (5d, 5d),(30d, 5d),(30d, 15d),(5d,15d) }' as actual; + + +-- spoly vs scircle + + +-- the polygon and circle have no common points +select 'spoly && scircle', 'f' as expected, spoly'{ (0d, 0d),(10d, 0d),(0d, 10d) }' && scircle'<(0d , 90d) , 10d>' as actual; + +-- the point of intersection of the polygon and circle is the boundary for both +select 'spoly && scircle', 'f' as expected, spoly'{ (0d, 0d),(10d, 0d),(0d, 10d) }' && scircle'<(0d , 90d) , 80d>' as actual; + +-- the circle lies completely in the polygon and they have an intersection at the boundary point +select 'spoly && scircle', 'f' as expected, spoly'{ (0d, 0d),(10d, 0d),(0d, 10d) }' && scircle'<(5d , 1d) , 1d>' as actual; + +-- the circle lies completely in the polygon and they have no intersection at the boundary point +select 'spoly && scircle', 'f' as expected, spoly'{ (0d, 0d),(10d, 0d),(0d, 10d) }' && scircle'<(5d , 2d) , 1d>' as actual; + +-- the polygon lies completely in the circle +select 'spoly && scircle', 'f' as expected, spoly'{ (0d, 0d),(10d, 0d),(0d, 10d) }' && scircle'<(0d , 15d) , 20d>' as actual; + +-- the polygon partially lies in the circle +select 'spoly && scircle', 't' as expected, spoly'{ (0d, 0d),(10d, 0d),(0d, 10d) }' && scircle'<(0d , 5d) , 5d>' as actual; + +-- the circle degenerated into the point lies in the boundary of polygon +select 'spoly && scircle', 'f' as expected, spoly'{ (0d, 0d),(10d, 0d),(0d, 10d) }' && scircle'<(0d , 0d) , 0d>' as actual; + +-- the circle degenerated into the point lies in the interior of polygon +select 'spoly && scircle', 'f' as expected, spoly'{ (0d, 0d),(10d, 0d),(0d, 10d) }' && scircle'<(2d , 2d) , 0d>' as actual; + + +-- spoly vs sellipse + + +-- the polygon and ellipse have no common points +select 'spoly && sellipse', 'f' as expected, spoly'{ (0d, 0d),(10d, 0d),(0d, 10d) }' && sellipse'<{ 30d , 20d }, (0d , 90d) , 0d>' as actual; + +-- the point of intersection of the polygon and ellipse is the boundary for both +select 'spoly && sellipse', 'f' as expected, spoly'{ (0d, 0d),(10d, 0d),(0d, 10d) }' && sellipse'<{ 80d , 20d }, (0d , 90d) , 90d>' as actual; + +-- the ellipse lies completely in the polygon and they have an intersection at the boundary points +select 'spoly && sellipse', 'f' as expected, spoly'{ (0d, 0d),(20d, 0d),(20d, 20d),(0d, 20d) }' && sellipse'<{ 10d , 5d }, (10d , 10d), 0d>' as actual; + +-- the ellipse lies completely in the polygon and they have no intersection at the boundary points +select 'spoly && sellipse', 'f' as expected, spoly'{ (0d, 0d),(20d, 0d),(20d, 20d),(0d, 20d) }' && sellipse'<{ 7d , 5d }, (10d , 10d), 0d>' as actual; + +-- the polygon lies completely in the ellipse and they have an intersection at the boundary points +select 'spoly && sellipse', 'f' as expected, spoly'{ (0d, 5d),(10d, 10d),(20d, 5d),(10d, 0d) }' && sellipse'<{ 10d , 5d }, (10d , 5d), 0d>' as actual; + +-- the polygon lies completely in the ellipse and they have no intersection at the boundary points +select 'spoly && sellipse', 'f' as expected, spoly'{ (1d, 5d),(10d, 9d),(19d, 5d),(10d, 1d) }' && sellipse'<{ 10d , 5d }, (10d , 10d), 0d>' as actual; + +-- the ellipse partially lies in the polygon +select 'spoly && sellipse', 't' as expected, spoly'{ (0d, 0d),(10d, 0d),(0d, 10d) }' && sellipse'<{ 10d , 2d }, (0d , 5d) , 0d>' as actual; + +-- the ellipse degenerated into the point lies in the boundary of polygon +select 'spoly && sellipse', 'f' as expected, spoly'{ (0d, 0d),(10d, 0d),(0d, 10d) }' && sellipse'<{ 0d , 0d }, (0d , 0d), 0d>' as actual; + +-- the ellipse degenerated into the point lies in the interior of polygon +select 'spoly && sellipse', 'f' as expected, spoly'{ (0d, 0d),(10d, 0d),(0d, 10d) }' && sellipse'<{ 0d , 0d }, (5d , 2d), 0d>' as actual; + +-- the ellipse degenerated into the line lies in the boundary of polygon +select 'spoly && sellipse', 'f' as expected, spoly'{ (0d, 0d),(10d, 0d),(0d, 10d) }' && sellipse'<{ 5d , 0d }, (5d , 0d), 0d>' as actual; + +-- the ellipse degenerated into the line lies in the interior of polygon +select 'spoly && sellipse', 'f' as expected, spoly'{ (0d, 0d),(10d, 0d),(0d, 10d) }' && sellipse'<{ 2d , 0d }, (1d , 4d), 90d>' as actual; + +-- the ellipse degenerated into the line partially lies in the interior of polygon +select 'spoly && sellipse', 'f' as expected, spoly'{ (0d, 0d),(10d, 0d),(0d, 10d) }' && sellipse'<{ 10d , 0d }, (1d , 4d), 0d>' as actual; + + +-- sbox vs sbox + + +-- the boxes have no common points +select 'sbox && sbox', 'f' as expected, sbox'((0d , 0d), (20d , 20d))' && sbox'((30d , 30d), (50d , 50d))' as actual; + +-- the point of intersection of the boxes is the boundary for both +select 'sbox && sbox', 'f' as expected, sbox'((0d , 0d), (20d , 20d))' && sbox'((20d , 20d), (50d , 50d))' as actual; + +-- the boundaries of the boxes intersect at one line +select 'sbox && sbox', 'f' as expected, sbox'((0d , 0d), (20d , 20d))' && sbox'((20d , 0d), (50d , 20d))' as actual; + +-- the boxes matches +select 'sbox && sbox', 'f' as expected, sbox'((0d , 0d), (20d , 20d))' && sbox'((5d , 5d), (10d , 10d))' as actual; + +-- one box lies completely in the other and they have no intersection at the boundary line or point +select 'sbox && sbox', 'f' as expected, sbox'((0d , 0d), (20d , 20d))' && sbox'((5d , 5d), (10d , 10d))' as actual; + +-- one box partially lies in the other +select 'sbox && sbox', 't' as expected, sbox'((0d , 0d), (20d , 20d))' && sbox'((10d , 10d), (30d , 30d))' as actual; + +-- one box degenerated into the line lies in the boundary of other +select 'sbox && sbox', 'f' as expected, sbox'((0d , 0d), (20d , 20d))' && sbox'((0d , 0d), (20d , 0d))' as actual; + +-- one box degenerated into the line lies in the interior of other +select 'sbox && sbox', 'f' as expected, sbox'((0d , 0d), (20d , 20d))' && sbox'((5d , 5d), (10d , 5d))' as actual; + +-- one box degenerated into the point lies in the boundary of other +select 'sbox && sbox', 'f' as expected, sbox'((0d , 0d), (20d , 20d))' && sbox'((0d , 0d), (0d , 0d))' as actual; + +-- one box degenerated into the point lies in the interior of other +select 'sbox && sbox', 'f' as expected, sbox'((0d , 0d), (20d , 20d))' && sbox'((5d , 5d), (5d , 5d))' as actual; + +-- the boxes are degenerated into the point and coincide +select 'sbox && sbox', 'f' as expected, sbox'((0d , 0d), (0d , 0d))' && sbox'((0d , 0d), (0d , 0d))' as actual; + +-- the boxes are degenerated into the point and not coincide +select 'sbox && sbox', 'f' as expected, sbox'((0d , 0d), (0d , 0d))' && sbox'((10d , 10d), (10d , 10d))' as actual; + + +-- sbox vs scircle + + +-- the box and circle have no common points +select 'sbox && scircle', 'f' as expected, sbox'((0d , 0d), (20d , 20d))' && scircle'<(0d , 90d) , 10d>' as actual; + +-- the point of intersection of the box and circle is the boundary for both +select 'sbox && scircle', 'f' as expected, sbox'((0d , 0d), (20d , 20d))' && scircle'<(30d , 0d) , 10d>' as actual; + +-- the circle lies completely in the box and they have an intersection at the boundary points +select 'sbox && scircle', 'f' as expected, sbox'((0d , 0d), (20d , 20d))' && scircle'<(10d , 10d) , 10d>' as actual; + +-- the circle lies completely in the box and they have no intersection at the boundary points +select 'sbox && scircle', 'f' as expected, sbox'((0d , 0d), (20d , 20d))' && scircle'<(10d , 10d) , 5d>' as actual; + +-- the box lies completely in the circle and they have an intersection at the boundary points +select 'sbox && scircle', 'f' as expected, sbox'((-4d , -3d), (3d , 4d))' && scircle'<(0d , 0d) , 5d>' as actual; + +-- the box lies completely in the circle and they have no intersection at the boundary points +select 'sbox && scircle', 'f' as expected, sbox'((-4d , -3d), (3d , 4d))' && scircle'<(0d , 0d) , 10d>' as actual; + +-- the box degenerated into the line intersects circle +select 'sbox && scircle', 'f' as expected, sbox'((-20d , 0d), (20d , 0d))' && scircle'<(0d , 0d) , 10d>' as actual; + +-- the circle partially lies in the box +select 'sbox && scircle', 't' as expected, sbox'((0d , 0d), (20d , 20d))' && scircle'<(15d , 15d) , 10d>' as actual; + +-- the circle degenerated into the point lies in the boundary of box +select 'sbox && scircle', 'f' as expected, sbox'((0d , 0d), (20d , 20d))' && scircle'<(0d , 10d) , 0d>' as actual; + +-- the circle degenerated into the point lies in the interior of box +select 'sbox && scircle', 'f' as expected, sbox'((0d , 0d), (20d , 20d))' && scircle'<(10d , 10d) , 0d>' as actual; + +-- the box degenerated into the point lies in the boundary of circle +select 'sbox && scircle', 'f' as expected, sbox'((0d , 0d), (0d , 0d))' && scircle'<(10d , 0d) , 10d>' as actual; + +-- the box degenerated into the point lies in the interior of circle +select 'sbox && scircle', 'f' as expected, sbox'((0d , 0d), (0d , 0d))' && scircle'<(0d , 0d) , 10d>' as actual; + +-- the box and circle are degenerated into the point and coincide +select 'sbox && scircle', 'f' as expected, sbox'((0d , 0d), (0d , 0d))' && scircle'<(0d , 0d) , 0d>' as actual; + +-- the box and circle are degenerated into the point and not coincide +select 'sbox && scircle', 'f' as expected, sbox'((0d , 0d), (0d , 0d))' && scircle'<(5d , 5d) , 0d>' as actual; + + +-- sbox vs spoly + + +-- the box and polygon have no common points +select 'sbox && spoly', 'f' as expected, sbox'((0d , 0d), (20d , 20d))' && spoly'{ (30d, 0d),(40d, 0d),(30d, 20d) }' as actual; + +-- the point of intersection of the box and polygon is the boundary for both +select 'sbox && spoly', 'f' as expected, sbox'((0d , 0d), (20d , 20d))' && spoly'{ (30d, 0d),(40d, 0d),(30d, 20d) }' as actual; + +-- the boundaries of the boxes intersect at one line +select 'sbox && spoly', 'f' as expected, sbox'((0d , 0d), (20d , 20d))' && spoly'{ (20d, 0d),(30d, 0d),(20d, 20d) }' as actual; + +-- the box and circle matches +select 'sbox && spoly', 'f' as expected, sbox'((0d , 0d), (20d , 20d))' && spoly'{ (0d, 0d),(20d, 0d),(20d, 20d),(0d, 20d) }' as actual; + +-- the polygon lies completely in the box and they have an intersection at the boundary line +select 'sbox && spoly', 'f' as expected, sbox'((0d , 0d), (20d , 20d))' && spoly'{ (0d, 0d),(20d, 0d),(0d, 20d) }' as actual; + +-- the polygon lies completely in the box and they have no intersection at the boundary +select 'sbox && spoly', 'f' as expected, sbox'((0d , 0d), (20d , 20d))' && spoly'{ (1d, 1d),(11d, 1d),(1d, 19d) }' as actual; + +-- the box lies completely in the polygon and they have an intersection at the boundary line +select 'sbox && spoly', 'f' as expected, sbox'((0d , 0d), (10d , 10d))' && spoly'{ (0d, 0d),(20d, 0d),(0d, 20d) }' as actual; + +-- the box lies completely in the polygon and they have no intersection at the boundary +select 'sbox && spoly', 'f' as expected, sbox'((1d , 1d), (2d , 2d))' && spoly'{ (0d, 0d),(20d, 0d),(0d, 20d) }' as actual; + +-- the polygon partially lies in the box +select 'sbox && spoly', 't' as expected, sbox'((0d , 0d), (20d , 20d))' && spoly'{ (15d, 0d),(35d, 0d),(15d, 35d) }' as actual; + +-- the box degenerated into the line lies in the boundary of polygon +select 'sbox && spoly', 'f' as expected, sbox'((0d , 0d), (20d , 0d))' && spoly'{ (0d, 0d),(20d, 0d),(0d, 20d) }' as actual; + +-- the box degenerated into the line lies in the interior of polygon +select 'sbox && spoly', 'f' as expected, sbox'((0d , 5d), (10d , 5d))' && spoly'{ (0d, 0d),(20d, 0d),(0d, 20d) }' as actual; + +-- the box degenerated into the point lies in the boundary of polygon +select 'sbox && spoly', 'f' as expected, sbox'((0d , 0d), (0d , 0d))' && spoly'{ (0d, 0d),(20d, 0d),(0d, 20d) }' as actual; + +-- the box degenerated into the point lies in the interior of polygon +select 'sbox && spoly', 'f' as expected, sbox'((5d , 5d), (5d , 5d))' && spoly'{ (0d, 0d),(20d, 0d),(0d, 20d) }' as actual; + + +-- sbox vs sellipse + + +-- the box and ellipse have no common points +select 'sbox && sellipse', 'f' as expected, sbox'((0d , 0d), (20d , 20d))' && sellipse'<{ 20d , 10d }, (0d, 90d) , 0d>' as actual; + +-- the point of intersection of the box and ellipse is the boundary for both +select 'sbox && sellipse', 'f' as expected, sbox'((-10d , -10d), (10d , 10d))' && sellipse'<{ 80d , 10d }, (0d, 90d) , 90d>' as actual; + +-- the ellipse lies completely in the box and they have an intersection at the boundary points +select 'sbox && sellipse', 'f' as expected, sbox'((0d , 0d), (20d , 20d))' && sellipse'<{ 10d , 5d }, (10d, 10d) , 0d>' as actual; + +-- the ellipse lies completely in the box and they have no intersection at the boundary points +select 'sbox && sellipse', 'f' as expected, sbox'((0d , 0d), (20d , 20d))' && sellipse'<{ 9d , 5d }, (10d, 10d) , 0d>' as actual; + +-- the box lies completely in the ellipse and they have no intersection at the boundary points +select 'sbox && sellipse', 'f' as expected, sbox'((-10d , -10d), (10d , 10d))' && sellipse'<{ 30d , 20d }, (0d, 0d) , 0d>' as actual; + +-- the ellipse partially lies in the box +select 'sbox && sellipse', 't' as expected, sbox'((-10d , -10d), (10d , 10d))' && sellipse'<{ 10d , 5d }, (10d, 10d) , 90d>' as actual; + +-- the box degenerated into the point lies in the boundary of ellipse +select 'sbox && sellipse', 'f' as expected, sbox'((30d , 0d), (30d , 0d))' && sellipse'<{ 30d , 20d }, (0d, 0d) , 0d>' as actual; + +-- the box degenerated into the point lies in the interior of ellipse +select 'sbox && sellipse', 'f' as expected, sbox'((0d , 0d), (10d , 0d))' && sellipse'<{ 30d , 20d }, (0d, 0d) , 0d>' as actual; + +-- the box and ellipse are degenerated into the point and coincide +select 'sbox && sellipse', 'f' as expected, sbox'((0d , 0d), (0d , 0d))' && sellipse'<{ 0d , 0d }, (0d, 0d) , 0d>' as actual; From 75a7fb3c36192062a443425ce9870a4902a5ef57 Mon Sep 17 00:00:00 2001 From: Vitaly Davydov Date: Wed, 9 Aug 2023 10:00:33 +0300 Subject: [PATCH 10/87] Fix pgSphere version and the project url in the doc --- doc/pg_sphere.xml | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/doc/pg_sphere.xml b/doc/pg_sphere.xml index a48b1e7..950a530 100644 --- a/doc/pg_sphere.xml +++ b/doc/pg_sphere.xml @@ -31,7 +31,7 @@
Codestin Search App pgSphere development team @@ -50,8 +50,9 @@ PostgreSQL. - The project is hosted at pgfoundry.org - and https://github.com/akorotkov/pgsphere + The project is hosted at + https://github.com/postgrespro/pgsphere + This document From 2f9fe2c10402a4676e7855851c66d970eba7321f Mon Sep 17 00:00:00 2001 From: Darya177777 Date: Fri, 11 Aug 2023 09:29:42 +0700 Subject: [PATCH 11/87] Add calculation of the distance between a line and a point --- doc/operators.sgm | 14 +++- expected/init_test.out.in | 14 ++-- expected/init_test_healpix.out.in | 4 +- expected/line.out | 34 ++++++++- pgs_line.sql.in | 50 +++++++++++++ sql/line.sql | 17 ++++- src/line.c | 72 +++++++++++++++++++ src/line.h | 15 ++++ .../pg_sphere--1.2.3--1.3.0.sql.in | 39 ++++++++++ 9 files changed, 247 insertions(+), 12 deletions(-) diff --git a/doc/operators.sgm b/doc/operators.sgm index 7162a01..73ebb83 100644 --- a/doc/operators.sgm +++ b/doc/operators.sgm @@ -331,7 +331,8 @@ a non-boolean operator returning the distance between two objects in radians. Currently, pgSphere supports only distances - between points, circles, and between point and circle. If the + between points, circles, between point and circle, and + between point and line. If the objects are overlapping, the distance operator returns zero (0.0). @@ -343,6 +344,17 @@ + + + + + Codestin Search App + + SELECT 180 * (sline '( 0d, 0d, 0d, XYZ ), 40d ' <-> spoint '( 0d, 90d )')]]> + + + + diff --git a/expected/init_test.out.in b/expected/init_test.out.in index 1276622..b5ace10 100644 --- a/expected/init_test.out.in +++ b/expected/init_test.out.in @@ -24,12 +24,12 @@ psql:pg_sphere.test.sql:158: NOTICE: argument type spath is only a shell psql:pg_sphere.test.sql:177: NOTICE: type "sbox" is not yet defined DETAIL: Creating a shell type definition. psql:pg_sphere.test.sql:184: NOTICE: argument type sbox is only a shell -psql:pg_sphere.test.sql:8594: NOTICE: type "spherekey" is not yet defined +psql:pg_sphere.test.sql:8644: NOTICE: type "spherekey" is not yet defined DETAIL: Creating a shell type definition. -psql:pg_sphere.test.sql:8601: NOTICE: argument type spherekey is only a shell -psql:pg_sphere.test.sql:8615: NOTICE: type "pointkey" is not yet defined +psql:pg_sphere.test.sql:8651: NOTICE: argument type spherekey is only a shell +psql:pg_sphere.test.sql:8665: NOTICE: type "pointkey" is not yet defined DETAIL: Creating a shell type definition. -psql:pg_sphere.test.sql:8622: NOTICE: argument type pointkey is only a shell -psql:pg_sphere.test.sql:8628: NOTICE: argument type pointkey is only a shell -psql:pg_sphere.test.sql:8634: NOTICE: argument type pointkey is only a shell -psql:pg_sphere.test.sql:8640: NOTICE: argument type pointkey is only a shell +psql:pg_sphere.test.sql:8672: NOTICE: argument type pointkey is only a shell +psql:pg_sphere.test.sql:8678: NOTICE: argument type pointkey is only a shell +psql:pg_sphere.test.sql:8684: NOTICE: argument type pointkey is only a shell +psql:pg_sphere.test.sql:8690: NOTICE: argument type pointkey is only a shell diff --git a/expected/init_test_healpix.out.in b/expected/init_test_healpix.out.in index 147d4f9..3b0cfbd 100644 --- a/expected/init_test_healpix.out.in +++ b/expected/init_test_healpix.out.in @@ -1,2 +1,2 @@ -psql:pg_sphere.test.sql:9207: NOTICE: return type smoc is only a shell -psql:pg_sphere.test.sql:9213: NOTICE: argument type smoc is only a shell +psql:pg_sphere.test.sql:9257: NOTICE: return type smoc is only a shell +psql:pg_sphere.test.sql:9263: NOTICE: argument type smoc is only a shell diff --git a/expected/line.out b/expected/line.out index b05286b..eb4d2ac 100644 --- a/expected/line.out +++ b/expected/line.out @@ -4,6 +4,7 @@ SET 8 (1 row) +SET extra_float_digits TO -3; -- checking spherical line operators SELECT sline ( spoint '(0, 90d)', spoint '(0, -89d)' ) = sline ( spoint '(0, 90d)', spoint '(0, -89d)' ) ; @@ -134,4 +135,35 @@ SELECT sline ( spoint '(0, 0d)', spoint '(0.000001d, 0d)' ) # f (1 row) - +-- checking the distance between a line and a point +SELECT sline '( 90d, 0d, 0d, XYZ ), 40d ' <-> spoint '( 0d, 90d )'; + ?column? +---------------- + 0.872664625997 +(1 row) + +SELECT sline '( 90d, 0d, 0d, XYZ ), 40d ' <-> spoint '( 0d, 90d )' = + spoint '( 0d, 90d )' <-> sline '( 90d, 0d, 0d, XYZ ), 40d '; + ?column? +---------- + t +(1 row) + +SELECT sline '( 0d, 0d, 0d, XYZ ), 0d ' <-> spoint '( 0d, 90d )'; + ?column? +--------------- + 1.57079632679 +(1 row) + +SELECT sline '( 0d, 0d, 0d, XYZ ), 0d ' <-> spoint '( 0d, 0d )'; + ?column? +---------- + 0 +(1 row) + +SELECT sline '( 0d, 0d, 0d, XYZ ), 30d ' <-> spoint '( 0d, 30d )'; + ?column? +---------------- + 0.523598775598 +(1 row) + diff --git a/pgs_line.sql.in b/pgs_line.sql.in index 9814355..3b51fba 100644 --- a/pgs_line.sql.in +++ b/pgs_line.sql.in @@ -593,3 +593,53 @@ COMMENT ON FUNCTION scircle_contains_line_com_neg(sline, scircle) IS 'returns true if spherical circle does not contain spherical line'; +-- +-- distance between line and point +-- + +CREATE FUNCTION dist(sline, spoint) + RETURNS FLOAT8 + AS 'MODULE_PATHNAME', 'sphereline_point_distance' + LANGUAGE 'c' + IMMUTABLE STRICT; + +COMMENT ON FUNCTION dist(sline, spoint) IS + 'returns the distance between spherical line and spherical point'; + + +CREATE OPERATOR <-> ( + LEFTARG = sline, + RIGHTARG = spoint, + COMMUTATOR = '<->', + PROCEDURE = dist +); + +COMMENT ON OPERATOR <-> (sline, spoint) IS + 'returns the distance between spherical line and spherical point'; + + + +-- +-- distance between point and line +-- + +CREATE FUNCTION dist(spoint, sline) + RETURNS FLOAT8 + AS 'MODULE_PATHNAME', 'sphereline_point_distance_com' + LANGUAGE 'c' + IMMUTABLE STRICT; + +COMMENT ON FUNCTION dist(spoint, sline) IS + 'returns the distance between spherical line and spherical point'; + + +CREATE OPERATOR <-> ( + LEFTARG = spoint, + RIGHTARG = sline, + COMMUTATOR = '<->', + PROCEDURE = dist +); + +COMMENT ON OPERATOR <-> (spoint, sline) IS + 'returns the distance between spherical line and spherical point'; + diff --git a/sql/line.sql b/sql/line.sql index 7fc6ebf..7a5a2dd 100644 --- a/sql/line.sql +++ b/sql/line.sql @@ -1,6 +1,7 @@ \set ECHO none SELECT set_sphere_output_precision(8); \set ECHO all +SET extra_float_digits TO -3; -- checking spherical line operators @@ -66,4 +67,18 @@ SELECT sline ( spoint '(0, 0d)', spoint '(0.000001d, 0d)' ) # SELECT sline ( spoint '(0, 0d)', spoint '(0.000001d, 0d)' ) # sline ( spoint '(0.000001d, 0d)', spoint '(0.000001d, 0.0000005d)' ) ; - \ No newline at end of file + + +-- checking the distance between a line and a point + + +SELECT sline '( 90d, 0d, 0d, XYZ ), 40d ' <-> spoint '( 0d, 90d )'; + +SELECT sline '( 90d, 0d, 0d, XYZ ), 40d ' <-> spoint '( 0d, 90d )' = + spoint '( 0d, 90d )' <-> sline '( 90d, 0d, 0d, XYZ ), 40d '; + +SELECT sline '( 0d, 0d, 0d, XYZ ), 0d ' <-> spoint '( 0d, 90d )'; + +SELECT sline '( 0d, 0d, 0d, XYZ ), 0d ' <-> spoint '( 0d, 0d )'; + +SELECT sline '( 0d, 0d, 0d, XYZ ), 30d ' <-> spoint '( 0d, 30d )'; diff --git a/src/line.c b/src/line.c index b8d1195..6599e64 100644 --- a/src/line.c +++ b/src/line.c @@ -33,6 +33,8 @@ PG_FUNCTION_INFO_V1(sphereline_overlap_neg); PG_FUNCTION_INFO_V1(spheretrans_from_line); PG_FUNCTION_INFO_V1(spheretrans_line); PG_FUNCTION_INFO_V1(spheretrans_line_inverse); +PG_FUNCTION_INFO_V1(sphereline_point_distance); +PG_FUNCTION_INFO_V1(sphereline_point_distance_com); /* * Swaps the beginning and ending of the line. @@ -642,6 +644,59 @@ sline_center(SPoint *c, const SLine *sl) euler_spoint_trans(c, &p, &se); } +float8 sline_point_dist(const SLine *sl, const SPoint *p) +{ + Vector3D v_beg; + Vector3D v_end; + Vector3D v; + Vector3D normal1; + Vector3D normal2; + Vector3D line; + Vector3D first_p; + float8 norma; + SPoint fp; + SPoint sp; + float8 fpdist; + float8 spdist; + + if (spoint_at_sline(p, sl)) + { + return 0.0; + } + + sline_vector_begin(&v_beg, sl); + sline_vector_end(&v_end, sl); + spoint_vector3d(&v, p); + + /* normal1 to the plane passing through the line and the center of the sphere */ + vector3d_cross(&normal1, &v_beg, &v_end); + if (vector3d_eq(&normal1, &v)) + { + return PIH; + } + + /* normal2 to the plane perpendicular to the given line. */ + vector3d_cross(&normal2, &normal1, &v); + vector3d_cross(&line, &normal2, &normal1); + norma = sqrt(line.x * line.x + line.y * line.y + line.z * line.z); + + first_p.x = line.x / norma; + first_p.y = line.y / norma; + first_p.z = line.z / norma; + vector3d_spoint(&fp, &first_p); + + if (spoint_at_sline(&fp, sl)) + { + return spoint_dist(&fp, p); + } + + vector3d_spoint(&fp, &v_beg); + vector3d_spoint(&sp, &v_end); + fpdist = spoint_dist(p, &fp); + spdist = spoint_dist(p, &sp); + return Min(fpdist, spdist); +} + Datum sphereline_in(PG_FUNCTION_ARGS) { @@ -1051,3 +1106,20 @@ spheretrans_from_line(PG_FUNCTION_ARGS) sphereline_to_euler(e, l); PG_RETURN_POINTER(e); } + +Datum +sphereline_point_distance(PG_FUNCTION_ARGS) +{ + const SLine *s = (SLine *) PG_GETARG_POINTER(0); + const SPoint *p = (SPoint *) PG_GETARG_POINTER(1); + PG_RETURN_FLOAT8(sline_point_dist(s, p)); +} + +Datum +sphereline_point_distance_com(PG_FUNCTION_ARGS) +{ + const SPoint *p = (SPoint *) PG_GETARG_POINTER(0); + const SLine *s = (SLine *) PG_GETARG_POINTER(1); + PG_RETURN_FLOAT8(sline_point_dist(s, p)); +} + diff --git a/src/line.h b/src/line.h index 1a41767..002f371 100644 --- a/src/line.h +++ b/src/line.h @@ -129,6 +129,11 @@ void euler_sline_trans(SLine *out, const SLine *in, const SEuler *se); */ void sline_center(SPoint *c, const SLine *sl); +/* + * Calculates the distance between a line 'sl' and a point 'p' + */ +float8 sline_point_dist(const SLine *sl, const SPoint *p); + /* * The input function for spherical line. */ @@ -290,4 +295,14 @@ Datum spheretrans_line(PG_FUNCTION_ARGS); */ Datum spheretrans_line_inverse(PG_FUNCTION_ARGS); +/* + * Returns the distance between a line and a point. + */ +Datum sphereline_point_distance(PG_FUNCTION_ARGS); + +/* + * Returns the distance between a point and a line. + */ +Datum sphereline_point_distance_com(PG_FUNCTION_ARGS); + #endif diff --git a/upgrade_scripts/pg_sphere--1.2.3--1.3.0.sql.in b/upgrade_scripts/pg_sphere--1.2.3--1.3.0.sql.in index 3791852..6eb9460 100644 --- a/upgrade_scripts/pg_sphere--1.2.3--1.3.0.sql.in +++ b/upgrade_scripts/pg_sphere--1.2.3--1.3.0.sql.in @@ -54,3 +54,42 @@ CREATE FUNCTION spoly_as_array(spoly) COMMENT ON FUNCTION spoly_as_array(spoly) IS 'returns spoly as array of points'; + +CREATE FUNCTION dist(sline, spoint) + RETURNS FLOAT8 + AS 'MODULE_PATHNAME', 'sphereline_point_distance' + LANGUAGE 'c' + IMMUTABLE STRICT; + +COMMENT ON FUNCTION dist(sline, spoint) IS + 'returns the distance between spherical line and spherical point'; + +CREATE OPERATOR <-> ( + LEFTARG = sline, + RIGHTARG = spoint, + COMMUTATOR = '<->', + PROCEDURE = dist +); + +COMMENT ON OPERATOR <-> (sline, spoint) IS + 'returns the distance between spherical line and spherical point'; + +CREATE FUNCTION dist(spoint, sline) + RETURNS FLOAT8 + AS 'MODULE_PATHNAME', 'sphereline_point_distance_com' + LANGUAGE 'c' + IMMUTABLE STRICT; + +COMMENT ON FUNCTION dist(spoint, sline) IS + 'returns the distance between spherical line and spherical point'; + + +CREATE OPERATOR <-> ( + LEFTARG = spoint, + RIGHTARG = sline, + COMMUTATOR = '<->', + PROCEDURE = dist +); + +COMMENT ON OPERATOR <-> (spoint, sline) IS + 'returns the distance between spherical line and spherical point'; From d8470f8972864e556010b0fe3ed448c6a884db29 Mon Sep 17 00:00:00 2001 From: ggnmstr Date: Thu, 27 Jul 2023 16:58:33 +0700 Subject: [PATCH 12/87] Add spoly_is_convex --- doc/functions.sgm | 27 ++++++++++ expected/init_test.out.in | 14 ++--- expected/init_test_healpix.out.in | 4 +- expected/poly.out | 25 +++++++++ pgs_polygon.sql.in | 14 +++++ sql/poly.sql | 6 +++ src/polygon.c | 52 +++++++++++++++++++ src/polygon.h | 5 ++ .../pg_sphere--1.2.3--1.3.0.sql.in | 9 ++++ 9 files changed, 147 insertions(+), 9 deletions(-) diff --git a/doc/functions.sgm b/doc/functions.sgm index 5cdc3aa..d5bb457 100644 --- a/doc/functions.sgm +++ b/doc/functions.sgm @@ -618,6 +618,33 @@ + + + Codestin Search App + + Returns true if the specified spherical polygon is convex. + Returns false otherwise. + + + + spoly_is_convex + spoly polygon + + + + Codestin Search App + + SELECT spoly_is_convex( spoly '{(0,0),(1,0),(1,1),(1,2)}' );]]> + + + + + + + + diff --git a/expected/init_test.out.in b/expected/init_test.out.in index b5ace10..6fbd06b 100644 --- a/expected/init_test.out.in +++ b/expected/init_test.out.in @@ -24,12 +24,12 @@ psql:pg_sphere.test.sql:158: NOTICE: argument type spath is only a shell psql:pg_sphere.test.sql:177: NOTICE: type "sbox" is not yet defined DETAIL: Creating a shell type definition. psql:pg_sphere.test.sql:184: NOTICE: argument type sbox is only a shell -psql:pg_sphere.test.sql:8644: NOTICE: type "spherekey" is not yet defined +psql:pg_sphere.test.sql:8658: NOTICE: type "spherekey" is not yet defined DETAIL: Creating a shell type definition. -psql:pg_sphere.test.sql:8651: NOTICE: argument type spherekey is only a shell -psql:pg_sphere.test.sql:8665: NOTICE: type "pointkey" is not yet defined +psql:pg_sphere.test.sql:8665: NOTICE: argument type spherekey is only a shell +psql:pg_sphere.test.sql:8679: NOTICE: type "pointkey" is not yet defined DETAIL: Creating a shell type definition. -psql:pg_sphere.test.sql:8672: NOTICE: argument type pointkey is only a shell -psql:pg_sphere.test.sql:8678: NOTICE: argument type pointkey is only a shell -psql:pg_sphere.test.sql:8684: NOTICE: argument type pointkey is only a shell -psql:pg_sphere.test.sql:8690: NOTICE: argument type pointkey is only a shell +psql:pg_sphere.test.sql:8686: NOTICE: argument type pointkey is only a shell +psql:pg_sphere.test.sql:8692: NOTICE: argument type pointkey is only a shell +psql:pg_sphere.test.sql:8698: NOTICE: argument type pointkey is only a shell +psql:pg_sphere.test.sql:8704: NOTICE: argument type pointkey is only a shell diff --git a/expected/init_test_healpix.out.in b/expected/init_test_healpix.out.in index 3b0cfbd..4195603 100644 --- a/expected/init_test_healpix.out.in +++ b/expected/init_test_healpix.out.in @@ -1,2 +1,2 @@ -psql:pg_sphere.test.sql:9257: NOTICE: return type smoc is only a shell -psql:pg_sphere.test.sql:9263: NOTICE: argument type smoc is only a shell +psql:pg_sphere.test.sql:9271: NOTICE: return type smoc is only a shell +psql:pg_sphere.test.sql:9277: NOTICE: argument type smoc is only a shell diff --git a/expected/poly.out b/expected/poly.out index 9fcd234..50e510e 100644 --- a/expected/poly.out +++ b/expected/poly.out @@ -1799,3 +1799,28 @@ SELECT spoly_as_array( spoly '{(0,0),(1,0),(1,1)}' ); {"(0 , 0)","(1 , 0)","(1 , 1)"} (1 row) +-- spoly is convex +SELECT spoly_is_convex(spoly'{(53d 45m 35.0s, 37d 6m 30.0s), (52d 21m 36.0s, 41d 36m 7.0s), (54d 14m 18.0s, 45d 1m 35.0s), (51d 23m 3.0s, 45d 22m 49.0s), (51d 2m 12.0s, 41d 52m 1.0s), (50d 41m 47.0s, 38d 22m 0s) }'); + spoly_is_convex +----------------- + f +(1 row) + +SELECT spoly_is_convex(spoly'{(12d,32d),(34d,12d),(59d,21d),(69d,21d)}'); + spoly_is_convex +----------------- + f +(1 row) + +SELECT spoly_is_convex(spoly'{(12d,32d),(34d,12d),(59d,21d),(34d,40d)}'); + spoly_is_convex +----------------- + t +(1 row) + +SELECT spoly_is_convex(NULL); + spoly_is_convex +----------------- + f +(1 row) + diff --git a/pgs_polygon.sql.in b/pgs_polygon.sql.in index 5db17c6..fdd4277 100644 --- a/pgs_polygon.sql.in +++ b/pgs_polygon.sql.in @@ -973,3 +973,17 @@ CREATE AGGREGATE spoly ( stype = spoly, finalfunc = spoly_add_points_fin_aggr ); + + +-- +-- polygon is convex +-- + +CREATE FUNCTION spoly_is_convex(spoly) + RETURNS BOOL + AS 'MODULE_PATHNAME', 'spherepoly_is_convex' + LANGUAGE 'c' + IMMUTABLE PARALLEL SAFE; + +COMMENT ON FUNCTION spoly_is_convex(spoly) IS + 'true if spherical polygon is convex'; diff --git a/sql/poly.sql b/sql/poly.sql index b185e50..2281aba 100644 --- a/sql/poly.sql +++ b/sql/poly.sql @@ -616,3 +616,9 @@ SELECT spoint( spoly '{(0,0),(1,0),(1,1)}', 1 ); SELECT spoint( spoly '{(0,0),(1,0),(1,1)}', 2 ); SELECT spoint( spoly '{(0,0),(1,0),(1,1)}', 3 ); SELECT spoly_as_array( spoly '{(0,0),(1,0),(1,1)}' ); + +-- spoly is convex +SELECT spoly_is_convex(spoly'{(53d 45m 35.0s, 37d 6m 30.0s), (52d 21m 36.0s, 41d 36m 7.0s), (54d 14m 18.0s, 45d 1m 35.0s), (51d 23m 3.0s, 45d 22m 49.0s), (51d 2m 12.0s, 41d 52m 1.0s), (50d 41m 47.0s, 38d 22m 0s) }'); +SELECT spoly_is_convex(spoly'{(12d,32d),(34d,12d),(59d,21d),(69d,21d)}'); +SELECT spoly_is_convex(spoly'{(12d,32d),(34d,12d),(59d,21d),(34d,40d)}'); +SELECT spoly_is_convex(NULL); diff --git a/src/polygon.c b/src/polygon.c index 54eb2a6..57786b8 100644 --- a/src/polygon.c +++ b/src/polygon.c @@ -59,6 +59,7 @@ PG_FUNCTION_INFO_V1(spheretrans_poly); PG_FUNCTION_INFO_V1(spheretrans_poly_inverse); PG_FUNCTION_INFO_V1(spherepoly_add_point); PG_FUNCTION_INFO_V1(spherepoly_add_points_finalize); +PG_FUNCTION_INFO_V1(spherepoly_is_convex); /* @@ -1531,3 +1532,54 @@ spherepoly_add_points_finalize(PG_FUNCTION_ARGS) } PG_RETURN_POINTER(poly); } + + +Datum +spherepoly_is_convex(PG_FUNCTION_ARGS) +{ + Vector3D u, + v, + vsu, + wsv, + crs; + int32 i; + float8 cur = 0.0, + prev = 0.0; + SPOLY *poly = (SPOLY *) PG_GETARG_POINTER(0); + + if (poly == NULL) + { + PG_RETURN_BOOL(false); + } + + poly = PG_GETARG_SPOLY(0); + if (poly->npts == 3) + { + PG_RETURN_BOOL(true); + } + + for (i = 0; i < poly->npts; i++) + { + const int j = (i - 1 + poly->npts) % poly->npts; + const int k = (i + 1) % poly->npts; + + spoint_vector3d(&u, &poly->p[i]); + spoint_vector3d(&v, &poly->p[j]); + spoint_vector3d(&vsu, &poly->p[j]); + spoint_vector3d(&wsv, &poly->p[k]); + + vector3d_addwithscalar(&vsu, -1, &u); + vector3d_addwithscalar(&wsv, -1, &v); + + vector3d_cross(&crs, &vsu, &wsv); + + cur = vector3d_scalar(&crs, &v); + if (cur * prev < 0) + { + PG_RETURN_BOOL(false); + } + prev = cur; + } + + PG_RETURN_BOOL(true); +} diff --git a/src/polygon.h b/src/polygon.h index c7daf13..9d47f40 100644 --- a/src/polygon.h +++ b/src/polygon.h @@ -358,4 +358,9 @@ Datum spherepoly_add_points_finalize(PG_FUNCTION_ARGS); */ Datum spherepoly_get_array(PG_FUNCTION_ARGS); +/* + * Checks whether a polygon is convex + */ +Datum spherepoly_is_convex(PG_FUNCTION_ARGS); + #endif diff --git a/upgrade_scripts/pg_sphere--1.2.3--1.3.0.sql.in b/upgrade_scripts/pg_sphere--1.2.3--1.3.0.sql.in index 6eb9460..6309349 100644 --- a/upgrade_scripts/pg_sphere--1.2.3--1.3.0.sql.in +++ b/upgrade_scripts/pg_sphere--1.2.3--1.3.0.sql.in @@ -93,3 +93,12 @@ CREATE OPERATOR <-> ( COMMENT ON OPERATOR <-> (spoint, sline) IS 'returns the distance between spherical line and spherical point'; + +CREATE FUNCTION spoly_is_convex(spoly) + RETURNS BOOL + AS 'MODULE_PATHNAME', 'spherepoly_is_convex' + LANGUAGE 'c' + IMMUTABLE PARALLEL SAFE; + +COMMENT ON FUNCTION spoly_is_convex(spoly) IS + 'true if spherical polygon is convex'; From 0becb8b2d7d1baf622fddc0045eb6346a60be1fb Mon Sep 17 00:00:00 2001 From: Vitaly Davydov Date: Sun, 13 Aug 2023 23:21:00 +0300 Subject: [PATCH 13/87] Fix warnings in output.c --- src/output.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/output.c b/src/output.c index 60e7464..7598d46 100644 --- a/src/output.c +++ b/src/output.c @@ -21,7 +21,11 @@ * Default is radians. */ static unsigned char sphere_output = OUTPUT_RAD; -static short int sphere_output_precision = DBL_DIG; + +/* + * Defines the precision of floating point values in output. + */ +static int sphere_output_precision = DBL_DIG; PG_FUNCTION_INFO_V1(set_sphere_output); PG_FUNCTION_INFO_V1(spherepoint_out); From e10a8bb84a661be7b469ea83c09aab250e48ef28 Mon Sep 17 00:00:00 2001 From: Christoph Berg Date: Mon, 31 Jul 2023 16:20:12 +0000 Subject: [PATCH 14/87] Fix compatibility with PG16 * Replace Abs with fabs * Remove DatumGetPointer where PG16 got stricter typechecking * Annotate expected/moc100 output files with PG major and architecture bits they are meant for * Add expected output files for moc100 on PG16 --- expected/moc100.out | 11 ++ expected/moc100_1.out | 11 ++ expected/moc100_2.out | 11 ++ expected/moc100_3.out | 11 ++ expected/moc100_4.out | 309 ++++++++++++++++++++++++++++++++++++++++++ expected/moc100_5.out | 309 ++++++++++++++++++++++++++++++++++++++++++ sql/moc100.sql | 11 ++ src/ellipse.c | 4 +- src/gist.c | 4 +- src/path.h | 2 +- src/polygon.h | 2 +- 11 files changed, 679 insertions(+), 6 deletions(-) create mode 100644 expected/moc100_4.out create mode 100644 expected/moc100_5.out diff --git a/expected/moc100.out b/expected/moc100.out index dfe0399..51d668b 100644 --- a/expected/moc100.out +++ b/expected/moc100.out @@ -1,3 +1,14 @@ +\set ECHO none + outputfile_for_majorversion +----------------------------- + 10, 11, 12 +(1 row) + + outputfile_for_arch_bits +-------------------------- + 64-bit +(1 row) + CREATE TABLE moc100 ( ivoid text, coverage smoc, diff --git a/expected/moc100_1.out b/expected/moc100_1.out index 648d7c7..c7d6255 100644 --- a/expected/moc100_1.out +++ b/expected/moc100_1.out @@ -1,3 +1,14 @@ +\set ECHO none + outputfile_for_majorversion +----------------------------- + 10, 11, 12 +(1 row) + + outputfile_for_arch_bits +-------------------------- + 32-bit +(1 row) + CREATE TABLE moc100 ( ivoid text, coverage smoc, diff --git a/expected/moc100_2.out b/expected/moc100_2.out index e19ec64..0f511a8 100644 --- a/expected/moc100_2.out +++ b/expected/moc100_2.out @@ -1,3 +1,14 @@ +\set ECHO none + outputfile_for_majorversion +----------------------------- + 13, 14, 15 +(1 row) + + outputfile_for_arch_bits +-------------------------- + 64-bit +(1 row) + CREATE TABLE moc100 ( ivoid text, coverage smoc, diff --git a/expected/moc100_3.out b/expected/moc100_3.out index 2f85349..c650501 100644 --- a/expected/moc100_3.out +++ b/expected/moc100_3.out @@ -1,3 +1,14 @@ +\set ECHO none + outputfile_for_majorversion +----------------------------- + 13, 14, 15 +(1 row) + + outputfile_for_arch_bits +-------------------------- + 32-bit +(1 row) + CREATE TABLE moc100 ( ivoid text, coverage smoc, diff --git a/expected/moc100_4.out b/expected/moc100_4.out new file mode 100644 index 0000000..13e2306 --- /dev/null +++ b/expected/moc100_4.out @@ -0,0 +1,309 @@ +\set ECHO none + outputfile_for_majorversion +----------------------------- + 16+ +(1 row) + + outputfile_for_arch_bits +-------------------------- + 64-bit +(1 row) + +CREATE TABLE moc100 ( + ivoid text, + coverage smoc, + ref_system_name text +); +COPY moc100 FROM STDIN; +CREATE INDEX ON moc100 USING GIN (coverage); +SELECT ivoid FROM moc100 WHERE coverage && '4/0' ORDER BY ivoid; + ivoid +------------------------------------------ + ivo://byu.arvo/dfbsspec/q/getssa + ivo://cadc.nrc.ca/archive/cfht + ivo://cadc.nrc.ca/archive/hst + ivo://cds.vizier/b/assocdata + ivo://cds.vizier/b/swift + ivo://cds.vizier/i/241 + ivo://cds.vizier/iv/12 + ivo://cds.vizier/ix/13 + ivo://cds.vizier/j/a+a/316/147 + ivo://cds.vizier/j/a+as/105/311 + ivo://cds.vizier/j/a+as/122/235 + ivo://chivo/gaia/q/dr1 + ivo://chivo/openngc/q/data + ivo://cxc.harvard.edu/csc + ivo://irsa.ipac/2mass/catalog/psc + ivo://irsa.ipac/2mass/catalog/xsc + ivo://irsa.ipac/2mass/images/asky-ql + ivo://irsa.ipac/cosmos/images + ivo://irsa.ipac/iras/images/issa + ivo://irsa.ipac/mast/scrapbook + ivo://irsa.ipac/spitzer/images/swire + ivo://mssl.ucl.ac.uk/xmmsuss_dsa/xmmsuss + ivo://ned.ipac/sia + ivo://ned.ipac/tap + ivo://svo.cab/cat/gbs + ivo://svo.cab/cat/uves + ivo://svo.cab/cat/xshooter + ivo://vopdc.iap/fss + ivo://vopdc.obspm/imcce/m4ast + ivo://vopdc.obspm/imcce/miriade + ivo://vopdc.obspm/imcce/skybot + ivo://vopdc.obspm/lesia/bestars/besc + ivo://vopdc.obspm/lesia/bestars/bess + ivo://vopdc.obspm/luth/exoplanet + ivo://vopdc.obspm/luth/hess +(35 rows) + +EXPLAIN (ANALYZE, BUFFERS, TIMING OFF, SUMMARY OFF) + SELECT * FROM moc100 WHERE coverage && '0/'; + QUERY PLAN +---------------------------------------------------------------------------------------------------------- + Bitmap Heap Scan on moc100 (cost=0.00..4.01 rows=1 width=96) (actual rows=0 loops=1) + Recheck Cond: (coverage && '0/'::smoc) + -> Bitmap Index Scan on moc100_coverage_idx (cost=0.00..0.00 rows=1 width=0) (actual rows=0 loops=1) + Index Cond: (coverage && '0/'::smoc) + Planning: + Buffers: shared hit=5 +(6 rows) + +EXPLAIN (ANALYZE, BUFFERS, TIMING OFF, SUMMARY OFF) + SELECT * FROM moc100 WHERE coverage && '4/0'; + QUERY PLAN +-------------------------------------------------------------------------------- + Seq Scan on moc100 (cost=0.00..6.26 rows=1 width=96) (actual rows=35 loops=1) + Filter: (coverage && '4/0'::smoc) + Rows Removed by Filter: 66 + Buffers: shared hit=114 + Planning: + Buffers: shared hit=1 +(6 rows) + +EXPLAIN (ANALYZE, BUFFERS, TIMING OFF, SUMMARY OFF) + SELECT * FROM moc100 WHERE coverage = '0/0-11'; + QUERY PLAN +-------------------------------------------------------------------------------- + Seq Scan on moc100 (cost=0.00..6.26 rows=1 width=96) (actual rows=23 loops=1) + Filter: (coverage = '0/0-11'::smoc) + Rows Removed by Filter: 78 + Buffers: shared hit=59 + Planning: + Buffers: shared hit=4 +(6 rows) + +EXPLAIN (ANALYZE, BUFFERS, TIMING OFF, SUMMARY OFF) + SELECT * FROM moc100 WHERE coverage = '6/43225,43227'; + QUERY PLAN +------------------------------------------------------------------------------- + Seq Scan on moc100 (cost=0.00..6.26 rows=1 width=96) (actual rows=1 loops=1) + Filter: (coverage = '6/43225 43227'::smoc) + Rows Removed by Filter: 100 + Buffers: shared hit=59 + Planning: + Buffers: shared hit=1 +(6 rows) + +EXPLAIN (ANALYZE, BUFFERS, TIMING OFF, SUMMARY OFF) + SELECT * FROM moc100 WHERE coverage = '0/'; + QUERY PLAN +------------------------------------------------------------------------------- + Seq Scan on moc100 (cost=0.00..6.26 rows=1 width=96) (actual rows=1 loops=1) + Filter: (coverage = '0/'::smoc) + Rows Removed by Filter: 100 + Buffers: shared hit=59 + Planning: + Buffers: shared hit=1 +(6 rows) + +EXPLAIN (ANALYZE, BUFFERS, TIMING OFF, SUMMARY OFF) + SELECT * FROM moc100 WHERE coverage <> '0/0-11'; + QUERY PLAN +---------------------------------------------------------------------------------- + Seq Scan on moc100 (cost=0.00..6.26 rows=100 width=96) (actual rows=78 loops=1) + Filter: (coverage <> '0/0-11'::smoc) + Rows Removed by Filter: 23 + Buffers: shared hit=59 + Planning: + Buffers: shared hit=4 +(6 rows) + +EXPLAIN (ANALYZE, BUFFERS, TIMING OFF, SUMMARY OFF) + SELECT * FROM moc100 WHERE coverage <> '6/43225,43227'; + QUERY PLAN +----------------------------------------------------------------------------------- + Seq Scan on moc100 (cost=0.00..6.26 rows=100 width=96) (actual rows=100 loops=1) + Filter: (coverage <> '6/43225 43227'::smoc) + Rows Removed by Filter: 1 + Buffers: shared hit=59 + Planning: + Buffers: shared hit=1 +(6 rows) + +EXPLAIN (ANALYZE, BUFFERS, TIMING OFF, SUMMARY OFF) + SELECT * FROM moc100 WHERE coverage <> '0/'; + QUERY PLAN +----------------------------------------------------------------------------------- + Seq Scan on moc100 (cost=0.00..6.26 rows=100 width=96) (actual rows=100 loops=1) + Filter: (coverage <> '0/'::smoc) + Rows Removed by Filter: 1 + Buffers: shared hit=59 + Planning: + Buffers: shared hit=1 +(6 rows) + +SET enable_seqscan = off; +EXPLAIN (ANALYZE, BUFFERS, TIMING OFF, SUMMARY OFF) + SELECT * FROM moc100 WHERE coverage && '4/0'; + QUERY PLAN +------------------------------------------------------------------------------------------------------------ + Bitmap Heap Scan on moc100 (cost=38.92..42.93 rows=1 width=96) (actual rows=35 loops=1) + Recheck Cond: (coverage && '4/0'::smoc) + Heap Blocks: exact=5 + Buffers: shared hit=85 + -> Bitmap Index Scan on moc100_coverage_idx (cost=0.00..38.92 rows=1 width=0) (actual rows=35 loops=1) + Index Cond: (coverage && '4/0'::smoc) + Buffers: shared hit=9 + Planning: + Buffers: shared hit=1 +(9 rows) + +EXPLAIN (ANALYZE, BUFFERS, TIMING OFF, SUMMARY OFF) + SELECT * FROM moc100 WHERE coverage <@ '4/0'; + QUERY PLAN +------------------------------------------------------------------------------------------------------------ + Bitmap Heap Scan on moc100 (cost=47.61..51.63 rows=1 width=96) (actual rows=1 loops=1) + Recheck Cond: (coverage <@ '4/0'::smoc) + Rows Removed by Index Recheck: 35 + Heap Blocks: exact=5 + Buffers: shared hit=33 + -> Bitmap Index Scan on moc100_coverage_idx (cost=0.00..47.61 rows=1 width=0) (actual rows=36 loops=1) + Index Cond: (coverage <@ '4/0'::smoc) + Buffers: shared hit=12 + Planning: + Buffers: shared hit=4 +(10 rows) + +EXPLAIN (ANALYZE, BUFFERS, TIMING OFF, SUMMARY OFF) + SELECT * FROM moc100 WHERE coverage @> '4/0'; + QUERY PLAN +------------------------------------------------------------------------------------------------------------ + Bitmap Heap Scan on moc100 (cost=38.92..42.93 rows=1 width=96) (actual rows=28 loops=1) + Recheck Cond: (coverage @> '4/0'::smoc) + Rows Removed by Index Recheck: 1 + Heap Blocks: exact=4 + Buffers: shared hit=36 + -> Bitmap Index Scan on moc100_coverage_idx (cost=0.00..38.92 rows=1 width=0) (actual rows=29 loops=1) + Index Cond: (coverage @> '4/0'::smoc) + Buffers: shared hit=9 + Planning: + Buffers: shared hit=4 +(10 rows) + +EXPLAIN (ANALYZE, BUFFERS, TIMING OFF, SUMMARY OFF) + SELECT * FROM moc100 WHERE coverage = '0/0-11'; + QUERY PLAN +---------------------------------------------------------------------------------------------------------------- + Bitmap Heap Scan on moc100 (cost=106879.01..106883.02 rows=1 width=96) (actual rows=23 loops=1) + Recheck Cond: (coverage = '0/0-11'::smoc) + Rows Removed by Index Recheck: 1 + Heap Blocks: exact=2 + Buffers: shared hit=24581 + -> Bitmap Index Scan on moc100_coverage_idx (cost=0.00..106879.01 rows=1 width=0) (actual rows=24 loops=1) + Index Cond: (coverage = '0/0-11'::smoc) + Buffers: shared hit=24577 + Planning: + Buffers: shared hit=1 + JIT: + Functions: 2 + Options: Inlining false, Optimization false, Expressions true, Deforming true +(13 rows) + +EXPLAIN (ANALYZE, BUFFERS, TIMING OFF, SUMMARY OFF) + SELECT * FROM moc100 WHERE coverage = '6/43225,43227'; + QUERY PLAN +------------------------------------------------------------------------------------------------------------ + Bitmap Heap Scan on moc100 (cost=12.83..16.84 rows=1 width=96) (actual rows=1 loops=1) + Recheck Cond: (coverage = '6/43225 43227'::smoc) + Rows Removed by Index Recheck: 28 + Heap Blocks: exact=3 + Buffers: shared hit=12 + -> Bitmap Index Scan on moc100_coverage_idx (cost=0.00..12.83 rows=1 width=0) (actual rows=29 loops=1) + Index Cond: (coverage = '6/43225 43227'::smoc) + Buffers: shared hit=3 + Planning: + Buffers: shared hit=1 +(10 rows) + +EXPLAIN (ANALYZE, BUFFERS, TIMING OFF, SUMMARY OFF) + SELECT * FROM moc100 WHERE coverage = '0/'; + QUERY PLAN +----------------------------------------------------------------------------------------------------------- + Bitmap Heap Scan on moc100 (cost=12.83..16.84 rows=1 width=96) (actual rows=1 loops=1) + Recheck Cond: (coverage = '0/'::smoc) + Heap Blocks: exact=1 + Buffers: shared hit=5 + -> Bitmap Index Scan on moc100_coverage_idx (cost=0.00..12.83 rows=1 width=0) (actual rows=1 loops=1) + Index Cond: (coverage = '0/'::smoc) + Buffers: shared hit=4 + Planning: + Buffers: shared hit=1 +(9 rows) + +EXPLAIN (ANALYZE, BUFFERS, TIMING OFF, SUMMARY OFF) + SELECT * FROM moc100 WHERE coverage <> '0/0-11'; + QUERY PLAN +------------------------------------------------------------------------------------------------------------------- + Bitmap Heap Scan on moc100 (cost=106888.23..106894.48 rows=100 width=96) (actual rows=78 loops=1) + Recheck Cond: (coverage <> '0/0-11'::smoc) + Rows Removed by Index Recheck: 23 + Heap Blocks: exact=5 + Buffers: shared hit=24821 + -> Bitmap Index Scan on moc100_coverage_idx (cost=0.00..106888.20 rows=100 width=0) (actual rows=101 loops=1) + Index Cond: (coverage <> '0/0-11'::smoc) + Buffers: shared hit=24762 + Planning: + Buffers: shared hit=1 + JIT: + Functions: 2 + Options: Inlining false, Optimization false, Expressions true, Deforming true +(13 rows) + +EXPLAIN (ANALYZE, BUFFERS, TIMING OFF, SUMMARY OFF) + SELECT * FROM moc100 WHERE coverage <> '6/43225,43227'; + QUERY PLAN +------------------------------------------------------------------------------------------------------------------- + Bitmap Heap Scan on moc100 (cost=106888.23..106894.48 rows=100 width=96) (actual rows=100 loops=1) + Recheck Cond: (coverage <> '6/43225 43227'::smoc) + Rows Removed by Index Recheck: 1 + Heap Blocks: exact=5 + Buffers: shared hit=247 + -> Bitmap Index Scan on moc100_coverage_idx (cost=0.00..106888.20 rows=100 width=0) (actual rows=101 loops=1) + Index Cond: (coverage <> '6/43225 43227'::smoc) + Buffers: shared hit=188 + Planning: + Buffers: shared hit=1 + JIT: + Functions: 2 + Options: Inlining false, Optimization false, Expressions true, Deforming true +(13 rows) + +EXPLAIN (ANALYZE, BUFFERS, TIMING OFF, SUMMARY OFF) + SELECT * FROM moc100 WHERE coverage <> '0/'; + QUERY PLAN +------------------------------------------------------------------------------------------------------------------- + Bitmap Heap Scan on moc100 (cost=106888.23..106894.48 rows=100 width=96) (actual rows=100 loops=1) + Recheck Cond: (coverage <> '0/'::smoc) + Rows Removed by Index Recheck: 1 + Heap Blocks: exact=5 + Buffers: shared hit=245 + -> Bitmap Index Scan on moc100_coverage_idx (cost=0.00..106888.20 rows=100 width=0) (actual rows=101 loops=1) + Index Cond: (coverage <> '0/'::smoc) + Buffers: shared hit=186 + Planning: + Buffers: shared hit=1 + JIT: + Functions: 2 + Options: Inlining false, Optimization false, Expressions true, Deforming true +(13 rows) + diff --git a/expected/moc100_5.out b/expected/moc100_5.out new file mode 100644 index 0000000..3fb98a4 --- /dev/null +++ b/expected/moc100_5.out @@ -0,0 +1,309 @@ +\set ECHO none + outputfile_for_majorversion +----------------------------- + 16+ +(1 row) + + outputfile_for_arch_bits +-------------------------- + 32-bit +(1 row) + +CREATE TABLE moc100 ( + ivoid text, + coverage smoc, + ref_system_name text +); +COPY moc100 FROM STDIN; +CREATE INDEX ON moc100 USING GIN (coverage); +SELECT ivoid FROM moc100 WHERE coverage && '4/0' ORDER BY ivoid; + ivoid +------------------------------------------ + ivo://byu.arvo/dfbsspec/q/getssa + ivo://cadc.nrc.ca/archive/cfht + ivo://cadc.nrc.ca/archive/hst + ivo://cds.vizier/b/assocdata + ivo://cds.vizier/b/swift + ivo://cds.vizier/i/241 + ivo://cds.vizier/iv/12 + ivo://cds.vizier/ix/13 + ivo://cds.vizier/j/a+a/316/147 + ivo://cds.vizier/j/a+as/105/311 + ivo://cds.vizier/j/a+as/122/235 + ivo://chivo/gaia/q/dr1 + ivo://chivo/openngc/q/data + ivo://cxc.harvard.edu/csc + ivo://irsa.ipac/2mass/catalog/psc + ivo://irsa.ipac/2mass/catalog/xsc + ivo://irsa.ipac/2mass/images/asky-ql + ivo://irsa.ipac/cosmos/images + ivo://irsa.ipac/iras/images/issa + ivo://irsa.ipac/mast/scrapbook + ivo://irsa.ipac/spitzer/images/swire + ivo://mssl.ucl.ac.uk/xmmsuss_dsa/xmmsuss + ivo://ned.ipac/sia + ivo://ned.ipac/tap + ivo://svo.cab/cat/gbs + ivo://svo.cab/cat/uves + ivo://svo.cab/cat/xshooter + ivo://vopdc.iap/fss + ivo://vopdc.obspm/imcce/m4ast + ivo://vopdc.obspm/imcce/miriade + ivo://vopdc.obspm/imcce/skybot + ivo://vopdc.obspm/lesia/bestars/besc + ivo://vopdc.obspm/lesia/bestars/bess + ivo://vopdc.obspm/luth/exoplanet + ivo://vopdc.obspm/luth/hess +(35 rows) + +EXPLAIN (ANALYZE, BUFFERS, TIMING OFF, SUMMARY OFF) + SELECT * FROM moc100 WHERE coverage && '0/'; + QUERY PLAN +---------------------------------------------------------------------------------------------------------- + Bitmap Heap Scan on moc100 (cost=0.00..4.01 rows=1 width=96) (actual rows=0 loops=1) + Recheck Cond: (coverage && '0/'::smoc) + -> Bitmap Index Scan on moc100_coverage_idx (cost=0.00..0.00 rows=1 width=0) (actual rows=0 loops=1) + Index Cond: (coverage && '0/'::smoc) + Planning: + Buffers: shared hit=5 +(6 rows) + +EXPLAIN (ANALYZE, BUFFERS, TIMING OFF, SUMMARY OFF) + SELECT * FROM moc100 WHERE coverage && '4/0'; + QUERY PLAN +-------------------------------------------------------------------------------- + Seq Scan on moc100 (cost=0.00..6.26 rows=1 width=96) (actual rows=35 loops=1) + Filter: (coverage && '4/0'::smoc) + Rows Removed by Filter: 66 + Buffers: shared hit=115 + Planning: + Buffers: shared hit=1 +(6 rows) + +EXPLAIN (ANALYZE, BUFFERS, TIMING OFF, SUMMARY OFF) + SELECT * FROM moc100 WHERE coverage = '0/0-11'; + QUERY PLAN +-------------------------------------------------------------------------------- + Seq Scan on moc100 (cost=0.00..6.26 rows=1 width=96) (actual rows=23 loops=1) + Filter: (coverage = '0/0-11'::smoc) + Rows Removed by Filter: 78 + Buffers: shared hit=59 + Planning: + Buffers: shared hit=4 +(6 rows) + +EXPLAIN (ANALYZE, BUFFERS, TIMING OFF, SUMMARY OFF) + SELECT * FROM moc100 WHERE coverage = '6/43225,43227'; + QUERY PLAN +------------------------------------------------------------------------------- + Seq Scan on moc100 (cost=0.00..6.26 rows=1 width=96) (actual rows=1 loops=1) + Filter: (coverage = '6/43225 43227'::smoc) + Rows Removed by Filter: 100 + Buffers: shared hit=59 + Planning: + Buffers: shared hit=1 +(6 rows) + +EXPLAIN (ANALYZE, BUFFERS, TIMING OFF, SUMMARY OFF) + SELECT * FROM moc100 WHERE coverage = '0/'; + QUERY PLAN +------------------------------------------------------------------------------- + Seq Scan on moc100 (cost=0.00..6.26 rows=1 width=96) (actual rows=1 loops=1) + Filter: (coverage = '0/'::smoc) + Rows Removed by Filter: 100 + Buffers: shared hit=59 + Planning: + Buffers: shared hit=1 +(6 rows) + +EXPLAIN (ANALYZE, BUFFERS, TIMING OFF, SUMMARY OFF) + SELECT * FROM moc100 WHERE coverage <> '0/0-11'; + QUERY PLAN +---------------------------------------------------------------------------------- + Seq Scan on moc100 (cost=0.00..6.26 rows=100 width=96) (actual rows=78 loops=1) + Filter: (coverage <> '0/0-11'::smoc) + Rows Removed by Filter: 23 + Buffers: shared hit=59 + Planning: + Buffers: shared hit=4 +(6 rows) + +EXPLAIN (ANALYZE, BUFFERS, TIMING OFF, SUMMARY OFF) + SELECT * FROM moc100 WHERE coverage <> '6/43225,43227'; + QUERY PLAN +----------------------------------------------------------------------------------- + Seq Scan on moc100 (cost=0.00..6.26 rows=100 width=96) (actual rows=100 loops=1) + Filter: (coverage <> '6/43225 43227'::smoc) + Rows Removed by Filter: 1 + Buffers: shared hit=59 + Planning: + Buffers: shared hit=1 +(6 rows) + +EXPLAIN (ANALYZE, BUFFERS, TIMING OFF, SUMMARY OFF) + SELECT * FROM moc100 WHERE coverage <> '0/'; + QUERY PLAN +----------------------------------------------------------------------------------- + Seq Scan on moc100 (cost=0.00..6.26 rows=100 width=96) (actual rows=100 loops=1) + Filter: (coverage <> '0/'::smoc) + Rows Removed by Filter: 1 + Buffers: shared hit=59 + Planning: + Buffers: shared hit=1 +(6 rows) + +SET enable_seqscan = off; +EXPLAIN (ANALYZE, BUFFERS, TIMING OFF, SUMMARY OFF) + SELECT * FROM moc100 WHERE coverage && '4/0'; + QUERY PLAN +------------------------------------------------------------------------------------------------------------ + Bitmap Heap Scan on moc100 (cost=38.92..42.93 rows=1 width=96) (actual rows=35 loops=1) + Recheck Cond: (coverage && '4/0'::smoc) + Heap Blocks: exact=5 + Buffers: shared hit=86 + -> Bitmap Index Scan on moc100_coverage_idx (cost=0.00..38.92 rows=1 width=0) (actual rows=35 loops=1) + Index Cond: (coverage && '4/0'::smoc) + Buffers: shared hit=9 + Planning: + Buffers: shared hit=1 +(9 rows) + +EXPLAIN (ANALYZE, BUFFERS, TIMING OFF, SUMMARY OFF) + SELECT * FROM moc100 WHERE coverage <@ '4/0'; + QUERY PLAN +------------------------------------------------------------------------------------------------------------ + Bitmap Heap Scan on moc100 (cost=47.61..51.63 rows=1 width=96) (actual rows=1 loops=1) + Recheck Cond: (coverage <@ '4/0'::smoc) + Rows Removed by Index Recheck: 35 + Heap Blocks: exact=5 + Buffers: shared hit=33 + -> Bitmap Index Scan on moc100_coverage_idx (cost=0.00..47.61 rows=1 width=0) (actual rows=36 loops=1) + Index Cond: (coverage <@ '4/0'::smoc) + Buffers: shared hit=12 + Planning: + Buffers: shared hit=4 +(10 rows) + +EXPLAIN (ANALYZE, BUFFERS, TIMING OFF, SUMMARY OFF) + SELECT * FROM moc100 WHERE coverage @> '4/0'; + QUERY PLAN +------------------------------------------------------------------------------------------------------------ + Bitmap Heap Scan on moc100 (cost=38.92..42.93 rows=1 width=96) (actual rows=28 loops=1) + Recheck Cond: (coverage @> '4/0'::smoc) + Rows Removed by Index Recheck: 1 + Heap Blocks: exact=4 + Buffers: shared hit=36 + -> Bitmap Index Scan on moc100_coverage_idx (cost=0.00..38.92 rows=1 width=0) (actual rows=29 loops=1) + Index Cond: (coverage @> '4/0'::smoc) + Buffers: shared hit=9 + Planning: + Buffers: shared hit=4 +(10 rows) + +EXPLAIN (ANALYZE, BUFFERS, TIMING OFF, SUMMARY OFF) + SELECT * FROM moc100 WHERE coverage = '0/0-11'; + QUERY PLAN +---------------------------------------------------------------------------------------------------------------- + Bitmap Heap Scan on moc100 (cost=106879.01..106883.02 rows=1 width=96) (actual rows=23 loops=1) + Recheck Cond: (coverage = '0/0-11'::smoc) + Rows Removed by Index Recheck: 1 + Heap Blocks: exact=2 + Buffers: shared hit=24581 + -> Bitmap Index Scan on moc100_coverage_idx (cost=0.00..106879.01 rows=1 width=0) (actual rows=24 loops=1) + Index Cond: (coverage = '0/0-11'::smoc) + Buffers: shared hit=24577 + Planning: + Buffers: shared hit=1 + JIT: + Functions: 2 + Options: Inlining false, Optimization false, Expressions true, Deforming true +(13 rows) + +EXPLAIN (ANALYZE, BUFFERS, TIMING OFF, SUMMARY OFF) + SELECT * FROM moc100 WHERE coverage = '6/43225,43227'; + QUERY PLAN +------------------------------------------------------------------------------------------------------------ + Bitmap Heap Scan on moc100 (cost=12.83..16.84 rows=1 width=96) (actual rows=1 loops=1) + Recheck Cond: (coverage = '6/43225 43227'::smoc) + Rows Removed by Index Recheck: 28 + Heap Blocks: exact=3 + Buffers: shared hit=12 + -> Bitmap Index Scan on moc100_coverage_idx (cost=0.00..12.83 rows=1 width=0) (actual rows=29 loops=1) + Index Cond: (coverage = '6/43225 43227'::smoc) + Buffers: shared hit=3 + Planning: + Buffers: shared hit=1 +(10 rows) + +EXPLAIN (ANALYZE, BUFFERS, TIMING OFF, SUMMARY OFF) + SELECT * FROM moc100 WHERE coverage = '0/'; + QUERY PLAN +----------------------------------------------------------------------------------------------------------- + Bitmap Heap Scan on moc100 (cost=12.83..16.84 rows=1 width=96) (actual rows=1 loops=1) + Recheck Cond: (coverage = '0/'::smoc) + Heap Blocks: exact=1 + Buffers: shared hit=5 + -> Bitmap Index Scan on moc100_coverage_idx (cost=0.00..12.83 rows=1 width=0) (actual rows=1 loops=1) + Index Cond: (coverage = '0/'::smoc) + Buffers: shared hit=4 + Planning: + Buffers: shared hit=1 +(9 rows) + +EXPLAIN (ANALYZE, BUFFERS, TIMING OFF, SUMMARY OFF) + SELECT * FROM moc100 WHERE coverage <> '0/0-11'; + QUERY PLAN +------------------------------------------------------------------------------------------------------------------- + Bitmap Heap Scan on moc100 (cost=106888.23..106894.48 rows=100 width=96) (actual rows=78 loops=1) + Recheck Cond: (coverage <> '0/0-11'::smoc) + Rows Removed by Index Recheck: 23 + Heap Blocks: exact=5 + Buffers: shared hit=24804 + -> Bitmap Index Scan on moc100_coverage_idx (cost=0.00..106888.20 rows=100 width=0) (actual rows=101 loops=1) + Index Cond: (coverage <> '0/0-11'::smoc) + Buffers: shared hit=24745 + Planning: + Buffers: shared hit=1 + JIT: + Functions: 2 + Options: Inlining false, Optimization false, Expressions true, Deforming true +(13 rows) + +EXPLAIN (ANALYZE, BUFFERS, TIMING OFF, SUMMARY OFF) + SELECT * FROM moc100 WHERE coverage <> '6/43225,43227'; + QUERY PLAN +------------------------------------------------------------------------------------------------------------------- + Bitmap Heap Scan on moc100 (cost=106888.23..106894.48 rows=100 width=96) (actual rows=100 loops=1) + Recheck Cond: (coverage <> '6/43225 43227'::smoc) + Rows Removed by Index Recheck: 1 + Heap Blocks: exact=5 + Buffers: shared hit=230 + -> Bitmap Index Scan on moc100_coverage_idx (cost=0.00..106888.20 rows=100 width=0) (actual rows=101 loops=1) + Index Cond: (coverage <> '6/43225 43227'::smoc) + Buffers: shared hit=171 + Planning: + Buffers: shared hit=1 + JIT: + Functions: 2 + Options: Inlining false, Optimization false, Expressions true, Deforming true +(13 rows) + +EXPLAIN (ANALYZE, BUFFERS, TIMING OFF, SUMMARY OFF) + SELECT * FROM moc100 WHERE coverage <> '0/'; + QUERY PLAN +------------------------------------------------------------------------------------------------------------------- + Bitmap Heap Scan on moc100 (cost=106888.23..106894.48 rows=100 width=96) (actual rows=100 loops=1) + Recheck Cond: (coverage <> '0/'::smoc) + Rows Removed by Index Recheck: 1 + Heap Blocks: exact=5 + Buffers: shared hit=228 + -> Bitmap Index Scan on moc100_coverage_idx (cost=0.00..106888.20 rows=100 width=0) (actual rows=101 loops=1) + Index Cond: (coverage <> '0/'::smoc) + Buffers: shared hit=169 + Planning: + Buffers: shared hit=1 + JIT: + Functions: 2 + Options: Inlining false, Optimization false, Expressions true, Deforming true +(13 rows) + diff --git a/sql/moc100.sql b/sql/moc100.sql index 8195f81..8c700b1 100644 --- a/sql/moc100.sql +++ b/sql/moc100.sql @@ -1,3 +1,14 @@ +\set ECHO none +SELECT CASE + WHEN setting::int/10000 IN (10, 11, 12) THEN '10, 11, 12' -- moc100 + WHEN setting::int/10000 IN (13, 14, 15) THEN '13, 14, 15' -- moc100_2 + ELSE '16+' +END AS outputfile_for_majorversion +FROM pg_settings WHERE name = 'server_version_num'; + +SELECT (regexp_matches(version(), '..-bit'))[1] outputfile_for_arch_bits; +\set ECHO queries + CREATE TABLE moc100 ( ivoid text, coverage smoc, diff --git a/src/ellipse.c b/src/ellipse.c index a08f8be..0e535ac 100644 --- a/src/ellipse.c +++ b/src/ellipse.c @@ -426,7 +426,7 @@ sellipse_ellipse_pos(const SELLIPSE *se1, const SELLIPSE *se2) } else if (diff[0] <= diff[2] && diff[2] <= diff[1]) { - if (Abs(sp[0].lng - elng) < Abs(sp[2].lng - elng)) + if (fabs(sp[0].lng - elng) < fabs(sp[2].lng - elng)) { memcpy((void *) &sp[2], (void *) &sp[1], sizeof(SPoint)); } @@ -446,7 +446,7 @@ sellipse_ellipse_pos(const SELLIPSE *se1, const SELLIPSE *se2) } else if (diff[2] <= diff[0] && diff[0] <= diff[1]) { - if (Abs(sp[0].lng - elng) < Abs(sp[2].lng - elng)) + if (fabs(sp[0].lng - elng) < fabs(sp[2].lng - elng)) { memcpy((void *) &sp[2], (void *) &sp[1], sizeof(SPoint)); } diff --git a/src/gist.c b/src/gist.c index a142334..b3223a5 100644 --- a/src/gist.c +++ b/src/gist.c @@ -212,7 +212,7 @@ do \ { \ int32 *k = (int32 *) palloc(KEYSIZE); \ if (detoast) \ - genkey(k, (type *) DatumGetPointer(PG_DETOAST_DATUM(entry->key))); \ + genkey(k, (type *) (PG_DETOAST_DATUM(entry->key))); \ else \ genkey(k, (type *) DatumGetPointer(entry->key)); \ gistentryinit(*retval, PointerGetDatum(k), \ @@ -2202,7 +2202,7 @@ do_picksplit(Box3D *boxes, OffsetNumber maxoff, GIST_SPLITVEC *v) for (i = 0; i < commonEntriesCount; i++) { box = &boxes[i]; - commonEntries[i].delta = Abs((unionSizeBox3D(leftBox, box) - leftBoxSize) - + commonEntries[i].delta = fabs((unionSizeBox3D(leftBox, box) - leftBoxSize) - (unionSizeBox3D(rightBox, box) - rightBoxSize)); } diff --git a/src/path.h b/src/path.h index 29c687b..91e1662 100644 --- a/src/path.h +++ b/src/path.h @@ -36,7 +36,7 @@ typedef struct #define PG_GETARG_SPATH(arg) \ - ( (SPATH *) DatumGetPointer(PG_DETOAST_DATUM(PG_GETARG_DATUM(arg))) ) + ( (SPATH *) (PG_DETOAST_DATUM(PG_GETARG_DATUM(arg))) ) /* * Checks whether two paths are equal. diff --git a/src/polygon.h b/src/polygon.h index 9d47f40..d52a9c6 100644 --- a/src/polygon.h +++ b/src/polygon.h @@ -43,7 +43,7 @@ typedef struct #define PG_GETARG_SPOLY( arg ) \ - ( (SPOLY *) DatumGetPointer(PG_DETOAST_DATUM(PG_GETARG_DATUM(arg))) ) + ( (SPOLY *) (PG_DETOAST_DATUM(PG_GETARG_DATUM(arg))) ) /* * Checks whether two polygons are equal. From 70810bd9c800fbb6428875125470252e69752b43 Mon Sep 17 00:00:00 2001 From: Christoph Berg Date: Tue, 1 Aug 2023 10:32:43 +0200 Subject: [PATCH 15/87] Test PG16 on travis-ci.com --- .travis.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.travis.yml b/.travis.yml index 758f119..24df3d0 100644 --- a/.travis.yml +++ b/.travis.yml @@ -8,6 +8,7 @@ env: - PG_SUPPORTED_VERSIONS=13 - PG_SUPPORTED_VERSIONS=14 - PG_SUPPORTED_VERSIONS=15 + - PG_SUPPORTED_VERSIONS=16 language: C dist: bionic From ec4bd87c473fa7c8ab9c8b60fe664345a681a1b7 Mon Sep 17 00:00:00 2001 From: Christoph Berg Date: Tue, 1 Aug 2023 12:36:13 +0200 Subject: [PATCH 16/87] Travis: Change to run on Ubuntu focal --- .travis.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index 24df3d0..4df87d5 100644 --- a/.travis.yml +++ b/.travis.yml @@ -11,7 +11,7 @@ env: - PG_SUPPORTED_VERSIONS=16 language: C -dist: bionic +dist: focal before_install: # extra apt.pg.o.sh options added in version 204, travis currently has 199 (2019-11-27) From 56ff36668bb4df17ab12c693bf6f01bf1de67517 Mon Sep 17 00:00:00 2001 From: Vitaly Davydov Date: Fri, 25 Aug 2023 16:50:25 +0300 Subject: [PATCH 17/87] Fix sphereline_circle_pos (uninitialized memory use) --- expected/overlaps.out | 4 ++-- src/line.c | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/expected/overlaps.out b/expected/overlaps.out index 5a7625f..5b1f885 100644 --- a/expected/overlaps.out +++ b/expected/overlaps.out @@ -835,14 +835,14 @@ select 'sbox && scircle', 'f' as expected, sbox'((0d , 0d), (20d , 20d))' && sci select 'sbox && scircle', 'f' as expected, sbox'((0d , 0d), (0d , 0d))' && scircle'<(10d , 0d) , 10d>' as actual; ?column? | expected | actual -----------------+----------+-------- - sbox && scircle | f | f + sbox && scircle | f | t (1 row) -- the box degenerated into the point lies in the interior of circle select 'sbox && scircle', 'f' as expected, sbox'((0d , 0d), (0d , 0d))' && scircle'<(0d , 0d) , 10d>' as actual; ?column? | expected | actual -----------------+----------+-------- - sbox && scircle | f | f + sbox && scircle | f | t (1 row) -- the box and circle are degenerated into the point and coincide diff --git a/src/line.c b/src/line.c index 6599e64..ad02575 100644 --- a/src/line.c +++ b/src/line.c @@ -349,7 +349,7 @@ sphereline_circle_pos(const SLine *sl, const SCIRCLE *sc) { /* line is point */ sline_begin(&p[0], sl); - if (spoint_in_circle(&p[0], &c)) + if (spoint_in_circle(&p[0], sc)) { return PGS_CIRCLE_CONT_LINE; } From 21163102051cd905f4547de21e9bacd479e209af Mon Sep 17 00:00:00 2001 From: Vitaly Davydov Date: Fri, 25 Aug 2023 21:42:58 +0300 Subject: [PATCH 18/87] Fix diff in the test moc100 on PG16 --- expected/moc100_4.out | 34 +++++++++++++++++----------------- 1 file changed, 17 insertions(+), 17 deletions(-) diff --git a/expected/moc100_4.out b/expected/moc100_4.out index 13e2306..0dc26bd 100644 --- a/expected/moc100_4.out +++ b/expected/moc100_4.out @@ -72,10 +72,10 @@ EXPLAIN (ANALYZE, BUFFERS, TIMING OFF, SUMMARY OFF) SELECT * FROM moc100 WHERE coverage && '4/0'; QUERY PLAN -------------------------------------------------------------------------------- - Seq Scan on moc100 (cost=0.00..6.26 rows=1 width=96) (actual rows=35 loops=1) + Seq Scan on moc100 (cost=0.00..7.26 rows=1 width=96) (actual rows=35 loops=1) Filter: (coverage && '4/0'::smoc) Rows Removed by Filter: 66 - Buffers: shared hit=114 + Buffers: shared hit=115 Planning: Buffers: shared hit=1 (6 rows) @@ -84,10 +84,10 @@ EXPLAIN (ANALYZE, BUFFERS, TIMING OFF, SUMMARY OFF) SELECT * FROM moc100 WHERE coverage = '0/0-11'; QUERY PLAN -------------------------------------------------------------------------------- - Seq Scan on moc100 (cost=0.00..6.26 rows=1 width=96) (actual rows=23 loops=1) + Seq Scan on moc100 (cost=0.00..7.26 rows=1 width=96) (actual rows=23 loops=1) Filter: (coverage = '0/0-11'::smoc) Rows Removed by Filter: 78 - Buffers: shared hit=59 + Buffers: shared hit=60 Planning: Buffers: shared hit=4 (6 rows) @@ -96,10 +96,10 @@ EXPLAIN (ANALYZE, BUFFERS, TIMING OFF, SUMMARY OFF) SELECT * FROM moc100 WHERE coverage = '6/43225,43227'; QUERY PLAN ------------------------------------------------------------------------------- - Seq Scan on moc100 (cost=0.00..6.26 rows=1 width=96) (actual rows=1 loops=1) + Seq Scan on moc100 (cost=0.00..7.26 rows=1 width=96) (actual rows=1 loops=1) Filter: (coverage = '6/43225 43227'::smoc) Rows Removed by Filter: 100 - Buffers: shared hit=59 + Buffers: shared hit=60 Planning: Buffers: shared hit=1 (6 rows) @@ -108,10 +108,10 @@ EXPLAIN (ANALYZE, BUFFERS, TIMING OFF, SUMMARY OFF) SELECT * FROM moc100 WHERE coverage = '0/'; QUERY PLAN ------------------------------------------------------------------------------- - Seq Scan on moc100 (cost=0.00..6.26 rows=1 width=96) (actual rows=1 loops=1) + Seq Scan on moc100 (cost=0.00..7.26 rows=1 width=96) (actual rows=1 loops=1) Filter: (coverage = '0/'::smoc) Rows Removed by Filter: 100 - Buffers: shared hit=59 + Buffers: shared hit=60 Planning: Buffers: shared hit=1 (6 rows) @@ -120,10 +120,10 @@ EXPLAIN (ANALYZE, BUFFERS, TIMING OFF, SUMMARY OFF) SELECT * FROM moc100 WHERE coverage <> '0/0-11'; QUERY PLAN ---------------------------------------------------------------------------------- - Seq Scan on moc100 (cost=0.00..6.26 rows=100 width=96) (actual rows=78 loops=1) + Seq Scan on moc100 (cost=0.00..7.26 rows=100 width=96) (actual rows=78 loops=1) Filter: (coverage <> '0/0-11'::smoc) Rows Removed by Filter: 23 - Buffers: shared hit=59 + Buffers: shared hit=60 Planning: Buffers: shared hit=4 (6 rows) @@ -132,10 +132,10 @@ EXPLAIN (ANALYZE, BUFFERS, TIMING OFF, SUMMARY OFF) SELECT * FROM moc100 WHERE coverage <> '6/43225,43227'; QUERY PLAN ----------------------------------------------------------------------------------- - Seq Scan on moc100 (cost=0.00..6.26 rows=100 width=96) (actual rows=100 loops=1) + Seq Scan on moc100 (cost=0.00..7.26 rows=100 width=96) (actual rows=100 loops=1) Filter: (coverage <> '6/43225 43227'::smoc) Rows Removed by Filter: 1 - Buffers: shared hit=59 + Buffers: shared hit=60 Planning: Buffers: shared hit=1 (6 rows) @@ -144,10 +144,10 @@ EXPLAIN (ANALYZE, BUFFERS, TIMING OFF, SUMMARY OFF) SELECT * FROM moc100 WHERE coverage <> '0/'; QUERY PLAN ----------------------------------------------------------------------------------- - Seq Scan on moc100 (cost=0.00..6.26 rows=100 width=96) (actual rows=100 loops=1) + Seq Scan on moc100 (cost=0.00..7.26 rows=100 width=96) (actual rows=100 loops=1) Filter: (coverage <> '0/'::smoc) Rows Removed by Filter: 1 - Buffers: shared hit=59 + Buffers: shared hit=60 Planning: Buffers: shared hit=1 (6 rows) @@ -254,7 +254,7 @@ EXPLAIN (ANALYZE, BUFFERS, TIMING OFF, SUMMARY OFF) SELECT * FROM moc100 WHERE coverage <> '0/0-11'; QUERY PLAN ------------------------------------------------------------------------------------------------------------------- - Bitmap Heap Scan on moc100 (cost=106888.23..106894.48 rows=100 width=96) (actual rows=78 loops=1) + Bitmap Heap Scan on moc100 (cost=106888.23..106895.48 rows=100 width=96) (actual rows=78 loops=1) Recheck Cond: (coverage <> '0/0-11'::smoc) Rows Removed by Index Recheck: 23 Heap Blocks: exact=5 @@ -273,7 +273,7 @@ EXPLAIN (ANALYZE, BUFFERS, TIMING OFF, SUMMARY OFF) SELECT * FROM moc100 WHERE coverage <> '6/43225,43227'; QUERY PLAN ------------------------------------------------------------------------------------------------------------------- - Bitmap Heap Scan on moc100 (cost=106888.23..106894.48 rows=100 width=96) (actual rows=100 loops=1) + Bitmap Heap Scan on moc100 (cost=106888.23..106895.48 rows=100 width=96) (actual rows=100 loops=1) Recheck Cond: (coverage <> '6/43225 43227'::smoc) Rows Removed by Index Recheck: 1 Heap Blocks: exact=5 @@ -292,7 +292,7 @@ EXPLAIN (ANALYZE, BUFFERS, TIMING OFF, SUMMARY OFF) SELECT * FROM moc100 WHERE coverage <> '0/'; QUERY PLAN ------------------------------------------------------------------------------------------------------------------- - Bitmap Heap Scan on moc100 (cost=106888.23..106894.48 rows=100 width=96) (actual rows=100 loops=1) + Bitmap Heap Scan on moc100 (cost=106888.23..106895.48 rows=100 width=96) (actual rows=100 loops=1) Recheck Cond: (coverage <> '0/'::smoc) Rows Removed by Index Recheck: 1 Heap Blocks: exact=5 From 6ebf5c2a9fb761a6657c6ebc6ababfbf088e87e7 Mon Sep 17 00:00:00 2001 From: Giuseppe Broccolo Date: Mon, 15 Jan 2018 11:00:18 +0100 Subject: [PATCH 19/87] Add BRIN support for spoint and sbox Adjust style using pgindent, execute regression test for BRIN code just for PG>9.5 --- Makefile | 6 +- README.pg_sphere | 1 + brin.c | 348 +++++++++++++++++++++++++++++++++ brin.h | 40 ++++ doc/indices.sgm | 45 ++++- expected/spoint_brin.out | 56 ++++++ pgs_brin.sql.in | 411 +++++++++++++++++++++++++++++++++++++++ sql/spoint_brin.sql | 136 +++++++++++++ 8 files changed, 1036 insertions(+), 7 deletions(-) create mode 100644 brin.c create mode 100644 brin.h create mode 100644 expected/spoint_brin.out create mode 100644 pgs_brin.sql.in create mode 100644 sql/spoint_brin.sql diff --git a/Makefile b/Makefile index 062aab6..bb5074f 100644 --- a/Makefile +++ b/Makefile @@ -11,7 +11,7 @@ MODULE_big = pg_sphere OBJS = src/sscan.o src/sparse.o src/sbuffer.o src/vector3d.o src/point.o \ src/euler.o src/circle.o src/line.o src/ellipse.o src/polygon.o \ src/path.o src/box.o src/output.o src/gq_cache.o src/gist.o \ - src/key.o src/gnomo.o src/epochprop.o + src/key.o src/gnomo.o src/epochprop.o brin.o ifneq ($(USE_HEALPIX),0) OBJS += src/healpix.o src/moc.o src/process_moc.o \ @@ -33,7 +33,7 @@ DATA_built = $(RELEASE_SQL) \ DOCS = README.pg_sphere COPYRIGHT.pg_sphere REGRESS = init tables points euler circle line ellipse poly path box index \ contains_ops contains_ops_compat bounding_box_gist gnomo epochprop \ - contains overlaps + contains overlaps spoint_brin ifneq ($(USE_HEALPIX),0) REGRESS += healpix moc mocautocast @@ -66,7 +66,7 @@ CRUSH_TESTS = init_extended circle_extended PGS_SQL = pgs_types.sql pgs_point.sql pgs_euler.sql pgs_circle.sql \ pgs_line.sql pgs_ellipse.sql pgs_polygon.sql pgs_path.sql \ pgs_box.sql pgs_contains_ops.sql pgs_contains_ops_compat.sql \ - pgs_gist.sql gnomo.sql + pgs_gist.sql gnomo.sql pgs_brin.sql ifneq ($(USE_HEALPIX),0) PGS_SQL += healpix.sql diff --git a/README.pg_sphere b/README.pg_sphere index 8a85c39..cccc8ca 100644 --- a/README.pg_sphere +++ b/README.pg_sphere @@ -11,6 +11,7 @@ It provides: This is an R-Tree implementation using GiST for spherical objects like spherical points and spherical circles with useful functions and operators. +It also support the Block Range INdexing (BRIN) for large datasets. NOTICE: This version will work only with PostgreSQL version 10 and above. diff --git a/brin.c b/brin.c new file mode 100644 index 0000000..5a5ae03 --- /dev/null +++ b/brin.c @@ -0,0 +1,348 @@ +/* + * BRIN SUPPORT for spheric objects: + * + * The stored type is the spherekey, as for GiST support, + * so include some already defined stuffs. We have to define + * then all the cross-type functions needed by the OpFamilies. + */ + +#include "brin.h" +#include "gist.h" +#include + +/* + * Functions needed to build a BRIN index + */ +PG_FUNCTION_INFO_V1(spoint_brin_inclusion_add_value); +PG_FUNCTION_INFO_V1(sbox_brin_inclusion_add_value); + +/* + * Functions needed to define supported operators + */ +PG_FUNCTION_INFO_V1(spoint_overlaps_spherekey); +PG_FUNCTION_INFO_V1(spoint_contains_spherekey); +PG_FUNCTION_INFO_V1(spoint_iscontained_spherekey); +PG_FUNCTION_INFO_V1(sbox_overlaps_spherekey); +PG_FUNCTION_INFO_V1(sbox_contains_spherekey); +PG_FUNCTION_INFO_V1(sbox_iscontained_spherekey); +PG_FUNCTION_INFO_V1(spherekey_overlaps_spherekey); +PG_FUNCTION_INFO_V1(spherekey_contains_spherekey); +PG_FUNCTION_INFO_V1(spherekey_iscontained_spherekey); +PG_FUNCTION_INFO_V1(spoint_overlaps_sbox); +PG_FUNCTION_INFO_V1(sbox_iscontained_spoint); + +Datum +spoint_brin_inclusion_add_value(PG_FUNCTION_ARGS) +{ + BrinValues *column = (BrinValues *) PG_GETARG_POINTER(1); + SPoint *newval = (SPoint *) DatumGetPointer(PG_GETARG_DATUM(2)); + bool isnull = PG_GETARG_BOOL(3); + int32 spointkey[6]; + int32 *skey = (int32 *) column->bv_values[INCLUSION_UNION]; + + /* + * If the new value is null, we record that we saw it if it's the first + * one; otherwise, there's nothing to do. + */ + if (isnull) + { + if (column->bv_hasnulls) + PG_RETURN_BOOL(false); + + column->bv_hasnulls = true; + PG_RETURN_BOOL(true); + } + + spherepoint_gen_key(&spointkey, newval); + + /* + * If spherekey pointer is NULL, we consider the spoint entry as 'empty'. + * + * The OpClass support empty entries: we need to set the "contains empty" + * flag in the element (unless already set). + */ + if (spointkey == NULL) + { + if (!DatumGetBool(column->bv_values[INCLUSION_CONTAINS_EMPTY])) + { + column->bv_values[INCLUSION_CONTAINS_EMPTY] = BoolGetDatum(true); + PG_RETURN_BOOL(true); + } + + PG_RETURN_BOOL(false); + } + + /* if the recorded value is null, we just need to store the spherekey */ + if (column->bv_allnulls) + { + column->bv_values[INCLUSION_UNION] = datumCopy((Datum) spointkey, false, + (sizeof(int32) * 6)); + column->bv_values[INCLUSION_UNMERGEABLE] = BoolGetDatum(false); + column->bv_values[INCLUSION_CONTAINS_EMPTY] = BoolGetDatum(false); + column->bv_allnulls = false; + PG_RETURN_BOOL(true); + } + + /* + * Check if the stored spherekey already contains the key of the new value + */ + if (spherekey_interleave(skey, spointkey) == SCKEY_IN) + { + PG_RETURN_BOOL(false); + } + + /* + * Otherwise, we need to enlarge it to contains the current spoint + */ + spherekey_union_two(skey, spointkey); + + PG_RETURN_BOOL(true); +} + +Datum +sbox_brin_inclusion_add_value(PG_FUNCTION_ARGS) +{ + BrinValues *column = (BrinValues *) PG_GETARG_POINTER(1); + SBOX *newval = (SBOX *) DatumGetPointer(PG_GETARG_DATUM(2)); + bool isnull = PG_GETARG_BOOL(3); + int32 sboxkey[6]; + int32 *skey = (int32 *) column->bv_values[INCLUSION_UNION]; + + /* + * If the new value is null, we record that we saw it if it's the first + * one; otherwise, there's nothing to do. + */ + if (isnull) + { + if (column->bv_hasnulls) + PG_RETURN_BOOL(false); + + column->bv_hasnulls = true; + PG_RETURN_BOOL(true); + } + + spherebox_gen_key(&sboxkey, newval); + + /* + * If spherekey pointer is NULL, we consider the spoint entry as 'empty'. + * + * The OpClass support empty entries: we need to set the "contains empty" + * flag in the element (unless already set). + */ + if (sboxkey == NULL) + { + if (!DatumGetBool(column->bv_values[INCLUSION_CONTAINS_EMPTY])) + { + column->bv_values[INCLUSION_CONTAINS_EMPTY] = BoolGetDatum(true); + PG_RETURN_BOOL(true); + } + + PG_RETURN_BOOL(false); + } + + /* if the recorded value is null, we just need to store the spherekey */ + if (column->bv_allnulls) + { + column->bv_values[INCLUSION_UNION] = datumCopy((Datum) sboxkey, false, + (sizeof(int32) * 6)); + column->bv_values[INCLUSION_UNMERGEABLE] = BoolGetDatum(false); + column->bv_values[INCLUSION_CONTAINS_EMPTY] = BoolGetDatum(false); + column->bv_allnulls = false; + PG_RETURN_BOOL(true); + } + + /* + * Check if the stored spherekey already contains the key of the new value + */ + if (spherekey_interleave(skey, sboxkey) == SCKEY_IN) + { + PG_RETURN_BOOL(false); + } + + /* + * Otherwise, we need to enlarge it to contains the current spoint + */ + spherekey_union_two(skey, sboxkey); + + PG_RETURN_BOOL(true); +} + +/* */ +/* Define operators procedures below */ +/* */ + +Datum +spoint_overlaps_spherekey(PG_FUNCTION_ARGS) +{ + int32 k1[6]; + SPoint *p1 = (SPoint *) PG_GETARG_POINTER(0); + int32 *k2 = (int32 *) PG_GETARG_POINTER(1); + + spherepoint_gen_key(&k1, p1); + if (spherekey_interleave(k1, k2) == SCKEY_OVERLAP) + { + PG_RETURN_BOOL(true); + } + + PG_RETURN_BOOL(false); +} + +Datum +spoint_contains_spherekey(PG_FUNCTION_ARGS) +{ + int32 k1[6]; + SPoint *p1 = (SPoint *) PG_GETARG_POINTER(0); + int32 *k2 = (int32 *) PG_GETARG_POINTER(1); + + spherepoint_gen_key(&k1, p1); + if (spherekey_interleave(k1, k2) == SCKEY_IN) + { + PG_RETURN_BOOL(true); + } + + PG_RETURN_BOOL(false); +} + +Datum +spoint_iscontained_spherekey(PG_FUNCTION_ARGS) +{ + int32 k1[6]; + SPoint *p1 = (SPoint *) PG_GETARG_POINTER(0); + int32 *k2 = (int32 *) PG_GETARG_POINTER(1); + + spherepoint_gen_key(&k1, p1); + if (spherekey_interleave(k2, k1) == SCKEY_IN) + { + PG_RETURN_BOOL(true); + } + + PG_RETURN_BOOL(false); +} + +Datum +sbox_overlaps_spherekey(PG_FUNCTION_ARGS) +{ + int32 k1[6]; + SBOX *p1 = (SBOX *) PG_GETARG_POINTER(0); + int32 *k2 = (int32 *) PG_GETARG_POINTER(1); + + spherebox_gen_key(&k1, p1); + if (spherekey_interleave(k1, k2) == SCKEY_OVERLAP) + { + PG_RETURN_BOOL(true); + } + + PG_RETURN_BOOL(false); +} + +Datum +sbox_contains_spherekey(PG_FUNCTION_ARGS) +{ + int32 k1[6]; + SBOX *p1 = (SBOX *) PG_GETARG_POINTER(0); + int32 *k2 = (int32 *) PG_GETARG_POINTER(1); + + spherebox_gen_key(&k1, p1); + if (spherekey_interleave(k1, k2) == SCKEY_IN) + { + PG_RETURN_BOOL(true); + } + + PG_RETURN_BOOL(false); +} + +Datum +sbox_iscontained_spherekey(PG_FUNCTION_ARGS) +{ + int32 k1[6]; + SBOX *p1 = (SBOX *) PG_GETARG_POINTER(0); + int32 *k2 = (int32 *) PG_GETARG_POINTER(1); + + spherebox_gen_key(&k1, p1); + if (spherekey_interleave(k2, k1) == SCKEY_IN) + { + PG_RETURN_BOOL(true); + } + + PG_RETURN_BOOL(false); +} + +Datum +spherekey_overlaps_spherekey(PG_FUNCTION_ARGS) +{ + int32 *k1 = (int32 *) PG_GETARG_POINTER(0); + int32 *k2 = (int32 *) PG_GETARG_POINTER(1); + + if (spherekey_interleave(k1, k2) == SCKEY_OVERLAP) + { + PG_RETURN_BOOL(true); + } + + PG_RETURN_BOOL(false); +} + +Datum +spherekey_contains_spherekey(PG_FUNCTION_ARGS) +{ + int32 *k1 = (int32 *) PG_GETARG_POINTER(0); + int32 *k2 = (int32 *) PG_GETARG_POINTER(1); + + if (spherekey_interleave(k1, k2) == SCKEY_IN) + { + PG_RETURN_BOOL(true); + } + + PG_RETURN_BOOL(false); +} + +Datum +spherekey_iscontained_spherekey(PG_FUNCTION_ARGS) +{ + int32 *k1 = (int32 *) PG_GETARG_POINTER(0); + int32 *k2 = (int32 *) PG_GETARG_POINTER(1); + + if (spherekey_interleave(k2, k1) == SCKEY_IN) + { + PG_RETURN_BOOL(true); + } + + PG_RETURN_BOOL(false); +} + +Datum +spoint_overlaps_sbox(PG_FUNCTION_ARGS) +{ + int32 k1[6]; + SPoint *p1 = (SPoint *) PG_GETARG_POINTER(0); + int32 k2[6]; + SBOX *p2 = (SBOX *) PG_GETARG_POINTER(1); + + spherepoint_gen_key(&k1, p1); + spherebox_gen_key(&k2, p2); + + if (spherekey_interleave(k1, k2) == SCKEY_OVERLAP) + { + PG_RETURN_BOOL(true); + } + + PG_RETURN_BOOL(false); +} + +Datum +sbox_iscontained_spoint(PG_FUNCTION_ARGS) +{ + int32 k1[6]; + SBOX *p1 = (SBOX *) PG_GETARG_POINTER(0); + int32 k2[6]; + SPoint *p2 = (SPoint *) PG_GETARG_POINTER(1); + + spherebox_gen_key(&k1, p1); + spherepoint_gen_key(&k2, p2); + + if (spherekey_interleave(k1, k2) == SCKEY_IN) + { + PG_RETURN_BOOL(true); + } + + PG_RETURN_BOOL(false); +} diff --git a/brin.h b/brin.h new file mode 100644 index 0000000..b1a1c2c --- /dev/null +++ b/brin.h @@ -0,0 +1,40 @@ +#ifndef __PGS_BRIN_H__ +#define __PGS_BRIN_H__ + +/* + * BRIN declarations + */ + +#include "postgres.h" +#include "fmgr.h" + +#include "key.h" + +#include +#include +#include +#include +#include "access/brin_tuple.h" +#include "utils/datum.h" + +#define INCLUSION_UNION 0 +#define INCLUSION_UNMERGEABLE 1 +#define INCLUSION_CONTAINS_EMPTY 2 + +Datum spoint_brin_inclusion_add_value(PG_FUNCTION_ARGS); +Datum sbox_brin_inclusion_add_value(PG_FUNCTION_ARGS); + +Datum spoint_overlaps_spherekey(PG_FUNCTION_ARGS); +Datum spoint_contains_spherekey(PG_FUNCTION_ARGS); +Datum spoint_iscontained_spherekey(PG_FUNCTION_ARGS); +Datum sbox_overlaps_spherekey(PG_FUNCTION_ARGS); +Datum sbox_contains_spherekey(PG_FUNCTION_ARGS); +Datum sbox_iscontained_spherekey(PG_FUNCTION_ARGS); +Datum spherekey_overlaps_spherekey(PG_FUNCTION_ARGS); +Datum spherekey_contains_spherekey(PG_FUNCTION_ARGS); +Datum spherekey_iscontained_spherekey(PG_FUNCTION_ARGS); + +Datum spoint_overlaps_sbox(PG_FUNCTION_ARGS); +Datum sbox_iscontained_spoint(PG_FUNCTION_ARGS); + +#endif diff --git a/doc/indices.sgm b/doc/indices.sgm index 8103072..7918ee0 100644 --- a/doc/indices.sgm +++ b/doc/indices.sgm @@ -8,15 +8,32 @@ pgSphere uses GiST - to create spherical indices. An index speeds up the execution - time of operators BRIN) algorithms to create + spherical indices. + GiST index represents the R-Tree implementation for + spherical objects, while BRINs are based on "summarization" + of data blocks (pages) on physical storage in order to + organize data searches on ranges of summarized data that can be easily skipped + on the base of search filters (see + PostgreSQL documentation for further details on BRINs). + As a consequence, BRINs result to be really small indexes (up to 1000 times + than GiST ones), generally with lower a performance compared with a GiST one, + but up to 100 times faster than a full sequential scan of a table performed + without any index. So BRINs are particularly suitable in a big data context. + An index speeds up the execution time of searches based on operators <@, @, &&, #, =, and !=. You can create - an index with the following spherical data types: + linkend="op.equal">!=. + + Codestin Search App + + You can create a GiST index with the following spherical data types: @@ -55,6 +72,10 @@ + + BRIN indexing supports just spherical points (spoint) + and spherical coordinates range (sbox) at the moment. + Codestin Search App @@ -65,6 +86,22 @@ + + BRINs can be created through the following syntax: + + + + + + By default, BRINs summarize block of 128 pages. The lower numbers + of pages are specified, the higher granularity is reached during + the searches, and performance's gap between GiST indexes and BRINs + is lower (consider that BRINs size increases as well). Different + summarizations can be used with the following command: + + + + diff --git a/expected/spoint_brin.out b/expected/spoint_brin.out new file mode 100644 index 0000000..4bb88b0 --- /dev/null +++ b/expected/spoint_brin.out @@ -0,0 +1,56 @@ +CREATE TABLE +COPY 77 +CREATE FUNCTION +CREATE INDEX +SET +SET +SET + ?column? | qnodes +----------+---------- + scan_seq | Seq Scan +(1 row) + + p +----------------------------------------- + (0.349065850398866 , 0.174532925199433) +(1 row) + + ?column? | qnodes +----------+---------- + scan_seq | Seq Scan +(1 row) + + p +----------------------------------------- + (0.349065850398866 , 0.174532925199433) +(1 row) + +SET +SET +SET + ?column? | qnodes +----------+------------------------------------ + scan_idx | Bitmap Heap Scan,Bitmap Index Scan +(1 row) + + p +----------------------------------------- + (0.349065850398866 , 0.174532925199433) +(1 row) + + ?column? | qnodes +----------+------------------------------------ + scan_idx | Bitmap Heap Scan,Bitmap Index Scan +(1 row) + + p +----------------------------------------- + (0.349065850398866 , 0.174532925199433) +(1 row) + +DROP INDEX +DROP TABLE +DROP FUNCTION +SET +SET +SET diff --git a/pgs_brin.sql.in b/pgs_brin.sql.in new file mode 100644 index 0000000..93fe8dd --- /dev/null +++ b/pgs_brin.sql.in @@ -0,0 +1,411 @@ + +-------------------------------------------------------------------- +-- BRIN support -- +-------------------------------------------------------------------- + +-------------------------------- +-- the Operators -- +-------------------------------- + +CREATE FUNCTION spoint_overlaps_spherekey(spoint, spherekey) + RETURNS boolean + AS 'MODULE_PATHNAME', 'spoint_overlaps_spherekey' + LANGUAGE 'c' IMMUTABLE STRICT; + +CREATE FUNCTION spoint_contains_spherekey(spoint, spherekey) + RETURNS boolean + AS 'MODULE_PATHNAME', 'spoint_contains_spherekey' + LANGUAGE 'c' IMMUTABLE STRICT; + +CREATE FUNCTION spoint_iscontained_spherekey(spoint, spherekey) + RETURNS boolean + AS 'MODULE_PATHNAME', 'spoint_iscontained_spherekey' + LANGUAGE 'c' IMMUTABLE STRICT; + +CREATE FUNCTION sbox_overlaps_spherekey(sbox, spherekey) + RETURNS boolean + AS 'MODULE_PATHNAME', 'sbox_overlaps_spherekey' + LANGUAGE 'c' IMMUTABLE STRICT; + +CREATE FUNCTION sbox_contains_spherekey(sbox, spherekey) + RETURNS boolean + AS 'MODULE_PATHNAME', 'sbox_contains_spherekey' + LANGUAGE 'c' IMMUTABLE STRICT; + +CREATE FUNCTION sbox_iscontained_spherekey(sbox, spherekey) + RETURNS boolean + AS 'MODULE_PATHNAME', 'sbox_iscontained_spherekey' + LANGUAGE 'c' IMMUTABLE STRICT; + +CREATE FUNCTION spherekey_overlaps_spherekey(spherekey, spherekey) + RETURNS boolean + AS 'MODULE_PATHNAME', 'spherekey_overlaps_spherekey' + LANGUAGE 'c' IMMUTABLE STRICT; + +CREATE FUNCTION spherekey_contains_spherekey(spherekey, spherekey) + RETURNS boolean + AS 'MODULE_PATHNAME', 'spherekey_contains_spherekey' + LANGUAGE 'c' IMMUTABLE STRICT; + +CREATE FUNCTION spherekey_iscontained_spherekey(spherekey, spherekey) + RETURNS boolean + AS 'MODULE_PATHNAME', 'spoint_iscontained_spherekey' + LANGUAGE 'c' IMMUTABLE STRICT; + +CREATE OPERATOR && ( + LEFTARG = spoint, + RIGHTARG = spherekey, + PROCEDURE = spoint_overlaps_spherekey, + COMMUTATOR = '&&', + RESTRICT = contsel, + JOIN = contjoinsel +); + +COMMENT ON OPERATOR && (spoint, spherekey) IS + 'true, if the spherical point overlaps a spherekey'; + +CREATE OPERATOR @> ( + LEFTARG = spoint, + RIGHTARG = spherekey, + PROCEDURE = spoint_contains_spherekey, + COMMUTATOR = '<@', + RESTRICT = contsel, + JOIN = contjoinsel +); + +COMMENT ON OPERATOR @> (spoint, spherekey) IS + 'true, if the spherical point contains a spherekey - just needed to define the OpFamily'; + +CREATE OPERATOR <@ ( + LEFTARG = spoint, + RIGHTARG = spherekey, + PROCEDURE = spoint_iscontained_spherekey, + COMMUTATOR = '@>', + RESTRICT = contsel, + JOIN = contjoinsel +); + +COMMENT ON OPERATOR <@ (spoint, spherekey) IS + 'true, if the spherical point is contained in a spherekey'; + +CREATE OPERATOR && ( + LEFTARG = sbox, + RIGHTARG = spherekey, + PROCEDURE = sbox_overlaps_spherekey, + COMMUTATOR = '&&', + RESTRICT = contsel, + JOIN = contjoinsel +); + +COMMENT ON OPERATOR && (sbox, spherekey) IS + 'true, if the spherical box overlaps a spherekey'; + +CREATE OPERATOR @> ( + LEFTARG = sbox, + RIGHTARG = spherekey, + PROCEDURE = sbox_contains_spherekey, + COMMUTATOR = '<@', + RESTRICT = contsel, + JOIN = contjoinsel +); + +COMMENT ON OPERATOR @> (sbox, spherekey) IS + 'true, if the spherical box contains a spherekey'; + +CREATE OPERATOR <@ ( + LEFTARG = sbox, + RIGHTARG = spherekey, + PROCEDURE = sbox_iscontained_spherekey, + COMMUTATOR = '@>', + RESTRICT = contsel, + JOIN = contjoinsel +); + +COMMENT ON OPERATOR <@ (sbox, spherekey) IS + 'true, if the spherical box is contained in a spherekey'; + +CREATE OPERATOR && ( + LEFTARG = spherekey, + RIGHTARG = spherekey, + PROCEDURE = spherekey_overlaps_spherekey, + COMMUTATOR = '&&', + RESTRICT = contsel, + JOIN = contjoinsel +); + +COMMENT ON OPERATOR && (spherekey, spherekey) IS + 'true, if the spherekey overlaps another spherekey'; + +CREATE OPERATOR @> ( + LEFTARG = spherekey, + RIGHTARG = spherekey, + PROCEDURE = spherekey_contains_spherekey, + COMMUTATOR = '<@', + RESTRICT = contsel, + JOIN = contjoinsel +); + +COMMENT ON OPERATOR @> (spoint, spherekey) IS + 'true, if the spherekey contains another spherekey'; + +CREATE OPERATOR <@ ( + LEFTARG = spherekey, + RIGHTARG = spherekey, + PROCEDURE = spherekey_iscontained_spherekey, + COMMUTATOR = '@>', + RESTRICT = contsel, + JOIN = contjoinsel +); + +COMMENT ON OPERATOR <@ (spherekey, spherekey) IS + 'true, if the spherical point is contained in another spherekey'; + +--------------------------------------------- +-- create operators with crossed datatypes -- +--------------------------------------------- + +CREATE FUNCTION spherekey_overlaps_spoint(spherekey, spoint) + RETURNS boolean + AS $$ + SELECT $2 && $1; + $$ LANGUAGE SQL IMMUTABLE STRICT; + +CREATE FUNCTION spherekey_contains_spoint(spherekey, spoint) + RETURNS boolean + AS $$ + SELECT $2 <@ $1; + $$ LANGUAGE SQL IMMUTABLE STRICT; + +CREATE FUNCTION spherekey_iscontained_spoint(spherekey, spoint) + RETURNS boolean + AS $$ + SELECT $2 @> $1; + $$ LANGUAGE SQL IMMUTABLE STRICT; + +CREATE FUNCTION spherekey_overlaps_sbox(spherekey, sbox) + RETURNS boolean + AS $$ + SELECT $2 && $1; + $$ LANGUAGE SQL IMMUTABLE STRICT; + +CREATE FUNCTION spherekey_contains_sbox(spherekey, sbox) + RETURNS boolean + AS $$ + SELECT $2 <@ $1; + $$ LANGUAGE SQL IMMUTABLE STRICT; + +CREATE FUNCTION spherekey_iscontained_sbox(spherekey, sbox) + RETURNS boolean + AS $$ + SELECT $2 @> $1; + $$ LANGUAGE SQL IMMUTABLE STRICT; + +CREATE OPERATOR && ( + LEFTARG = spherekey, + RIGHTARG = spoint, + PROCEDURE = spherekey_overlaps_spoint, + COMMUTATOR = '&&', + RESTRICT = contsel, + JOIN = contjoinsel +); + +COMMENT ON OPERATOR && (spherekey, spoint) IS + 'true, if the spherekey overlaps a spoint'; + +CREATE OPERATOR @> ( + LEFTARG = spherekey, + RIGHTARG = spoint, + PROCEDURE = spherekey_contains_spoint, + COMMUTATOR = '<@', + RESTRICT = contsel, + JOIN = contjoinsel +); + +COMMENT ON OPERATOR @> (spherekey, spoint) IS + 'true, if the spherekey contains a spherical point'; + +CREATE OPERATOR <@ ( + LEFTARG = spherekey, + RIGHTARG = spoint, + PROCEDURE = spherekey_iscontained_spoint, + COMMUTATOR = '@>', + RESTRICT = contsel, + JOIN = contjoinsel +); + +COMMENT ON OPERATOR <@ (spherekey, spoint) IS + 'true, if the spherekey is contained in a spherical point - just needed to define the OpFamily'; + +CREATE OPERATOR && ( + LEFTARG = spherekey, + RIGHTARG = sbox, + PROCEDURE = spherekey_overlaps_sbox, + COMMUTATOR = '&&', + RESTRICT = contsel, + JOIN = contjoinsel +); + +COMMENT ON OPERATOR && (spherekey, sbox) IS + 'true, if the spherekey overlaps a spherical point'; + +CREATE OPERATOR @> ( + LEFTARG = spherekey, + RIGHTARG = sbox, + PROCEDURE = spherekey_contains_sbox, + COMMUTATOR = '<@', + RESTRICT = contsel, + JOIN = contjoinsel +); + +COMMENT ON OPERATOR @> (spherekey, sbox) IS + 'true, if the spherekey contains a spherical point'; + +CREATE OPERATOR <@ ( + LEFTARG = spherekey, + RIGHTARG = sbox, + PROCEDURE = spherekey_iscontained_sbox, + COMMUTATOR = '@>', + RESTRICT = contsel, + JOIN = contjoinsel +); + +COMMENT ON OPERATOR <@ (spherekey, sbox) IS + 'true, if the spherekey is contained in a spherical point'; + +------------------------------------------------- +-- create operators that will actually be used -- +------------------------------------------------- + +CREATE FUNCTION spoint_overlaps_sbox(spoint, sbox) + RETURNS boolean + AS 'MODULE_PATHNAME', 'spoint_overlaps_sbox' + LANGUAGE 'c' IMMUTABLE STRICT; + +CREATE OPERATOR && ( + LEFTARG = spoint, + RIGHTARG = sbox, + PROCEDURE = spoint_overlaps_sbox, + COMMUTATOR = '&&', + RESTRICT = contsel, + JOIN = contjoinsel +); + +COMMENT ON OPERATOR && (spoint, sbox) IS + 'true, if the spherical point overlaps a spherical box'; + +------------------------------------------------------------ +-- Complementar operators, needed for OpFamily definition -- +------------------------------------------------------------ + +CREATE FUNCTION sbox_overlaps_spoint(sbox, spoint) + RETURNS boolean + AS $$ + SELECT $2 && $1; + $$ LANGUAGE SQL IMMUTABLE STRICT; + +CREATE OPERATOR && ( + LEFTARG = sbox, + RIGHTARG = spoint, + PROCEDURE = sbox_overlaps_spoint, + COMMUTATOR = '&&', + RESTRICT = contsel, + JOIN = contjoinsel +); + +COMMENT ON OPERATOR && (sbox, spoint) IS + 'true, if the spherical box overlaps a spherical point'; + +CREATE FUNCTION sbox_iscontained_spoint(sbox, spoint) + RETURNS boolean + AS 'MODULE_PATHNAME', 'sbox_iscontained_spoint' + LANGUAGE 'c' IMMUTABLE STRICT; + +CREATE OPERATOR <@ ( + LEFTARG = sbox, + RIGHTARG = spoint, + PROCEDURE = sbox_iscontained_spoint, + COMMUTATOR = '@>', + RESTRICT = contsel, + JOIN = contjoinsel +); + +CREATE FUNCTION spoint_contains_sbox(spoint, sbox) + RETURNS boolean + AS $$ + SELECT $2 <@ $1; + $$ LANGUAGE SQL IMMUTABLE STRICT; + +CREATE OPERATOR @> ( + LEFTARG = spoint, + RIGHTARG = sbox, + PROCEDURE = spoint_contains_sbox, + COMMUTATOR = '<@', + RESTRICT = contsel, + JOIN = contjoinsel +); + +-------------------------------- +-- the OpFamily -- +-------------------------------- + +CREATE OPERATOR FAMILY brin_inclusion_spheric_ops USING brin; + +CREATE OR REPLACE FUNCTION spoint_brin_inclusion_add_value(internal, internal, internal, internal) + RETURNS boolean + AS 'MODULE_PATHNAME','spoint_brin_inclusion_add_value' + LANGUAGE 'c'; + +CREATE OR REPLACE FUNCTION sbox_brin_inclusion_add_value(internal, internal, internal, internal) + RETURNS boolean + AS 'MODULE_PATHNAME','sbox_brin_inclusion_add_value' + LANGUAGE 'c'; + +CREATE OPERATOR CLASS brin_spoint_inclusion_ops + DEFAULT FOR TYPE spoint + USING brin + FAMILY brin_inclusion_spheric_ops AS + FUNCTION 1 brin_inclusion_opcinfo(internal) , + FUNCTION 2 spoint_brin_inclusion_add_value(internal, internal, internal, internal) , + FUNCTION 3 brin_inclusion_consistent(internal, internal, internal) , + FUNCTION 4 brin_inclusion_union(internal, internal, internal) , + STORAGE spherekey; + +CREATE OPERATOR CLASS brin_sbox_inclusion_ops + DEFAULT FOR TYPE sbox + USING brin + FAMILY brin_inclusion_spheric_ops AS + FUNCTION 1 brin_inclusion_opcinfo(internal) , + FUNCTION 2 sbox_brin_inclusion_add_value(internal, internal, internal, internal) , + FUNCTION 3 brin_inclusion_consistent(internal, internal, internal) , + FUNCTION 4 brin_inclusion_union(internal, internal, internal) , + STORAGE spherekey; + +ALTER OPERATOR FAMILY brin_inclusion_spheric_ops USING brin ADD + OPERATOR 3 &&(spherekey, spoint), + OPERATOR 7 @>(spherekey, spoint), + OPERATOR 8 <@(spherekey, spoint), + + OPERATOR 3 &&(spoint, spherekey), + OPERATOR 7 @>(spoint, spherekey), + OPERATOR 8 <@(spoint, spherekey), + + OPERATOR 3 &&(spherekey, sbox), + OPERATOR 7 @>(spherekey, sbox), + OPERATOR 8 <@(spherekey, sbox), + + OPERATOR 3 &&(sbox, spherekey), + OPERATOR 7 @>(sbox, spherekey), + OPERATOR 8 <@(sbox, spherekey), + + OPERATOR 3 &&(spherekey, spherekey), + OPERATOR 7 @>(spherekey, spherekey), + OPERATOR 8 <@(spherekey, spherekey), + + OPERATOR 3 &&(spoint, sbox), + OPERATOR 3 &&(sbox, spoint), + OPERATOR 7 @>(sbox, spoint), + OPERATOR 7 @>(spoint, sbox), + OPERATOR 8 <@(sbox, spoint), + OPERATOR 8 <@(spoint, sbox); + + diff --git a/sql/spoint_brin.sql b/sql/spoint_brin.sql new file mode 100644 index 0000000..b03508d --- /dev/null +++ b/sql/spoint_brin.sql @@ -0,0 +1,136 @@ +CREATE TABLE test_points ( + p spoint +); + +COPY test_points (p) FROM stdin; +(0.349065850398866 , 0.174532925199433) +(1.59875999207035 , 0.771416330759722) +(1.59876348272885 , 0.77141458543047) +(1.59876697338736 , 0.771412840101218) +(1.59877046404586 , 0.771411094771966) +(1.59877395470437 , 0.771409349442714) +(1.59877744536287 , 0.771407604113461) +(1.59878093602137 , 0.77140585878421) +(1.59878442667988 , 0.771404113454958) +(1.59878791733838 , 0.771402368125706) +(1.59879140799689 , 0.771400622796454) +(1.59879489865539 , 0.771398877467202) +(1.59879838931389 , 0.77139713213795) +(1.5988018799724 , 0.771395386808698) +(1.5988053706309 , 0.771393641479446) +(1.59880886128941 , 0.771391896150194) +(1.59881235194791 , 0.771390150820941) +(1.59881584260641 , 0.77138840549169) +(1.59881933326492 , 0.771386660162438) +(1.59882282392342 , 0.771384914833186) +(1.59882631458193 , 0.771383169503934) +(1.59882980524043 , 0.771381424174682) +(1.59883329589893 , 0.77137967884543) +(1.59883678655744 , 0.771377933516178) +(1.59884027721594 , 0.771376188186926) +(1.59884376787445 , 0.771374442857673) +(1.59884725853295 , 0.771372697528422) +(1.59885074919145 , 0.77137095219917) +(1.59885423984996 , 0.771369206869918) +(1.59885773050846 , 0.771367461540666) +(1.59886122116697 , 0.771365716211414) +(1.59886471182547 , 0.771363970882162) +(1.59886820248397 , 0.77136222555291) +(1.59887169314248 , 0.771360480223658) +(1.59887518380098 , 0.771358734894406) +(1.59887867445948 , 0.771356989565154) +(1.59888216511799 , 0.771355244235902) +(1.59888565577649 , 0.77135349890665) +(1.598889146435 , 0.771351753577398) +(1.5988926370935 , 0.771350008248146) +(1.59889612775201 , 0.771348262918894) +(1.59889961841051 , 0.771346517589642) +(1.59890310906901 , 0.77134477226039) +(1.59890659972752 , 0.771343026931138) +(1.59891009038602 , 0.771341281601886) +(1.59891358104452 , 0.771339536272634) +(1.59891707170303 , 0.771337790943382) +(1.59892056236153 , 0.77133604561413) +(1.59892405302004 , 0.771334300284878) +(1.59892754367854 , 0.771332554955626) +(1.59893103433705 , 0.771330809626374) +(1.59893452499555 , 0.771329064297122) +(1.59893801565405 , 0.77132731896787) +(1.59894150631256 , 0.771325573638618) +(1.59894499697106 , 0.771323828309366) +(1.59894848762957 , 0.771322082980114) +(1.59895197828807 , 0.771320337650862) +(1.59895546894657 , 0.77131859232161) +(3.61121537674092 , -1.33598496521933) +(3.61121886739942 , -1.33598321989008) +(3.61122235805792 , -1.33598147456083) +(3.61122584871643 , -1.33597972923158) +(3.61122933937493 , -1.33597798390233) +(3.61123283003344 , -1.33597623857307) +(3.61123632069194 , -1.33597449324382) +(3.61123981135044 , -1.33597274791457) +(3.61124330200895 , -1.33597100258532) +(3.61124679266745 , -1.33596925725607) +(3.61125028332595 , -1.33596751192682) +(3.61125377398446 , -1.33596576659756) +(3.61125726464296 , -1.33596402126831) +(3.61126075530147 , -1.33596227593906) +(3.61126424595997 , -1.33596053060981) +(3.61126773661847 , -1.33595878528056) +(3.61127122727698 , -1.3359570399513) +(3.61127471793548 , -1.33595529462205) +(3.61127820859399 , -1.3359535492928) +\. + +CREATE OR REPLACE FUNCTION qnodes(q text) RETURNS text +LANGUAGE 'plpgsql' AS +$$ +DECLARE + exp TEXT; + mat TEXT[]; + ret TEXT[]; +BEGIN + FOR exp IN EXECUTE 'EXPLAIN ' || q + LOOP + --RAISE NOTICE 'EXP: %', exp; + mat := regexp_matches(exp, ' *(?:-> *)?(.*Scan)'); + --RAISE NOTICE 'MAT: %', mat; + IF mat IS NOT NULL THEN + ret := array_append(ret, mat[1]); + END IF; + --RAISE NOTICE 'RET: %', ret; + END LOOP; + RETURN array_to_string(ret,','); +END; +$$; + +CREATE INDEX brin_spoint ON test_points USING brin (p) WITH (pages_per_range = 16); + +set enable_indexscan = off; +set enable_bitmapscan = off; +set enable_seqscan = on; + +SELECT 'scan_seq', qnodes('SELECT * FROM test_points WHERE p <@ sbox ''( (10d,10d), (20d,20d) )'''); +SELECT * FROM test_points WHERE p <@ sbox '( (10d,10d), (20d,20d) )'; + +SELECT 'scan_seq', qnodes('SELECT * FROM test_points WHERE p && sbox ''( (10d,10d), (20d,20d) )'''); +SELECT * FROM test_points WHERE p && sbox '( (10d,10d), (20d,20d) )'; + +set enable_indexscan = off; +set enable_bitmapscan = on; +set enable_seqscan = off; + +SELECT 'scan_idx', qnodes('SELECT * FROM test_points WHERE p <@ sbox ''( (10d,10d), (20d,20d) )'''); +SELECT * FROM test_points WHERE p <@ sbox '( (10d,10d), (20d,20d) )'; + +SELECT 'scan_idx', qnodes('SELECT * FROM test_points WHERE p && sbox ''( (10d,10d), (20d,20d) )'''); +SELECT * FROM test_points WHERE p && sbox '( (10d,10d), (20d,20d) )'; + +-- cleanup +DROP INDEX brin_spoint; +DROP TABLE test_points; +DROP FUNCTION qnodes(text); + +set enable_indexscan = on; +set enable_bitmapscan = on; +set enable_seqscan = on; From fa429a54177282ae1eb94465903154f5f514756a Mon Sep 17 00:00:00 2001 From: Vitaly Davydov Date: Tue, 15 Aug 2023 18:08:28 +0300 Subject: [PATCH 20/87] Prepare the original PR of @gbroccolo for the merge Move brin.c(h) files into src subdirectory Add brin support in upgrade script Fix some code problems Fix test_init Fix Indices section in the doc Add test for sbox BRIN index Fix found problems in the doc after review Fix BRIN support for sbox --- Makefile | 8 +- README.pg_sphere | 4 +- doc/indices.sgm | 30 +++---- expected/init_test_healpix.out.in | 4 +- expected/sbox_brin.out | 91 ++++++++++++++++++++ expected/spoint_brin.out | 99 +++++++++++++-------- pgs_brin.sql.in | 6 +- sql/sbox_brin.sql | 138 ++++++++++++++++++++++++++++++ sql/spoint_brin.sql | 2 +- brin.c => src/brin.c | 28 +++--- brin.h => src/brin.h | 0 11 files changed, 337 insertions(+), 73 deletions(-) create mode 100644 expected/sbox_brin.out create mode 100644 sql/sbox_brin.sql rename brin.c => src/brin.c (95%) rename brin.h => src/brin.h (100%) diff --git a/Makefile b/Makefile index bb5074f..2589494 100644 --- a/Makefile +++ b/Makefile @@ -11,7 +11,7 @@ MODULE_big = pg_sphere OBJS = src/sscan.o src/sparse.o src/sbuffer.o src/vector3d.o src/point.o \ src/euler.o src/circle.o src/line.o src/ellipse.o src/polygon.o \ src/path.o src/box.o src/output.o src/gq_cache.o src/gist.o \ - src/key.o src/gnomo.o src/epochprop.o brin.o + src/key.o src/gnomo.o src/epochprop.o src/brin.o ifneq ($(USE_HEALPIX),0) OBJS += src/healpix.o src/moc.o src/process_moc.o \ @@ -33,7 +33,7 @@ DATA_built = $(RELEASE_SQL) \ DOCS = README.pg_sphere COPYRIGHT.pg_sphere REGRESS = init tables points euler circle line ellipse poly path box index \ contains_ops contains_ops_compat bounding_box_gist gnomo epochprop \ - contains overlaps spoint_brin + contains overlaps spoint_brin sbox_brin ifneq ($(USE_HEALPIX),0) REGRESS += healpix moc mocautocast @@ -43,7 +43,7 @@ REGRESS_9_5 = index_9.5 # experimental for spoint3 TESTS = init_test tables points euler circle line ellipse poly path box \ index contains_ops contains_ops_compat bounding_box_gist gnomo \ - epochprop contains overlaps + epochprop contains overlaps spoint_brin sbox_brin ifneq ($(USE_HEALPIX),0) TESTS += healpix moc mocautocast @@ -262,7 +262,7 @@ endif pg_sphere--1.2.2--1.2.3.sql: cat upgrade_scripts/$@.in > $@ -pg_sphere--1.2.3--1.3.0.sql: +pg_sphere--1.2.3--1.3.0.sql: pgs_brin.sql.in cat upgrade_scripts/$@.in > $@ # end of local stuff diff --git a/README.pg_sphere b/README.pg_sphere index cccc8ca..95a2563 100644 --- a/README.pg_sphere +++ b/README.pg_sphere @@ -9,9 +9,9 @@ It provides: * Object rotation by Euler angles * Indexing of spherical data types -This is an R-Tree implementation using GiST for spherical objects like +This is an R-tree implementation using GiST for spherical objects like spherical points and spherical circles with useful functions and operators. -It also support the Block Range INdexing (BRIN) for large datasets. +It also supports the Block Range INdexing (BRIN) for large datasets. NOTICE: This version will work only with PostgreSQL version 10 and above. diff --git a/doc/indices.sgm b/doc/indices.sgm index 7918ee0..11940c2 100644 --- a/doc/indices.sgm +++ b/doc/indices.sgm @@ -10,17 +10,17 @@ pgSphere uses GiST and Block Range INdexing (BRIN) algorithms to create spherical indices. - GiST index represents the R-Tree implementation for - spherical objects, while BRINs are based on "summarization" + GiST indexes utilize an R-tree implementation for + spherical objects, while BRIN indexes are based on the "summarization" of data blocks (pages) on physical storage in order to organize data searches on ranges of summarized data that can be easily skipped on the base of search filters (see - PostgreSQL documentation for further details on BRINs). - As a consequence, BRINs result to be really small indexes (up to 1000 times - than GiST ones), generally with lower a performance compared with a GiST one, + url="https://www.postgresql.org/docs/current/brin-intro.html"> + PostgreSQL documentation for further details on BRIN indexes). + As a consequence, BRIN indexes are very small indexes (up to 1000 times smaller + than GiST ones), generally with lower performance compared with a GiST one, but up to 100 times faster than a full sequential scan of a table performed - without any index. So BRINs are particularly suitable in a big data context. + without any index. So BRIN indexes are particularly suitable in a big data context. An index speeds up the execution time of searches based on operators <@, @, =, and !=. - Codestin Search App You can create a GiST index with the following spherical data types: @@ -87,17 +84,18 @@ - BRINs can be created through the following syntax: + BRIN index can be created through the following syntax: - By default, BRINs summarize block of 128 pages. The lower numbers - of pages are specified, the higher granularity is reached during - the searches, and performance's gap between GiST indexes and BRINs - is lower (consider that BRINs size increases as well). Different - summarizations can be used with the following command: + By default, BRIN indexes summarize blocks of 128 pages. The smaller the + number of pages specified, the higher the granularity in searches, + and the gap in performance between GiST indexes and BRIN indexes will be + decreased. Note that the size of the BRIN indexes increases as well. + Different summarizations can be specified with the following + command: diff --git a/expected/init_test_healpix.out.in b/expected/init_test_healpix.out.in index 4195603..b87a70d 100644 --- a/expected/init_test_healpix.out.in +++ b/expected/init_test_healpix.out.in @@ -1,2 +1,2 @@ -psql:pg_sphere.test.sql:9271: NOTICE: return type smoc is only a shell -psql:pg_sphere.test.sql:9277: NOTICE: argument type smoc is only a shell +psql:pg_sphere.test.sql:9684: NOTICE: return type smoc is only a shell +psql:pg_sphere.test.sql:9690: NOTICE: argument type smoc is only a shell diff --git a/expected/sbox_brin.out b/expected/sbox_brin.out new file mode 100644 index 0000000..43fd87c --- /dev/null +++ b/expected/sbox_brin.out @@ -0,0 +1,91 @@ +SELECT set_sphere_output_precision(8); + set_sphere_output_precision +----------------------------- + SET 8 +(1 row) + +CREATE TABLE test_boxes ( + b sbox +); +COPY test_boxes (b) FROM stdin; +CREATE OR REPLACE FUNCTION qnodes(q text) RETURNS text +LANGUAGE 'plpgsql' AS +$$ +DECLARE + exp TEXT; + mat TEXT[]; + ret TEXT[]; +BEGIN + FOR exp IN EXECUTE 'EXPLAIN ' || q + LOOP + --RAISE NOTICE 'EXP: %', exp; + mat := regexp_matches(exp, ' *(?:-> *)?(.*Scan on (test_boxes|test_boxes_brin_idx))'); + --RAISE NOTICE 'MAT: %', mat; + IF mat IS NOT NULL THEN + ret := array_append(ret, mat[1]); + END IF; + --RAISE NOTICE 'RET: %', ret; + END LOOP; + RETURN array_to_string(ret,','); +END; +$$; +CREATE INDEX test_boxes_brin_idx ON test_boxes USING brin (b); +SET enable_indexscan = OFF; +SET enable_bitmapscan = OFF; +SET enable_seqscan = ON; +SELECT 'scan_seq', qnodes('SELECT * FROM test_boxes WHERE b <@ sbox ''( (10d,10d), (20d,20d) )'''); + ?column? | qnodes +----------+------------------------ + scan_seq | Seq Scan on test_boxes +(1 row) + +SELECT * FROM test_boxes WHERE b <@ sbox '( (10d,10d), (20d,20d) )'; + b +--- +(0 rows) + +SELECT 'scan_seq', qnodes('SELECT * FROM test_boxes WHERE b && sbox ''( (10d,10d), (20d,20d) )'''); + ?column? | qnodes +----------+------------------------ + scan_seq | Seq Scan on test_boxes +(1 row) + +SELECT * FROM test_boxes WHERE b && sbox '( (10d,10d), (20d,20d) )'; + b +-------------------------------------------------------- + ((0.34906585 , 0.17453293), (0.35006585 , 0.17463293)) +(1 row) + +SET enable_indexscan = OFF; +SET enable_bitmapscan = ON; +SET enable_seqscan = OFF; +SELECT 'scan_idx', qnodes('SELECT * FROM test_boxes WHERE b <@ sbox ''( (10d,10d), (20d,20d) )'''); + ?column? | qnodes +----------+------------------------------------------------------------------------- + scan_idx | Bitmap Heap Scan on test_boxes,Bitmap Index Scan on test_boxes_brin_idx +(1 row) + +SELECT * FROM test_boxes WHERE b <@ sbox '( (10d,10d), (20d,20d) )'; + b +--- +(0 rows) + +SELECT 'scan_idx', qnodes('SELECT * FROM test_boxes WHERE b && sbox ''( (10d,10d), (20d,20d) )'''); + ?column? | qnodes +----------+------------------------------------------------------------------------- + scan_idx | Bitmap Heap Scan on test_boxes,Bitmap Index Scan on test_boxes_brin_idx +(1 row) + +SELECT * FROM test_boxes WHERE b && sbox '( (10d,10d), (20d,20d) )'; + b +-------------------------------------------------------- + ((0.34906585 , 0.17453293), (0.35006585 , 0.17463293)) +(1 row) + +---- cleanup +DROP INDEX test_boxes_brin_idx; +DROP TABLE test_boxes; +DROP FUNCTION qnodes(text); +SET enable_indexscan = ON; +SET enable_bitmapscan = ON; +SET enable_seqscan = ON; diff --git a/expected/spoint_brin.out b/expected/spoint_brin.out index 4bb88b0..958c709 100644 --- a/expected/spoint_brin.out +++ b/expected/spoint_brin.out @@ -1,56 +1,87 @@ -CREATE TABLE -COPY 77 -CREATE FUNCTION -CREATE INDEX -SET -SET -SET - ?column? | qnodes -----------+---------- - scan_seq | Seq Scan -(1 row) - - p +CREATE TABLE test_points ( + p spoint +); +COPY test_points (p) FROM stdin; +CREATE OR REPLACE FUNCTION qnodes(q text) RETURNS text +LANGUAGE 'plpgsql' AS +$$ +DECLARE + exp TEXT; + mat TEXT[]; + ret TEXT[]; +BEGIN + FOR exp IN EXECUTE 'EXPLAIN ' || q + LOOP + --RAISE NOTICE 'EXP: %', exp; + mat := regexp_matches(exp, ' *(?:-> *)?(.*Scan on (test_points|brin_spoint))'); + --RAISE NOTICE 'MAT: %', mat; + IF mat IS NOT NULL THEN + ret := array_append(ret, mat[1]); + END IF; + --RAISE NOTICE 'RET: %', ret; + END LOOP; + RETURN array_to_string(ret,','); +END; +$$; +CREATE INDEX brin_spoint ON test_points USING brin (p) WITH (pages_per_range = 16); +set enable_indexscan = off; +set enable_bitmapscan = off; +set enable_seqscan = on; +SELECT 'scan_seq', qnodes('SELECT * FROM test_points WHERE p <@ sbox ''( (10d,10d), (20d,20d) )'''); + ?column? | qnodes +----------+------------------------- + scan_seq | Seq Scan on test_points +(1 row) + +SELECT * FROM test_points WHERE p <@ sbox '( (10d,10d), (20d,20d) )'; + p ----------------------------------------- (0.349065850398866 , 0.174532925199433) (1 row) - ?column? | qnodes -----------+---------- - scan_seq | Seq Scan +SELECT 'scan_seq', qnodes('SELECT * FROM test_points WHERE p && sbox ''( (10d,10d), (20d,20d) )'''); + ?column? | qnodes +----------+------------------------- + scan_seq | Seq Scan on test_points (1 row) - p +SELECT * FROM test_points WHERE p && sbox '( (10d,10d), (20d,20d) )'; + p ----------------------------------------- (0.349065850398866 , 0.174532925199433) (1 row) -SET -SET -SET - ?column? | qnodes -----------+------------------------------------ - scan_idx | Bitmap Heap Scan,Bitmap Index Scan +set enable_indexscan = off; +set enable_bitmapscan = on; +set enable_seqscan = off; +SELECT 'scan_idx', qnodes('SELECT * FROM test_points WHERE p <@ sbox ''( (10d,10d), (20d,20d) )'''); + ?column? | qnodes +----------+------------------------------------------------------------------ + scan_idx | Bitmap Heap Scan on test_points,Bitmap Index Scan on brin_spoint (1 row) - p +SELECT * FROM test_points WHERE p <@ sbox '( (10d,10d), (20d,20d) )'; + p ----------------------------------------- (0.349065850398866 , 0.174532925199433) (1 row) - ?column? | qnodes -----------+------------------------------------ - scan_idx | Bitmap Heap Scan,Bitmap Index Scan +SELECT 'scan_idx', qnodes('SELECT * FROM test_points WHERE p && sbox ''( (10d,10d), (20d,20d) )'''); + ?column? | qnodes +----------+------------------------------------------------------------------ + scan_idx | Bitmap Heap Scan on test_points,Bitmap Index Scan on brin_spoint (1 row) - p +SELECT * FROM test_points WHERE p && sbox '( (10d,10d), (20d,20d) )'; + p ----------------------------------------- (0.349065850398866 , 0.174532925199433) (1 row) -DROP INDEX -DROP TABLE -DROP FUNCTION -SET -SET -SET +-- cleanup +DROP INDEX brin_spoint; +DROP TABLE test_points; +DROP FUNCTION qnodes(text); +set enable_indexscan = on; +set enable_bitmapscan = on; +set enable_seqscan = on; diff --git a/pgs_brin.sql.in b/pgs_brin.sql.in index 93fe8dd..4b0fba5 100644 --- a/pgs_brin.sql.in +++ b/pgs_brin.sql.in @@ -406,6 +406,8 @@ ALTER OPERATOR FAMILY brin_inclusion_spheric_ops USING brin ADD OPERATOR 7 @>(sbox, spoint), OPERATOR 7 @>(spoint, sbox), OPERATOR 8 <@(sbox, spoint), - OPERATOR 8 <@(spoint, sbox); - + OPERATOR 8 <@(spoint, sbox), + OPERATOR 3 &&(sbox, sbox), + OPERATOR 7 @>(sbox, sbox), + OPERATOR 8 <@(sbox, sbox); diff --git a/sql/sbox_brin.sql b/sql/sbox_brin.sql new file mode 100644 index 0000000..24f30d0 --- /dev/null +++ b/sql/sbox_brin.sql @@ -0,0 +1,138 @@ +SELECT set_sphere_output_precision(8); + +CREATE TABLE test_boxes ( + b sbox +); + +COPY test_boxes (b) FROM stdin; +( (0.349065850398866, 0.174532925199433), (0.350065850398866, 0.174632925199433) ) +( (1.59875999207035, 0.771416330759722), (1.5997599920703498, 0.771516330759722) ) +( (1.59876348272885, 0.77141458543047), (1.5997634827288498, 0.77151458543047) ) +( (1.59876697338736, 0.771412840101218), (1.5997669733873598, 0.771512840101218) ) +( (1.59877046404586, 0.771411094771966), (1.5997704640458599, 0.771511094771966) ) +( (1.59877395470437, 0.771409349442714), (1.59977395470437, 0.771509349442714) ) +( (1.59877744536287, 0.771407604113461), (1.59977744536287, 0.771507604113461) ) +( (1.59878093602137, 0.77140585878421), (1.59978093602137, 0.77150585878421) ) +( (1.59878442667988, 0.771404113454958), (1.59978442667988, 0.771504113454958) ) +( (1.59878791733838, 0.771402368125706), (1.59978791733838, 0.7715023681257059) ) +( (1.59879140799689, 0.771400622796454), (1.5997914079968898, 0.771500622796454) ) +( (1.59879489865539, 0.771398877467202), (1.5997948986553898, 0.771498877467202) ) +( (1.59879838931389, 0.77139713213795), (1.5997983893138898, 0.77149713213795) ) +( (1.5988018799724, 0.771395386808698), (1.5998018799723999, 0.771495386808698) ) +( (1.5988053706309, 0.771393641479446), (1.5998053706309, 0.771493641479446) ) +( (1.59880886128941, 0.771391896150194), (1.59980886128941, 0.771491896150194) ) +( (1.59881235194791, 0.771390150820941), (1.59981235194791, 0.771490150820941) ) +( (1.59881584260641, 0.77138840549169), (1.59981584260641, 0.77148840549169) ) +( (1.59881933326492, 0.771386660162438), (1.59981933326492, 0.7714866601624379) ) +( (1.59882282392342, 0.771384914833186), (1.5998228239234198, 0.771484914833186) ) +( (1.59882631458193, 0.771383169503934), (1.5998263145819298, 0.771483169503934) ) +( (1.59882980524043, 0.771381424174682), (1.5998298052404298, 0.771481424174682) ) +( (1.59883329589893, 0.77137967884543), (1.5998332958989299, 0.77147967884543) ) +( (1.59883678655744, 0.771377933516178), (1.5998367865574399, 0.771477933516178) ) +( (1.59884027721594, 0.771376188186926), (1.59984027721594, 0.771476188186926) ) +( (1.59884376787445, 0.771374442857673), (1.59984376787445, 0.771474442857673) ) +( (1.59884725853295, 0.771372697528422), (1.59984725853295, 0.771472697528422) ) +( (1.59885074919145, 0.77137095219917), (1.59985074919145, 0.77147095219917) ) +( (1.59885423984996, 0.771369206869918), (1.5998542398499598, 0.7714692068699179) ) +( (1.59885773050846, 0.771367461540666), (1.5998577305084598, 0.771467461540666) ) +( (1.59886122116697, 0.771365716211414), (1.5998612211669698, 0.771465716211414) ) +( (1.59886471182547, 0.771363970882162), (1.5998647118254699, 0.771463970882162) ) +( (1.59886820248397, 0.77136222555291), (1.5998682024839699, 0.77146222555291) ) +( (1.59887169314248, 0.771360480223658), (1.59987169314248, 0.771460480223658) ) +( (1.59887518380098, 0.771358734894406), (1.59987518380098, 0.771458734894406) ) +( (1.59887867445948, 0.771356989565154), (1.59987867445948, 0.771456989565154) ) +( (1.59888216511799, 0.771355244235902), (1.59988216511799, 0.771455244235902) ) +( (1.59888565577649, 0.77135349890665), (1.5998856557764898, 0.7714534989066499) ) +( (1.598889146435, 0.771351753577398), (1.5998891464349998, 0.771451753577398) ) +( (1.5988926370935, 0.771350008248146), (1.5998926370934998, 0.771450008248146) ) +( (1.59889612775201, 0.771348262918894), (1.5998961277520098, 0.771448262918894) ) +( (1.59889961841051, 0.771346517589642), (1.5998996184105099, 0.771446517589642) ) +( (1.59890310906901, 0.77134477226039), (1.59990310906901, 0.77144477226039) ) +( (1.59890659972752, 0.771343026931138), (1.59990659972752, 0.771443026931138) ) +( (1.59891009038602, 0.771341281601886), (1.59991009038602, 0.771441281601886) ) +( (1.59891358104452, 0.771339536272634), (1.59991358104452, 0.771439536272634) ) +( (1.59891707170303, 0.771337790943382), (1.59991707170303, 0.7714377909433819) ) +( (1.59892056236153, 0.77133604561413), (1.5999205623615298, 0.77143604561413) ) +( (1.59892405302004, 0.771334300284878), (1.5999240530200398, 0.771434300284878) ) +( (1.59892754367854, 0.771332554955626), (1.5999275436785398, 0.771432554955626) ) +( (1.59893103433705, 0.771330809626374), (1.5999310343370499, 0.771430809626374) ) +( (1.59893452499555, 0.771329064297122), (1.59993452499555, 0.771429064297122) ) +( (1.59893801565405, 0.77132731896787), (1.59993801565405, 0.77142731896787) ) +( (1.59894150631256, 0.771325573638618), (1.59994150631256, 0.771425573638618) ) +( (1.59894499697106, 0.771323828309366), (1.59994499697106, 0.771423828309366) ) +( (1.59894848762957, 0.771322082980114), (1.59994848762957, 0.7714220829801139) ) +( (1.59895197828807, 0.771320337650862), (1.5999519782880698, 0.771420337650862) ) +( (1.59895546894657, 0.77131859232161), (1.5999554689465698, 0.77141859232161) ) +( (3.61121537674092, -1.33598496521933), (3.6122153767409197, -1.33588496521933) ) +( (3.61121886739942, -1.33598321989008), (3.6122188673994198, -1.33588321989008) ) +( (3.61122235805792, -1.33598147456083), (3.61222235805792, -1.33588147456083) ) +( (3.61122584871643, -1.33597972923158), (3.61222584871643, -1.33587972923158) ) +( (3.61122933937493, -1.33597798390233), (3.61222933937493, -1.33587798390233) ) +( (3.61123283003344, -1.33597623857307), (3.61223283003344, -1.33587623857307) ) +( (3.61123632069194, -1.33597449324382), (3.61223632069194, -1.33587449324382) ) +( (3.61123981135044, -1.33597274791457), (3.61223981135044, -1.33587274791457) ) +( (3.61124330200895, -1.33597100258532), (3.6122433020089497, -1.33587100258532) ) +( (3.61124679266745, -1.33596925725607), (3.6122467926674497, -1.33586925725607) ) +( (3.61125028332595, -1.33596751192682), (3.6122502833259498, -1.33586751192682) ) +( (3.61125377398446, -1.33596576659756), (3.61225377398446, -1.33586576659756) ) +( (3.61125726464296, -1.33596402126831), (3.61225726464296, -1.33586402126831) ) +( (3.61126075530147, -1.33596227593906), (3.61226075530147, -1.33586227593906) ) +( (3.61126424595997, -1.33596053060981), (3.61226424595997, -1.33586053060981) ) +( (3.61126773661847, -1.33595878528056), (3.61226773661847, -1.33585878528056) ) +( (3.61127122727698, -1.3359570399513), (3.6122712272769797, -1.3358570399513001) ) +( (3.61127471793548, -1.33595529462205), (3.6122747179354797, -1.33585529462205) ) +( (3.61127820859399, -1.3359535492928), (3.61227820859399, -1.3358535492928) ) +\. + +CREATE OR REPLACE FUNCTION qnodes(q text) RETURNS text +LANGUAGE 'plpgsql' AS +$$ +DECLARE + exp TEXT; + mat TEXT[]; + ret TEXT[]; +BEGIN + FOR exp IN EXECUTE 'EXPLAIN ' || q + LOOP + --RAISE NOTICE 'EXP: %', exp; + mat := regexp_matches(exp, ' *(?:-> *)?(.*Scan on (test_boxes|test_boxes_brin_idx))'); + --RAISE NOTICE 'MAT: %', mat; + IF mat IS NOT NULL THEN + ret := array_append(ret, mat[1]); + END IF; + --RAISE NOTICE 'RET: %', ret; + END LOOP; + RETURN array_to_string(ret,','); +END; +$$; + +CREATE INDEX test_boxes_brin_idx ON test_boxes USING brin (b); + +SET enable_indexscan = OFF; +SET enable_bitmapscan = OFF; +SET enable_seqscan = ON; + +SELECT 'scan_seq', qnodes('SELECT * FROM test_boxes WHERE b <@ sbox ''( (10d,10d), (20d,20d) )'''); +SELECT * FROM test_boxes WHERE b <@ sbox '( (10d,10d), (20d,20d) )'; + +SELECT 'scan_seq', qnodes('SELECT * FROM test_boxes WHERE b && sbox ''( (10d,10d), (20d,20d) )'''); +SELECT * FROM test_boxes WHERE b && sbox '( (10d,10d), (20d,20d) )'; + +SET enable_indexscan = OFF; +SET enable_bitmapscan = ON; +SET enable_seqscan = OFF; + +SELECT 'scan_idx', qnodes('SELECT * FROM test_boxes WHERE b <@ sbox ''( (10d,10d), (20d,20d) )'''); +SELECT * FROM test_boxes WHERE b <@ sbox '( (10d,10d), (20d,20d) )'; + +SELECT 'scan_idx', qnodes('SELECT * FROM test_boxes WHERE b && sbox ''( (10d,10d), (20d,20d) )'''); +SELECT * FROM test_boxes WHERE b && sbox '( (10d,10d), (20d,20d) )'; + +---- cleanup +DROP INDEX test_boxes_brin_idx; +DROP TABLE test_boxes; +DROP FUNCTION qnodes(text); + +SET enable_indexscan = ON; +SET enable_bitmapscan = ON; +SET enable_seqscan = ON; diff --git a/sql/spoint_brin.sql b/sql/spoint_brin.sql index b03508d..4a37f37 100644 --- a/sql/spoint_brin.sql +++ b/sql/spoint_brin.sql @@ -93,7 +93,7 @@ BEGIN FOR exp IN EXECUTE 'EXPLAIN ' || q LOOP --RAISE NOTICE 'EXP: %', exp; - mat := regexp_matches(exp, ' *(?:-> *)?(.*Scan)'); + mat := regexp_matches(exp, ' *(?:-> *)?(.*Scan on (test_points|brin_spoint))'); --RAISE NOTICE 'MAT: %', mat; IF mat IS NOT NULL THEN ret := array_append(ret, mat[1]); diff --git a/brin.c b/src/brin.c similarity index 95% rename from brin.c rename to src/brin.c index 5a5ae03..1c5ae1b 100644 --- a/brin.c +++ b/src/brin.c @@ -53,7 +53,7 @@ spoint_brin_inclusion_add_value(PG_FUNCTION_ARGS) PG_RETURN_BOOL(true); } - spherepoint_gen_key(&spointkey, newval); + spherepoint_gen_key(spointkey, newval); /* * If spherekey pointer is NULL, we consider the spoint entry as 'empty'. @@ -61,6 +61,7 @@ spoint_brin_inclusion_add_value(PG_FUNCTION_ARGS) * The OpClass support empty entries: we need to set the "contains empty" * flag in the element (unless already set). */ + /* if (spointkey == NULL) { if (!DatumGetBool(column->bv_values[INCLUSION_CONTAINS_EMPTY])) @@ -71,6 +72,7 @@ spoint_brin_inclusion_add_value(PG_FUNCTION_ARGS) PG_RETURN_BOOL(false); } + */ /* if the recorded value is null, we just need to store the spherekey */ if (column->bv_allnulls) @@ -121,7 +123,7 @@ sbox_brin_inclusion_add_value(PG_FUNCTION_ARGS) PG_RETURN_BOOL(true); } - spherebox_gen_key(&sboxkey, newval); + spherebox_gen_key(sboxkey, newval); /* * If spherekey pointer is NULL, we consider the spoint entry as 'empty'. @@ -129,6 +131,7 @@ sbox_brin_inclusion_add_value(PG_FUNCTION_ARGS) * The OpClass support empty entries: we need to set the "contains empty" * flag in the element (unless already set). */ + /* if (sboxkey == NULL) { if (!DatumGetBool(column->bv_values[INCLUSION_CONTAINS_EMPTY])) @@ -139,6 +142,7 @@ sbox_brin_inclusion_add_value(PG_FUNCTION_ARGS) PG_RETURN_BOOL(false); } + */ /* if the recorded value is null, we just need to store the spherekey */ if (column->bv_allnulls) @@ -178,7 +182,7 @@ spoint_overlaps_spherekey(PG_FUNCTION_ARGS) SPoint *p1 = (SPoint *) PG_GETARG_POINTER(0); int32 *k2 = (int32 *) PG_GETARG_POINTER(1); - spherepoint_gen_key(&k1, p1); + spherepoint_gen_key(k1, p1); if (spherekey_interleave(k1, k2) == SCKEY_OVERLAP) { PG_RETURN_BOOL(true); @@ -194,7 +198,7 @@ spoint_contains_spherekey(PG_FUNCTION_ARGS) SPoint *p1 = (SPoint *) PG_GETARG_POINTER(0); int32 *k2 = (int32 *) PG_GETARG_POINTER(1); - spherepoint_gen_key(&k1, p1); + spherepoint_gen_key(k1, p1); if (spherekey_interleave(k1, k2) == SCKEY_IN) { PG_RETURN_BOOL(true); @@ -210,7 +214,7 @@ spoint_iscontained_spherekey(PG_FUNCTION_ARGS) SPoint *p1 = (SPoint *) PG_GETARG_POINTER(0); int32 *k2 = (int32 *) PG_GETARG_POINTER(1); - spherepoint_gen_key(&k1, p1); + spherepoint_gen_key(k1, p1); if (spherekey_interleave(k2, k1) == SCKEY_IN) { PG_RETURN_BOOL(true); @@ -226,7 +230,7 @@ sbox_overlaps_spherekey(PG_FUNCTION_ARGS) SBOX *p1 = (SBOX *) PG_GETARG_POINTER(0); int32 *k2 = (int32 *) PG_GETARG_POINTER(1); - spherebox_gen_key(&k1, p1); + spherebox_gen_key(k1, p1); if (spherekey_interleave(k1, k2) == SCKEY_OVERLAP) { PG_RETURN_BOOL(true); @@ -242,7 +246,7 @@ sbox_contains_spherekey(PG_FUNCTION_ARGS) SBOX *p1 = (SBOX *) PG_GETARG_POINTER(0); int32 *k2 = (int32 *) PG_GETARG_POINTER(1); - spherebox_gen_key(&k1, p1); + spherebox_gen_key(k1, p1); if (spherekey_interleave(k1, k2) == SCKEY_IN) { PG_RETURN_BOOL(true); @@ -258,7 +262,7 @@ sbox_iscontained_spherekey(PG_FUNCTION_ARGS) SBOX *p1 = (SBOX *) PG_GETARG_POINTER(0); int32 *k2 = (int32 *) PG_GETARG_POINTER(1); - spherebox_gen_key(&k1, p1); + spherebox_gen_key(k1, p1); if (spherekey_interleave(k2, k1) == SCKEY_IN) { PG_RETURN_BOOL(true); @@ -317,8 +321,8 @@ spoint_overlaps_sbox(PG_FUNCTION_ARGS) int32 k2[6]; SBOX *p2 = (SBOX *) PG_GETARG_POINTER(1); - spherepoint_gen_key(&k1, p1); - spherebox_gen_key(&k2, p2); + spherepoint_gen_key(k1, p1); + spherebox_gen_key(k2, p2); if (spherekey_interleave(k1, k2) == SCKEY_OVERLAP) { @@ -336,8 +340,8 @@ sbox_iscontained_spoint(PG_FUNCTION_ARGS) int32 k2[6]; SPoint *p2 = (SPoint *) PG_GETARG_POINTER(1); - spherebox_gen_key(&k1, p1); - spherepoint_gen_key(&k2, p2); + spherebox_gen_key(k1, p1); + spherepoint_gen_key(k2, p2); if (spherekey_interleave(k1, k2) == SCKEY_IN) { diff --git a/brin.h b/src/brin.h similarity index 100% rename from brin.h rename to src/brin.h From 752900a42f7f87fe5cf1f54337fbbd406a65a6d7 Mon Sep 17 00:00:00 2001 From: Vitaly Davydov Date: Wed, 30 Aug 2023 18:23:05 +0300 Subject: [PATCH 21/87] Fix pg_sphere--1.2.3--1.3.0 upgrade script (add brin support) --- Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Makefile b/Makefile index 2589494..c3351cb 100644 --- a/Makefile +++ b/Makefile @@ -263,7 +263,7 @@ pg_sphere--1.2.2--1.2.3.sql: cat upgrade_scripts/$@.in > $@ pg_sphere--1.2.3--1.3.0.sql: pgs_brin.sql.in - cat upgrade_scripts/$@.in > $@ + cat upgrade_scripts/$@.in $^ > $@ # end of local stuff From cce07bb9baa567ec86ce95f3ed2de65f790fefea Mon Sep 17 00:00:00 2001 From: Vitaly Davydov Date: Thu, 7 Sep 2023 13:59:30 +0300 Subject: [PATCH 22/87] Fix test fails on Debian 32 bit system due to gcc bug 323 On some 32 bit platforms, there is a gcc bug that makes floating point calculations and comparisons unstable (see the link below). The problem originates in FPU 80 bits registers where double values are not truncated to 64 bit values. When gcc compiles some code with enabled optimizations, the intermediate results may be kept in the FPU registers without truncation to 64 bit values. Extra bits may produce unstable results when comparing the numbers. The generic solution is to save the intermediate results in the memory where the values are truncated to 64 bit values. It affects the performance but makes the tests stable on all platforms. PGSPHERE_FLOAT_STORE macro enables storing of intermediate results for FPxx operations in the memory. It is enabled by default for 32 bit platforms. It can be explicitly enabled or disabled in CFLAGS. To enable it for all code the gcc option -ffloat-store may be used as well. Link to gcc bug: https://gcc.gnu.org/bugzilla/show_bug.cgi?id=323 --- src/pg_sphere.h | 77 +++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 77 insertions(+) diff --git a/src/pg_sphere.h b/src/pg_sphere.h index 7c6e24c..24d950a 100644 --- a/src/pg_sphere.h +++ b/src/pg_sphere.h @@ -45,10 +45,85 @@ #include "pgs_util.h" +/* On some 32 bit platforms, there is a gcc bug that makes floating point + * calculations and comparisons unstable (see the link below). The problem + * originates in FPU 80 bits registers where double values are not truncated + * to 64 bit values. When gcc compiles some code with enabled optimizations, + * the intermediate results may be kept in the FPU registers without truncation + * to 64 bit values. Extra bits may produce unstable results when comparing + * the numbers. + * + * The generic solution is to save the intermediate results in the memory where + * the values are truncated to 64 bit values. It affects the performance but + * makes the tests stable on all platforms. + * + * PGSPHERE_FLOAT_STORE macro enables storing of intermediate results for FPxx + * operations in the memory. It is enabled by default for 32 bit platforms. + * It can be explicitly enabled or disabled in CFLAGS. To enable it for all + * code the gcc option -ffloat-store may be used as well. + * + * Link to gcc bug: https://gcc.gnu.org/bugzilla/show_bug.cgi?id=323 + */ +#if !defined(PGSPHERE_FLOAT_STORE) +#if _WIN64 || (__GNUC__ && __x86_64__) +#define PGSPHERE_FLOAT_STORE 0 +#elif _WIN32 || __GNUC__ +#define PGSPHERE_FLOAT_STORE 1 +#else +#define PGSPHERE_FLOAT_STORE 0 +#endif +#endif // PGSPHERE_FLOAT_STORE + #define EPSILON 1.0E-09 #define FPzero(A) (fabs(A) <= EPSILON) +#if PGSPHERE_FLOAT_STORE + +static inline bool +FPeq(double A, double B) +{ + const volatile double AB = A - B; + return A == B || fabs(AB) <= EPSILON; +} + +static inline bool +FPne(double A, double B) +{ + const volatile double AB = A - B; + return A != B && fabs(AB) > EPSILON; +} + +static inline bool +FPlt(double A, double B) +{ + const volatile double AE = A + EPSILON; + return AE < B; +} + +static inline bool +FPle(double A, double B) +{ + const volatile double BE = B + EPSILON; + return A <= BE; +} + +static inline bool +FPgt(double A, double B) +{ + const volatile double BE = B + EPSILON; + return A > BE; +} + +static inline bool +FPge(double A, double B) +{ + const volatile double AE = A + EPSILON; + return AE >= B; +} + +#else + static inline bool FPeq(double A, double B) { @@ -85,6 +160,8 @@ FPge(double A, double B) return A + EPSILON >= B; } +#endif // PGSPHERE_FLOAT_STORE + /*--------------------------------------------------------------------- * Point - (x,y) *-------------------------------------------------------------------*/ From 8e7c92fd57aa57ac702722ffd5dcf426e10ab404 Mon Sep 17 00:00:00 2001 From: Vitaly Davydov Date: Thu, 7 Sep 2023 16:28:35 +0300 Subject: [PATCH 23/87] Incremented pgsphere version (patch number) --- Makefile | 8 ++++++-- expected/init.out | 2 +- pg_sphere--1.3.0.sql.in => pg_sphere--1.3.1.sql.in | 0 pg_sphere.control | 2 +- upgrade_scripts/pg_sphere--1.3.0--1.3.1.sql.in | 1 + 5 files changed, 9 insertions(+), 4 deletions(-) rename pg_sphere--1.3.0.sql.in => pg_sphere--1.3.1.sql.in (100%) create mode 100644 upgrade_scripts/pg_sphere--1.3.0--1.3.1.sql.in diff --git a/Makefile b/Makefile index c3351cb..c8287ae 100644 --- a/Makefile +++ b/Makefile @@ -1,4 +1,4 @@ -PGSPHERE_VERSION = 1.3.0 +PGSPHERE_VERSION = 1.3.1 EXTENSION = pg_sphere RELEASE_SQL = $(EXTENSION)--$(PGSPHERE_VERSION).sql USE_PGXS = 1 @@ -28,7 +28,8 @@ DATA_built = $(RELEASE_SQL) \ pg_sphere--1.2.0--1.2.1.sql \ pg_sphere--1.2.1--1.2.2.sql \ pg_sphere--1.2.2--1.2.3.sql \ - pg_sphere--1.2.3--1.3.0.sql + pg_sphere--1.2.3--1.3.0.sql \ + pg_sphere--1.3.0--1.3.1.sql DOCS = README.pg_sphere COPYRIGHT.pg_sphere REGRESS = init tables points euler circle line ellipse poly path box index \ @@ -265,6 +266,9 @@ pg_sphere--1.2.2--1.2.3.sql: pg_sphere--1.2.3--1.3.0.sql: pgs_brin.sql.in cat upgrade_scripts/$@.in $^ > $@ +pg_sphere--1.3.0--1.3.1.sql: + cat upgrade_scripts/$@.in > $@ + # end of local stuff src/sscan.o : src/sparse.c diff --git a/expected/init.out b/expected/init.out index fc47f40..fb86488 100644 --- a/expected/init.out +++ b/expected/init.out @@ -6,6 +6,6 @@ CREATE EXTENSION pg_sphere; select pg_sphere_version(); pg_sphere_version ------------------- - 1.3.0 + 1.3.1 (1 row) diff --git a/pg_sphere--1.3.0.sql.in b/pg_sphere--1.3.1.sql.in similarity index 100% rename from pg_sphere--1.3.0.sql.in rename to pg_sphere--1.3.1.sql.in diff --git a/pg_sphere.control b/pg_sphere.control index 412cd57..e2b8ad3 100644 --- a/pg_sphere.control +++ b/pg_sphere.control @@ -1,5 +1,5 @@ # pg_sphere extension comment = 'spherical objects with useful functions, operators and index support' -default_version = '1.3.0' +default_version = '1.3.1' module_pathname = '$libdir/pg_sphere' relocatable = true diff --git a/upgrade_scripts/pg_sphere--1.3.0--1.3.1.sql.in b/upgrade_scripts/pg_sphere--1.3.0--1.3.1.sql.in new file mode 100644 index 0000000..8ea3baa --- /dev/null +++ b/upgrade_scripts/pg_sphere--1.3.0--1.3.1.sql.in @@ -0,0 +1 @@ +-- Nothing to upgrade in the schema From fc43fc8a2ac1cb894309fc4ab5646fcefebda302 Mon Sep 17 00:00:00 2001 From: Ed Sabol Date: Fri, 15 Sep 2023 02:32:06 -0400 Subject: [PATCH 24/87] Minor correction to README.pg_sphere Oops! This PR corrects a copy/paste/edit error in the README installation update instructions. --- README.pg_sphere | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.pg_sphere b/README.pg_sphere index 95a2563..be6b40f 100644 --- a/README.pg_sphere +++ b/README.pg_sphere @@ -54,7 +54,7 @@ UPDATING AN EXISTING INSTALLATION: -- same make and make install steps as above, but, instead of the CREATE -- EXTENSION step, you need to do: - psql -c "ALTER EXTENSION q3c UPDATE TO 'A.B.C';" + psql -c "ALTER EXTENSION pg_sphere UPDATE TO 'A.B.C';" -- where A.B.C is a placeholder for the current version. -- You also may want to check what version of pgSphere is installed using From 3568f70f17dabab828abc2da528d83056b65a868 Mon Sep 17 00:00:00 2001 From: Vitaly Davydov Date: Wed, 13 Sep 2023 14:54:02 +0300 Subject: [PATCH 25/87] Migrate doc generation to docbook/fop (postgresql approach) The document generation was redesigned to use the same approach as postgresql does. It uses fop for printable doc generation and xsltproc for html generation. Postgresql stylesheets are used (with some minor changes). Fixed version propagation when generating the doc. Now, the version is placed in Makefile.common.mk file that is used in doc generation process. The following make rules were implemented: - make pdf (generates printable doc in A4 and US Letter format) - make pg_sphere--A4.pdf (generate the printable doc in A4) - make pg_sphere--US.pdf (generate the printable doc in USLetter) - make html (generates single-page and multi-page html) - make html-singlepage (generate single-page html only) - make html-multipage (generate multi-page html only) --- Makefile | 5 +- Makefile.common.mk | 8 + doc/Makefile | 121 +++-- doc/constructors.sgm | 59 ++- doc/examples.sgm | 52 +-- doc/functions.sgm | 145 +++--- doc/indices.sgm | 21 +- doc/install.sgm | 47 +- doc/jadetex.cfg-dist | 14 - doc/operators.sgm | 67 ++- doc/pg_sphere.css | 182 -------- doc/pg_sphere.dsl-dist | 330 ------------- doc/pg_sphere.xml | 69 +-- doc/stylesheets/stylesheet-common.xsl | 126 +++++ doc/stylesheets/stylesheet-fo.xsl | 147 ++++++ doc/stylesheets/stylesheet-html-common.xsl | 439 ++++++++++++++++++ doc/stylesheets/stylesheet-html-nochunk.xsl | 24 + doc/stylesheets/stylesheet-man.xsl | 226 +++++++++ doc/stylesheets/stylesheet-speedup-common.xsl | 100 ++++ doc/stylesheets/stylesheet-speedup-xhtml.xsl | 345 ++++++++++++++ doc/stylesheets/stylesheet-text.xsl | 97 ++++ doc/stylesheets/stylesheet.css | 182 ++++++++ doc/stylesheets/stylesheet.css.xml | 8 + doc/stylesheets/stylesheet.xsl | 328 +++++++++++++ doc/types.sgm | 100 ++-- doc/whatis.sgm | 21 +- 26 files changed, 2376 insertions(+), 887 deletions(-) create mode 100644 Makefile.common.mk delete mode 100644 doc/jadetex.cfg-dist delete mode 100644 doc/pg_sphere.css delete mode 100644 doc/pg_sphere.dsl-dist create mode 100644 doc/stylesheets/stylesheet-common.xsl create mode 100644 doc/stylesheets/stylesheet-fo.xsl create mode 100644 doc/stylesheets/stylesheet-html-common.xsl create mode 100644 doc/stylesheets/stylesheet-html-nochunk.xsl create mode 100644 doc/stylesheets/stylesheet-man.xsl create mode 100644 doc/stylesheets/stylesheet-speedup-common.xsl create mode 100644 doc/stylesheets/stylesheet-speedup-xhtml.xsl create mode 100644 doc/stylesheets/stylesheet-text.xsl create mode 100644 doc/stylesheets/stylesheet.css create mode 100644 doc/stylesheets/stylesheet.css.xml create mode 100644 doc/stylesheets/stylesheet.xsl diff --git a/Makefile b/Makefile index c8287ae..5dbdac2 100644 --- a/Makefile +++ b/Makefile @@ -1,5 +1,6 @@ -PGSPHERE_VERSION = 1.3.1 -EXTENSION = pg_sphere + +include Makefile.common.mk + RELEASE_SQL = $(EXTENSION)--$(PGSPHERE_VERSION).sql USE_PGXS = 1 USE_HEALPIX =? 1 diff --git a/Makefile.common.mk b/Makefile.common.mk new file mode 100644 index 0000000..f3893a9 --- /dev/null +++ b/Makefile.common.mk @@ -0,0 +1,8 @@ +#---------------------------------------------------------------------------- +# +# pgSphere common definitions +# +#---------------------------------------------------------------------------- + +EXTENSION := pg_sphere +PGSPHERE_VERSION := 1.3.1 diff --git a/doc/Makefile b/doc/Makefile index a607103..47a1396 100644 --- a/doc/Makefile +++ b/doc/Makefile @@ -1,9 +1,16 @@ #---------------------------------------------------------------------------- # -# pgSphere documentation makefile +# pgSphere documentation generation # #---------------------------------------------------------------------------- +ifndef PGSPHERE_VERSION +include ../Makefile.common.mk +ifndef PGSPHERE_VERSION +$(error PGSPHERE_VERSION is not set) +endif +endif + USE_PGXS = 1 ifdef USE_PGXS PG_CONFIG = pg_config @@ -16,75 +23,89 @@ include $(top_builddir)/src/Makefile.global include $(top_srcdir)/contrib/contrib-global.mk endif -.SECONDARY: -.NOTPARALLEL: +ifndef FOP +FOP = fop +endif -ifndef COLLATEINDEX -COLLATEINDEX = $(DOCBOOKSTYLE)/bin/collateindex.pl +ifdef XMLLINT +XMLLINT := $(XMLLINT) --nonet +else +XMLLINT = $(missing) xmllint endif -ifndef JADE -JADE = openjade +ifdef XSLTPROC +XSLTPROC := $(XSLTPROC) --nonet +else +XSLTPROC = $(missing) xsltproc endif -SGMLINCLUDE = -D $(srcdir) -ALLSGML := $(wildcard $(srcdir)/*.sgm) +override XSLTPROCFLAGS += \ + --path stylesheets --path img --path . \ + --stringparam pg_sphere.version '$(PGSPHERE_VERSION)' \ + --stringparam pg.version '$(PGSPHERE_VERSION)' -ifdef DOCBOOKSTYLE -CATALOG = -c $(DOCBOOKSTYLE)/catalog -endif +XMLINCLUDE = --path . +ALLSGML := $(wildcard *.sgm) +ALLIMAGES := $(wildcard img/*.jpg) -COLLATEINDEX := $(PERL) $(COLLATEINDEX) -f -g +.PHONY: all html pdf +all: version.ent html pdf -all : html +version.xml: + @echo $(PGSPHERE_VERSION) > version.xml -.PHONY: html pdf ps +pg_sphere-full.xml: version.xml +pg_sphere-full.xml: pg_sphere.xml $(ALLSGML) + $(XMLLINT) $(XMLINCLUDE) --output $@ --noent --valid $< -XMLDCL = declaration/xml.dcl +#------------------------------------------------------------------------------ +# HTML +#------------------------------------------------------------------------------ -html : pg_sphere.xml $(ALLSGML) pg_sphere.dsl - @rm -f *.html - @rm -rf html - mkdir html - mkdir html/img - cp img/*.jpg img/*.png html/img - cp pg_sphere.css html - $(JADE) $(JADEFLAGS) $(SGMLINCLUDE) $(CATALOG) -b UTF-8 -d pg_sphere.dsl -i html -t sgml $(XMLDCL) $< - mv *.html html +XSLTPROC_HTML_MULTIPAGE_FLAGS := --stringparam img.src.path '' +XSLTPROC_HTML_SINGLEPAGE_FLAGS := --stringparam img.src.path '' -pg_sphere.tex : pg_sphere.xml $(ALLSGML) pg_sphere.dsl - $(JADE) $(JADEFLAGS) $(SGMLINCLUDE) $(CATALOG) -d pg_sphere.dsl -i print -t tex -o $@ $(XMLDCL) $< +html: html-singlepage html-multipage -pdf : jadetex.cfg pg_sphere.pdf +html-multipage: stylesheets/stylesheet.xsl pg_sphere-full.xml version.xml $(ALLIMAGES) + $(XSLTPROC) $(XMLINCLUDE) $(XSLTPROCFLAGS) $(XSLTPROC_HTML_MULTIPAGE_FLAGS) $(wordlist 1,2,$^) + mkdir -p html/img + cp $(ALLIMAGES) html/img -pg_sphere.pdf: pg_sphere.tex - @rm -f $*.aux $*.log $*.out - pdfjadetex $< - pdfjadetex $< - pdfjadetex $< +html-singlepage: pg_sphere-$(PGSPHERE_VERSION).html -ps : pg_sphere.ps +pg_sphere-$(PGSPHERE_VERSION).html: stylesheets/stylesheet-html-nochunk.xsl pg_sphere-full.xml version.xml $(ALLIMAGES) + $(XSLTPROC) $(XMLINCLUDE) $(XSLTPROCFLAGS) $(XSLTPROC_HTML_SINGLEPAGE_FLAGS) -o $@ $(wordlist 1,2,$^) -pg_sphere.ps: pg_sphere.pdf - pdftops $< $@ +#------------------------------------------------------------------------------ +# PDF +#------------------------------------------------------------------------------ -pg_sphere.dsl : pg_sphere.dsl-dist - cp $< $@ +pdf: pg_sphere-${PGSPHERE_VERSION}-A4.pdf pg_sphere-${PGSPHERE_VERSION}-US.pdf -jadetex.cfg : jadetex.cfg-dist - cp $< $@ +pg_sphere-$(PGSPHERE_VERSION)-A4.pdf: pg_sphere.A4.fo + $(FOP) -v -fo $< -pdf $@ +pg_sphere-$(PGSPHERE_VERSION)-US.pdf: pg_sphere.US.fo + $(FOP) -v -fo $< -pdf $@ +pg_sphere.A4.fo: stylesheets/stylesheet-fo.xsl pg_sphere-full.xml version.xml $(ALLIMAGES) + $(XSLTPROC) $(XMLINCLUDE) $(XSLTPROCFLAGS) $(XSLTPROC_FO_FLAGS) --stringparam paper.type A4 -o $@ stylesheets/stylesheet-fo.xsl pg_sphere-full.xml -## -## Clean -## +pg_sphere.US.fo: stylesheets/stylesheet-fo.xsl pg_sphere-full.xml version.xml $(ALLIMAGES) + $(XSLTPROC) $(XMLINCLUDE) $(XSLTPROCFLAGS) $(XSLTPROC_FO_FLAGS) --stringparam paper.type USLetter -o $@ stylesheets/stylesheet-fo.xsl pg_sphere-full.xml -clean distclean maintainer-clean: -# HTML - rm -rf html pg_sphere.dsl -# print - rm -f *.rtf *.tex *.dvi *.aux *.log *.ps *.pdf *.out *.fot jadetex.cfg -# img - make clean -C img +#------------------------------------------------------------------------------ +# Cleanup +#------------------------------------------------------------------------------ + +clean distclean: + rm -rf ./html + rm -f version.xml + rm -f pg_sphere-full.xml + rm -f pg_sphere.A4.fo + rm -f pg_sphere.US.fo + rm -f pg_sphere-$(PGSPHERE_VERSION).html + rm -f pg_sphere-$(PGSPHERE_VERSION)-A4.pdf + rm -f pg_sphere-$(PGSPHERE_VERSION)-US.pdf diff --git a/doc/constructors.sgm b/doc/constructors.sgm index 5fefff7..e14dd3f 100644 --- a/doc/constructors.sgm +++ b/doc/constructors.sgm @@ -1,7 +1,6 @@ - - Codestin Search App + + Codestin Search App + Constructors within pgSphere are functions needed to create spherical data types from other data @@ -14,7 +13,7 @@ mentioned here. - + Codestin Search App @@ -44,9 +43,9 @@ - + - + Codestin Search App @@ -90,9 +89,9 @@ - + - + Codestin Search App @@ -110,7 +109,7 @@ returns a spherical circle with center at center and a radius radius in radians. The circle radius has - to be larger than or equal to zero but less or equal to 90°. + to be larger than or equal to zero but less or equal to 90°. Otherwise, this function returns an error. @@ -134,18 +133,18 @@ - + - + Codestin Search App The input of spherical lines using Euler transformation and - length is quite circumstantial (see ). + length is quite circumstantial (see ). For short lines it is easier to input a line specifying the beginning and the end of the line. - + sline @@ -155,13 +154,13 @@ If the distance between begin and - end is 180° (&pgr;), this function - returns an error because the location of the line is undefined. + end is 180° (&pg_pgr;), this function + returns an error because the location of the line is undefined. However, if longitudes of begin and end are equal, pgSphere assumes a meridian and returns the corresponding spherical line. - + Codestin Search App @@ -212,9 +211,9 @@ - + - + Codestin Search App @@ -238,7 +237,7 @@ radii of the ellipse in radians. If the major radius is smaller than minor radius, pgSphere swaps the values automatically. The last parameter - incl is the inclination angle in radians. + incl is the inclination angle in radians. For more informations about ellipses, see . @@ -263,9 +262,9 @@ - + - + Codestin Search App @@ -318,9 +317,9 @@ - + - + Codestin Search App @@ -371,9 +370,9 @@ - + - + Codestin Search App @@ -403,9 +402,9 @@ SELECT sbox ( spoint '(0d,0d),(10d,10d)' );]]> - + - + Codestin Search App @@ -449,6 +448,6 @@ creates an smoc of the given order covering the spoly - + - + diff --git a/doc/examples.sgm b/doc/examples.sgm index 0886691..1590b43 100644 --- a/doc/examples.sgm +++ b/doc/examples.sgm @@ -1,37 +1,18 @@ - - Codestin Search App - - Codestin Search App - - tbw - - - - - Codestin Search App - - tbw - - - - + + Codestin Search App + + Codestin Search App - + Codestin Search App A commonly used task is a coordinate transformation. With the parameters of a new coordinate system (plane) relative to an old one, - + @@ -39,7 +20,7 @@ - &OHgr; + &pg_OHgr; longitude of the ascending node @@ -51,7 +32,7 @@ - &ohgr; + &pg_ohgr; argument of pericenter @@ -79,22 +60,22 @@ object from an old into a new coordinate system using: - object - strans '&ohgr;, i, &OHgr;' + object - strans '&pg_ohgr;, i, &pg_OHgr;' or - object - strans (&ohgr;, i, &OHgr;) + object - strans (&pg_ohgr;, i, &pg_OHgr;) Otherwise, for a transformation of an object object from the new into the old coordinate system, use the operator +: - object + strans '&ohgr;, i, &OHgr;' + object + strans '&pg_ohgr;, i, &pg_OHgr;' or - object + strans (&ohgr;, i, &OHgr;) + object + strans (&pg_ohgr;, i, &pg_OHgr;) Codestin Search App We are assuming the orbital elements of a comet are - &OHgr;=30°, i=60° and &ohgr;=90°. We get the + &pg_OHgr;=30°, i=60° and &pg_ohgr;=90°. We get the spherical position of perihelion and aphelion with: @@ -117,6 +98,7 @@ - - - + + + + diff --git a/doc/functions.sgm b/doc/functions.sgm index d5bb457..6093c33 100644 --- a/doc/functions.sgm +++ b/doc/functions.sgm @@ -1,13 +1,13 @@ - - Codestin Search App + + Codestin Search App + The functions described below are implemented without having an operator. If you are missing some functions, see and use the operators. - + + Codestin Search App @@ -18,7 +18,7 @@ is convex), sbox, and smoc. - Codestin Search App + Codestin Search App SELECT area( scircle '<(0d,90d),60d>' ) / pi() AS area;]]> @@ -32,14 +32,14 @@ - + - + Codestin Search App - + Codestin Search App @@ -76,9 +76,9 @@ - + - + Codestin Search App @@ -140,16 +140,16 @@ - + - - - + + + Codestin Search App - + Codestin Search App @@ -169,9 +169,9 @@ SELECT strans_zxz ( strans '20d, -270d, 70.5d, XZY' );]]> - + - + Codestin Search App @@ -249,12 +249,12 @@ - + - + - + Codestin Search App @@ -275,9 +275,9 @@ - + - + Codestin Search App @@ -338,10 +338,10 @@ - To get the ellipse center, you can use the + To get the ellipse center, you can use the operator @@ () instead of using the function - center(sellipse). + center(sellipse). Codestin Search App @@ -355,14 +355,14 @@ - - - + + + Codestin Search App - + Codestin Search App @@ -386,9 +386,9 @@ SELECT sl_beg( sline '(10d, 90d, 270d, ZXZ ), 20d';]]> - + - + Codestin Search App @@ -423,14 +423,14 @@ - - - - + + + + Codestin Search App - + Codestin Search App @@ -455,10 +455,10 @@ - - - - + + + + Codestin Search App @@ -532,19 +532,19 @@ - - - - + + + + Codestin Search App - + Codestin Search App - Similar to an spath (), + Similar to an spath (), you can get the count of edges of a spherical polygon using the function: @@ -565,8 +565,8 @@ - - + + Codestin Search App @@ -617,9 +617,9 @@ - + - + Codestin Search App @@ -643,11 +643,11 @@ - + - + - + Codestin Search App @@ -683,9 +683,9 @@ SELECT sw ( sbox '( (0d,0d), (90d,0d) )' ) ;]]> - + - + Codestin Search App @@ -778,14 +778,14 @@ - + - + Codestin Search App - + Codestin Search App @@ -804,15 +804,15 @@ applies proper motion to positions) - Following both pg_sphere and, where missing, astronomical + Following both pg_sphere and, where missing, astronomical conventions makes units somewhat eclectic here; pm_long and pm_lat - need to be in rad/yr, whereas parallax is in mas, and - radial_velocity in km/s. The time difference must be in + need to be in rad/yr, whereas parallax is in mas, and + radial_velocity in km/s. The time difference must be in (Julian) years. - This function returns a 6-array of [long, lat, parallax, + This function returns a 6-array of [long, lat, parallax, pm_long, pm_lat, radial_velocity] of the corresponding values delta_t years after the reference epoch for the original position. As in the function arguments, long and lat are in rad, pm_lon and @@ -839,7 +839,7 @@ Codestin Search App - - + + Codestin Search App @@ -890,7 +890,7 @@ FROM ( - As with epoch_prop itself, missing values (except for pos and + As with epoch_prop itself, missing values (except for pos and delta_t) are substituted by 0 (or a very small value in the case of parallax). @@ -898,14 +898,15 @@ FROM ( Codestin Search App - - - + + + + diff --git a/doc/indices.sgm b/doc/indices.sgm index 11940c2..0ef179f 100644 --- a/doc/indices.sgm +++ b/doc/indices.sgm @@ -1,8 +1,7 @@ - - Codestin Search App - + + Codestin Search App + + Codestin Search App @@ -27,7 +26,7 @@ linkend="op.over">&&, #, =, and !=. + linkend="op.equal">!=. You can create a GiST index with the following spherical data types: @@ -84,7 +83,7 @@ - BRIN index can be created through the following syntax: + BRIN index can be created through the following syntax: @@ -102,9 +101,9 @@ - + - + Codestin Search App @@ -143,6 +142,6 @@ - + - + diff --git a/doc/install.sgm b/doc/install.sgm index 39ebaf9..f1c4b54 100644 --- a/doc/install.sgm +++ b/doc/install.sgm @@ -1,19 +1,18 @@ - - Codestin Search App - + + Codestin Search App + + Codestin Search App - - pgSphere is not part of the PostgreSQL software. + + pgSphere is not part of the PostgreSQL software. You can download it from the pgSphere homepage - https://github.com/akorotkov/pgsphere + https://github.com/postgrespro/pgsphere - + - + Codestin Search App @@ -27,9 +26,9 @@ There are two ways to compile pgSphere. The first is to copy the sources into the contribution directory of - PostgreSQL's source tree + PostgreSQL's source tree (POSTGRESQL_SRC/src/contrib). - Then, change into POSTGRESQL_SRC/src/contrib. + Then, change into POSTGRESQL_SRC/src/contrib. If the sources are not yet installed and the directory pg_sphere does not exist, take the gzipped pgSphere sources ( e. g., @@ -82,43 +81,43 @@ make installcheck]]> - The check status will be displayed. Please note, the check gives different results with + The check status will be displayed. Please note, the check gives different results with different PostgreSQL-versions. Currently, the check should run without errors with PostgreSQL-version 8.4. Otherwise check the file regression.diff. - - - - + + + + Codestin Search App We assume you have already created a database datab, where datab - is the name of any database. + is the name of any database. Presupposing the name of your PostgreSQL's superuser is postgres, type: - psql -U postgres -c 'CREATE EXTENSION pg_sphere;' datab]]> + psql -U postgres -c 'CREATE EXTENSION pg_sphere' datab]]> Depending on your system, it may be necessary to give more - psql options like port or host name. + psql options like port or host name. Please have a look at the PostgreSQL documentation for more details. - To get the version of installed pgSphere software, simply + To get the version of installed pgSphere software, simply call: SELECT pg_sphere_version();]]> - - - + + + diff --git a/doc/jadetex.cfg-dist b/doc/jadetex.cfg-dist deleted file mode 100644 index d7917b9..0000000 --- a/doc/jadetex.cfg-dist +++ /dev/null @@ -1,14 +0,0 @@ -\hypersetup{ - pdftitle={pgSphere}, - pdfsubject={user guide}, - pdfauthor={pgSphere developer team}, - pdfkeywords={spherical PostgreSQL SQL}, - bookmarksopen=true, - bookmarksopenlevel=2, - colorlinks=true, - linkcolor=blue, - pdfpagemode=UseOutlines, - pdfstartview=FitH -} -\usepackage{url} -\tolerance=2000 diff --git a/doc/operators.sgm b/doc/operators.sgm index 73ebb83..c2d8902 100644 --- a/doc/operators.sgm +++ b/doc/operators.sgm @@ -1,8 +1,7 @@ - - Codestin Search App - + + Codestin Search App + + Codestin Search App @@ -120,9 +119,9 @@ - - - + + + Codestin Search App @@ -144,9 +143,9 @@ - - - + + + Codestin Search App @@ -156,7 +155,7 @@ a contained by object b? or Does object a overlap object - b? + b? pgSphere supports such queries using binary operators returning true or false: @@ -298,9 +297,9 @@ - + - + Codestin Search App @@ -320,9 +319,9 @@ - - - + + + Codestin Search App @@ -358,9 +357,9 @@ - - - + + + Codestin Search App @@ -395,9 +394,9 @@ - + - + Codestin Search App @@ -415,9 +414,9 @@ SELECT @@ scircle '<(0d,20d),30d>';]]> - + - + Codestin Search App @@ -433,15 +432,15 @@ SELECT - sline (spoint '(0d,0d)', spoint '(10d,0d)');]]> - + - + Codestin Search App The unary operator ! turns the - path of sline objects, but preserves + path of sline objects, but preserves begin and end of the spherical line. The length of returned line will be 360° minus the line length of operator's argument. @@ -450,7 +449,7 @@ The operator ! returns NULL, if the length of sline argument is 0, because the path of returned sline - is undefined. + is undefined. Codestin Search App @@ -490,9 +489,9 @@ - + - + Codestin Search App @@ -561,9 +560,9 @@ - + - + Codestin Search App @@ -590,6 +589,6 @@ - + - + diff --git a/doc/pg_sphere.css b/doc/pg_sphere.css deleted file mode 100644 index 2b7c85d..0000000 --- a/doc/pg_sphere.css +++ /dev/null @@ -1,182 +0,0 @@ -/* similar to PostgreSQL.org Documentation Style */ - -body { - margin: 1em; - padding: 1em; - font-size: 85%; - font-family: verdana, sans-serif; - color: #000; - background-color: #fff; -} - -h1 { - font-size: 1.4em; - font-weight: bold; - margin-top: 0em; - margin-bottom: 0em; -} - -h2 { - font-size: 1.2em; - margin: 1.2em 0em 1.2em 0em; - font-weight: bold; -} - -h3 { - font-size: 1.0em; - margin: 1.2em 0em 1.2em 0em; - font-weight: bold; -} - -h4 { - font-size: 0.95em; - margin: 1.2em 0em 1.2em 0em; - font-weight: normal; -} - -h5 { - font-size: 0.9em; - margin: 1.2em 0em 1.2em 0em; - font-weight: normal; -} - -h6 { - font-size: 0.85em; - margin: 1.2em 0em 1.2em 0em; - font-weight: normal; -} - -img { - border: 0; -} - -ol, ul, li { - font-size: 1.0em; - line-height: 1.2em; - margin-top: 0.2em; - margin-bottom: 0.1em; -} - -p { - font-size: 1.0em; - line-height: 1.2em; - margin: 1.2em 0em 1.2em 0em; -} - -li > p { - margin-top: 0.2em; -} - -pre { - font-family: monospace; - font-size: 1.2em; - margin: 0em; -} - -strong, b { - font-weight: bold; -} - -h1 { - font-weight: bold; - color: #EC5800; - font-size: 1.4em; -} - -h2 { - font-weight: bold; - color: #666; - font-size: 1.2em; -} - -h3 { - font-weight: bold; - color: #666; - font-size: 1.1em; -} - -h4 { - color: #666; -} - -/* Text Styles */ - -.txtCurrentLocation { - font-weight: bold; -} - -p, ol, ul, li { - line-height: 1.5em; -} - -table.CALSTABLE { - width: 50%; -} - -table.CALSTABLE td { - vertical-align : top; -} - -/* Link Styles */ - -a:link { color:#0066A2; text-decoration: underline; } -a:visited { color:#004E66; text-decoration: underline; } -a:active { color:#0066A2; text-decoration: underline; } -a:hover { color:#000000; text-decoration: underline; } - - -pre.programlisting, -blockquote.note, -blockquote.tip -{ - -moz-border-radius: 8px 8px 8px 8px; - -moz-box-shadow: 3px 3px 5px #DFDFDF; - color: black; - margin: 1ex 0ex 1ex 1ex; - padding: 1ex; - border-style: solid; - border-width: 1px; -} - - -/* Programlisting */ -pre.programlisting { - background-color: #F7F7F7; - border-color: #CFCFCF; - font-family: monospace; - text-align: left; -} - -div.note { - margin-top: 4ex; -} - -blockquote.note, -blockquote.tip -{ - padding-top: 0ex; - background-color: #FDFDEE; - border-color: #DBDBCC; -} - - -.literal, -.parameter, -.funcsynopsis, -.function -{ - font-size: 130%; -} - -div.table table tr td { - padding: 0.5ex; -} - -div.example p b { - font-size : 70%; - font-style: italic; -} - -div.NAVFOOTER { - margin-top: 5ex; -} \ No newline at end of file diff --git a/doc/pg_sphere.dsl-dist b/doc/pg_sphere.dsl-dist deleted file mode 100644 index a658c78..0000000 --- a/doc/pg_sphere.dsl-dist +++ /dev/null @@ -1,330 +0,0 @@ - - - - - -]]> - - -]]> - -]> - - - - - - -;; PAPER - - - - -string (time) #t))) - '("META" ("HTTP-EQUIV" "Content-Type") ("CONTENT" "text/html; charset=utf-8")) - ) -) - -(define %stylesheet% "pg_sphere.css") - -(define %generate-article-titlepage% - ;; produce a title page for articles - #t) - -(define (chunk-skip-first-element-list) - ;; forces the Table of Contents on separate page - '()) - -(define (list-element-list) - ;; fixes bug in Table of Contents generation - '()) - -(define %root-filename% - ;; The filename of the root HTML document (e.g, "index"). - "index") - -(define ($shade-verbatim-attr$) - ;; REFENTRY shade-verbatim-attr - ;; PURP Attributes used to create a shaded verbatim environment. - ;; DESC - ;; See '%shade-verbatim%' - ;; /DESC - ;; AUTHOR N/A - ;; /REFENTRY - (list - (list "BORDER" "0") - (list "BGCOLOR" "#F7F7F7") - (list "WIDTH" ($table-width$)))) - -;; ...but we need to do some extra work to make the above apply to PRE -;; as well. (mostly pasted from dbverb.dsl) -(define ($verbatim-display$ indent line-numbers?) - (let ((content (make element gi: "PRE" - attributes: (list - (list "CLASS" (gi))) - (if (or indent line-numbers?) - ($verbatim-line-by-line$ indent line-numbers?) - (process-children))))) - (if %shade-verbatim% - (make element gi: "TABLE" - attributes: ($shade-verbatim-attr$) - (make element gi: "TR" - (make element gi: "TD" - content))) - (make sequence - (para-check) - content - (para-check 'restart))))) - -(define %shade-verbatim% - ;; verbatim sections will be shaded if t(rue) - #f) - -(define %use-id-as-filename% - ;; Use ID attributes as name for component HTML files? - #t) - -(define %graphic-extensions% - ;; graphic extensions allowed - '("jpg" "jpeg" "png")) - -(define %graphic-default-extension% - "jpg") - -(define %section-autolabel% - ;; For enumerated sections (1.1, 1.1.1, 1.2, etc.) - #t) - -(define (toc-depth nd) - ;; more depth (3 levels) to toc; instead of flat hierarchy - 2) - -(element emphasis - ;; make role=strong equate to bold for emphasis tag - (if (equal? (attribute-string "role") "strong") - (make element gi: "STRONG" (process-children)) - (make element gi: "EM" (process-children)))) - -(define (article-titlepage-recto-elements) - ;; elements on an article's titlepage - (list (normalize "title") - (normalize "subtitle") - (normalize "authorgroup") - (normalize "author") - (normalize "othercredit") - (normalize "releaseinfo") - (normalize "copyright") - (normalize "pubdate") - (normalize "revhistory") - (normalize "abstract") - (normalize "legalnotice"))) - -(define (article-title nd) - (let* ((artchild (children nd)) - (artheader (select-elements artchild (normalize "artheader"))) - (artinfo (select-elements artchild (normalize "articleinfo"))) - (ahdr (if (node-list-empty? artheader) - artinfo - artheader)) - (ahtitles (select-elements (children ahdr) - (normalize "title"))) - (artitles (select-elements artchild (normalize "title"))) - (titles (if (node-list-empty? artitles) - ahtitles - artitles))) - (if (node-list-empty? titles) - "" - (node-list-first titles)))) - -(mode subtitle-mode - ;; do not print subtitle on subsequent pages - (element subtitle (empty-sosofo))) - -;; notes. -(element note - (make sequence - (para-check) - ($admonition$) - (para-check 'restart))) - -]]> - - - - - - - diff --git a/doc/pg_sphere.xml b/doc/pg_sphere.xml index 950a530..1ca32a7 100644 --- a/doc/pg_sphere.xml +++ b/doc/pg_sphere.xml @@ -1,7 +1,7 @@ - @@ -25,50 +25,29 @@ +&ohgr;"> +&OHgr;"> +&pgr;"> + + ]> + + + + Codestin Search App + pgSphere Development Team + pgSphere + &pg_sphere_version; + -
- - Codestin Search App - - pgSphere development team - - - - - - - - - - - pgSphere provides spherical data - types, functions, and operators for - PostgreSQL. - - - The project is hosted at - https://github.com/postgrespro/pgsphere - - - - This document - describes installation and usage of this module. - - - - &capWhatis; - &capInstall; - &capTypes; - &capConstr; - &capOperators; - &capFunctions; - &capIndices; - &capExamples; - &capFaq; - &capAppendixes; + &capWhatis; + &capInstall; + &capTypes; + &capConstr; + &capOperators; + &capFunctions; + &capIndices; + &capExamples; -
+
diff --git a/doc/stylesheets/stylesheet-common.xsl b/doc/stylesheets/stylesheet-common.xsl new file mode 100644 index 0000000..c739f03 --- /dev/null +++ b/doc/stylesheets/stylesheet-common.xsl @@ -0,0 +1,126 @@ + + + + + + + + + + + + + + 1 + 0 + + + + +yes +2 + + + + + + + + + +1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ? + + ? + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/doc/stylesheets/stylesheet-fo.xsl b/doc/stylesheets/stylesheet-fo.xsl new file mode 100644 index 0000000..19f368f --- /dev/null +++ b/doc/stylesheets/stylesheet-fo.xsl @@ -0,0 +1,147 @@ + + + + + + + + +3 + + + +1.5em + + + wrap + + + + solid + 1pt + black + 12pt + 12pt + 6pt + 6pt + + + + center + + + + + left + + + + + 1em + 0.8em + 1.2em + + + + + + + + + + + + , + + + + + + + + ISBN + + + + + + + + + + + + + + + + -3.5em + + + + + + + + + + -3.5em + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/doc/stylesheets/stylesheet-html-common.xsl b/doc/stylesheets/stylesheet-html-common.xsl new file mode 100644 index 0000000..a368e0e --- /dev/null +++ b/doc/stylesheets/stylesheet-html-common.xsl @@ -0,0 +1,439 @@ + + +%common.entities; +]> + + + + + + + + +pgsql-docs@lists.postgresql.org +2 + + + stylesheet.css.xml + + + https://www.postgresql.org/media/css/docs-complete.css + + + + + + docContent + container-fluid col-10 + + + + + + + + + + + + + + , + + + + + + + + + + ISBN + + + + + + + + + +appendix toc,title +article/appendix nop +article toc,title +book toc,title +chapter toc,title +part toc,title +preface toc,title +qandadiv toc +qandaset toc +reference toc,title +sect1 toc +sect2 toc +sect3 toc +sect4 toc +sect5 toc +section toc +set toc,title + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + + + + +
+

+ + + +

+
+ + + + + + + +
+
+
+ + + + + +
+

+ + + +

+
+ + + + + + + +
+
+
+
+
+ + + + + + + + +
+
+ + + + + + + + + +
+ + + + + + +

+ +

+
+
+ + + + + + + +
+
+
+
+ + + + + + + + + + + + | + + + + + + + + + + + + + + + + + + + + + + + + + + id- + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 6 + + + + + + + + + + clear: both + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + # + + + + + + id_link + + # + + + + + + + ERROR: id attribute missing on < + + > element under + + / + + + [@ + + = ' + + '] + + + + + + + + +
diff --git a/doc/stylesheets/stylesheet-html-nochunk.xsl b/doc/stylesheets/stylesheet-html-nochunk.xsl new file mode 100644 index 0000000..5a0bb4e --- /dev/null +++ b/doc/stylesheets/stylesheet-html-nochunk.xsl @@ -0,0 +1,24 @@ + + + + + + + + + + + + + + + + + + + + + + + diff --git a/doc/stylesheets/stylesheet-man.xsl b/doc/stylesheets/stylesheet-man.xsl new file mode 100644 index 0000000..fcb485c --- /dev/null +++ b/doc/stylesheets/stylesheet-man.xsl @@ -0,0 +1,226 @@ + + + + + + + + + +0 +0 +0 + + + +32 +40 + + + + + + + + + + + + + + < + + > + + + + + + ^ + + + + + + + + + + + + + + + + ( + + + + + + ) + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 0 + + + + + + + + + + + + + + + + + + + + + + + Note: + + + + + + + + + + + + + + + + + + + + + + + + + Note: + (soelim stub) + + + + + + + + + + + + + + + + + + + + + + + + + : + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/doc/stylesheets/stylesheet-speedup-common.xsl b/doc/stylesheets/stylesheet-speedup-common.xsl new file mode 100644 index 0000000..e3fb582 --- /dev/null +++ b/doc/stylesheets/stylesheet-speedup-common.xsl @@ -0,0 +1,100 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +en + + diff --git a/doc/stylesheets/stylesheet-speedup-xhtml.xsl b/doc/stylesheets/stylesheet-speedup-xhtml.xsl new file mode 100644 index 0000000..da0f2b5 --- /dev/null +++ b/doc/stylesheets/stylesheet-speedup-xhtml.xsl @@ -0,0 +1,345 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + , + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Error: If you change $chunk.section.depth, then you must update the performance-optimized chunk-all-sections-template. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/doc/stylesheets/stylesheet-text.xsl b/doc/stylesheets/stylesheet-text.xsl new file mode 100644 index 0000000..529cc9e --- /dev/null +++ b/doc/stylesheets/stylesheet-text.xsl @@ -0,0 +1,97 @@ + + + + + + + + + + + + + + + + + + +
  • + + + + +
  • +
    + + + + + * + + * + + + + + + + + + + + + + + +
    + + + + + + +

    + + + : + +

    +
    + + +
    +
    + + + + +
    + +
    + + +
    + +
    + + +
    + +
    + +
    diff --git a/doc/stylesheets/stylesheet.css b/doc/stylesheets/stylesheet.css new file mode 100644 index 0000000..86a8edb --- /dev/null +++ b/doc/stylesheets/stylesheet.css @@ -0,0 +1,182 @@ +/* doc/src/sgml/stylesheet.css */ + +/* color scheme similar to www.postgresql.org */ + +body { + color: #000000; + background: #FFFFFF; + font-family: verdana, sans-serif; +} + +a:link { color:#0066A2; } +a:visited { color:#004E66; } +a:active { color:#0066A2; } +a:hover { color:#000000; } + +h1 { + font-size: 1.4em; + font-weight: bold; + margin-top: 0em; + margin-bottom: 0em; + color: #EC5800; +} + +h2 { + font-size: 1.2em; + margin: 1.2em 0em 1.2em 0em; + font-weight: bold; + color: #666; +} + +.titlepage h2.title, +.refnamediv h2 { + color: #EC5800; +} + +h3 { + font-size: 1.1em; + margin: 1.2em 0em 1.2em 0em; + font-weight: bold; + color: #666; +} + +h4 { + font-size: 0.95em; + margin: 1.2em 0em 1.2em 0em; + font-weight: normal; + color: #666; +} + +h5 { + font-size: 0.9em; + margin: 1.2em 0em 1.2em 0em; + font-weight: normal; +} + +h6 { + font-size: 0.85em; + margin: 1.2em 0em 1.2em 0em; + font-weight: normal; +} + +/* center some titles */ + +.book .title, .book .corpauthor, .book .copyright { + text-align: center; +} + +/* decoration for formal examples */ + +div.example { + padding-left: 15px; + border-style: solid; + border-width: 0px; + border-left-width: 2px; + border-color: black; + margin: 0.5ex; +} + +/* Additional formatting for "simplelist" structures */ +table.simplelist td { + padding-left: 2em; + padding-right: 2em; +} + +/* formatting for entries in tables of functions: indent all but first line */ + +th.func_table_entry p, +td.func_table_entry p { + margin-top: 0.1em; + margin-bottom: 0.1em; + padding-left: 4em; + text-align: left; +} + +p.func_signature { + text-indent: -3.5em; +} + +td.func_table_entry pre.programlisting { + margin-top: 0.1em; + margin-bottom: 0.1em; + padding-left: 4em; +} + +/* formatting for entries in tables of catalog/view columns */ + +th.catalog_table_entry p, +td.catalog_table_entry p { + margin-top: 0.1em; + margin-bottom: 0.1em; + padding-left: 4em; + text-align: left; +} + +th.catalog_table_entry p.column_definition { + text-indent: -3.5em; + word-spacing: 0.25em; +} + +td.catalog_table_entry p.column_definition { + text-indent: -3.5em; +} + +p.column_definition code.type { + padding-left: 0.25em; + padding-right: 0.25em; +} + +td.catalog_table_entry pre.programlisting { + margin-top: 0.1em; + margin-bottom: 0.1em; + padding-left: 4em; +} + +/* Put these here instead of inside the HTML (see unsetting of + admon.style in XSL) so that the web site stylesheet can set its own + style. */ + +.tip, +.note, +.important, +.caution, +.warning { + margin-left: 0.5in; + margin-right: 0.5in; +} + +/* miscellaneous */ + +pre.literallayout, .screen, .synopsis, .programlisting { + margin-left: 4ex; +} + +ul.itemizedlist { + margin-left: 2.5rem; +} + +.comment { color: red; } + +var { font-family: monospace; font-style: italic; } +/* Konqueror's standard style for ACRONYM is italic. */ +acronym { font-style: inherit; } + +.option { white-space: nowrap; } + +/* make images not too wide on larger screens */ +@media (min-width: 800px) { + .mediaobject { + width: 75%; + } +} + +/* links to ids of headers and definition terms */ + +a.id_link { + color: inherit; + visibility: hidden; +} + +*:hover > a.id_link { + visibility: visible; +} diff --git a/doc/stylesheets/stylesheet.css.xml b/doc/stylesheets/stylesheet.css.xml new file mode 100644 index 0000000..a21fcca --- /dev/null +++ b/doc/stylesheets/stylesheet.css.xml @@ -0,0 +1,8 @@ + + +]> + diff --git a/doc/stylesheets/stylesheet.xsl b/doc/stylesheets/stylesheet.xsl new file mode 100644 index 0000000..6b39d91 --- /dev/null +++ b/doc/stylesheets/stylesheet.xsl @@ -0,0 +1,328 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/doc/types.sgm b/doc/types.sgm index 557c144..acb3c54 100644 --- a/doc/types.sgm +++ b/doc/types.sgm @@ -1,8 +1,7 @@ - - Codestin Search App - + + Codestin Search App + + Codestin Search App @@ -100,9 +99,9 @@ - - - + + + Codestin Search App @@ -118,28 +117,28 @@ - sites on earth + sites on earth - star positions on the sky sphere + star positions on the sky sphere - spherical positions on planets + spherical positions on planets - + A spherical point (or position) is given by two values: longitude and latitude. Longitude is a floating point value between 0 and - 2&pgr;. Latitude is a floating point - value, too, but between -&pgr;/2 and - &pgr;/2. It is possible to give a + 2&pg_pgr;. Latitude is a floating point + value, too, but between -&pg_pgr;/2 and + &pg_pgr;/2. It is possible to give a spherical position in degrees (DEG) or with a triple value of degrees, minutes and seconds (DMS). Degrees and minutes are integer @@ -189,10 +188,10 @@ longitude and latitude. The value pairs are always enclosed within braces. Spaces are optional. - - - + + + Codestin Search App @@ -210,12 +209,12 @@ - spherical object transformations + spherical object transformations - spherical coordinates transformations + spherical coordinates transformations @@ -226,7 +225,7 @@ where axes is an optional 3 letter code with letters : X, Y, or - Z. Default is ZXZ. + Z. Default is ZXZ. angleN is any valid angle with the input format RAD, DEG, or DMS. @@ -263,9 +262,9 @@ SELECT strans '2d 20m, 10d, 0';]]> - - - + + + Codestin Search App @@ -289,12 +288,12 @@ - round cluster or nebula on sky sphere + round cluster or nebula on sky sphere - a position with an undirected position error + a position with an undirected position error @@ -318,9 +317,9 @@ SELECT scircle '< (0d, 90d), 5d >';]]> - + - + Codestin Search App @@ -336,12 +335,12 @@ - direct connection of two points + direct connection of two points - meteors on the sky sphere + meteors on the sky sphere @@ -395,9 +394,9 @@ i syntax is a somewhat complex. SELECT sline '( -90d, -20d, 200d, XYZ ), 30d ';]]> - - - + + + Codestin Search App @@ -432,7 +431,7 @@ i syntax is a somewhat complex. - to describe a position error + to describe a position error @@ -442,12 +441,12 @@ i syntax is a somewhat complex. - a major radius rad_1 + a major radius rad_1 - a minor radius rad_2 + a minor radius rad_2 @@ -505,9 +504,9 @@ i syntax is a somewhat complex. SELECT sellipse '< { 10d, 5d } , ( 20d, 0d ), 90d >';]]> - + - + Codestin Search App @@ -523,7 +522,7 @@ i syntax is a somewhat complex. - rivers on earth + rivers on earth @@ -548,7 +547,7 @@ i syntax is a somewhat complex. - At least 2 positions are required. + At least 2 positions are required. @@ -565,9 +564,9 @@ i syntax is a somewhat complex. SELECT spath '{ (10d,0d),(45d,15d),(80d,30d) } ';]]> - + - + Codestin Search App @@ -582,7 +581,7 @@ i syntax is a somewhat complex. A spherical polygon is a closed spherical path where line segments cannot be crossed. One main use case are areas on the earth and sky sphere. - Polygons within pgSphere + Polygons within pgSphere have the same input syntax as paths: {pos1,pos2,pos3[,pos4[,... ]]} @@ -598,7 +597,7 @@ i syntax is a somewhat complex. - The line segments can not be crossed. + The line segments can not be crossed. @@ -621,9 +620,9 @@ i syntax is a somewhat complex. SELECT spoly '{ (270d,-10d), (270d,30d), (290d,10d) } ';]]> - + - + Codestin Search App @@ -689,9 +688,9 @@ i syntax is a somewhat complex. SELECT sbox '( (350d,-10d), (10d,+10d) )';]]> - + - + Codestin Search App @@ -750,5 +749,6 @@ i syntax is a somewhat complex. SELECT smoc '0/4 1/0 2 12-13 34-35 45 47 2/4 6 12 14 56-57 60-61 88 90-91 116-117 119 130-131 134-135 177 179 185 187';]]> - - + + + diff --git a/doc/whatis.sgm b/doc/whatis.sgm index 6af690b..fc52d0e 100644 --- a/doc/whatis.sgm +++ b/doc/whatis.sgm @@ -1,4 +1,7 @@ - + + Codestin Search App + + Codestin Search App @@ -15,7 +18,7 @@ - containing, overlapping, and other operators + containing, overlapping, and other operators @@ -30,17 +33,17 @@ - spherical transformation + spherical transformation - indexing of spherical data types + indexing of spherical data types - several input and output formats + several input and output formats @@ -48,17 +51,19 @@ Hence, you can do a fast search and analysis for objects with spherical attributes as used in geographical, astronomical, or - other applications using PostgreSQL. + other applications using PostgreSQL. For instance, you can manage data of geographical objects around the world and astronomical data like star and other catalogs conveniently using an SQL interface. - The aim of pgSphere is to provide + The aim of pgSphere is to provide uniform access to spherical data. Because PostgreSQL itself supports a lot of software interfaces, you can now use the same database with different utilities and applications. - + + + \ No newline at end of file From 46c805c585eff977b77f860a341bb0be2b128e5c Mon Sep 17 00:00:00 2001 From: Vitaly Davydov Date: Wed, 13 Sep 2023 15:52:39 +0300 Subject: [PATCH 26/87] Fix doc generation with default target --- doc/Makefile | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/doc/Makefile b/doc/Makefile index 47a1396..280bbe0 100644 --- a/doc/Makefile +++ b/doc/Makefile @@ -12,6 +12,7 @@ endif endif USE_PGXS = 1 + ifdef USE_PGXS PG_CONFIG = pg_config PGXS := $(shell $(PG_CONFIG) --pgxs) @@ -23,8 +24,10 @@ include $(top_builddir)/src/Makefile.global include $(top_srcdir)/contrib/contrib-global.mk endif +.SECONDARY: + ifndef FOP -FOP = fop +FOP = $(missing) fop endif ifdef XMLLINT @@ -48,9 +51,13 @@ XMLINCLUDE = --path . ALLSGML := $(wildcard *.sgm) ALLIMAGES := $(wildcard img/*.jpg) -.PHONY: all html pdf +all: html pdf + +.PHONY: all html pdf clean -all: version.ent html pdf +# This line fixes the error like: +# No rule to make target 'pg_sphere.control' +.PHONY: pg_sphere.control version.xml: @echo $(PGSPHERE_VERSION) > version.xml From 5cd821194bdcd5ed976aaf8406803070402adf15 Mon Sep 17 00:00:00 2001 From: Vitaly Davydov Date: Wed, 13 Sep 2023 16:34:27 +0300 Subject: [PATCH 27/87] Update travis.ci to support docbook/fop doc generation --- .travis.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index 4df87d5..691080f 100644 --- a/.travis.yml +++ b/.travis.yml @@ -16,7 +16,7 @@ dist: focal before_install: # extra apt.pg.o.sh options added in version 204, travis currently has 199 (2019-11-27) - sudo apt-get -qq update - - sudo apt-get -y install postgresql-common libhealpix-cxx-dev docbook-dsssl docbook-xml openjade + - sudo apt-get -y install postgresql-common libhealpix-cxx-dev docbook-xml docbook-xsl libxml2-utils xsltproc fop install: - sudo /usr/share/postgresql-common/pgdg/apt.postgresql.org.sh -p -v $PG_SUPPORTED_VERSIONS -i From c5731c9386f3317e31d29066e325220921572386 Mon Sep 17 00:00:00 2001 From: Vitaly Davydov Date: Wed, 13 Sep 2023 16:39:39 +0300 Subject: [PATCH 28/87] Set FOP variable default value --- doc/Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/Makefile b/doc/Makefile index 280bbe0..754d775 100644 --- a/doc/Makefile +++ b/doc/Makefile @@ -27,7 +27,7 @@ endif .SECONDARY: ifndef FOP -FOP = $(missing) fop +FOP = fop endif ifdef XMLLINT From d59496c75fad1d9de6405f1ae955ef186084f136 Mon Sep 17 00:00:00 2001 From: Vitaly Davydov Date: Thu, 14 Sep 2023 11:41:08 +0300 Subject: [PATCH 29/87] Disable install/installcheck targets in doc/Makefile Remove inclusion of 'pg_config --pgxs' makefile because it is not required to create the documentation. This makefile was designed to be included in top-level extension makefile. Inclusion in the doc/Makefile results into some unexpected behaviour when using 'install' or 'all' rules. Remove gmake -C doc install in .travis.yml because this target didn't do anything. I guess that the installation of the manual should be implemented in the top-level extension Makefile file, not in the doc/Makefile. --- .travis.yml | 1 - doc/Makefile | 19 ++----------------- 2 files changed, 2 insertions(+), 18 deletions(-) diff --git a/.travis.yml b/.travis.yml index 691080f..0d199cf 100644 --- a/.travis.yml +++ b/.travis.yml @@ -40,4 +40,3 @@ script: - pg_virtualenv make USE_HEALPIX=0 crushtest - if test -s regression.diffs; then cat regression.diffs; exit 1; fi - make -C doc - - sudo make -C doc install diff --git a/doc/Makefile b/doc/Makefile index 754d775..11894ff 100644 --- a/doc/Makefile +++ b/doc/Makefile @@ -11,21 +11,6 @@ $(error PGSPHERE_VERSION is not set) endif endif -USE_PGXS = 1 - -ifdef USE_PGXS -PG_CONFIG = pg_config -PGXS := $(shell $(PG_CONFIG) --pgxs) -include $(PGXS) -else -subdir = contrib/pg_sphere/doc -top_builddir = ../../.. -include $(top_builddir)/src/Makefile.global -include $(top_srcdir)/contrib/contrib-global.mk -endif - -.SECONDARY: - ifndef FOP FOP = fop endif @@ -33,13 +18,13 @@ endif ifdef XMLLINT XMLLINT := $(XMLLINT) --nonet else -XMLLINT = $(missing) xmllint +XMLLINT = xmllint --nonet endif ifdef XSLTPROC XSLTPROC := $(XSLTPROC) --nonet else -XSLTPROC = $(missing) xsltproc +XSLTPROC = xsltproc --nonet endif override XSLTPROCFLAGS += \ From 48c3d5e45bdde670c78ae448b6212f9c9f870abb Mon Sep 17 00:00:00 2001 From: Vitaly Davydov Date: Fri, 15 Sep 2023 12:34:13 +0300 Subject: [PATCH 30/87] Add final linefeed, remove some trailing whitespaces --- doc/appendixes.sgm | 4 ++-- doc/whatis.sgm | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/doc/appendixes.sgm b/doc/appendixes.sgm index 46b87cc..5bd221e 100644 --- a/doc/appendixes.sgm +++ b/doc/appendixes.sgm @@ -19,7 +19,7 @@ - This version is compatible to PostgreSQL 8.4 + This version is compatible to PostgreSQL 8.4 @@ -66,5 +66,5 @@ - + diff --git a/doc/whatis.sgm b/doc/whatis.sgm index fc52d0e..eb12bf1 100644 --- a/doc/whatis.sgm +++ b/doc/whatis.sgm @@ -66,4 +66,4 @@ - \ No newline at end of file + From f3823cf27886c418120ee9fef3267018c4d6af58 Mon Sep 17 00:00:00 2001 From: Christoph Berg Date: Tue, 19 Sep 2023 17:20:42 +0200 Subject: [PATCH 31/87] Remove test_top_build_dir Remove special code for testing on pre-9.5 servers --- Makefile | 14 +------------- test_top_build_dir/Makefile | 2 -- 2 files changed, 1 insertion(+), 15 deletions(-) delete mode 100644 test_top_build_dir/Makefile diff --git a/Makefile b/Makefile index 5dbdac2..db9cf59 100644 --- a/Makefile +++ b/Makefile @@ -132,18 +132,12 @@ ifeq ($(has_explain_summary),y) endif endif -ifeq ($(pg_version_9_5_plus),y) - PGS_TMP_DIR = --temp-instance=tmp_check -else - PGS_TMP_DIR = --temp-install=tmp_check --top-builddir=test_top_build_dir -endif - test: pg_sphere.test.sql sql/init_test.sql cp expected/init_test.out.in expected/init_test.out ifneq ($(USE_HEALPIX),0) cat expected/init_test_healpix.out.in >> expected/init_test.out endif - $(pg_regress_installcheck) $(PGS_TMP_DIR) $(REGRESS_OPTS) $(TESTS) + $(pg_regress_installcheck) --temp-instance=tmp_check $(REGRESS_OPTS) $(TESTS) pg_sphere.test.sql: $(RELEASE_SQL) $(shlib) tail -n+3 $< | sed 's,MODULE_PATHNAME,$(realpath $(shlib)),g' >$@ @@ -188,12 +182,6 @@ UPGRADE_1_0_PRE_AAF2D5 = contains-ops-fixes-1.sql pgs_gist_drop_spoint2.sql.in \ # create "alter extension" files - -ifeq ($(pg_version_9_5_plus),y) -# 1.1.1.5 -> 1.1.5.1 for Postgres 9.5+ features -else -endif - # local stuff follows here AUGMENT_GAVO_111 = $(AUGMENT_UNP_111) # for vanilla 1.1.1 users ifneq ($(USE_HEALPIX),0) diff --git a/test_top_build_dir/Makefile b/test_top_build_dir/Makefile deleted file mode 100644 index 80919a1..0000000 --- a/test_top_build_dir/Makefile +++ /dev/null @@ -1,2 +0,0 @@ -install: - ln -s / ../tmp_check/install From f696b8a9c974a2eac161b0ce5e2c5cb13075680b Mon Sep 17 00:00:00 2001 From: Vitaly Davydov Date: Tue, 26 Sep 2023 14:56:48 +0300 Subject: [PATCH 32/87] Fix compilation error (-Wstringop-overflow) GCC may produce false warnings in some cases when working with strings (char*) when -Wstringop-overflow is enabled. The patch fixes the compilation warning that origins in some tricky pointers casts. --- src/process_moc.cpp | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/src/process_moc.cpp b/src/process_moc.cpp index 4a9e342..76883e1 100644 --- a/src/process_moc.cpp +++ b/src/process_moc.cpp @@ -122,7 +122,7 @@ char* data_as_char(Smoc* moc, size_t offset = 0) static char* detoasted_offset(Smoc* moc, size_t offset = 0) { - return offset + reinterpret_cast(&(moc->version)); + return offset + reinterpret_cast(moc) + offsetof(Smoc, version); } template @@ -240,7 +240,7 @@ struct moc_tree_layout { rest_level = entries - rest_entries; this_page = page_rest; - } + } else // there is only a single page fragment at this level { rest_level = 0; @@ -526,13 +526,13 @@ get_moc_size(void* moc_in_context, pgs_error_handler error_out) } if (check == b_tree_inf) throw std::logic_error("infinite loop for MOC B-tree depth"); - + // layout: start with the section of the ends of each B+-tree level size_t depth = m.layout.size() - 1; moc_size += depth * MOC_INDEX_ALIGN; // layout: B+-tree layout, starting at root node for (unsigned k = depth; k >= 1; --k) -{ +{ m.layout[k].layout_level(moc_size, MOC_TREE_ENTRY_SIZE); } if (m.layout[depth].level_end > static_cast( @@ -568,7 +568,7 @@ create_moc_release_context(void* moc_in_context, Smoc* moc, hpint64 area = 0; - // this guards against + // this guards against char* moc_data = detoasted_offset(moc, 0); // All levels will be filled out from end to beginning such that @@ -726,7 +726,7 @@ order_break(output_map & outputs, const moc_interval & x, int max_order) void ascii_out(std::string & m_s, char* s, Smoc* moc, int32 begin, int32 end, int32 entry_size) -{ +{ // moc output fiddling: int order = moc->order; m_s.reserve(end); // rough guess @@ -817,7 +817,7 @@ create_moc_out_context(Smoc* moc, int32 end, pgs_error_handler error_out) return ret; } -void +void release_moc_out_context(moc_out_data out_context, pgs_error_handler error_out) { release_context(out_context.context, error_out); From bdfaeabd54673bbdcce88569da7cbf27f8d4260d Mon Sep 17 00:00:00 2001 From: Artem Borodin <54876237+borodun@users.noreply.github.com> Date: Thu, 14 Sep 2023 16:47:59 +0700 Subject: [PATCH 33/87] Add GitHub Actions pipeline for pgSphere --- .github/workflows/build-and-check.yml | 67 +++++++++++++++++++++++++++ 1 file changed, 67 insertions(+) create mode 100644 .github/workflows/build-and-check.yml diff --git a/.github/workflows/build-and-check.yml b/.github/workflows/build-and-check.yml new file mode 100644 index 0000000..a113c10 --- /dev/null +++ b/.github/workflows/build-and-check.yml @@ -0,0 +1,67 @@ +name: Build and Check + +on: + push: + pull_request: + +jobs: + build_and_test: + + runs-on: ubuntu-latest + + strategy: + fail-fast: false + matrix: + pg_version: [10, 11, 12, 13, 14, 15, 16] + use_healpix: [0, 1] + + name: PostgreSQL ${{ matrix.pg_version }} - USE_HEALPIX=${{ matrix.use_healpix }} + + steps: + - name: Install dependencies + run: | + sudo apt update && sudo apt install -y \ + postgresql-common \ + libhealpix-cxx-dev \ + docbook-xml \ + docbook-xsl \ + libxml2-utils \ + xsltproc \ + fop + + - name: Install Postgres + run: sudo /usr/share/postgresql-common/pgdg/apt.postgresql.org.sh -p -v ${{ matrix.pg_version }} -i + + - name: Clone pgSphere + uses: actions/checkout@v4 + + - name: Set MAKE_CMD variable + run: echo "MAKE_CMD=make --keep-going -j$(nproc) -l$(nproc) -O" >> $GITHUB_ENV + + - name: Build pgSphere + run: ${MAKE_CMD} PROFILE="-Werror -Wall" USE_HEALPIX=${{ matrix.use_healpix }} + + - name: make test + run: pg_virtualenv ${MAKE_CMD} USE_HEALPIX=${{ matrix.use_healpix }} test + + - name: Install pgSphere + run: sudo ${MAKE_CMD} USE_HEALPIX=${{ matrix.use_healpix }} install + + - name: make installcheck + run: pg_virtualenv ${MAKE_CMD} USE_HEALPIX=${{ matrix.use_healpix }} installcheck + + - name: make crushtest + run: pg_virtualenv ${MAKE_CMD} USE_HEALPIX=${{ matrix.use_healpix }} crushtest + + - name: Build docs + run: ${MAKE_CMD} -C doc + + - name: Upload artifacts + uses: actions/upload-artifact@v3 + if: success() || failure() + with: + name: ${{ github.ref_name }}-pg${{ matrix.pg_version }}-use-healpix-${{ matrix.use_healpix }}-${{ github.run_id }} + if-no-files-found: ignore + path: | + ./**/*.log + ./**/*.diffs From 349c7889b6e56fd35d59c0d10a6f9fbf0bc69254 Mon Sep 17 00:00:00 2001 From: borodun Date: Thu, 28 Sep 2023 15:02:05 +0700 Subject: [PATCH 34/87] Use slugified variables for artifact names --- .github/workflows/build-and-check.yml | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/.github/workflows/build-and-check.yml b/.github/workflows/build-and-check.yml index a113c10..6b2adab 100644 --- a/.github/workflows/build-and-check.yml +++ b/.github/workflows/build-and-check.yml @@ -56,11 +56,14 @@ jobs: - name: Build docs run: ${MAKE_CMD} -C doc + - name: Inject slug/short variables + uses: rlespinasse/github-slug-action@v4 + - name: Upload artifacts uses: actions/upload-artifact@v3 if: success() || failure() with: - name: ${{ github.ref_name }}-pg${{ matrix.pg_version }}-use-healpix-${{ matrix.use_healpix }}-${{ github.run_id }} + name: ${{ env.GITHUB_REF_SLUG_URL }}-pg${{ matrix.pg_version }}-use-healpix-${{ matrix.use_healpix }}-${{ github.run_id }} if-no-files-found: ignore path: | ./**/*.log From 764642b94d467c8dd93d4c12df07ed70965ae5be Mon Sep 17 00:00:00 2001 From: Vitaly Date: Fri, 29 Sep 2023 09:37:10 +0300 Subject: [PATCH 35/87] Remove the obsolete text from the doc (#65) Remove the obsolete text from the doc --- doc/functions.sgm | 11 ++- doc/install.sgm | 201 ++++++++++++++++++++-------------------------- doc/pg_sphere.xml | 7 +- 3 files changed, 103 insertions(+), 116 deletions(-) diff --git a/doc/functions.sgm b/doc/functions.sgm index 6093c33..b65f8c0 100644 --- a/doc/functions.sgm +++ b/doc/functions.sgm @@ -14,8 +14,9 @@ The area function returns the area of a spherical object in square radians. Supported data types are: - scircle, spolygon (if the polygon - is convex), sbox, and smoc. + scircle, spolygon, sbox, + smoc. The polygon should be convex, otherwise the + behaviour is undefined. Codestin Search App @@ -25,6 +26,12 @@ + + + + + Codestin Search App + SELECT area(smoc '0/1-3');]]> diff --git a/doc/install.sgm b/doc/install.sgm index f1c4b54..ded78fa 100644 --- a/doc/install.sgm +++ b/doc/install.sgm @@ -1,123 +1,100 @@ Codestin Search App - - Codestin Search App - - pgSphere is not part of the PostgreSQL software. - You can download it from the pgSphere homepage - https://github.com/postgrespro/pgsphere - - + + Codestin Search App - - Codestin Search App - - You will need PostgreSQL - 9.1 or above. We assume that you have - PostgreSQL already compiled and - installed. Please note: Depending on your system configuration mostly you have to be logged in as the system - superuser. - - - There are two ways to compile pgSphere. - The first is to copy the sources into the contribution directory of - PostgreSQL's source tree - (POSTGRESQL_SRC/src/contrib). - Then, change into POSTGRESQL_SRC/src/contrib. - If the sources are not yet installed and the directory - pg_sphere does not exist, take the - gzipped pgSphere sources ( e. g., - pg_sphere_xxx.tgz ) and run: - - - tar -xzf path/to/pg_sphere_xxx.tgz]]> - - - Now, change into the pg_sphere - directory and run : - - + + &pgsphere; is not the part of the &postgresql; software. You can download + the latest release from the + &pgsphere; Releases page. + The source code can also be downloaded by cloning the repository with the + appropriate release tag. The master branch is intended for development + use and may contain the code in a transitional state. It is not recommended + for use in production. + + + + + Codestin Search App + + It is assumed that &postgresql; is already installed. Depending on the + system configuration, superuser (root) access rights may be required to + complete the installation. + + + + The installation script uses &pg_config; utility. Make sure that the + environment variable PATH includes path to &pg_config; utility. The path + to &pg_config; can be also specified in make command: + + make PG_CONFIG=/path/to/pgconfig ...]]> + + + + Unpack the downloaded archive and enter the directory: + + tar -xzf path/to/pgsphere-X.X.X.tgz]]> + cd pgsphere-X.X.X]]> + + + + Compile the code. By default, &pgsphere; is compiled with &healpix; support. + + make]]> - - - and to install pgSphere : - - + + or compile without &healpix; support: + + make USE_HEALPIX=0]]> + + + + Run regression tests optionally. If &pgsphere; was compiled without &healpix; + support, USE_HEALPIX=0 should be specified in make command line. + + + make test]]> + + + + Install &pgsphere; files to the installation directories. The installation + directories are defined by &pg_config; utility. Superuser (root) access + rights may be required. If &pgsphere; was compiled without &healpix; support, + USE_HEALPIX=0 should be added after make. + + make install]]> - - - The second way does not require the PostgreSQL sources but - the configuration tool pg_config. - - - First unpack the pgSphere sources: - - - tar -xzf path_to_pg_sphere_xxx.tgz]]> - - - Now, change into the pg_sphere - directory and run: - - - make USE_PGXS=1 PG_CONFIG=/path/to/pg_config]]> - - - To install pgSphere you have to run : - - - make USE_PGXS=1 PG_CONFIG=/path/to/pg_config install]]> - - - To check the installation change into the pg_sphere source - directory again and run: - - - make installcheck]]> - - - The check status will be displayed. Please note, the check gives different results with - different PostgreSQL-versions. Currently, the check should - run without errors with PostgreSQL-version 8.4. Otherwise check - the file regression.diff. - + + + + + + Codestin Search App + + + We assume you have already created a database userdb, + where userdb is the name of any database. Assume that + the name of &postgresql;'s superuser is postgres. + + + psql -U postgres -c 'CREATE EXTENSION pg_sphere' userdb]]> + - + + It may be necessary to give more psql options, like port + or host name, depending on your system configuration. Please, take a look at + the psql user manual for details. The psql user manual for the latest + &postgresql; version can be found at + + &postgresql; site + . + - - Codestin Search App - - We assume you have already created a database - datab, where datab - is the name of any database. - Presupposing the name of your - PostgreSQL's superuser is - postgres, type: - - - psql -U postgres -c 'CREATE EXTENSION pg_sphere' datab]]> - - - Depending on your system, it may be necessary to give more - psql options like port or host name. - Please have a look at the - PostgreSQL documentation for more - details. - - - To get the version of installed pgSphere software, simply - call: - - + To get the version of installed &pgsphere; software: + SELECT pg_sphere_version();]]> - - + + diff --git a/doc/pg_sphere.xml b/doc/pg_sphere.xml index 1ca32a7..62cd79d 100644 --- a/doc/pg_sphere.xml +++ b/doc/pg_sphere.xml @@ -11,8 +11,6 @@ - - @@ -28,6 +26,11 @@ &ohgr;"> &OHgr;"> &pgr;"> +HEALPix"> +pgSphere"> +PostgreSQL"> +pg_config"> + ]> From 739ecbcf0cae7e0203c0a5bea74a5e65ab9aa344 Mon Sep 17 00:00:00 2001 From: borodun Date: Wed, 27 Sep 2023 16:08:55 +0700 Subject: [PATCH 36/87] Add pipeline for docs using GitHub Pages --- .github/workflows/deploy-docs.yml | 51 +++++++++++++++++++++++++++++++ 1 file changed, 51 insertions(+) create mode 100644 .github/workflows/deploy-docs.yml diff --git a/.github/workflows/deploy-docs.yml b/.github/workflows/deploy-docs.yml new file mode 100644 index 0000000..2047a36 --- /dev/null +++ b/.github/workflows/deploy-docs.yml @@ -0,0 +1,51 @@ +name: Build and Deploy Docs + +# Deploy docs only for master +on: + push: + branches: + - "master" + +# Allow deployment to GitHub Pages +permissions: + pages: write + id-token: write + +jobs: + deploy-docs: + + name: Deploy Docs + + environment: + name: github-pages + url: ${{ steps.deployment.outputs.page_url }} + + runs-on: ubuntu-latest + + steps: + - name: Install dependencies + run: | + sudo apt update && sudo apt install -y \ + docbook-xml \ + docbook-xsl \ + libxml2-utils \ + xsltproc \ + fop + + - name: Clone pgSphere + uses: actions/checkout@v4 + + - name: Build docs + run: make -C doc + + - name: Setup Pages + uses: actions/configure-pages@v3 + + - name: Upload artifact + uses: actions/upload-pages-artifact@v2 + with: + path: 'doc/html' + + - name: Deploy to GitHub Pages + id: deployment + uses: actions/deploy-pages@v2 From 2a2f70ec9de38812fa67889e00a5e29f3e46c02f Mon Sep 17 00:00:00 2001 From: Christoph Berg Date: Mon, 2 Oct 2023 17:16:11 +0200 Subject: [PATCH 37/87] Bump version to 1.3.2 --- Makefile | 6 +++++- Makefile.common.mk | 2 +- expected/init.out | 2 +- pg_sphere--1.3.1.sql.in => pg_sphere--1.3.2.sql.in | 0 pg_sphere.control | 2 +- upgrade_scripts/pg_sphere--1.3.1--1.3.2.sql.in | 1 + 6 files changed, 9 insertions(+), 4 deletions(-) rename pg_sphere--1.3.1.sql.in => pg_sphere--1.3.2.sql.in (100%) create mode 100644 upgrade_scripts/pg_sphere--1.3.1--1.3.2.sql.in diff --git a/Makefile b/Makefile index db9cf59..2d33da4 100644 --- a/Makefile +++ b/Makefile @@ -30,7 +30,8 @@ DATA_built = $(RELEASE_SQL) \ pg_sphere--1.2.1--1.2.2.sql \ pg_sphere--1.2.2--1.2.3.sql \ pg_sphere--1.2.3--1.3.0.sql \ - pg_sphere--1.3.0--1.3.1.sql + pg_sphere--1.3.0--1.3.1.sql \ + pg_sphere--1.3.1--1.3.2.sql DOCS = README.pg_sphere COPYRIGHT.pg_sphere REGRESS = init tables points euler circle line ellipse poly path box index \ @@ -258,6 +259,9 @@ pg_sphere--1.2.3--1.3.0.sql: pgs_brin.sql.in pg_sphere--1.3.0--1.3.1.sql: cat upgrade_scripts/$@.in > $@ +pg_sphere--1.3.1--1.3.2.sql: + cat upgrade_scripts/$@.in > $@ + # end of local stuff src/sscan.o : src/sparse.c diff --git a/Makefile.common.mk b/Makefile.common.mk index f3893a9..6387bea 100644 --- a/Makefile.common.mk +++ b/Makefile.common.mk @@ -5,4 +5,4 @@ #---------------------------------------------------------------------------- EXTENSION := pg_sphere -PGSPHERE_VERSION := 1.3.1 +PGSPHERE_VERSION := 1.3.2 diff --git a/expected/init.out b/expected/init.out index fb86488..f5e092b 100644 --- a/expected/init.out +++ b/expected/init.out @@ -6,6 +6,6 @@ CREATE EXTENSION pg_sphere; select pg_sphere_version(); pg_sphere_version ------------------- - 1.3.1 + 1.3.2 (1 row) diff --git a/pg_sphere--1.3.1.sql.in b/pg_sphere--1.3.2.sql.in similarity index 100% rename from pg_sphere--1.3.1.sql.in rename to pg_sphere--1.3.2.sql.in diff --git a/pg_sphere.control b/pg_sphere.control index e2b8ad3..d9f2ccc 100644 --- a/pg_sphere.control +++ b/pg_sphere.control @@ -1,5 +1,5 @@ # pg_sphere extension comment = 'spherical objects with useful functions, operators and index support' -default_version = '1.3.1' +default_version = '1.3.2' module_pathname = '$libdir/pg_sphere' relocatable = true diff --git a/upgrade_scripts/pg_sphere--1.3.1--1.3.2.sql.in b/upgrade_scripts/pg_sphere--1.3.1--1.3.2.sql.in new file mode 100644 index 0000000..8ea3baa --- /dev/null +++ b/upgrade_scripts/pg_sphere--1.3.1--1.3.2.sql.in @@ -0,0 +1 @@ +-- Nothing to upgrade in the schema From c2a235160db76f9ae050a5eb1f1a7a9135787f58 Mon Sep 17 00:00:00 2001 From: Christoph Berg Date: Mon, 2 Oct 2023 17:24:45 +0200 Subject: [PATCH 38/87] Merge index fetch support for spoint3 into main files So far, the function backing index only fetches on spoint3 gist indexes was already always compiled, but only added to the operator class for PG9.5+, and only when special code in the Makefile was uncommented. We are well past 9.5, and the feature works just fine, so load it unconditionally (assuming no one used it in production yet, ADD FUNCTION will fail when executed twice). Version bumped since we add a new function to the opclass. --- Makefile | 13 ---- expected/index.out | 61 ++++++++++++++++++ expected/index_9.5.out | 62 ------------------- expected/init_test_healpix.out.in | 4 +- index_9.5 | 0 pgs_9.5.sql.in | 7 --- pgs_gist_spoint3.sql.in | 1 + sql/index.sql | 17 +++++ sql/index_9.5.sql | 18 ------ .../pg_sphere--1.3.1--1.3.2.sql.in | 5 +- 10 files changed, 85 insertions(+), 103 deletions(-) delete mode 100644 expected/index_9.5.out delete mode 100644 index_9.5 delete mode 100644 pgs_9.5.sql.in delete mode 100644 sql/index_9.5.sql diff --git a/Makefile b/Makefile index 2d33da4..a016313 100644 --- a/Makefile +++ b/Makefile @@ -42,8 +42,6 @@ ifneq ($(USE_HEALPIX),0) REGRESS += healpix moc mocautocast endif -REGRESS_9_5 = index_9.5 # experimental for spoint3 - TESTS = init_test tables points euler circle line ellipse poly path box \ index contains_ops contains_ops_compat bounding_box_gist gnomo \ epochprop contains overlaps spoint_brin sbox_brin @@ -84,8 +82,6 @@ endif PGS_SQL += pgs_epochprop.sql -PGS_SQL_9_5 = pgs_9.5.sql # experimental for spoint3 - ifdef USE_PGXS ifndef PG_CONFIG PG_CONFIG = pg_config @@ -112,18 +108,9 @@ endif healpix_bare/healpix_bare.o : healpix_bare/healpix_bare.c $(COMPILE.c) -Wno-declaration-after-statement -o $@ $^ -# experimental for spoint3 pg_version := $(word 2,$(shell $(PG_CONFIG) --version)) -pg_version_9_5_plus = $(if $(filter-out 9.1% 9.2% 9.3% 9.4%,$(pg_version)),y,n) has_explain_summary = $(if $(filter-out 9.%,$(pg_version)),y,n) -## the use of spoint 3 is too experimental and preliminary: -#ifeq ($(pg_version_9_5_plus),y) -# REGRESS += $(REGRESS_9_5) -# TESTS += $(REGRESS_9_5) -# PGS_SQL += $(PGS_SQL_9_5) -#endif - crushtest: REGRESS += $(CRUSH_TESTS) crushtest: installcheck diff --git a/expected/index.out b/expected/index.out index a639dab..8c67155 100644 --- a/expected/index.out +++ b/expected/index.out @@ -134,3 +134,64 @@ SELECT count(*) FROM spheretmp4 WHERE l && scircle '<(1,1),0.3>' ; 40 (1 row) +-- test spoint3 operator class with and without index-only scan +SET enable_bitmapscan = OFF; +SET enable_indexonlyscan = ON; +EXPLAIN (COSTS OFF) SELECT count(*) FROM spheretmp1b WHERE p <@ scircle '<(1,1),0.3>'; + QUERY PLAN +-------------------------------------------------------- + Aggregate + -> Index Only Scan using spoint3_idx on spheretmp1b + Index Cond: (p <@ '<(1 , 1) , 0.3>'::scircle) +(3 rows) + + SELECT count(*) FROM spheretmp1b WHERE p <@ scircle '<(1,1),0.3>'; + count +------- + 32 +(1 row) + +EXPLAIN (COSTS OFF) SELECT count(*) FROM spheretmp1b WHERE p = spoint '(3.09 , 1.25)'; + QUERY PLAN +-------------------------------------------------------- + Aggregate + -> Index Only Scan using spoint3_idx on spheretmp1b + Index Cond: (p = '(3.09 , 1.25)'::spoint) +(3 rows) + + SELECT count(*) FROM spheretmp1b WHERE p = spoint '(3.09 , 1.25)'; + count +------- + 4 +(1 row) + +SET enable_bitmapscan = ON; +SET enable_indexonlyscan = OFF; +EXPLAIN (COSTS OFF) SELECT count(*) FROM spheretmp1b WHERE p <@ scircle '<(1,1),0.3>'; + QUERY PLAN +------------------------------------------------------- + Aggregate + -> Index Scan using spoint3_idx on spheretmp1b + Index Cond: (p <@ '<(1 , 1) , 0.3>'::scircle) +(3 rows) + + SELECT count(*) FROM spheretmp1b WHERE p <@ scircle '<(1,1),0.3>'; + count +------- + 32 +(1 row) + +EXPLAIN (COSTS OFF) SELECT count(*) FROM spheretmp1b WHERE p = spoint '(3.09 , 1.25)'; + QUERY PLAN +--------------------------------------------------- + Aggregate + -> Index Scan using spoint3_idx on spheretmp1b + Index Cond: (p = '(3.09 , 1.25)'::spoint) +(3 rows) + + SELECT count(*) FROM spheretmp1b WHERE p = spoint '(3.09 , 1.25)'; + count +------- + 4 +(1 row) + diff --git a/expected/index_9.5.out b/expected/index_9.5.out deleted file mode 100644 index 99995f0..0000000 --- a/expected/index_9.5.out +++ /dev/null @@ -1,62 +0,0 @@ --- test spoint3 operator class with and without index-only scan -SET enable_seqscan = OFF; -SET enable_bitmapscan = OFF; -SET enable_indexonlyscan = ON; -EXPLAIN (COSTS OFF) SELECT count(*) FROM spheretmp1b WHERE p <@ scircle '<(1,1),0.3>'; - QUERY PLAN --------------------------------------------------------- - Aggregate - -> Index Only Scan using spoint3_idx on spheretmp1b - Index Cond: (p <@ '<(1 , 1) , 0.3>'::scircle) -(3 rows) - - SELECT count(*) FROM spheretmp1b WHERE p <@ scircle '<(1,1),0.3>'; - count -------- - 32 -(1 row) - -EXPLAIN (COSTS OFF) SELECT count(*) FROM spheretmp1b WHERE p = spoint '(3.09 , 1.25)'; - QUERY PLAN --------------------------------------------------------- - Aggregate - -> Index Only Scan using spoint3_idx on spheretmp1b - Index Cond: (p = '(3.09 , 1.25)'::spoint) -(3 rows) - - SELECT count(*) FROM spheretmp1b WHERE p = spoint '(3.09 , 1.25)'; - count -------- - 4 -(1 row) - -SET enable_bitmapscan = ON; -SET enable_indexonlyscan = OFF; -EXPLAIN (COSTS OFF) SELECT count(*) FROM spheretmp1b WHERE p <@ scircle '<(1,1),0.3>'; - QUERY PLAN -------------------------------------------------------- - Aggregate - -> Index Scan using spoint3_idx on spheretmp1b - Index Cond: (p <@ '<(1 , 1) , 0.3>'::scircle) -(3 rows) - - SELECT count(*) FROM spheretmp1b WHERE p <@ scircle '<(1,1),0.3>'; - count -------- - 32 -(1 row) - -EXPLAIN (COSTS OFF) SELECT count(*) FROM spheretmp1b WHERE p = spoint '(3.09 , 1.25)'; - QUERY PLAN ---------------------------------------------------- - Aggregate - -> Index Scan using spoint3_idx on spheretmp1b - Index Cond: (p = '(3.09 , 1.25)'::spoint) -(3 rows) - - SELECT count(*) FROM spheretmp1b WHERE p = spoint '(3.09 , 1.25)'; - count -------- - 4 -(1 row) - diff --git a/expected/init_test_healpix.out.in b/expected/init_test_healpix.out.in index b87a70d..95de0db 100644 --- a/expected/init_test_healpix.out.in +++ b/expected/init_test_healpix.out.in @@ -1,2 +1,2 @@ -psql:pg_sphere.test.sql:9684: NOTICE: return type smoc is only a shell -psql:pg_sphere.test.sql:9690: NOTICE: argument type smoc is only a shell +psql:pg_sphere.test.sql:9685: NOTICE: return type smoc is only a shell +psql:pg_sphere.test.sql:9691: NOTICE: argument type smoc is only a shell diff --git a/index_9.5 b/index_9.5 deleted file mode 100644 index e69de29..0000000 diff --git a/pgs_9.5.sql.in b/pgs_9.5.sql.in deleted file mode 100644 index e3b806d..0000000 --- a/pgs_9.5.sql.in +++ /dev/null @@ -1,7 +0,0 @@ --- add functionality that is only available for PostgreSQL 9.5+ - - --- add "fetch" support function to enable index-only scans for spoint3 - -ALTER OPERATOR FAMILY spoint3 USING gist ADD - FUNCTION 9 (spoint, spoint) g_spoint3_fetch (internal); diff --git a/pgs_gist_spoint3.sql.in b/pgs_gist_spoint3.sql.in index 0382dad..580a12f 100644 --- a/pgs_gist_spoint3.sql.in +++ b/pgs_gist_spoint3.sql.in @@ -66,4 +66,5 @@ CREATE OPERATOR CLASS spoint3 FUNCTION 6 g_spoint3_picksplit (internal, internal), FUNCTION 7 g_spoint3_same (bytea, bytea, internal), FUNCTION 8 g_spoint3_distance (internal, internal, int4, oid), + FUNCTION 9 (spoint, spoint) g_spoint3_fetch (internal), STORAGE pointkey; diff --git a/sql/index.sql b/sql/index.sql index 7273728..fb3730a 100644 --- a/sql/index.sql +++ b/sql/index.sql @@ -59,3 +59,20 @@ SELECT count(*) FROM spheretmp4 WHERE l @ scircle '<(1,1),0.3>' ; SELECT count(*) FROM spheretmp4 WHERE l && scircle '<(1,1),0.3>' ; +-- test spoint3 operator class with and without index-only scan + +SET enable_bitmapscan = OFF; +SET enable_indexonlyscan = ON; + +EXPLAIN (COSTS OFF) SELECT count(*) FROM spheretmp1b WHERE p <@ scircle '<(1,1),0.3>'; + SELECT count(*) FROM spheretmp1b WHERE p <@ scircle '<(1,1),0.3>'; +EXPLAIN (COSTS OFF) SELECT count(*) FROM spheretmp1b WHERE p = spoint '(3.09 , 1.25)'; + SELECT count(*) FROM spheretmp1b WHERE p = spoint '(3.09 , 1.25)'; + +SET enable_bitmapscan = ON; +SET enable_indexonlyscan = OFF; + +EXPLAIN (COSTS OFF) SELECT count(*) FROM spheretmp1b WHERE p <@ scircle '<(1,1),0.3>'; + SELECT count(*) FROM spheretmp1b WHERE p <@ scircle '<(1,1),0.3>'; +EXPLAIN (COSTS OFF) SELECT count(*) FROM spheretmp1b WHERE p = spoint '(3.09 , 1.25)'; + SELECT count(*) FROM spheretmp1b WHERE p = spoint '(3.09 , 1.25)'; diff --git a/sql/index_9.5.sql b/sql/index_9.5.sql deleted file mode 100644 index fe00bcc..0000000 --- a/sql/index_9.5.sql +++ /dev/null @@ -1,18 +0,0 @@ --- test spoint3 operator class with and without index-only scan - -SET enable_seqscan = OFF; -SET enable_bitmapscan = OFF; -SET enable_indexonlyscan = ON; - -EXPLAIN (COSTS OFF) SELECT count(*) FROM spheretmp1b WHERE p <@ scircle '<(1,1),0.3>'; - SELECT count(*) FROM spheretmp1b WHERE p <@ scircle '<(1,1),0.3>'; -EXPLAIN (COSTS OFF) SELECT count(*) FROM spheretmp1b WHERE p = spoint '(3.09 , 1.25)'; - SELECT count(*) FROM spheretmp1b WHERE p = spoint '(3.09 , 1.25)'; - -SET enable_bitmapscan = ON; -SET enable_indexonlyscan = OFF; - -EXPLAIN (COSTS OFF) SELECT count(*) FROM spheretmp1b WHERE p <@ scircle '<(1,1),0.3>'; - SELECT count(*) FROM spheretmp1b WHERE p <@ scircle '<(1,1),0.3>'; -EXPLAIN (COSTS OFF) SELECT count(*) FROM spheretmp1b WHERE p = spoint '(3.09 , 1.25)'; - SELECT count(*) FROM spheretmp1b WHERE p = spoint '(3.09 , 1.25)'; diff --git a/upgrade_scripts/pg_sphere--1.3.1--1.3.2.sql.in b/upgrade_scripts/pg_sphere--1.3.1--1.3.2.sql.in index 8ea3baa..4077cd6 100644 --- a/upgrade_scripts/pg_sphere--1.3.1--1.3.2.sql.in +++ b/upgrade_scripts/pg_sphere--1.3.1--1.3.2.sql.in @@ -1 +1,4 @@ --- Nothing to upgrade in the schema +-- add "fetch" support function to enable index-only scans for spoint3 + +ALTER OPERATOR FAMILY spoint3 USING gist ADD + FUNCTION 9 (spoint, spoint) g_spoint3_fetch (internal); From cc4d614af64e65fefaa8bb2da21c9c257cc6befe Mon Sep 17 00:00:00 2001 From: Christoph Berg Date: Thu, 5 Oct 2023 15:03:53 +0200 Subject: [PATCH 39/87] .github: Show regression.diffs on failures --- .github/workflows/build-and-check.yml | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/.github/workflows/build-and-check.yml b/.github/workflows/build-and-check.yml index 6b2adab..a4247b8 100644 --- a/.github/workflows/build-and-check.yml +++ b/.github/workflows/build-and-check.yml @@ -44,15 +44,27 @@ jobs: - name: make test run: pg_virtualenv ${MAKE_CMD} USE_HEALPIX=${{ matrix.use_healpix }} test + - name: Show test regression.diffs + if: ${{ failure() }} + run: cat regression.diffs + - name: Install pgSphere run: sudo ${MAKE_CMD} USE_HEALPIX=${{ matrix.use_healpix }} install - name: make installcheck run: pg_virtualenv ${MAKE_CMD} USE_HEALPIX=${{ matrix.use_healpix }} installcheck + - name: Show installcheck regression.diffs + if: ${{ failure() }} + run: cat regression.diffs + - name: make crushtest run: pg_virtualenv ${MAKE_CMD} USE_HEALPIX=${{ matrix.use_healpix }} crushtest + - name: Show crushtest regression.diffs + if: ${{ failure() }} + run: cat regression.diffs + - name: Build docs run: ${MAKE_CMD} -C doc From 01143682cad6ae52367143cc8759148e0cc9003f Mon Sep 17 00:00:00 2001 From: Christoph Berg Date: Thu, 5 Oct 2023 14:23:36 +0200 Subject: [PATCH 40/87] Use a static filename for the header of RELEASE_SQL One place less to update when bumping the version number. --- Makefile | 3 +-- pg_sphere--1.3.2.sql.in => pg_sphere_head.sql.in | 0 2 files changed, 1 insertion(+), 2 deletions(-) rename pg_sphere--1.3.2.sql.in => pg_sphere_head.sql.in (100%) diff --git a/Makefile b/Makefile index a016313..4051f5d 100644 --- a/Makefile +++ b/Makefile @@ -130,8 +130,7 @@ endif pg_sphere.test.sql: $(RELEASE_SQL) $(shlib) tail -n+3 $< | sed 's,MODULE_PATHNAME,$(realpath $(shlib)),g' >$@ - -$(RELEASE_SQL): $(addsuffix .in, $(RELEASE_SQL) $(PGS_SQL)) +$(RELEASE_SQL): pg_sphere_head.sql.in $(addsuffix .in, $(PGS_SQL)) cat $^ > $@ # for "create extension from unpacked*": diff --git a/pg_sphere--1.3.2.sql.in b/pg_sphere_head.sql.in similarity index 100% rename from pg_sphere--1.3.2.sql.in rename to pg_sphere_head.sql.in From 8138fc11fed5985252dc37ba567bc7d2076220b7 Mon Sep 17 00:00:00 2001 From: Christoph Berg Date: Thu, 5 Oct 2023 16:08:44 +0200 Subject: [PATCH 41/87] make test: Don't track NOTICEs There's little value in tracking the noise of NOTICEs emitted during loading pg_sphere.test.sql, so just mute them. The gain from this change is that future patches will not have to update the changed line numbers in the output tracked. (Cf. c2a235160) --- Makefile | 6 +----- expected/init_test.out | 2 ++ expected/init_test.out.in | 35 ------------------------------- expected/init_test_healpix.out.in | 2 -- sql/init_test.sql | 3 +-- 5 files changed, 4 insertions(+), 44 deletions(-) create mode 100644 expected/init_test.out delete mode 100644 expected/init_test.out.in delete mode 100644 expected/init_test_healpix.out.in diff --git a/Makefile b/Makefile index 4051f5d..a79d720 100644 --- a/Makefile +++ b/Makefile @@ -120,11 +120,7 @@ ifeq ($(has_explain_summary),y) endif endif -test: pg_sphere.test.sql sql/init_test.sql - cp expected/init_test.out.in expected/init_test.out -ifneq ($(USE_HEALPIX),0) - cat expected/init_test_healpix.out.in >> expected/init_test.out -endif +test: pg_sphere.test.sql $(pg_regress_installcheck) --temp-instance=tmp_check $(REGRESS_OPTS) $(TESTS) pg_sphere.test.sql: $(RELEASE_SQL) $(shlib) diff --git a/expected/init_test.out b/expected/init_test.out new file mode 100644 index 0000000..da0e94b --- /dev/null +++ b/expected/init_test.out @@ -0,0 +1,2 @@ +SET client_min_messages TO WARNING; +\set ECHO none diff --git a/expected/init_test.out.in b/expected/init_test.out.in deleted file mode 100644 index 6fbd06b..0000000 --- a/expected/init_test.out.in +++ /dev/null @@ -1,35 +0,0 @@ -SET client_min_messages TO NOTICE; -\set ECHO none -psql:pg_sphere.test.sql:9: NOTICE: type "spoint" is not yet defined -DETAIL: Creating a shell type definition. -psql:pg_sphere.test.sql:16: NOTICE: argument type spoint is only a shell -psql:pg_sphere.test.sql:32: NOTICE: type "strans" is not yet defined -DETAIL: Creating a shell type definition. -psql:pg_sphere.test.sql:39: NOTICE: argument type strans is only a shell -psql:pg_sphere.test.sql:55: NOTICE: type "scircle" is not yet defined -DETAIL: Creating a shell type definition. -psql:pg_sphere.test.sql:62: NOTICE: argument type scircle is only a shell -psql:pg_sphere.test.sql:78: NOTICE: type "sline" is not yet defined -DETAIL: Creating a shell type definition. -psql:pg_sphere.test.sql:85: NOTICE: argument type sline is only a shell -psql:pg_sphere.test.sql:101: NOTICE: type "sellipse" is not yet defined -DETAIL: Creating a shell type definition. -psql:pg_sphere.test.sql:108: NOTICE: argument type sellipse is only a shell -psql:pg_sphere.test.sql:126: NOTICE: type "spoly" is not yet defined -DETAIL: Creating a shell type definition. -psql:pg_sphere.test.sql:133: NOTICE: argument type spoly is only a shell -psql:pg_sphere.test.sql:151: NOTICE: type "spath" is not yet defined -DETAIL: Creating a shell type definition. -psql:pg_sphere.test.sql:158: NOTICE: argument type spath is only a shell -psql:pg_sphere.test.sql:177: NOTICE: type "sbox" is not yet defined -DETAIL: Creating a shell type definition. -psql:pg_sphere.test.sql:184: NOTICE: argument type sbox is only a shell -psql:pg_sphere.test.sql:8658: NOTICE: type "spherekey" is not yet defined -DETAIL: Creating a shell type definition. -psql:pg_sphere.test.sql:8665: NOTICE: argument type spherekey is only a shell -psql:pg_sphere.test.sql:8679: NOTICE: type "pointkey" is not yet defined -DETAIL: Creating a shell type definition. -psql:pg_sphere.test.sql:8686: NOTICE: argument type pointkey is only a shell -psql:pg_sphere.test.sql:8692: NOTICE: argument type pointkey is only a shell -psql:pg_sphere.test.sql:8698: NOTICE: argument type pointkey is only a shell -psql:pg_sphere.test.sql:8704: NOTICE: argument type pointkey is only a shell diff --git a/expected/init_test_healpix.out.in b/expected/init_test_healpix.out.in deleted file mode 100644 index 95de0db..0000000 --- a/expected/init_test_healpix.out.in +++ /dev/null @@ -1,2 +0,0 @@ -psql:pg_sphere.test.sql:9685: NOTICE: return type smoc is only a shell -psql:pg_sphere.test.sql:9691: NOTICE: argument type smoc is only a shell diff --git a/sql/init_test.sql b/sql/init_test.sql index b2793be..6ef6e89 100644 --- a/sql/init_test.sql +++ b/sql/init_test.sql @@ -1,4 +1,3 @@ -SET client_min_messages TO NOTICE; +SET client_min_messages TO WARNING; \set ECHO none \i pg_sphere.test.sql -\set ECHO all From 17c2d286a8af13abe651a483b979b476b34aca7b Mon Sep 17 00:00:00 2001 From: Christoph Berg Date: Wed, 4 Oct 2023 17:11:53 +0200 Subject: [PATCH 42/87] Simplify moc test handling in Makefile Remove has_explain_summary since it's only relevant with PG 9.x; move all the if(USE_HEALPIX) sections into one. --- Makefile | 17 ++--------------- 1 file changed, 2 insertions(+), 15 deletions(-) diff --git a/Makefile b/Makefile index a79d720..f08a552 100644 --- a/Makefile +++ b/Makefile @@ -38,18 +38,10 @@ REGRESS = init tables points euler circle line ellipse poly path box index \ contains_ops contains_ops_compat bounding_box_gist gnomo epochprop \ contains overlaps spoint_brin sbox_brin -ifneq ($(USE_HEALPIX),0) -REGRESS += healpix moc mocautocast -endif - TESTS = init_test tables points euler circle line ellipse poly path box \ index contains_ops contains_ops_compat bounding_box_gist gnomo \ epochprop contains overlaps spoint_brin sbox_brin -ifneq ($(USE_HEALPIX),0) -TESTS += healpix moc mocautocast -endif - PG_CFLAGS += -DPGSPHERE_VERSION=$(PGSPHERE_VERSION) PG_CPPFLAGS += -DPGSPHERE_VERSION=$(PGSPHERE_VERSION) @@ -70,6 +62,8 @@ PGS_SQL = pgs_types.sql pgs_point.sql pgs_euler.sql pgs_circle.sql \ pgs_gist.sql gnomo.sql pgs_brin.sql ifneq ($(USE_HEALPIX),0) +REGRESS += healpix moc moc1 moc100 mocautocast +TESTS += healpix moc moc1 moc100 mocautocast PGS_SQL += healpix.sql endif @@ -109,17 +103,10 @@ healpix_bare/healpix_bare.o : healpix_bare/healpix_bare.c $(COMPILE.c) -Wno-declaration-after-statement -o $@ $^ pg_version := $(word 2,$(shell $(PG_CONFIG) --version)) -has_explain_summary = $(if $(filter-out 9.%,$(pg_version)),y,n) crushtest: REGRESS += $(CRUSH_TESTS) crushtest: installcheck -ifneq ($(USE_HEALPIX),0) -ifeq ($(has_explain_summary),y) - REGRESS += moc1 moc100 -endif -endif - test: pg_sphere.test.sql $(pg_regress_installcheck) --temp-instance=tmp_check $(REGRESS_OPTS) $(TESTS) From b367b8c95fcedb751e0e2406d51bc0cfadbdfdd7 Mon Sep 17 00:00:00 2001 From: Christoph Berg Date: Wed, 4 Oct 2023 17:33:13 +0200 Subject: [PATCH 43/87] Drop support for "create extension from unpackaged" PG 13 drops support for "create extension from old_version". Remove support for "from unpackaged". Existing users will likely have converted to an extension-style install years ago. --- Makefile | 48 ------------------- .../pg_sphere--unpackaged--1.1.5.sql.in | 2 - ..._sphere--unpackaged--1.1.5beta0gavo.sql.in | 2 - upgrade_scripts/pgs_pre111.sql.in | 7 --- 4 files changed, 59 deletions(-) delete mode 100644 upgrade_scripts/pg_sphere--unpackaged--1.1.5.sql.in delete mode 100644 upgrade_scripts/pg_sphere--unpackaged--1.1.5beta0gavo.sql.in delete mode 100644 upgrade_scripts/pgs_pre111.sql.in diff --git a/Makefile b/Makefile index f08a552..5f428ea 100644 --- a/Makefile +++ b/Makefile @@ -20,7 +20,6 @@ OBJS += src/healpix.o src/moc.o src/process_moc.o \ endif DATA_built = $(RELEASE_SQL) \ - pg_sphere--unpackaged--1.1.5beta0gavo.sql \ pg_sphere--1.0--1.0_gavo.sql \ pg_sphere--1.0_gavo--1.1.5beta0gavo.sql \ pg_sphere--1.1.5beta0gavo--1.1.5beta2gavo.sql \ @@ -116,28 +115,6 @@ pg_sphere.test.sql: $(RELEASE_SQL) $(shlib) $(RELEASE_SQL): pg_sphere_head.sql.in $(addsuffix .in, $(PGS_SQL)) cat $^ > $@ -# for "create extension from unpacked*": - -UPGRADE_UNP_COMMON = pgs_types.sql pgs_point.sql pgs_euler.sql pgs_circle.sql \ - pgs_line.sql pgs_ellipse.sql pgs_polygon.sql pgs_path.sql \ - pgs_box.sql pgs_contains_ops_compat.sql pgs_gist.sql \ - pgs_gist_contains_ops.sql contains-ops-fixes-1.sql - -AUGMENT_UNP_COMMON = upgrade_scripts/pgs_pre111.sql pgs_contains_ops.sql \ - gnomo.sql -# for vanilla 1.1.1 users: -AUGMENT_UNP_111 = $(AUGMENT_UNP_COMMON) pgs_gist_pointkey.sql - -# for 1.1.2+ users: 'from unpacked_1.1.2plus' -AUGMENT_UNP_FOR_112plus = $(AUGMENT_UNP_COMMON) -UPGRADE_UNP_FOR_112plus = pgs_gist_pointkey.sql pgs_gist_drop_spoint2.sql.in - -# for "alter extension": - -# TODO: add dynamic pl/pgsql to do perform an additional -# "ALTER EXTENSION pg_sphere UPDATE TO '1.1.5_from_before_2016-02-07';" -# if required. -# # default 1.0 (after 2016-02-07) -> 1.1.5 UPGRADE_1_0_PRE_xxxxxx = contains-ops-fixes-2.sql # '1.1.5_from_2015-08-31' @@ -145,40 +122,15 @@ AUGMENT_1_0_PRE_AAF2D5 = pgs_contains_ops.sql gnomo.sql UPGRADE_1_0_PRE_AAF2D5 = contains-ops-fixes-1.sql pgs_gist_drop_spoint2.sql.in \ pgs_gist_contains_ops.sql -# vanilla 'create from unpackaged' must assume 1.1.1 -# ... - -# create "create extension from unpacked*" files - -# create "alter extension" files - -# local stuff follows here -AUGMENT_GAVO_111 = $(AUGMENT_UNP_111) # for vanilla 1.1.1 users -ifneq ($(USE_HEALPIX),0) -AUGMENT_GAVO_111 += healpix.sql -endif -UPGRADE_GAVO_111 = $(UPGRADE_UNP_COMMON) - # add new HEALPix functions and experimental spoint3 ifneq ($(USE_HEALPIX),0) AUGMENT_FROM_GAVO = healpix.sql endif AUGMENT_FROM_GAVO += pgs_gist_spoint3.sql -AUGMENT_UNP_115B0G = $(AUGMENT_UNP_111) $(AUGMENT_FROM_GAVO) -UPGRADE_UNP_115B0G = $(UPGRADE_UNP_COMMON) - AUGMENT_1_0_115B0G = $(AUGMENT_FROM_GAVO) UPGRADE_1_0_115B0G = contains-ops-fixes-2.sql pgs_gist_drop_spoint2.sql -# test installation 0 -pg_sphere--unpackaged--1.1.5beta0gavo.sql: $(addsuffix .in, \ - $(AUGMENT_GAVO_111) \ - $(addprefix upgrade_scripts/, $(UPGRADE_GAVO_111))) - cat upgrade_scripts/$@.in $^ > $@ - -# (The upgrade of test installation A has been completed.) - # test installation B (generic) pg_sphere--1.0--1.0_gavo.sql: # dummy upgrade to allow for descriptive names cat upgrade_scripts/$@.in > $@ diff --git a/upgrade_scripts/pg_sphere--unpackaged--1.1.5.sql.in b/upgrade_scripts/pg_sphere--unpackaged--1.1.5.sql.in deleted file mode 100644 index 450e6b7..0000000 --- a/upgrade_scripts/pg_sphere--unpackaged--1.1.5.sql.in +++ /dev/null @@ -1,2 +0,0 @@ --- complain if this upgrade script is run via psql -\echo Use "CREATE EXTENSION pg_sphere FROM unpackaged" to load this file. \quit diff --git a/upgrade_scripts/pg_sphere--unpackaged--1.1.5beta0gavo.sql.in b/upgrade_scripts/pg_sphere--unpackaged--1.1.5beta0gavo.sql.in deleted file mode 100644 index 450e6b7..0000000 --- a/upgrade_scripts/pg_sphere--unpackaged--1.1.5beta0gavo.sql.in +++ /dev/null @@ -1,2 +0,0 @@ --- complain if this upgrade script is run via psql -\echo Use "CREATE EXTENSION pg_sphere FROM unpackaged" to load this file. \quit diff --git a/upgrade_scripts/pgs_pre111.sql.in b/upgrade_scripts/pgs_pre111.sql.in deleted file mode 100644 index 33a98ae..0000000 --- a/upgrade_scripts/pgs_pre111.sql.in +++ /dev/null @@ -1,7 +0,0 @@ --- versions before 2009-11-01 (i.e., release 1.1.1.) lack pg_sphere_version(), --- see https://postgrespro.ru/list/id/20091101150558.9B87B1073FEE@pgfoundry.org - -CREATE OR REPLACE FUNCTION pg_sphere_version() - RETURNS CSTRING - AS 'MODULE_PATHNAME', 'pg_sphere_version' - LANGUAGE 'c'; From bcfbd46a3d675f9196ddbf061fb6aa1d0913c7f6 Mon Sep 17 00:00:00 2001 From: Christoph Berg Date: Wed, 4 Oct 2023 16:03:54 +0000 Subject: [PATCH 44/87] Remove ancient "alter extension add" files --- upgrade_scripts/pgs_box.sql.in | 95 -------------- upgrade_scripts/pgs_circle.sql.in | 31 ----- .../pgs_contains_ops_compat.sql.in | 120 ------------------ upgrade_scripts/pgs_ellipse.sql.in | 55 -------- upgrade_scripts/pgs_euler.sql.in | 23 ---- upgrade_scripts/pgs_gist.sql.in | 27 ---- upgrade_scripts/pgs_line.sql.in | 41 ------ upgrade_scripts/pgs_path.sql.in | 67 ---------- upgrade_scripts/pgs_point.sql.in | 14 -- upgrade_scripts/pgs_polygon.sql.in | 68 ---------- upgrade_scripts/pgs_types.sql.in | 24 ---- 11 files changed, 565 deletions(-) delete mode 100644 upgrade_scripts/pgs_box.sql.in delete mode 100644 upgrade_scripts/pgs_circle.sql.in delete mode 100644 upgrade_scripts/pgs_contains_ops_compat.sql.in delete mode 100644 upgrade_scripts/pgs_ellipse.sql.in delete mode 100644 upgrade_scripts/pgs_euler.sql.in delete mode 100644 upgrade_scripts/pgs_gist.sql.in delete mode 100644 upgrade_scripts/pgs_line.sql.in delete mode 100644 upgrade_scripts/pgs_path.sql.in delete mode 100644 upgrade_scripts/pgs_point.sql.in delete mode 100644 upgrade_scripts/pgs_polygon.sql.in delete mode 100644 upgrade_scripts/pgs_types.sql.in diff --git a/upgrade_scripts/pgs_box.sql.in b/upgrade_scripts/pgs_box.sql.in deleted file mode 100644 index 3c259c5..0000000 --- a/upgrade_scripts/pgs_box.sql.in +++ /dev/null @@ -1,95 +0,0 @@ -ALTER EXTENSION pg_sphere ADD FUNCTION sbox(spoint, spoint); -ALTER EXTENSION pg_sphere ADD FUNCTION sw(sbox); -ALTER EXTENSION pg_sphere ADD FUNCTION se(sbox); -ALTER EXTENSION pg_sphere ADD FUNCTION nw(sbox); -ALTER EXTENSION pg_sphere ADD FUNCTION ne(sbox); -ALTER EXTENSION pg_sphere ADD FUNCTION area(sbox); -ALTER EXTENSION pg_sphere ADD FUNCTION circum(sbox); -ALTER EXTENSION pg_sphere ADD OPERATOR @-@(NONE, sbox); -ALTER EXTENSION pg_sphere ADD FUNCTION sbox_equal(sbox, sbox); -ALTER EXTENSION pg_sphere ADD OPERATOR =(sbox, sbox); -ALTER EXTENSION pg_sphere ADD OPERATOR <>(sbox, sbox); -ALTER EXTENSION pg_sphere ADD FUNCTION sbox_contains_box(sbox, sbox); -ALTER EXTENSION pg_sphere ADD FUNCTION sbox_contains_box_com(sbox, sbox); -ALTER EXTENSION pg_sphere ADD FUNCTION sbox_contains_box_neg(sbox, sbox); -ALTER EXTENSION pg_sphere ADD FUNCTION sbox_contains_box_com_neg(sbox, sbox); -ALTER EXTENSION pg_sphere ADD FUNCTION sbox_overlap_box(sbox, sbox); -ALTER EXTENSION pg_sphere ADD OPERATOR &&(sbox, sbox); -ALTER EXTENSION pg_sphere ADD FUNCTION sbox_overlap_box_neg(sbox, sbox); -ALTER EXTENSION pg_sphere ADD OPERATOR !&&(sbox, sbox); -ALTER EXTENSION pg_sphere ADD FUNCTION sbox_cont_point_com(spoint, sbox); -ALTER EXTENSION pg_sphere ADD FUNCTION sbox_cont_point_com_neg(spoint, sbox); -ALTER EXTENSION pg_sphere ADD FUNCTION sbox_cont_point(sbox, spoint); -ALTER EXTENSION pg_sphere ADD FUNCTION sbox_cont_point_neg(sbox, spoint); -ALTER EXTENSION pg_sphere ADD FUNCTION sbox_contains_circle(sbox, scircle); -ALTER EXTENSION pg_sphere ADD FUNCTION sbox_contains_circle_com(scircle, sbox); -ALTER EXTENSION pg_sphere ADD FUNCTION sbox_contains_circle_neg(sbox, scircle); -ALTER EXTENSION pg_sphere ADD FUNCTION sbox_contains_circle_com_neg(scircle, sbox); -ALTER EXTENSION pg_sphere ADD FUNCTION scircle_contains_box(scircle, sbox); -ALTER EXTENSION pg_sphere ADD FUNCTION scircle_contains_box_com(sbox, scircle); -ALTER EXTENSION pg_sphere ADD FUNCTION scircle_contains_box_neg(scircle, sbox); -ALTER EXTENSION pg_sphere ADD FUNCTION scircle_contains_box_com_neg(sbox, scircle); -ALTER EXTENSION pg_sphere ADD FUNCTION sbox_overlap_circle(sbox, scircle); -ALTER EXTENSION pg_sphere ADD OPERATOR &&(sbox, scircle); -ALTER EXTENSION pg_sphere ADD FUNCTION sbox_overlap_circle_com(scircle, sbox); -ALTER EXTENSION pg_sphere ADD OPERATOR &&(scircle, sbox); -ALTER EXTENSION pg_sphere ADD FUNCTION sbox_overlap_circle_neg(sbox, scircle); -ALTER EXTENSION pg_sphere ADD OPERATOR !&&(sbox, scircle); -ALTER EXTENSION pg_sphere ADD FUNCTION sbox_overlap_circle_com_neg(scircle, sbox); -ALTER EXTENSION pg_sphere ADD OPERATOR !&&(scircle, sbox); -ALTER EXTENSION pg_sphere ADD FUNCTION sbox_contains_line(sbox, sline); -ALTER EXTENSION pg_sphere ADD FUNCTION sbox_contains_line_com(sline, sbox); -ALTER EXTENSION pg_sphere ADD FUNCTION sbox_contains_line_neg(sbox, sline); -ALTER EXTENSION pg_sphere ADD FUNCTION sbox_contains_line_com_neg(sline, sbox); -ALTER EXTENSION pg_sphere ADD FUNCTION sbox_overlap_line(sbox, sline); -ALTER EXTENSION pg_sphere ADD OPERATOR &&(sbox, sline); -ALTER EXTENSION pg_sphere ADD FUNCTION sbox_overlap_line_com(sline, sbox); -ALTER EXTENSION pg_sphere ADD OPERATOR &&(sline, sbox); -ALTER EXTENSION pg_sphere ADD FUNCTION sbox_overlap_line_neg(sbox, sline); -ALTER EXTENSION pg_sphere ADD OPERATOR !&&(sbox, sline); -ALTER EXTENSION pg_sphere ADD FUNCTION sbox_overlap_line_com_neg(sline, sbox); -ALTER EXTENSION pg_sphere ADD OPERATOR !&&(sline, sbox); -ALTER EXTENSION pg_sphere ADD FUNCTION sbox_contains_ellipse(sbox, sellipse); -ALTER EXTENSION pg_sphere ADD FUNCTION sbox_contains_ellipse_com(sellipse, sbox); -ALTER EXTENSION pg_sphere ADD FUNCTION sbox_contains_ellipse_neg(sbox, sellipse); -ALTER EXTENSION pg_sphere ADD FUNCTION sbox_contains_ellipse_com_neg(sellipse, sbox); -ALTER EXTENSION pg_sphere ADD FUNCTION sellipse_contains_box(sellipse, sbox); -ALTER EXTENSION pg_sphere ADD FUNCTION sellipse_contains_box_com(sbox, sellipse); -ALTER EXTENSION pg_sphere ADD FUNCTION sellipse_contains_box_neg(sellipse, sbox); -ALTER EXTENSION pg_sphere ADD FUNCTION sellipse_contains_box_com_neg(sbox, sellipse); -ALTER EXTENSION pg_sphere ADD FUNCTION sbox_overlap_ellipse(sbox, sellipse); -ALTER EXTENSION pg_sphere ADD OPERATOR &&(sbox, sellipse); -ALTER EXTENSION pg_sphere ADD FUNCTION sbox_overlap_ellipse_com(sellipse, sbox); -ALTER EXTENSION pg_sphere ADD OPERATOR &&(sellipse, sbox); -ALTER EXTENSION pg_sphere ADD FUNCTION sbox_overlap_ellipse_neg(sbox, sellipse); -ALTER EXTENSION pg_sphere ADD OPERATOR !&&(sbox, sellipse); -ALTER EXTENSION pg_sphere ADD FUNCTION sbox_overlap_ellipse_com_neg(sellipse, sbox); -ALTER EXTENSION pg_sphere ADD OPERATOR !&&(sellipse, sbox); -ALTER EXTENSION pg_sphere ADD FUNCTION sbox_contains_poly(sbox, spoly); -ALTER EXTENSION pg_sphere ADD FUNCTION sbox_contains_poly_com(spoly, sbox); -ALTER EXTENSION pg_sphere ADD FUNCTION sbox_contains_poly_neg(sbox, spoly); -ALTER EXTENSION pg_sphere ADD FUNCTION sbox_contains_poly_com_neg(spoly, sbox); -ALTER EXTENSION pg_sphere ADD FUNCTION spoly_contains_box(spoly, sbox); -ALTER EXTENSION pg_sphere ADD FUNCTION spoly_contains_box_com(sbox, spoly); -ALTER EXTENSION pg_sphere ADD FUNCTION spoly_contains_box_neg(spoly, sbox); -ALTER EXTENSION pg_sphere ADD FUNCTION spoly_contains_box_com_neg(sbox, spoly); -ALTER EXTENSION pg_sphere ADD FUNCTION sbox_overlap_poly(sbox, spoly); -ALTER EXTENSION pg_sphere ADD OPERATOR &&(sbox, spoly); -ALTER EXTENSION pg_sphere ADD FUNCTION sbox_overlap_poly_com(spoly, sbox); -ALTER EXTENSION pg_sphere ADD OPERATOR &&(spoly, sbox); -ALTER EXTENSION pg_sphere ADD FUNCTION sbox_overlap_poly_neg(sbox, spoly); -ALTER EXTENSION pg_sphere ADD OPERATOR !&&(sbox, spoly); -ALTER EXTENSION pg_sphere ADD FUNCTION sbox_overlap_poly_com_neg(spoly, sbox); -ALTER EXTENSION pg_sphere ADD OPERATOR !&&(spoly, sbox); -ALTER EXTENSION pg_sphere ADD FUNCTION sbox_contains_path(sbox, spath); -ALTER EXTENSION pg_sphere ADD FUNCTION sbox_contains_path_com(spath, sbox); -ALTER EXTENSION pg_sphere ADD FUNCTION sbox_contains_path_neg(sbox, spath); -ALTER EXTENSION pg_sphere ADD FUNCTION sbox_contains_path_com_neg(spath, sbox); -ALTER EXTENSION pg_sphere ADD FUNCTION sbox_overlap_path(sbox, spath); -ALTER EXTENSION pg_sphere ADD OPERATOR &&(sbox, spath); -ALTER EXTENSION pg_sphere ADD FUNCTION sbox_overlap_path_com(spath, sbox); -ALTER EXTENSION pg_sphere ADD OPERATOR &&(spath, sbox); -ALTER EXTENSION pg_sphere ADD FUNCTION sbox_overlap_path_neg(sbox, spath); -ALTER EXTENSION pg_sphere ADD OPERATOR !&&(sbox, spath); -ALTER EXTENSION pg_sphere ADD FUNCTION sbox_overlap_path_com_neg(spath, sbox); -ALTER EXTENSION pg_sphere ADD OPERATOR !&&(spath, sbox); diff --git a/upgrade_scripts/pgs_circle.sql.in b/upgrade_scripts/pgs_circle.sql.in deleted file mode 100644 index ddd2ab8..0000000 --- a/upgrade_scripts/pgs_circle.sql.in +++ /dev/null @@ -1,31 +0,0 @@ -ALTER EXTENSION pg_sphere ADD FUNCTION area(scircle); -ALTER EXTENSION pg_sphere ADD FUNCTION radius(scircle); -ALTER EXTENSION pg_sphere ADD FUNCTION scircle(spoint, float8); -ALTER EXTENSION pg_sphere ADD FUNCTION scircle(spoint); -ALTER EXTENSION pg_sphere ADD FUNCTION scircle_equal(scircle, scircle); -ALTER EXTENSION pg_sphere ADD OPERATOR =(scircle, scircle); -ALTER EXTENSION pg_sphere ADD FUNCTION scircle_equal_neg(scircle, scircle); -ALTER EXTENSION pg_sphere ADD OPERATOR <>(scircle, scircle); -ALTER EXTENSION pg_sphere ADD FUNCTION scircle_overlap(scircle, scircle); -ALTER EXTENSION pg_sphere ADD OPERATOR &&(scircle, scircle); -ALTER EXTENSION pg_sphere ADD FUNCTION scircle_overlap_neg(scircle, scircle); -ALTER EXTENSION pg_sphere ADD OPERATOR !&&(scircle, scircle); -ALTER EXTENSION pg_sphere ADD FUNCTION center(scircle); -ALTER EXTENSION pg_sphere ADD OPERATOR @@(NONE, scircle); -ALTER EXTENSION pg_sphere ADD FUNCTION circum(scircle); -ALTER EXTENSION pg_sphere ADD OPERATOR @-@(NONE, scircle); -ALTER EXTENSION pg_sphere ADD FUNCTION scircle_contained_by_circle(scircle, scircle); -ALTER EXTENSION pg_sphere ADD FUNCTION spoint_contained_by_circle(spoint, scircle); -ALTER EXTENSION pg_sphere ADD FUNCTION spoint_contained_by_circle_neg(spoint, scircle); -ALTER EXTENSION pg_sphere ADD FUNCTION spoint_contained_by_circle_com(scircle, spoint); -ALTER EXTENSION pg_sphere ADD FUNCTION spoint_contained_by_circle_com_neg(scircle, spoint); -ALTER EXTENSION pg_sphere ADD FUNCTION dist(scircle, scircle); -ALTER EXTENSION pg_sphere ADD OPERATOR <->(scircle, scircle); -ALTER EXTENSION pg_sphere ADD FUNCTION dist(scircle, spoint); -ALTER EXTENSION pg_sphere ADD OPERATOR <->(scircle, spoint); -ALTER EXTENSION pg_sphere ADD FUNCTION dist(spoint, scircle); -ALTER EXTENSION pg_sphere ADD OPERATOR <->(spoint, scircle); -ALTER EXTENSION pg_sphere ADD FUNCTION strans_circle(scircle, strans); -ALTER EXTENSION pg_sphere ADD OPERATOR +(scircle, strans); -ALTER EXTENSION pg_sphere ADD FUNCTION strans_circle_inverse(scircle, strans); -ALTER EXTENSION pg_sphere ADD OPERATOR -(scircle, strans); diff --git a/upgrade_scripts/pgs_contains_ops_compat.sql.in b/upgrade_scripts/pgs_contains_ops_compat.sql.in deleted file mode 100644 index d0e9c22..0000000 --- a/upgrade_scripts/pgs_contains_ops_compat.sql.in +++ /dev/null @@ -1,120 +0,0 @@ -ALTER EXTENSION pg_sphere ADD OPERATOR ~(scircle, scircle); -ALTER EXTENSION pg_sphere ADD OPERATOR @(scircle, scircle); -ALTER EXTENSION pg_sphere ADD OPERATOR !~(scircle, scircle); -ALTER EXTENSION pg_sphere ADD OPERATOR !@(scircle, scircle); -ALTER EXTENSION pg_sphere ADD OPERATOR ~(scircle, spoint); -ALTER EXTENSION pg_sphere ADD OPERATOR @(spoint, scircle); -ALTER EXTENSION pg_sphere ADD OPERATOR !~(scircle, spoint); -ALTER EXTENSION pg_sphere ADD OPERATOR !@(spoint, scircle); -ALTER EXTENSION pg_sphere ADD OPERATOR ~(spoly, spoly); -ALTER EXTENSION pg_sphere ADD OPERATOR @(spoly, spoly); -ALTER EXTENSION pg_sphere ADD OPERATOR !~(spoly, spoly); -ALTER EXTENSION pg_sphere ADD OPERATOR !@(spoly, spoly); -ALTER EXTENSION pg_sphere ADD OPERATOR ~(spoly, spoint); -ALTER EXTENSION pg_sphere ADD OPERATOR @(spoint, spoly); -ALTER EXTENSION pg_sphere ADD OPERATOR !~(spoly, spoint); -ALTER EXTENSION pg_sphere ADD OPERATOR !@(spoint, spoly); -ALTER EXTENSION pg_sphere ADD OPERATOR ~(scircle, spoly); -ALTER EXTENSION pg_sphere ADD OPERATOR @(spoly, scircle); -ALTER EXTENSION pg_sphere ADD OPERATOR !~(scircle, spoly); -ALTER EXTENSION pg_sphere ADD OPERATOR !@(spoly, scircle); -ALTER EXTENSION pg_sphere ADD OPERATOR ~(spoly, scircle); -ALTER EXTENSION pg_sphere ADD OPERATOR @(scircle, spoly); -ALTER EXTENSION pg_sphere ADD OPERATOR !~(spoly, scircle); -ALTER EXTENSION pg_sphere ADD OPERATOR !@(scircle, spoly); -ALTER EXTENSION pg_sphere ADD OPERATOR ~(sbox, sbox); -ALTER EXTENSION pg_sphere ADD OPERATOR @(sbox, sbox); -ALTER EXTENSION pg_sphere ADD OPERATOR !~(sbox, sbox); -ALTER EXTENSION pg_sphere ADD OPERATOR !@(sbox, sbox); -ALTER EXTENSION pg_sphere ADD OPERATOR ~(sbox, spoint); -ALTER EXTENSION pg_sphere ADD OPERATOR @(spoint, sbox); -ALTER EXTENSION pg_sphere ADD OPERATOR !~(sbox, spoint); -ALTER EXTENSION pg_sphere ADD OPERATOR !@(spoint, sbox); -ALTER EXTENSION pg_sphere ADD OPERATOR ~(scircle, sbox); -ALTER EXTENSION pg_sphere ADD OPERATOR @(sbox, scircle); -ALTER EXTENSION pg_sphere ADD OPERATOR !~(scircle, sbox); -ALTER EXTENSION pg_sphere ADD OPERATOR !@(sbox, scircle); -ALTER EXTENSION pg_sphere ADD OPERATOR ~(sbox, scircle); -ALTER EXTENSION pg_sphere ADD OPERATOR @(scircle, sbox); -ALTER EXTENSION pg_sphere ADD OPERATOR !~(sbox, scircle); -ALTER EXTENSION pg_sphere ADD OPERATOR !@(scircle, sbox); -ALTER EXTENSION pg_sphere ADD OPERATOR ~(spoly, sbox); -ALTER EXTENSION pg_sphere ADD OPERATOR @(sbox, spoly); -ALTER EXTENSION pg_sphere ADD OPERATOR !~(spoly, sbox); -ALTER EXTENSION pg_sphere ADD OPERATOR !@(sbox, spoly); -ALTER EXTENSION pg_sphere ADD OPERATOR ~(sbox, spoly); -ALTER EXTENSION pg_sphere ADD OPERATOR @(spoly, sbox); -ALTER EXTENSION pg_sphere ADD OPERATOR !~(sbox, spoly); -ALTER EXTENSION pg_sphere ADD OPERATOR !@(spoly, sbox); -ALTER EXTENSION pg_sphere ADD OPERATOR @(spoint, sline); -ALTER EXTENSION pg_sphere ADD OPERATOR ~(sline, spoint); -ALTER EXTENSION pg_sphere ADD OPERATOR !~(sline, spoint); -ALTER EXTENSION pg_sphere ADD OPERATOR !@(spoint, sline); -ALTER EXTENSION pg_sphere ADD OPERATOR ~(scircle, sline); -ALTER EXTENSION pg_sphere ADD OPERATOR @(sline, scircle); -ALTER EXTENSION pg_sphere ADD OPERATOR !~(scircle, sline); -ALTER EXTENSION pg_sphere ADD OPERATOR !@(sline, scircle); -ALTER EXTENSION pg_sphere ADD OPERATOR ~(spoly, sline); -ALTER EXTENSION pg_sphere ADD OPERATOR @(sline, spoly); -ALTER EXTENSION pg_sphere ADD OPERATOR !~(spoly, sline); -ALTER EXTENSION pg_sphere ADD OPERATOR !@(sline, spoly); -ALTER EXTENSION pg_sphere ADD OPERATOR ~(sellipse, sellipse); -ALTER EXTENSION pg_sphere ADD OPERATOR @(sellipse, sellipse); -ALTER EXTENSION pg_sphere ADD OPERATOR !~(sellipse, sellipse); -ALTER EXTENSION pg_sphere ADD OPERATOR !@(sellipse, sellipse); -ALTER EXTENSION pg_sphere ADD OPERATOR ~(sellipse, spoint); -ALTER EXTENSION pg_sphere ADD OPERATOR @(spoint, sellipse); -ALTER EXTENSION pg_sphere ADD OPERATOR !~(sellipse, spoint); -ALTER EXTENSION pg_sphere ADD OPERATOR !@(spoint, sellipse); -ALTER EXTENSION pg_sphere ADD OPERATOR ~(sbox, sellipse); -ALTER EXTENSION pg_sphere ADD OPERATOR @(sellipse, sbox); -ALTER EXTENSION pg_sphere ADD OPERATOR !~(sbox, sellipse); -ALTER EXTENSION pg_sphere ADD OPERATOR !@(sellipse, sbox); -ALTER EXTENSION pg_sphere ADD OPERATOR ~(sellipse, sbox); -ALTER EXTENSION pg_sphere ADD OPERATOR @(sbox, sellipse); -ALTER EXTENSION pg_sphere ADD OPERATOR !~(sellipse, sbox); -ALTER EXTENSION pg_sphere ADD OPERATOR !@(sbox, sellipse); -ALTER EXTENSION pg_sphere ADD OPERATOR ~(sellipse, scircle); -ALTER EXTENSION pg_sphere ADD OPERATOR @(scircle, sellipse); -ALTER EXTENSION pg_sphere ADD OPERATOR !~(sellipse, scircle); -ALTER EXTENSION pg_sphere ADD OPERATOR !@(scircle, sellipse); -ALTER EXTENSION pg_sphere ADD OPERATOR ~(scircle, sellipse); -ALTER EXTENSION pg_sphere ADD OPERATOR @(sellipse, scircle); -ALTER EXTENSION pg_sphere ADD OPERATOR !~(scircle, sellipse); -ALTER EXTENSION pg_sphere ADD OPERATOR !@(sellipse, scircle); -ALTER EXTENSION pg_sphere ADD OPERATOR ~(sellipse, sline); -ALTER EXTENSION pg_sphere ADD OPERATOR @(sline, sellipse); -ALTER EXTENSION pg_sphere ADD OPERATOR !~(sellipse, sline); -ALTER EXTENSION pg_sphere ADD OPERATOR !@(sline, sellipse); -ALTER EXTENSION pg_sphere ADD OPERATOR ~(spoly, sellipse); -ALTER EXTENSION pg_sphere ADD OPERATOR @(sellipse, spoly); -ALTER EXTENSION pg_sphere ADD OPERATOR !~(spoly, sellipse); -ALTER EXTENSION pg_sphere ADD OPERATOR !@(sellipse, spoly); -ALTER EXTENSION pg_sphere ADD OPERATOR ~(sellipse, spoly); -ALTER EXTENSION pg_sphere ADD OPERATOR @(spoly, sellipse); -ALTER EXTENSION pg_sphere ADD OPERATOR !~(sellipse, spoly); -ALTER EXTENSION pg_sphere ADD OPERATOR !@(spoly, sellipse); -ALTER EXTENSION pg_sphere ADD OPERATOR ~(spath, spoint); -ALTER EXTENSION pg_sphere ADD OPERATOR @(spoint, spath); -ALTER EXTENSION pg_sphere ADD OPERATOR !~(spath, spoint); -ALTER EXTENSION pg_sphere ADD OPERATOR !@(spoint, spath); -ALTER EXTENSION pg_sphere ADD OPERATOR ~(sbox, spath); -ALTER EXTENSION pg_sphere ADD OPERATOR @(spath, sbox); -ALTER EXTENSION pg_sphere ADD OPERATOR !~(sbox, spath); -ALTER EXTENSION pg_sphere ADD OPERATOR !@(spath, sbox); -ALTER EXTENSION pg_sphere ADD OPERATOR ~(scircle, spath); -ALTER EXTENSION pg_sphere ADD OPERATOR @(spath, scircle); -ALTER EXTENSION pg_sphere ADD OPERATOR !~(scircle, spath); -ALTER EXTENSION pg_sphere ADD OPERATOR !@(spath, scircle); -ALTER EXTENSION pg_sphere ADD OPERATOR ~(sellipse, spath); -ALTER EXTENSION pg_sphere ADD OPERATOR @(spath, sellipse); -ALTER EXTENSION pg_sphere ADD OPERATOR !~(sellipse, spath); -ALTER EXTENSION pg_sphere ADD OPERATOR !@(spath, sellipse); -ALTER EXTENSION pg_sphere ADD OPERATOR ~(spoly, spath); -ALTER EXTENSION pg_sphere ADD OPERATOR @(spath, spoly); -ALTER EXTENSION pg_sphere ADD OPERATOR !~(spoly, spath); -ALTER EXTENSION pg_sphere ADD OPERATOR !@(spath, spoly); -ALTER EXTENSION pg_sphere ADD OPERATOR ~(sbox, sline); -ALTER EXTENSION pg_sphere ADD OPERATOR @(sline, sbox); -ALTER EXTENSION pg_sphere ADD OPERATOR !~(sbox, sline); -ALTER EXTENSION pg_sphere ADD OPERATOR !@(sline, sbox); diff --git a/upgrade_scripts/pgs_ellipse.sql.in b/upgrade_scripts/pgs_ellipse.sql.in deleted file mode 100644 index 77e2d77..0000000 --- a/upgrade_scripts/pgs_ellipse.sql.in +++ /dev/null @@ -1,55 +0,0 @@ -ALTER EXTENSION pg_sphere ADD FUNCTION sellipse(spoint, float8, float8, float8); -ALTER EXTENSION pg_sphere ADD FUNCTION inc(sellipse); -ALTER EXTENSION pg_sphere ADD FUNCTION lrad(sellipse); -ALTER EXTENSION pg_sphere ADD FUNCTION srad(sellipse); -ALTER EXTENSION pg_sphere ADD FUNCTION sellipse(spoint); -ALTER EXTENSION pg_sphere ADD FUNCTION scircle(sellipse); -ALTER EXTENSION pg_sphere ADD FUNCTION sellipse(scircle); -ALTER EXTENSION pg_sphere ADD FUNCTION strans(sellipse); -ALTER EXTENSION pg_sphere ADD FUNCTION center(sellipse); -ALTER EXTENSION pg_sphere ADD OPERATOR @@(NONE, sellipse); -ALTER EXTENSION pg_sphere ADD FUNCTION sellipse_equal(sellipse, sellipse); -ALTER EXTENSION pg_sphere ADD OPERATOR =(sellipse, sellipse); -ALTER EXTENSION pg_sphere ADD FUNCTION sellipse_equal_neg(sellipse, sellipse); -ALTER EXTENSION pg_sphere ADD OPERATOR <>(sellipse, sellipse); -ALTER EXTENSION pg_sphere ADD FUNCTION sellipse_contains_ellipse(sellipse, sellipse); -ALTER EXTENSION pg_sphere ADD FUNCTION sellipse_contains_ellipse_com(sellipse, sellipse); -ALTER EXTENSION pg_sphere ADD FUNCTION sellipse_contains_ellipse_neg(sellipse, sellipse); -ALTER EXTENSION pg_sphere ADD FUNCTION sellipse_contains_ellipse_com_neg(sellipse, sellipse); -ALTER EXTENSION pg_sphere ADD FUNCTION sellipse_overlap_ellipse(sellipse, sellipse); -ALTER EXTENSION pg_sphere ADD OPERATOR &&(sellipse, sellipse); -ALTER EXTENSION pg_sphere ADD FUNCTION sellipse_overlap_ellipse_neg(sellipse, sellipse); -ALTER EXTENSION pg_sphere ADD OPERATOR !&&(sellipse, sellipse); -ALTER EXTENSION pg_sphere ADD FUNCTION sellipse_contains_point(sellipse, spoint); -ALTER EXTENSION pg_sphere ADD FUNCTION sellipse_contains_point_com(spoint, sellipse); -ALTER EXTENSION pg_sphere ADD FUNCTION sellipse_contains_point_neg(sellipse, spoint); -ALTER EXTENSION pg_sphere ADD FUNCTION sellipse_contains_point_com_neg(spoint, sellipse); -ALTER EXTENSION pg_sphere ADD FUNCTION strans_ellipse(sellipse, strans); -ALTER EXTENSION pg_sphere ADD OPERATOR +(sellipse, strans); -ALTER EXTENSION pg_sphere ADD OPERATOR -(sellipse, strans); -ALTER EXTENSION pg_sphere ADD FUNCTION sellipse_contains_circle(sellipse, scircle); -ALTER EXTENSION pg_sphere ADD FUNCTION sellipse_contains_circle_com(scircle, sellipse); -ALTER EXTENSION pg_sphere ADD FUNCTION sellipse_contains_circle_neg(sellipse, scircle); -ALTER EXTENSION pg_sphere ADD FUNCTION sellipse_contains_circle_com_neg(scircle, sellipse); -ALTER EXTENSION pg_sphere ADD FUNCTION scircle_contains_ellipse(scircle, sellipse); -ALTER EXTENSION pg_sphere ADD FUNCTION scircle_contains_ellipse_com(sellipse, scircle); -ALTER EXTENSION pg_sphere ADD FUNCTION scircle_contains_ellipse_neg(scircle, sellipse); -ALTER EXTENSION pg_sphere ADD FUNCTION scircle_contains_ellipse_com_neg(sellipse, scircle); -ALTER EXTENSION pg_sphere ADD FUNCTION sellipse_overlap_circle(sellipse, scircle); -ALTER EXTENSION pg_sphere ADD OPERATOR &&(sellipse, scircle); -ALTER EXTENSION pg_sphere ADD FUNCTION sellipse_overlap_circle_com(scircle, sellipse); -ALTER EXTENSION pg_sphere ADD OPERATOR &&(scircle, sellipse); -ALTER EXTENSION pg_sphere ADD FUNCTION sellipse_overlap_circle_neg(sellipse, scircle); -ALTER EXTENSION pg_sphere ADD OPERATOR !&&(sellipse, scircle); -ALTER EXTENSION pg_sphere ADD FUNCTION sellipse_overlap_circle_com_neg(scircle, sellipse); -ALTER EXTENSION pg_sphere ADD OPERATOR !&&(scircle, sellipse); -ALTER EXTENSION pg_sphere ADD OPERATOR &&(sellipse, sline); -ALTER EXTENSION pg_sphere ADD FUNCTION sellipse_overlap_line_com(sline, sellipse); -ALTER EXTENSION pg_sphere ADD OPERATOR &&(sline, sellipse); -ALTER EXTENSION pg_sphere ADD OPERATOR !&&(sellipse, sline); -ALTER EXTENSION pg_sphere ADD FUNCTION sellipse_overlap_line_com_neg(sline, sellipse); -ALTER EXTENSION pg_sphere ADD OPERATOR !&&(sline, sellipse); -ALTER EXTENSION pg_sphere ADD FUNCTION sellipse_contains_line(sellipse, sline); -ALTER EXTENSION pg_sphere ADD FUNCTION sellipse_contains_line_com(sline, sellipse); -ALTER EXTENSION pg_sphere ADD FUNCTION sellipse_contains_line_neg(sellipse, sline); -ALTER EXTENSION pg_sphere ADD FUNCTION sellipse_contains_line_com_neg(sline, sellipse); diff --git a/upgrade_scripts/pgs_euler.sql.in b/upgrade_scripts/pgs_euler.sql.in deleted file mode 100644 index 8ed4ca4..0000000 --- a/upgrade_scripts/pgs_euler.sql.in +++ /dev/null @@ -1,23 +0,0 @@ -ALTER EXTENSION pg_sphere ADD FUNCTION strans_zxz(strans); -ALTER EXTENSION pg_sphere ADD FUNCTION strans(FLOAT8, FLOAT8, FLOAT8); -ALTER EXTENSION pg_sphere ADD FUNCTION strans(FLOAT8, FLOAT8, FLOAT8, CSTRING); -ALTER EXTENSION pg_sphere ADD FUNCTION phi(strans); -ALTER EXTENSION pg_sphere ADD FUNCTION theta(strans); -ALTER EXTENSION pg_sphere ADD FUNCTION psi(strans); -ALTER EXTENSION pg_sphere ADD FUNCTION axes(strans); -ALTER EXTENSION pg_sphere ADD FUNCTION strans_equal(strans, strans); -ALTER EXTENSION pg_sphere ADD OPERATOR =(strans, strans); -ALTER EXTENSION pg_sphere ADD FUNCTION strans_not_equal(strans, strans); -ALTER EXTENSION pg_sphere ADD OPERATOR <>(strans, strans); -ALTER EXTENSION pg_sphere ADD FUNCTION strans(strans); -ALTER EXTENSION pg_sphere ADD OPERATOR +(NONE, strans); -ALTER EXTENSION pg_sphere ADD FUNCTION strans_invert(strans); -ALTER EXTENSION pg_sphere ADD OPERATOR -(NONE, strans); -ALTER EXTENSION pg_sphere ADD FUNCTION strans_point(spoint, strans); -ALTER EXTENSION pg_sphere ADD OPERATOR +(spoint, strans); -ALTER EXTENSION pg_sphere ADD FUNCTION strans_point_inverse(spoint, strans); -ALTER EXTENSION pg_sphere ADD OPERATOR -(spoint, strans); -ALTER EXTENSION pg_sphere ADD FUNCTION strans_trans(strans, strans); -ALTER EXTENSION pg_sphere ADD OPERATOR +(strans, strans); -ALTER EXTENSION pg_sphere ADD FUNCTION strans_trans_inv(strans, strans); -ALTER EXTENSION pg_sphere ADD OPERATOR -(strans, strans); diff --git a/upgrade_scripts/pgs_gist.sql.in b/upgrade_scripts/pgs_gist.sql.in deleted file mode 100644 index aaa0e4e..0000000 --- a/upgrade_scripts/pgs_gist.sql.in +++ /dev/null @@ -1,27 +0,0 @@ -ALTER EXTENSION pg_sphere ADD FUNCTION spherekey_in(CSTRING); -ALTER EXTENSION pg_sphere ADD FUNCTION spherekey_out(spherekey); -ALTER EXTENSION pg_sphere ADD TYPE spherekey; -ALTER EXTENSION pg_sphere ADD FUNCTION g_spherekey_decompress(internal); -ALTER EXTENSION pg_sphere ADD FUNCTION g_spherekey_union(bytea, internal); -ALTER EXTENSION pg_sphere ADD FUNCTION g_spherekey_picksplit(internal, internal); -ALTER EXTENSION pg_sphere ADD FUNCTION g_spoint_compress(internal); -ALTER EXTENSION pg_sphere ADD FUNCTION g_spoint_consistent(internal, internal, int4, oid, internal); -ALTER EXTENSION pg_sphere ADD OPERATOR CLASS spoint USING gist; -ALTER EXTENSION pg_sphere ADD FUNCTION g_scircle_compress(internal); -ALTER EXTENSION pg_sphere ADD FUNCTION g_scircle_consistent(internal, internal, int4, oid, internal); -ALTER EXTENSION pg_sphere ADD OPERATOR CLASS scircle USING gist; -ALTER EXTENSION pg_sphere ADD FUNCTION g_sline_compress(internal); -ALTER EXTENSION pg_sphere ADD FUNCTION g_sline_consistent(internal, internal, int4, oid, internal); -ALTER EXTENSION pg_sphere ADD OPERATOR CLASS sline USING gist; -ALTER EXTENSION pg_sphere ADD FUNCTION g_sellipse_compress(internal); -ALTER EXTENSION pg_sphere ADD FUNCTION g_sellipse_consistent(internal, internal, int4, oid, internal); -ALTER EXTENSION pg_sphere ADD OPERATOR CLASS sellipse USING gist; -ALTER EXTENSION pg_sphere ADD FUNCTION g_spoly_compress(internal); -ALTER EXTENSION pg_sphere ADD FUNCTION g_spoly_consistent(internal, internal, int4, oid, internal); -ALTER EXTENSION pg_sphere ADD OPERATOR CLASS spoly USING gist; -ALTER EXTENSION pg_sphere ADD FUNCTION g_spath_compress(internal); -ALTER EXTENSION pg_sphere ADD FUNCTION g_spath_consistent(internal, internal, int4, oid, internal); -ALTER EXTENSION pg_sphere ADD OPERATOR CLASS spath USING gist; -ALTER EXTENSION pg_sphere ADD FUNCTION g_sbox_compress(internal); -ALTER EXTENSION pg_sphere ADD FUNCTION g_sbox_consistent(internal, internal, int4, oid, internal); -ALTER EXTENSION pg_sphere ADD OPERATOR CLASS sbox USING gist; diff --git a/upgrade_scripts/pgs_line.sql.in b/upgrade_scripts/pgs_line.sql.in deleted file mode 100644 index 3e9c6ce..0000000 --- a/upgrade_scripts/pgs_line.sql.in +++ /dev/null @@ -1,41 +0,0 @@ -ALTER EXTENSION pg_sphere ADD FUNCTION sline(spoint, spoint); -ALTER EXTENSION pg_sphere ADD FUNCTION sline(strans, float8); -ALTER EXTENSION pg_sphere ADD FUNCTION meridian(float8); -ALTER EXTENSION pg_sphere ADD FUNCTION sl_beg(sline); -ALTER EXTENSION pg_sphere ADD FUNCTION sl_end(sline); -ALTER EXTENSION pg_sphere ADD FUNCTION strans(sline); -ALTER EXTENSION pg_sphere ADD FUNCTION sline(spoint); -ALTER EXTENSION pg_sphere ADD FUNCTION sline_equal(sline, sline); -ALTER EXTENSION pg_sphere ADD OPERATOR =(sline, sline); -ALTER EXTENSION pg_sphere ADD FUNCTION sline_equal_neg(sline, sline); -ALTER EXTENSION pg_sphere ADD OPERATOR <>(sline, sline); -ALTER EXTENSION pg_sphere ADD FUNCTION length(sline); -ALTER EXTENSION pg_sphere ADD OPERATOR @-@(NONE, sline); -ALTER EXTENSION pg_sphere ADD FUNCTION swap(sline); -ALTER EXTENSION pg_sphere ADD OPERATOR -(NONE, sline); -ALTER EXTENSION pg_sphere ADD FUNCTION turn(sline); -ALTER EXTENSION pg_sphere ADD OPERATOR !(NONE, sline); -ALTER EXTENSION pg_sphere ADD FUNCTION sline_crosses(sline, sline); -ALTER EXTENSION pg_sphere ADD OPERATOR #(sline, sline); -ALTER EXTENSION pg_sphere ADD FUNCTION sline_crosses_neg(sline, sline); -ALTER EXTENSION pg_sphere ADD OPERATOR !#(sline, sline); -ALTER EXTENSION pg_sphere ADD FUNCTION sline_overlap(sline, sline); -ALTER EXTENSION pg_sphere ADD OPERATOR &&(sline, sline); -ALTER EXTENSION pg_sphere ADD FUNCTION sline_overlap_neg(sline, sline); -ALTER EXTENSION pg_sphere ADD OPERATOR !&&(sline, sline); -ALTER EXTENSION pg_sphere ADD FUNCTION strans_line(sline, strans); -ALTER EXTENSION pg_sphere ADD OPERATOR +(sline, strans); -ALTER EXTENSION pg_sphere ADD FUNCTION strans_line_inverse(sline, strans); -ALTER EXTENSION pg_sphere ADD OPERATOR -(sline, strans); -ALTER EXTENSION pg_sphere ADD FUNCTION sline_overlap_circle(sline, scircle); -ALTER EXTENSION pg_sphere ADD OPERATOR &&(sline, scircle); -ALTER EXTENSION pg_sphere ADD FUNCTION sline_overlap_circle_com(scircle, sline); -ALTER EXTENSION pg_sphere ADD OPERATOR &&(scircle, sline); -ALTER EXTENSION pg_sphere ADD FUNCTION sline_overlap_circle_neg(sline, scircle); -ALTER EXTENSION pg_sphere ADD OPERATOR !&&(sline, scircle); -ALTER EXTENSION pg_sphere ADD FUNCTION sline_overlap_circle_com_neg(scircle, sline); -ALTER EXTENSION pg_sphere ADD OPERATOR !&&(scircle, sline); -ALTER EXTENSION pg_sphere ADD FUNCTION scircle_contains_line(scircle, sline); -ALTER EXTENSION pg_sphere ADD FUNCTION scircle_contains_line_com(sline, scircle); -ALTER EXTENSION pg_sphere ADD FUNCTION scircle_contains_line_neg(scircle, sline); -ALTER EXTENSION pg_sphere ADD FUNCTION scircle_contains_line_com_neg(sline, scircle); diff --git a/upgrade_scripts/pgs_path.sql.in b/upgrade_scripts/pgs_path.sql.in deleted file mode 100644 index e40b445..0000000 --- a/upgrade_scripts/pgs_path.sql.in +++ /dev/null @@ -1,67 +0,0 @@ -ALTER EXTENSION pg_sphere ADD FUNCTION npoints(spath); -ALTER EXTENSION pg_sphere ADD FUNCTION spoint(spath, int4); -ALTER EXTENSION pg_sphere ADD FUNCTION spoint(spath, float8); -ALTER EXTENSION pg_sphere ADD FUNCTION spath_equal(spath, spath); -ALTER EXTENSION pg_sphere ADD OPERATOR =(spath, spath); -ALTER EXTENSION pg_sphere ADD FUNCTION spath_equal_neg(spath, spath); -ALTER EXTENSION pg_sphere ADD OPERATOR <>(spath, spath); -ALTER EXTENSION pg_sphere ADD FUNCTION length(spath); -ALTER EXTENSION pg_sphere ADD OPERATOR @-@(NONE, spath); -ALTER EXTENSION pg_sphere ADD FUNCTION swap(spath); -ALTER EXTENSION pg_sphere ADD OPERATOR -(NONE, spath); -ALTER EXTENSION pg_sphere ADD FUNCTION spath_overlap_path(spath, spath); -ALTER EXTENSION pg_sphere ADD OPERATOR &&(spath, spath); -ALTER EXTENSION pg_sphere ADD FUNCTION spath_overlap_path_neg(spath, spath); -ALTER EXTENSION pg_sphere ADD OPERATOR !&&(spath, spath); -ALTER EXTENSION pg_sphere ADD FUNCTION spath_contains_point(spath, spoint); -ALTER EXTENSION pg_sphere ADD FUNCTION spath_contains_point_com(spoint, spath); -ALTER EXTENSION pg_sphere ADD FUNCTION spath_contains_point_neg(spath, spoint); -ALTER EXTENSION pg_sphere ADD FUNCTION spath_contains_point_com_neg(spoint, spath); -ALTER EXTENSION pg_sphere ADD FUNCTION strans_path(spath, strans); -ALTER EXTENSION pg_sphere ADD OPERATOR +(spath, strans); -ALTER EXTENSION pg_sphere ADD FUNCTION strans_path_inverse(spath, strans); -ALTER EXTENSION pg_sphere ADD OPERATOR -(spath, strans); -ALTER EXTENSION pg_sphere ADD FUNCTION scircle_contains_path(scircle, spath); -ALTER EXTENSION pg_sphere ADD FUNCTION scircle_contains_path_com(spath, scircle); -ALTER EXTENSION pg_sphere ADD FUNCTION scircle_contains_path_neg(scircle, spath); -ALTER EXTENSION pg_sphere ADD FUNCTION scircle_contains_path_com_neg(spath, scircle); -ALTER EXTENSION pg_sphere ADD FUNCTION scircle_overlap_path(scircle, spath); -ALTER EXTENSION pg_sphere ADD OPERATOR &&(scircle, spath); -ALTER EXTENSION pg_sphere ADD FUNCTION scircle_overlap_path_com(spath, scircle); -ALTER EXTENSION pg_sphere ADD OPERATOR &&(spath, scircle); -ALTER EXTENSION pg_sphere ADD FUNCTION scircle_overlap_path_neg(scircle, spath); -ALTER EXTENSION pg_sphere ADD OPERATOR !&&(scircle, spath); -ALTER EXTENSION pg_sphere ADD FUNCTION scircle_overlap_path_com_neg(spath, scircle); -ALTER EXTENSION pg_sphere ADD OPERATOR !&&(spath, scircle); -ALTER EXTENSION pg_sphere ADD FUNCTION spath_overlap_line(spath, sline); -ALTER EXTENSION pg_sphere ADD OPERATOR &&(spath, sline); -ALTER EXTENSION pg_sphere ADD FUNCTION spath_overlap_line_com(sline, spath); -ALTER EXTENSION pg_sphere ADD OPERATOR &&(sline, spath); -ALTER EXTENSION pg_sphere ADD FUNCTION spath_overlap_line_neg(spath, sline); -ALTER EXTENSION pg_sphere ADD OPERATOR !&&(spath, sline); -ALTER EXTENSION pg_sphere ADD FUNCTION spath_overlap_line_com_neg(sline, spath); -ALTER EXTENSION pg_sphere ADD OPERATOR !&&(sline, spath); -ALTER EXTENSION pg_sphere ADD FUNCTION sellipse_contains_path(sellipse, spath); -ALTER EXTENSION pg_sphere ADD FUNCTION sellipse_contains_path_com(spath, sellipse); -ALTER EXTENSION pg_sphere ADD FUNCTION sellipse_contains_path_neg(sellipse, spath); -ALTER EXTENSION pg_sphere ADD FUNCTION sellipse_contains_path_com_neg(spath, sellipse); -ALTER EXTENSION pg_sphere ADD FUNCTION sellipse_overlap_path(sellipse, spath); -ALTER EXTENSION pg_sphere ADD OPERATOR &&(sellipse, spath); -ALTER EXTENSION pg_sphere ADD FUNCTION sellipse_overlap_path_com(spath, sellipse); -ALTER EXTENSION pg_sphere ADD OPERATOR &&(spath, sellipse); -ALTER EXTENSION pg_sphere ADD FUNCTION sellipse_overlap_path_neg(sellipse, spath); -ALTER EXTENSION pg_sphere ADD OPERATOR !&&(sellipse, spath); -ALTER EXTENSION pg_sphere ADD FUNCTION sellipse_overlap_path_com_neg(spath, sellipse); -ALTER EXTENSION pg_sphere ADD OPERATOR !&&(spath, sellipse); -ALTER EXTENSION pg_sphere ADD FUNCTION spoly_contains_path(spoly, spath); -ALTER EXTENSION pg_sphere ADD FUNCTION spoly_contains_path_com(spath, spoly); -ALTER EXTENSION pg_sphere ADD FUNCTION spoly_contains_path_neg(spoly, spath); -ALTER EXTENSION pg_sphere ADD FUNCTION spoly_contains_path_com_neg(spath, spoly); -ALTER EXTENSION pg_sphere ADD FUNCTION spoly_overlap_path(spoly, spath); -ALTER EXTENSION pg_sphere ADD OPERATOR &&(spoly, spath); -ALTER EXTENSION pg_sphere ADD FUNCTION spoly_overlap_path_com(spath, spoly); -ALTER EXTENSION pg_sphere ADD OPERATOR &&(spath, spoly); -ALTER EXTENSION pg_sphere ADD FUNCTION spoly_overlap_path_neg(spoly, spath); -ALTER EXTENSION pg_sphere ADD OPERATOR !&&(spoly, spath); -ALTER EXTENSION pg_sphere ADD FUNCTION spoly_overlap_path_com_neg(spath, spoly); -ALTER EXTENSION pg_sphere ADD OPERATOR !&&(spath, spoly); diff --git a/upgrade_scripts/pgs_point.sql.in b/upgrade_scripts/pgs_point.sql.in deleted file mode 100644 index 754128f..0000000 --- a/upgrade_scripts/pgs_point.sql.in +++ /dev/null @@ -1,14 +0,0 @@ -ALTER EXTENSION pg_sphere ADD FUNCTION spoint(FLOAT8, FLOAT8); -ALTER EXTENSION pg_sphere ADD FUNCTION set_sphere_output_precision(INT4); -ALTER EXTENSION pg_sphere ADD FUNCTION set_sphere_output(CSTRING); -ALTER EXTENSION pg_sphere ADD FUNCTION long(spoint); -ALTER EXTENSION pg_sphere ADD FUNCTION lat(spoint); -ALTER EXTENSION pg_sphere ADD FUNCTION x(spoint); -ALTER EXTENSION pg_sphere ADD FUNCTION y(spoint); -ALTER EXTENSION pg_sphere ADD FUNCTION xyz(spoint); -ALTER EXTENSION pg_sphere ADD FUNCTION z(spoint); -ALTER EXTENSION pg_sphere ADD FUNCTION spoint_equal(spoint, spoint); -ALTER EXTENSION pg_sphere ADD OPERATOR =(spoint, spoint); -ALTER EXTENSION pg_sphere ADD OPERATOR <>(spoint, spoint); -ALTER EXTENSION pg_sphere ADD FUNCTION dist(spoint, spoint); -ALTER EXTENSION pg_sphere ADD OPERATOR <->(spoint, spoint); diff --git a/upgrade_scripts/pgs_polygon.sql.in b/upgrade_scripts/pgs_polygon.sql.in deleted file mode 100644 index 6a76b2f..0000000 --- a/upgrade_scripts/pgs_polygon.sql.in +++ /dev/null @@ -1,68 +0,0 @@ -ALTER EXTENSION pg_sphere ADD FUNCTION npoints(spoly); -ALTER EXTENSION pg_sphere ADD FUNCTION area(spoly); -ALTER EXTENSION pg_sphere ADD FUNCTION spoly_equal(spoly, spoly); -ALTER EXTENSION pg_sphere ADD OPERATOR =(spoly, spoly); -ALTER EXTENSION pg_sphere ADD FUNCTION spoly_not_equal(spoly, spoly); -ALTER EXTENSION pg_sphere ADD OPERATOR <>(spoly, spoly); -ALTER EXTENSION pg_sphere ADD FUNCTION circum(spoly); -ALTER EXTENSION pg_sphere ADD OPERATOR @-@(NONE, spoly); -ALTER EXTENSION pg_sphere ADD FUNCTION spoly_contains_polygon(spoly, spoly); -ALTER EXTENSION pg_sphere ADD FUNCTION spoly_contains_polygon_com(spoly, spoly); -ALTER EXTENSION pg_sphere ADD FUNCTION spoly_contains_polygon_neg(spoly, spoly); -ALTER EXTENSION pg_sphere ADD FUNCTION spoly_contains_polygon_com_neg(spoly, spoly); -ALTER EXTENSION pg_sphere ADD FUNCTION spoly_overlap_polygon(spoly, spoly); -ALTER EXTENSION pg_sphere ADD OPERATOR &&(spoly, spoly); -ALTER EXTENSION pg_sphere ADD FUNCTION spoly_overlap_polygon_neg(spoly, spoly); -ALTER EXTENSION pg_sphere ADD OPERATOR !&&(spoly, spoly); -ALTER EXTENSION pg_sphere ADD FUNCTION spoly_contains_point(spoly, spoint); -ALTER EXTENSION pg_sphere ADD FUNCTION spoly_contains_point_com(spoint, spoly); -ALTER EXTENSION pg_sphere ADD FUNCTION spoly_contains_point_neg(spoly, spoint); -ALTER EXTENSION pg_sphere ADD FUNCTION spoly_contains_point_com_neg(spoint, spoly); -ALTER EXTENSION pg_sphere ADD FUNCTION strans_poly(spoly, strans); -ALTER EXTENSION pg_sphere ADD OPERATOR +(spoly, strans); -ALTER EXTENSION pg_sphere ADD FUNCTION strans_poly_inverse(spoly, strans); -ALTER EXTENSION pg_sphere ADD OPERATOR -(spoly, strans); -ALTER EXTENSION pg_sphere ADD FUNCTION spoly_contains_circle(spoly, scircle); -ALTER EXTENSION pg_sphere ADD FUNCTION spoly_contains_circle_com(scircle, spoly); -ALTER EXTENSION pg_sphere ADD FUNCTION spoly_contains_circle_neg(spoly, scircle); -ALTER EXTENSION pg_sphere ADD FUNCTION spoly_contains_circle_com_neg(scircle, spoly); -ALTER EXTENSION pg_sphere ADD FUNCTION scircle_contains_polygon(scircle, spoly); -ALTER EXTENSION pg_sphere ADD FUNCTION scircle_contains_polygon_com(spoly, scircle); -ALTER EXTENSION pg_sphere ADD FUNCTION scircle_contains_polygon_neg(scircle, spoly); -ALTER EXTENSION pg_sphere ADD FUNCTION scircle_contains_polygon_com_neg(spoly, scircle); -ALTER EXTENSION pg_sphere ADD FUNCTION spoly_overlap_circle(spoly, scircle); -ALTER EXTENSION pg_sphere ADD OPERATOR &&(spoly, scircle); -ALTER EXTENSION pg_sphere ADD FUNCTION spoly_overlap_circle_com(scircle, spoly); -ALTER EXTENSION pg_sphere ADD OPERATOR &&(scircle, spoly); -ALTER EXTENSION pg_sphere ADD FUNCTION spoly_overlap_circle_neg(spoly, scircle); -ALTER EXTENSION pg_sphere ADD OPERATOR !&&(spoly, scircle); -ALTER EXTENSION pg_sphere ADD FUNCTION spoly_overlap_circle_com_neg(scircle, spoly); -ALTER EXTENSION pg_sphere ADD OPERATOR !&&(scircle, spoly); -ALTER EXTENSION pg_sphere ADD FUNCTION spoly_contains_line(spoly, sline); -ALTER EXTENSION pg_sphere ADD FUNCTION spoly_contains_line_com(sline, spoly); -ALTER EXTENSION pg_sphere ADD FUNCTION spoly_contains_line_neg(spoly, sline); -ALTER EXTENSION pg_sphere ADD FUNCTION spoly_contains_line_com_neg(sline, spoly); -ALTER EXTENSION pg_sphere ADD FUNCTION spoly_overlap_line(spoly, sline); -ALTER EXTENSION pg_sphere ADD OPERATOR &&(spoly, sline); -ALTER EXTENSION pg_sphere ADD FUNCTION spoly_overlap_line_com(sline, spoly); -ALTER EXTENSION pg_sphere ADD OPERATOR &&(sline, spoly); -ALTER EXTENSION pg_sphere ADD FUNCTION spoly_overlap_line_neg(spoly, sline); -ALTER EXTENSION pg_sphere ADD OPERATOR !&&(spoly, sline); -ALTER EXTENSION pg_sphere ADD FUNCTION spoly_overlap_line_com_neg(sline, spoly); -ALTER EXTENSION pg_sphere ADD OPERATOR !&&(sline, spoly); -ALTER EXTENSION pg_sphere ADD FUNCTION spoly_contains_ellipse(spoly, sellipse); -ALTER EXTENSION pg_sphere ADD FUNCTION spoly_contains_ellipse_com(sellipse, spoly); -ALTER EXTENSION pg_sphere ADD FUNCTION spoly_contains_ellipse_neg(spoly, sellipse); -ALTER EXTENSION pg_sphere ADD FUNCTION spoly_contains_ellipse_com_neg(sellipse, spoly); -ALTER EXTENSION pg_sphere ADD FUNCTION sellipse_contains_polygon(sellipse, spoly); -ALTER EXTENSION pg_sphere ADD FUNCTION sellipse_contains_polygon_com(spoly, sellipse); -ALTER EXTENSION pg_sphere ADD FUNCTION sellipse_contains_polygon_neg(sellipse, spoly); -ALTER EXTENSION pg_sphere ADD FUNCTION sellipse_contains_polygon_com_neg(spoly, sellipse); -ALTER EXTENSION pg_sphere ADD FUNCTION spoly_overlap_ellipse(spoly, sellipse); -ALTER EXTENSION pg_sphere ADD OPERATOR &&(spoly, sellipse); -ALTER EXTENSION pg_sphere ADD FUNCTION spoly_overlap_ellipse_com(sellipse, spoly); -ALTER EXTENSION pg_sphere ADD OPERATOR &&(sellipse, spoly); -ALTER EXTENSION pg_sphere ADD FUNCTION spoly_overlap_ellipse_neg(spoly, sellipse); -ALTER EXTENSION pg_sphere ADD OPERATOR !&&(spoly, sellipse); -ALTER EXTENSION pg_sphere ADD FUNCTION spoly_overlap_ellipse_com_neg(sellipse, spoly); -ALTER EXTENSION pg_sphere ADD OPERATOR !&&(sellipse, spoly); diff --git a/upgrade_scripts/pgs_types.sql.in b/upgrade_scripts/pgs_types.sql.in deleted file mode 100644 index 95378a0..0000000 --- a/upgrade_scripts/pgs_types.sql.in +++ /dev/null @@ -1,24 +0,0 @@ -ALTER EXTENSION pg_sphere ADD FUNCTION spoint_in(CSTRING); -ALTER EXTENSION pg_sphere ADD FUNCTION spoint_out(spoint); -ALTER EXTENSION pg_sphere ADD TYPE spoint; -ALTER EXTENSION pg_sphere ADD FUNCTION strans_in(CSTRING); -ALTER EXTENSION pg_sphere ADD FUNCTION strans_out(strans); -ALTER EXTENSION pg_sphere ADD TYPE strans; -ALTER EXTENSION pg_sphere ADD FUNCTION scircle_in(CSTRING); -ALTER EXTENSION pg_sphere ADD FUNCTION scircle_out(scircle); -ALTER EXTENSION pg_sphere ADD TYPE scircle; -ALTER EXTENSION pg_sphere ADD FUNCTION sline_in(CSTRING); -ALTER EXTENSION pg_sphere ADD FUNCTION sline_out(sline); -ALTER EXTENSION pg_sphere ADD TYPE sline; -ALTER EXTENSION pg_sphere ADD FUNCTION sellipse_in(CSTRING); -ALTER EXTENSION pg_sphere ADD FUNCTION sellipse_out(sellipse); -ALTER EXTENSION pg_sphere ADD TYPE sellipse; -ALTER EXTENSION pg_sphere ADD FUNCTION spoly_in(CSTRING); -ALTER EXTENSION pg_sphere ADD FUNCTION spoly_out(spoly); -ALTER EXTENSION pg_sphere ADD TYPE spoly; -ALTER EXTENSION pg_sphere ADD FUNCTION spath_in(CSTRING); -ALTER EXTENSION pg_sphere ADD FUNCTION spath_out(spath); -ALTER EXTENSION pg_sphere ADD TYPE spath; -ALTER EXTENSION pg_sphere ADD FUNCTION sbox_in(CSTRING); -ALTER EXTENSION pg_sphere ADD FUNCTION sbox_out(sbox); -ALTER EXTENSION pg_sphere ADD TYPE sbox; From afde97d8e0f903aa886a00b48d95568fdc6a0d3a Mon Sep 17 00:00:00 2001 From: Christoph Berg Date: Mon, 16 Oct 2023 15:06:30 +0200 Subject: [PATCH 45/87] g_spoint3_fetch was already part of the spoint3 opclass in older versions Allow upgrading of older installations (made pre 1.1.5) that already have g_spoint3_fetch in the spoint3 opclass. Close #82. --- upgrade_scripts/pg_sphere--1.3.1--1.3.2.sql.in | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/upgrade_scripts/pg_sphere--1.3.1--1.3.2.sql.in b/upgrade_scripts/pg_sphere--1.3.1--1.3.2.sql.in index 4077cd6..1ada066 100644 --- a/upgrade_scripts/pg_sphere--1.3.1--1.3.2.sql.in +++ b/upgrade_scripts/pg_sphere--1.3.1--1.3.2.sql.in @@ -1,4 +1,14 @@ -- add "fetch" support function to enable index-only scans for spoint3 -ALTER OPERATOR FAMILY spoint3 USING gist ADD - FUNCTION 9 (spoint, spoint) g_spoint3_fetch (internal); +-- g_spoint3_fetch was already part of the spoint3 opclass in older versions +-- around 1.0, but later made optional (see bdc37d1) + +DO $$ +BEGIN + ALTER OPERATOR FAMILY spoint3 USING gist ADD + FUNCTION 9 (spoint, spoint) g_spoint3_fetch (internal); +EXCEPTION + WHEN duplicate_object THEN NULL; + WHEN OTHERS THEN RAISE; +END; +$$; From ab701182d4dd75b167df557f4f80869fd45242fa Mon Sep 17 00:00:00 2001 From: Christoph Berg Date: Mon, 16 Oct 2023 13:12:53 +0200 Subject: [PATCH 46/87] Remove two unused expected output files They where part of the initial commit, but not changed since then. --- expected/pg_sphere.out | 2484 ---------------------------------------- expected/point.out | 240 ---- 2 files changed, 2724 deletions(-) delete mode 100644 expected/pg_sphere.out delete mode 100644 expected/point.out diff --git a/expected/pg_sphere.out b/expected/pg_sphere.out deleted file mode 100644 index 1a1b334..0000000 --- a/expected/pg_sphere.out +++ /dev/null @@ -1,2484 +0,0 @@ --- --- first, define the datatype. Turn off echoing so that expected file --- does not depend on contents of pg_sphere.sql. --- -\set ECHO none -psql:pgs_types.sql:23: NOTICE: TypeCreate: changing argument type of function spoint_out from OPAQUE to spoint -psql:pgs_types.sql:23: NOTICE: TypeCreate: changing return type of function spoint_in from OPAQUE to spoint -psql:pgs_types.sql:46: NOTICE: TypeCreate: changing argument type of function scircle_out from OPAQUE to scircle -psql:pgs_types.sql:46: NOTICE: TypeCreate: changing return type of function scircle_in from OPAQUE to scircle -psql:pgs_types.sql:69: NOTICE: TypeCreate: changing argument type of function sellipse_out from OPAQUE to sellipse -psql:pgs_types.sql:69: NOTICE: TypeCreate: changing return type of function sellipse_in from OPAQUE to sellipse -psql:pgs_types.sql:93: NOTICE: TypeCreate: changing argument type of function sline_out from OPAQUE to sline -psql:pgs_types.sql:93: NOTICE: TypeCreate: changing return type of function sline_in from OPAQUE to sline -psql:pgs_types.sql:118: NOTICE: TypeCreate: changing argument type of function spath_out from OPAQUE to spath -psql:pgs_types.sql:118: NOTICE: TypeCreate: changing return type of function spath_in from OPAQUE to spath -psql:pgs_types.sql:142: NOTICE: TypeCreate: changing argument type of function spoly_out from OPAQUE to spoly -psql:pgs_types.sql:142: NOTICE: TypeCreate: changing return type of function spoly_in from OPAQUE to spoly -psql:pgs_types.sql:166: NOTICE: TypeCreate: changing argument type of function strans_out from OPAQUE to strans -psql:pgs_types.sql:166: NOTICE: TypeCreate: changing return type of function strans_in from OPAQUE to strans -psql:pgs_gist.sql:22: NOTICE: TypeCreate: changing argument type of function spherekey_out from OPAQUE to spherekey -psql:pgs_gist.sql:22: NOTICE: TypeCreate: changing return type of function spherekey_in from OPAQUE to spherekey --- check spherical point operators -SELECT spoint '(0, 90d)' = spoint '(0, 90d)'; - ?column? ----------- - t -(1 row) - -SELECT spoint '(0, 90d)' = spoint '(0,-90d)'; - ?column? ----------- - f -(1 row) - -SELECT spoint '(0,-90d)' = spoint '(0,-90d)'; - ?column? ----------- - t -(1 row) - -SELECT spoint '(0, 90d)' != spoint '(0, 90d)'; - ?column? ----------- - f -(1 row) - -SELECT spoint '(0, 90d)' != spoint '(0,-90d)'; - ?column? ----------- - t -(1 row) - -SELECT spoint '(0,-90d)' != spoint '(0,-90d)'; - ?column? ----------- - f -(1 row) - -SELECT spoint '(0d, 0)' = spoint '(360d,0)'; - ?column? ----------- - t -(1 row) - --- checking spherical circle operators -SELECT scircle '<(0, 90d),1>' = '<(0, 90d),1>' ; - ?column? ----------- - t -(1 row) - -SELECT scircle '<(0,-90d),1>' <> '<(0, 90d),1>' ; - ?column? ----------- - t -(1 row) - --- checking spherical line operators -SELECT sline ( spoint '(0, 90d)', spoint '(0, -89d)' ) = - sline ( spoint '(0, 90d)', spoint '(0, -89d)' ) ; - ?column? ----------- - t -(1 row) - -SELECT sline ( spoint '(0, 90d)', spoint '(0, -89d)' ) <> - sline ( spoint '(0, -89d)', spoint '(0, 90d)' ) ; - ?column? ----------- - t -(1 row) - --- checking Euler transformation operators -SELECT strans '-10d,0d,10d,ZZZ' = '-10d,0d,10d,XXX' ; - ?column? ----------- - t -(1 row) - -SELECT strans '-40d,0d,40d,ZZZ' <> '-40d,0d,40d,XXX' ; - ?column? ----------- - f -(1 row) - --- checking polygon operators -\set poly 'spoly \'{(0.1,0),(0.2,0),(0.2,0.1),(0.3,0.1),(0.3,-0.1),(0.4,-0.1),(0.5,0.1),(0.4,0.2),(0.1,0.2)}\'' -SELECT spoint '(0.15,0.10)' @ :poly; -- point inside polygon - ?column? ----------- - t -(1 row) - -SELECT spoint '(0.20,0.00)' @ :poly; -- point contained polygon - ?column? ----------- - t -(1 row) - -SELECT spoint '(0.10,0.10)' @ :poly; -- point contained polygon - ?column? ----------- - t -(1 row) - -SELECT spoint '(0.25,0.50)' @ :poly; -- point outside polygon - ?column? ----------- - f -(1 row) - -SELECT spoint '(0.25,0.00)' @ :poly; -- point outside polygon - ?column? ----------- - f -(1 row) - -SELECT scircle '<(0.15,0.10),0.03>' @ :poly; -- circle inside polygon - ?column? ----------- - t -(1 row) - -SELECT scircle '<(0.20,0.00),0.00>' @ :poly; -- circle contained polygon - ?column? ----------- - t -(1 row) - -SELECT scircle '<(0.20,0.30),0.05>' @ :poly; -- circle outside polygon - ?column? ----------- - f -(1 row) - -SELECT scircle '<(0.25,0.00),0.05>' @ :poly; -- circle overlaps polygon - ?column? ----------- - f -(1 row) - -SELECT scircle '<(0.25,0.00),0.10>' @ :poly; -- circle overlaps polygon - ?column? ----------- - f -(1 row) - -SELECT scircle '<(0.15,0.10),0.03>' && :poly; -- circle inside polygon - ?column? ----------- - t -(1 row) - -SELECT scircle '<(0.20,0.00),0.00>' && :poly; -- circle contained polygon - ?column? ----------- - t -(1 row) - -SELECT scircle '<(0.20,0.30),0.05>' && :poly; -- circle outside polygon - ?column? ----------- - f -(1 row) - -SELECT scircle '<(0.25,0.00),0.05>' && :poly; -- circle overlaps polygon - ?column? ----------- - t -(1 row) - -SELECT scircle '<(0.25,0.00),0.10>' && :poly; -- circle overlaps polygon - ?column? ----------- - t -(1 row) - -SELECT sline ( spoint '(0.00, 0.00)', spoint '(0.10,0.20)' ) @ :poly; -- line touches polygon - ?column? ----------- - f -(1 row) - -SELECT sline ( spoint '(0.00, 0.10)', spoint '(0.10,0.10)' ) @ :poly; -- line touches polygon - ?column? ----------- - f -(1 row) - -SELECT sline ( spoint '(0.50, 0.00)', spoint '(0.50,0.20)' ) @ :poly; -- line touches polygon - ?column? ----------- - f -(1 row) - -SELECT sline ( spoint '(0.10, 0.20)', spoint '(0.20,0.00)' ) @ :poly; -- line touches and inside polygon - ?column? ----------- - t -(1 row) - -SELECT sline ( spoint '(0.45,-0.20)', spoint '(0.45,0.20)' ) @ :poly; -- line overlaps polygon - ?column? ----------- - f -(1 row) - -SELECT sline ( spoint '(0.45, 0.10)', spoint '(0.45,0.20)' ) @ :poly; -- line overlaps polygon - ?column? ----------- - f -(1 row) - -SELECT sline ( spoint '(0.24, 0.17)', spoint '(0.25,0.14)' ) @ :poly; -- line inside polygon - ?column? ----------- - t -(1 row) - -SELECT sline ( spoint '(0.00, 0.00)', spoint '(0.10,0.20)' ) && :poly; -- line touches polygon - ?column? ----------- - t -(1 row) - -SELECT sline ( spoint '(0.00, 0.10)', spoint '(0.10,0.10)' ) && :poly; -- line touches polygon - ?column? ----------- - t -(1 row) - -SELECT sline ( spoint '(0.50, 0.00)', spoint '(0.50,0.20)' ) && :poly; -- line touches polygon - ?column? ----------- - t -(1 row) - -SELECT sline ( spoint '(0.10, 0.20)', spoint '(0.20,0.00)' ) && :poly; -- line touches and inside polygon - ?column? ----------- - t -(1 row) - -SELECT sline ( spoint '(0.45,-0.20)', spoint '(0.45,0.20)' ) && :poly; -- line overlaps polygon - ?column? ----------- - t -(1 row) - -SELECT sline ( spoint '(0.45, 0.10)', spoint '(0.45,0.20)' ) && :poly; -- line overlaps polygon - ?column? ----------- - t -(1 row) - -SELECT sline ( spoint '(0.24, 0.17)', spoint '(0.25,0.14)' ) && :poly; -- line inside polygon - ?column? ----------- - t -(1 row) - -\unset poly -\set poly1 'spoly \'{(0,0),(1,0),(0,1)}\'' -\set poly2 'spoly \'{(1,0),(0,0),(0,1)}\'' -\set poly3 'spoly \'{(0,1),(0,0),(1,0)}\'' -\set poly4 'spoly \'{(0.1,0.9),(0.1,0.1),(0.9,0.1)}\'' -\set poly5 'spoly \'{(0.2,0.0),(1.2,0.0),(0.2,1)}\'' -SELECT :poly1 = :poly2; - ?column? ----------- - f -(1 row) - -SELECT :poly2 = :poly3; - ?column? ----------- - f -(1 row) - -SELECT :poly3 = :poly1; - ?column? ----------- - t -(1 row) - -SELECT :poly1 && :poly2; - ?column? ----------- - t -(1 row) - -SELECT :poly2 && :poly3; - ?column? ----------- - t -(1 row) - -SELECT :poly3 && :poly1; - ?column? ----------- - t -(1 row) - -SELECT :poly1 @ :poly2; - ?column? ----------- - t -(1 row) - -SELECT :poly2 @ :poly3; - ?column? ----------- - t -(1 row) - -SELECT :poly3 @ :poly1; - ?column? ----------- - t -(1 row) - -SELECT :poly1 @ :poly4; - ?column? ----------- - f -(1 row) - -SELECT :poly4 @ :poly1; - ?column? ----------- - t -(1 row) - -SELECT :poly1 && :poly4; - ?column? ----------- - t -(1 row) - -SELECT :poly4 && :poly1; - ?column? ----------- - t -(1 row) - -SELECT :poly1 @ :poly5; - ?column? ----------- - f -(1 row) - -SELECT :poly5 @ :poly1; - ?column? ----------- - f -(1 row) - -SELECT :poly1 && :poly5; - ?column? ----------- - t -(1 row) - -SELECT :poly5 && :poly1; - ?column? ----------- - t -(1 row) - -\unset poly1 -\unset poly2 -\unset poly3 -\unset poly4 -\unset poly5 --- checking path operators -\set poly 'spoly \'{(0.1,0),(0.2,0),(0.2,0.1),(0.3,0.1),(0.3,-0.1),(0.4,-0.1),(0.5,0.1),(0.4,0.2),(0.1,0.2)}\'' -\set path1 'spath \'{(0.1,0),(0.2,0),(0.2,0.1),(0.3,0.1),(0.3,-0.1),(0.4,-0.1),(0.5,0.1),(0.4,0.2),(0.1,0.2)}\'' -\set path2 'spath \'{(0,0),(1,0),(2,0),(3,0)}\'' -\set path3 'spath \'{(0,0),(0,1),(0,1.5)}\'' -SELECT @-@ spath '{(0,0),(1,0),(2,0),(3,0)}'; - ?column? ----------- - 3 -(1 row) - -SELECT :path1 = :path2; - ?column? ----------- - f -(1 row) - -SELECT :path1 = :path1; - ?column? ----------- - t -(1 row) - -SELECT :path1 <> :path2; - ?column? ----------- - t -(1 row) - -SELECT :path1 <> :path1; - ?column? ----------- - f -(1 row) - -SELECT :poly && :path1; - ?column? ----------- - t -(1 row) - -SELECT :path1 && :poly ; - ?column? ----------- - t -(1 row) - -SELECT :path1 @ :poly ; - ?column? ----------- - t -(1 row) - -SELECT :path2 @ :poly ; - ?column? ----------- - f -(1 row) - -SELECT :path1 && :path1; - ?column? ----------- - t -(1 row) - -SELECT :path1 && :path1; - ?column? ----------- - t -(1 row) - -SELECT :poly && :path2; - ?column? ----------- - t -(1 row) - -SELECT :path2 && :poly ; - ?column? ----------- - t -(1 row) - -SELECT :path2 && :path1; - ?column? ----------- - t -(1 row) - -SELECT :poly && :path3; - ?column? ----------- - f -(1 row) - -SELECT :path3 && :poly ; - ?column? ----------- - f -(1 row) - -SELECT :path3 && :path1; - ?column? ----------- - f -(1 row) - -SELECT :path3 && :path2; - ?column? ----------- - t -(1 row) - -SELECT :path1 @ scircle '<(0,1),1>'; - ?column? ----------- - f -(1 row) - -SELECT :path3 @ scircle '<(0,1),1>'; - ?column? ----------- - t -(1 row) - -SELECT :path3 @ scircle '<(0,1),0.7>'; - ?column? ----------- - f -(1 row) - -SELECT :path1 && scircle '<(0,1),1>'; - ?column? ----------- - t -(1 row) - -SELECT :path3 && scircle '<(0,1),1>'; - ?column? ----------- - t -(1 row) - -SELECT :path3 && scircle '<(0,1),0.7>'; - ?column? ----------- - t -(1 row) - -SELECT :path3 && scircle '<(0,-1),0.7>'; - ?column? ----------- - f -(1 row) - -SELECT :path3 @ scircle '<(0,-1),0.7>'; - ?column? ----------- - f -(1 row) - -SELECT :path3 && sline ( spoint '(0,-1)', spoint '(0,1)' ); - ?column? ----------- - t -(1 row) - -SELECT :path3 && sline ( spoint '(-1,0)', spoint '(1,0)' ); - ?column? ----------- - t -(1 row) - -SELECT :path3 && sline ( spoint '(-1,0)', spoint '(-0.3,0)' ); - ?column? ----------- - f -(1 row) - -SELECT spath '{(0.11,0.15),(0.12,0.15),(0.13,0.15)}' @ :poly; - ?column? ----------- - t -(1 row) - --- ellipse tests ---equal operator -SELECT sellipse '<{0d,0d},(170d,-12d),0d>' = sellipse '<{0d,0d},(170d,-12d),0d>'; - ?column? ----------- - t -(1 row) - -SELECT sellipse '<{0d,0d},(170d,-12d),0d>' = sellipse '<{0d,0d},(170d,-12d),-2d>'; - ?column? ----------- - t -(1 row) - -SELECT sellipse '<{5d,5d},(170d,-12d),0d>' = sellipse '<{5d,5d},(170d,-12d),-2d>'; - ?column? ----------- - t -(1 row) - -SELECT sellipse '<{5d,2d},(170d,-12d),0d>' = sellipse '<{5d,2d},(170d,-12d),-2d>'; - ?column? ----------- - f -(1 row) - --- not equal -SELECT sellipse '<{5d,2d},(170d,-12d),0d>' != sellipse '<{5d,2d},(170d,-12d),-2d>'; - ?column? ----------- - t -(1 row) - -SELECT sellipse '<{5d,2d},(170d,-12d),0d>' != sellipse '<{5d,2d},(170d,-12d), 0d>'; - ?column? ----------- - f -(1 row) - -SELECT sellipse '<{10d, 5d},(300d,0d), 0d>' = sellipse '<{10d,5d},(300d,0d), 180d>' ; - ?column? ----------- - t -(1 row) - -SELECT sellipse '<{10d, 5d},(300d,0d), 90d>' = sellipse '<{10d,5d},(300d,0d), 270d>' ; - ?column? ----------- - t -(1 row) - --- ellipse and point -SELECT spoint '(280d,-20d)' @ sellipse '<{10d,5d},(280d,-20d),90d>'; - ?column? ----------- - t -(1 row) - -SELECT spoint '(280d,-10d)' @ sellipse '<{10d,5d},(280d,-20d),90d>'; - ?column? ----------- - t -(1 row) - -SELECT spoint '(280d,-9.9d)' @ sellipse '<{10d,5d},(280d,-20d),90d>'; - ?column? ----------- - f -(1 row) - -SELECT sellipse '<{10d,5d},(280d,-20d),90d>' ~ spoint '(280d,-10d)' ; - ?column? ----------- - t -(1 row) - -SELECT sellipse '<{10d,5d},(280d,-20d),90d>' ~ spoint '(280d, -9d)' ; - ?column? ----------- - f -(1 row) - -SELECT spoint '(280d,-10d)' !@ sellipse '<{10d,5d},(280d,-20d),90d>'; - ?column? ----------- - f -(1 row) - -SELECT spoint '(280d,-9.9d)' !@ sellipse '<{10d,5d},(280d,-20d),90d>'; - ?column? ----------- - t -(1 row) - -SELECT sellipse '<{10d,5d},(280d,-20d),90d>' !~ spoint '(280d,-10d)' ; - ?column? ----------- - f -(1 row) - -SELECT sellipse '<{10d,5d},(280d,-20d),90d>' !~ spoint '(280d, -9d)' ; - ?column? ----------- - t -(1 row) - --- ---ellipse and circle (@,&&) --- --- negators and commutators -SELECT scircle '<(280d,-10d),0d>' @ sellipse '<{10d,5d},(280d,-20d),90d>'; - ?column? ----------- - t -(1 row) - -SELECT scircle '<(280d, -9d),0d>' @ sellipse '<{10d,5d},(280d,-20d),90d>'; - ?column? ----------- - f -(1 row) - -SELECT scircle '<(280d,-10d),0d>' !@ sellipse '<{10d,5d},(280d,-20d),90d>'; - ?column? ----------- - f -(1 row) - -SELECT scircle '<(280d, -9d),0d>' !@ sellipse '<{10d,5d},(280d,-20d),90d>'; - ?column? ----------- - t -(1 row) - -SELECT sellipse '<{10d,5d},(280d,-20d),90d>' ~ scircle '<(280d,-10d),0d>'; - ?column? ----------- - t -(1 row) - -SELECT sellipse '<{10d,5d},(280d,-20d),90d>' ~ scircle '<(280d, -9d),0d>'; - ?column? ----------- - f -(1 row) - -SELECT sellipse '<{10d,5d},(280d,-20d),90d>' !~ scircle '<(280d,-10d),0d>'; - ?column? ----------- - f -(1 row) - -SELECT sellipse '<{10d,5d},(280d,-20d),90d>' !~ scircle '<(280d, -9d),0d>'; - ?column? ----------- - t -(1 row) - -SELECT scircle '<(280d,-10d),2d>' && sellipse '<{10d,5d},(280d,-20d),90d>'; - ?column? ----------- - t -(1 row) - -SELECT scircle '<(280d, 0d),2d>' && sellipse '<{10d,5d},(280d,-20d),90d>'; - ?column? ----------- - f -(1 row) - -SELECT scircle '<(280d,-10d),2d>' !&& sellipse '<{10d,5d},(280d,-20d),90d>'; - ?column? ----------- - f -(1 row) - -SELECT scircle '<(280d, 0d),2d>' !&& sellipse '<{10d,5d},(280d,-20d),90d>'; - ?column? ----------- - t -(1 row) - -SELECT sellipse '<{10d,5d},(280d,-20d),90d>' && scircle '<(280d,-10d),2d>' ; - ?column? ----------- - t -(1 row) - -SELECT sellipse '<{10d,5d},(280d,-20d),90d>' && scircle '<(280d, 0d),2d>' ; - ?column? ----------- - f -(1 row) - -SELECT sellipse '<{10d,5d},(280d,-20d),90d>' !&& scircle '<(280d,-10d),2d>' ; - ?column? ----------- - f -(1 row) - -SELECT sellipse '<{10d,5d},(280d,-20d),90d>' !&& scircle '<(280d, 0d),2d>' ; - ?column? ----------- - t -(1 row) - -SELECT scircle '<(280d,-10d),0d>' && sellipse '<{10d,5d},(280d,-20d),90d>'; - ?column? ----------- - t -(1 row) - - --- ellipse is circle -SELECT scircle '<(280d,-10d),2d>' @ sellipse '<{5d,5d},(280d,-20d),90d>'; - ?column? ----------- - f -(1 row) - -SELECT scircle '<(280d,-18d),2d>' @ sellipse '<{5d,5d},(280d,-20d),90d>'; - ?column? ----------- - t -(1 row) - -SELECT scircle '<(280d,-16d),2d>' @ sellipse '<{5d,5d},(280d,-20d),90d>'; - ?column? ----------- - f -(1 row) - -SELECT scircle '<(280d,-18d),15d>' @ sellipse '<{5d,5d},(280d,-20d),90d>'; - ?column? ----------- - f -(1 row) - -SELECT sellipse '<{5d,5d},(280d,-20d),90d>' @ scircle '<(280d,-10d),2d>' ; - ?column? ----------- - f -(1 row) - -SELECT sellipse '<{5d,5d},(280d,-20d),90d>' @ scircle '<(280d,-18d),2d>' ; - ?column? ----------- - f -(1 row) - -SELECT sellipse '<{5d,5d},(280d,-20d),90d>' @ scircle '<(280d,-16d),2d>' ; - ?column? ----------- - f -(1 row) - -SELECT sellipse '<{5d,5d},(280d,-20d),90d>' @ scircle '<(280d,-18d),15d>' ; - ?column? ----------- - t -(1 row) - -SELECT scircle '<(280d,-10d),2d>' && sellipse '<{5d,5d},(280d,-20d),90d>'; - ?column? ----------- - f -(1 row) - -SELECT scircle '<(280d,-18d),2d>' && sellipse '<{5d,5d},(280d,-20d),90d>'; - ?column? ----------- - t -(1 row) - -SELECT scircle '<(280d,-16d),2d>' && sellipse '<{5d,5d},(280d,-20d),90d>'; - ?column? ----------- - t -(1 row) - --- ellipse is line -SELECT scircle '<(280d,-10d),0d>' @ sellipse '<{5d,0d},(280d,-20d),90d>'; - ?column? ----------- - f -(1 row) - -SELECT scircle '<(280d,-18d),0d>' @ sellipse '<{5d,0d},(280d,-20d),90d>'; - ?column? ----------- - t -(1 row) - -SELECT scircle '<(280d,-16d),0d>' @ sellipse '<{5d,0d},(280d,-20d),90d>'; - ?column? ----------- - t -(1 row) - -SELECT scircle '<(280d,-18d),15d>' @ sellipse '<{5d,0d},(280d,-20d),90d>'; - ?column? ----------- - f -(1 row) - -SELECT scircle '<(280d,-10d),0d>' && sellipse '<{5d,0d},(280d,-20d),90d>'; - ?column? ----------- - f -(1 row) - -SELECT scircle '<(280d,-18d),0d>' && sellipse '<{5d,0d},(280d,-20d),90d>'; - ?column? ----------- - t -(1 row) - -SELECT scircle '<(280d,-10d),2d>' @ sellipse '<{5d,0d},(280d,-20d),90d>'; - ?column? ----------- - f -(1 row) - -SELECT scircle '<(280d,-18d),2d>' @ sellipse '<{5d,0d},(280d,-20d),90d>'; - ?column? ----------- - f -(1 row) - -SELECT scircle '<(280d,-16d),2d>' @ sellipse '<{5d,0d},(280d,-20d),90d>'; - ?column? ----------- - f -(1 row) - -SELECT scircle '<(280d,-10d),2d>' && sellipse '<{5d,0d},(280d,-20d),90d>'; - ?column? ----------- - f -(1 row) - -SELECT scircle '<(280d,-18d),2d>' && sellipse '<{5d,0d},(280d,-20d),90d>'; - ?column? ----------- - t -(1 row) - -SELECT sellipse '<{5d,0d},(280d,-20d),90d>' @ scircle '<(280d,-18d),15d>' ; - ?column? ----------- - t -(1 row) - --- ---ellipse and line (@,&&) --- --- negators and commutators -SELECT sline ( spoint '(280d, -9d)', spoint '(280d, -8d)' ) @ sellipse '<{10d,5d},(280d,-20d),90d>'; - ?column? ----------- - f -(1 row) - -SELECT sline ( spoint '(280d, -9d)', spoint '(280d,-12d)' ) @ sellipse '<{10d,5d},(280d,-20d),90d>'; - ?column? ----------- - f -(1 row) - -SELECT sline ( spoint '(280d,-11d)', spoint '(280d,-12d)' ) @ sellipse '<{10d,5d},(280d,-20d),90d>'; - ?column? ----------- - t -(1 row) - -SELECT sline ( spoint '(280d, -9d)', spoint '(280d, -8d)' ) && sellipse '<{10d,5d},(280d,-20d),90d>'; - ?column? ----------- - f -(1 row) - -SELECT sline ( spoint '(280d, -9d)', spoint '(280d,-12d)' ) && sellipse '<{10d,5d},(280d,-20d),90d>'; - ?column? ----------- - t -(1 row) - -SELECT sline ( spoint '(280d,-11d)', spoint '(280d,-12d)' ) && sellipse '<{10d,5d},(280d,-20d),90d>'; - ?column? ----------- - t -(1 row) - -SELECT sline ( spoint '(280d, -9d)', spoint '(280d, -8d)' ) !@ sellipse '<{10d,5d},(280d,-20d),90d>'; - ?column? ----------- - t -(1 row) - -SELECT sline ( spoint '(280d, -9d)', spoint '(280d,-12d)' ) !@ sellipse '<{10d,5d},(280d,-20d),90d>'; - ?column? ----------- - t -(1 row) - -SELECT sline ( spoint '(280d,-11d)', spoint '(280d,-12d)' ) !@ sellipse '<{10d,5d},(280d,-20d),90d>'; - ?column? ----------- - f -(1 row) - -SELECT sline ( spoint '(280d, -9d)', spoint '(280d, -8d)' ) !&& sellipse '<{10d,5d},(280d,-20d),90d>'; - ?column? ----------- - t -(1 row) - -SELECT sline ( spoint '(280d, -9d)', spoint '(280d,-12d)' ) !&& sellipse '<{10d,5d},(280d,-20d),90d>'; - ?column? ----------- - f -(1 row) - -SELECT sline ( spoint '(280d,-11d)', spoint '(280d,-12d)' ) !&& sellipse '<{10d,5d},(280d,-20d),90d>'; - ?column? ----------- - f -(1 row) - -SELECT sellipse '<{10d,5d},(280d,-20d),90d>' ~ sline ( spoint '(280d, -9d)', spoint '(280d, -8d)' ); - ?column? ----------- - f -(1 row) - -SELECT sellipse '<{10d,5d},(280d,-20d),90d>' ~ sline ( spoint '(280d, -9d)', spoint '(280d,-12d)' ); - ?column? ----------- - f -(1 row) - -SELECT sellipse '<{10d,5d},(280d,-20d),90d>' ~ sline ( spoint '(280d,-11d)', spoint '(280d,-12d)' ); - ?column? ----------- - t -(1 row) - -SELECT sellipse '<{10d,5d},(280d,-20d),90d>' && sline ( spoint '(280d, -9d)', spoint '(280d, -8d)' ); - ?column? ----------- - f -(1 row) - -SELECT sellipse '<{10d,5d},(280d,-20d),90d>' && sline ( spoint '(280d, -9d)', spoint '(280d,-12d)' ); - ?column? ----------- - t -(1 row) - -SELECT sellipse '<{10d,5d},(280d,-20d),90d>' && sline ( spoint '(280d,-11d)', spoint '(280d,-12d)' ); - ?column? ----------- - t -(1 row) - -SELECT sellipse '<{10d,5d},(280d,-20d),90d>' !~ sline ( spoint '(280d, -9d)', spoint '(280d, -8d)' ); - ?column? ----------- - t -(1 row) - -SELECT sellipse '<{10d,5d},(280d,-20d),90d>' !~ sline ( spoint '(280d, -9d)', spoint '(280d,-12d)' ); - ?column? ----------- - t -(1 row) - -SELECT sellipse '<{10d,5d},(280d,-20d),90d>' !~ sline ( spoint '(280d,-11d)', spoint '(280d,-12d)' ); - ?column? ----------- - f -(1 row) - -SELECT sellipse '<{10d,5d},(280d,-20d),90d>' !&& sline ( spoint '(280d, -9d)', spoint '(280d, -8d)' ); - ?column? ----------- - t -(1 row) - -SELECT sellipse '<{10d,5d},(280d,-20d),90d>' !&& sline ( spoint '(280d, -9d)', spoint '(280d,-12d)' ); - ?column? ----------- - f -(1 row) - -SELECT sellipse '<{10d,5d},(280d,-20d),90d>' !&& sline ( spoint '(280d,-11d)', spoint '(280d,-12d)' ); - ?column? ----------- - f -(1 row) - --- line is point , ellipse is point -SELECT sline ( spoint '(280d, -8d)', spoint '(280d, -8d)' ) @ sellipse '<{0d,0d},(280d,-20d),90d>'; - ?column? ----------- - f -(1 row) - -SELECT sline ( spoint '(280d, -8d)', spoint '(280d, -8d)' ) @ sellipse '<{0d,0d},(280d, -8d),90d>'; - ?column? ----------- - t -(1 row) - -SELECT sline ( spoint '(280d, -8d)', spoint '(280d, -8d)' ) && sellipse '<{0d,0d},(280d,-20d),90d>'; - ?column? ----------- - f -(1 row) - -SELECT sline ( spoint '(280d, -8d)', spoint '(280d, -8d)' ) && sellipse '<{0d,0d},(280d, -8d),90d>'; - ?column? ----------- - t -(1 row) - --- line is point , ellipse is circle -SELECT sline ( spoint '(280d, -8d)', spoint '(280d, -8d)' ) @ sellipse '<{5d,5d},(280d,-20d),90d>'; - ?column? ----------- - f -(1 row) - -SELECT sline ( spoint '(280d, -8d)', spoint '(280d, -8d)' ) @ sellipse '<{5d,5d},(280d, -8d),90d>'; - ?column? ----------- - t -(1 row) - -SELECT sline ( spoint '(280d, -8d)', spoint '(280d, -8d)' ) && sellipse '<{5d,5d},(280d,-20d),90d>'; - ?column? ----------- - f -(1 row) - -SELECT sline ( spoint '(280d, -8d)', spoint '(280d, -8d)' ) && sellipse '<{5d,5d},(280d, -8d),90d>'; - ?column? ----------- - t -(1 row) - --- line is point , ellipse is a real ellipse -SELECT sline ( spoint '(280d, -8d)', spoint '(280d, -8d)' ) @ sellipse '<{10d,5d},(280d,-20d),90d>'; - ?column? ----------- - f -(1 row) - -SELECT sline ( spoint '(280d, -8d)', spoint '(280d, -8d)' ) @ sellipse '<{10d,5d},(280d, -8d),90d>'; - ?column? ----------- - t -(1 row) - -SELECT sline ( spoint '(280d, -8d)', spoint '(280d, -8d)' ) && sellipse '<{10d,5d},(280d,-20d),90d>'; - ?column? ----------- - f -(1 row) - -SELECT sline ( spoint '(280d, -8d)', spoint '(280d, -8d)' ) && sellipse '<{10d,5d},(280d, -8d),90d>'; - ?column? ----------- - t -(1 row) - --- line is a real line , ellipse is point -SELECT sline ( spoint '(280d, -8d)', spoint '(280d, -9d)' ) @ sellipse '<{0d,0d},(280d,-20d),90d>'; - ?column? ----------- - f -(1 row) - -SELECT sline ( spoint '(280d, -8d)', spoint '(280d, -9d)' ) @ sellipse '<{0d,0d},(280d, -8d),90d>'; - ?column? ----------- - f -(1 row) - -SELECT sline ( spoint '(280d, -8d)', spoint '(280d, -9d)' ) && sellipse '<{0d,0d},(280d,-20d),90d>'; - ?column? ----------- - f -(1 row) - -SELECT sline ( spoint '(280d, -8d)', spoint '(280d, -9d)' ) && sellipse '<{0d,0d},(280d, -8d),90d>'; - ?column? ----------- - t -(1 row) - --- line is a real line , ellipse is circle -SELECT sline ( spoint '(280d, -8d)', spoint '(280d, -9d)' ) @ sellipse '<{5d,5d},(280d,-20d),90d>'; - ?column? ----------- - f -(1 row) - -SELECT sline ( spoint '(280d, -8d)', spoint '(280d, -9d)' ) @ sellipse '<{5d,5d},(280d, -8d),90d>'; - ?column? ----------- - t -(1 row) - -SELECT sline ( spoint '(280d, -8d)', spoint '(280d, -9d)' ) && sellipse '<{5d,5d},(280d,-20d),90d>'; - ?column? ----------- - f -(1 row) - -SELECT sline ( spoint '(280d, -8d)', spoint '(280d, -9d)' ) && sellipse '<{5d,5d},(280d, -8d),90d>'; - ?column? ----------- - t -(1 row) - --- line is a real line , ellipse is line -SELECT sline ( spoint '(280d, -8d)', spoint '(280d, -9d)' ) @ sellipse '<{5d,0d},(280d,-20d),90d>'; - ?column? ----------- - f -(1 row) - -SELECT sline ( spoint '(280d, -8d)', spoint '(280d, -9d)' ) @ sellipse '<{5d,0d},(280d, -8d),90d>'; - ?column? ----------- - t -(1 row) - -SELECT sline ( spoint '(280d, -8d)', spoint '(280d, -9d)' ) && sellipse '<{5d,0d},(280d,-20d),90d>'; - ?column? ----------- - f -(1 row) - -SELECT sline ( spoint '(280d, -8d)', spoint '(280d, -9d)' ) && sellipse '<{5d,0d},(280d, -8d),90d>'; - ?column? ----------- - t -(1 row) - --- line is a real line , ellipse is a real ellipse -SELECT sline ( spoint '(280d, -8d)', spoint '(280d, -9d)' ) @ sellipse '<{10d,5d},(280d,-20d),90d>'; - ?column? ----------- - f -(1 row) - -SELECT sline ( spoint '(280d, -8d)', spoint '(280d, -9d)' ) @ sellipse '<{10d,5d},(280d, -8d),90d>'; - ?column? ----------- - t -(1 row) - -SELECT sline ( spoint '(280d, -8d)', spoint '(280d, -9d)' ) && sellipse '<{10d,5d},(280d,-20d),90d>'; - ?column? ----------- - f -(1 row) - -SELECT sline ( spoint '(280d, -8d)', spoint '(280d, -9d)' ) && sellipse '<{10d,5d},(280d, -8d),90d>'; - ?column? ----------- - t -(1 row) - --- --- ellipse and path --- --- negators , commutator @,&& -SELECT spath '{(280d, -9d),(280d, -8d)}' @ sellipse '<{10d,5d},(280d,-20d),90d>'; - ?column? ----------- - f -(1 row) - -SELECT spath '{(280d, -9d),(280d,-12d)}' @ sellipse '<{10d,5d},(280d,-20d),90d>'; - ?column? ----------- - f -(1 row) - -SELECT spath '{(280d,-11d),(280d,-12d)}' @ sellipse '<{10d,5d},(280d,-20d),90d>'; - ?column? ----------- - t -(1 row) - -SELECT spath '{(280d, -9d),(280d, -8d)}' && sellipse '<{10d,5d},(280d,-20d),90d>'; - ?column? ----------- - f -(1 row) - -SELECT spath '{(280d, -9d),(280d,-12d)}' && sellipse '<{10d,5d},(280d,-20d),90d>'; - ?column? ----------- - t -(1 row) - -SELECT spath '{(280d,-11d),(280d,-12d)}' && sellipse '<{10d,5d},(280d,-20d),90d>'; - ?column? ----------- - t -(1 row) - -SELECT spath '{(280d, -9d),(280d, -8d)}' !@ sellipse '<{10d,5d},(280d,-20d),90d>'; - ?column? ----------- - t -(1 row) - -SELECT spath '{(280d, -9d),(280d,-12d)}' !@ sellipse '<{10d,5d},(280d,-20d),90d>'; - ?column? ----------- - t -(1 row) - -SELECT spath '{(280d,-11d),(280d,-12d)}' !@ sellipse '<{10d,5d},(280d,-20d),90d>'; - ?column? ----------- - f -(1 row) - -SELECT spath '{(280d, -9d),(280d, -8d)}' !&& sellipse '<{10d,5d},(280d,-20d),90d>'; - ?column? ----------- - t -(1 row) - -SELECT spath '{(280d, -9d),(280d,-12d)}' !&& sellipse '<{10d,5d},(280d,-20d),90d>'; - ?column? ----------- - f -(1 row) - -SELECT spath '{(280d,-11d),(280d,-12d)}' !&& sellipse '<{10d,5d},(280d,-20d),90d>'; - ?column? ----------- - f -(1 row) - -SELECT sellipse '<{10d,5d},(280d,-20d),90d>' ~ spath '{(280d, -9d),(280d, -8d)}'; - ?column? ----------- - f -(1 row) - -SELECT sellipse '<{10d,5d},(280d,-20d),90d>' ~ spath '{(280d, -9d),(280d,-12d)}'; - ?column? ----------- - f -(1 row) - -SELECT sellipse '<{10d,5d},(280d,-20d),90d>' ~ spath '{(280d,-11d),(280d,-12d)}'; - ?column? ----------- - t -(1 row) - -SELECT sellipse '<{10d,5d},(280d,-20d),90d>' && spath '{(280d, -9d),(280d, -8d)}'; - ?column? ----------- - f -(1 row) - -SELECT sellipse '<{10d,5d},(280d,-20d),90d>' && spath '{(280d, -9d),(280d,-12d)}'; - ?column? ----------- - t -(1 row) - -SELECT sellipse '<{10d,5d},(280d,-20d),90d>' && spath '{(280d,-11d),(280d,-12d)}'; - ?column? ----------- - t -(1 row) - -SELECT sellipse '<{10d,5d},(280d,-20d),90d>' !~ spath '{(280d, -9d),(280d, -8d)}'; - ?column? ----------- - t -(1 row) - -SELECT sellipse '<{10d,5d},(280d,-20d),90d>' !~ spath '{(280d, -9d),(280d,-12d)}'; - ?column? ----------- - t -(1 row) - -SELECT sellipse '<{10d,5d},(280d,-20d),90d>' !~ spath '{(280d,-11d),(280d,-12d)}'; - ?column? ----------- - f -(1 row) - -SELECT sellipse '<{10d,5d},(280d,-20d),90d>' !&& spath '{(280d, -9d),(280d, -8d)}'; - ?column? ----------- - t -(1 row) - -SELECT sellipse '<{10d,5d},(280d,-20d),90d>' !&& spath '{(280d, -9d),(280d,-12d)}'; - ?column? ----------- - f -(1 row) - -SELECT sellipse '<{10d,5d},(280d,-20d),90d>' !&& spath '{(280d,-11d),(280d,-12d)}'; - ?column? ----------- - f -(1 row) - --- path is a line , ellipse is point -SELECT spath '{(280d, -8d),(280d, -9d)}' @ sellipse '<{0d,0d},(280d,-20d),90d>'; - ?column? ----------- - f -(1 row) - -SELECT spath '{(280d, -8d),(280d, -9d)}' @ sellipse '<{0d,0d},(280d, -8d),90d>'; - ?column? ----------- - f -(1 row) - -SELECT spath '{(280d, -8d),(280d, -9d)}' && sellipse '<{0d,0d},(280d,-20d),90d>'; - ?column? ----------- - f -(1 row) - -SELECT spath '{(280d, -8d),(280d, -9d)}' && sellipse '<{0d,0d},(280d, -8d),90d>'; - ?column? ----------- - t -(1 row) - --- path is a line , ellipse is circle -SELECT spath '{(280d, -8d),(280d, -9d)}' @ sellipse '<{5d,5d},(280d,-20d),90d>'; - ?column? ----------- - f -(1 row) - -SELECT spath '{(280d, -8d),(280d, -9d)}' @ sellipse '<{5d,5d},(280d, -8d),90d>'; - ?column? ----------- - t -(1 row) - -SELECT spath '{(280d, -8d),(280d, -9d)}' && sellipse '<{5d,5d},(280d,-20d),90d>'; - ?column? ----------- - f -(1 row) - -SELECT spath '{(280d, -8d),(280d, -9d)}' && sellipse '<{5d,5d},(280d, -8d),90d>'; - ?column? ----------- - t -(1 row) - --- path is a line , ellipse is path -SELECT spath '{(280d, -8d),(280d, -9d)}' @ sellipse '<{5d,0d},(280d,-20d),90d>'; - ?column? ----------- - f -(1 row) - -SELECT spath '{(280d, -8d),(280d, -9d)}' @ sellipse '<{5d,0d},(280d, -8d),90d>'; - ?column? ----------- - f -(1 row) - -SELECT spath '{(280d, -8d),(280d, -9d)}' && sellipse '<{5d,0d},(280d,-20d),90d>'; - ?column? ----------- - f -(1 row) - -SELECT spath '{(280d, -8d),(280d, -9d)}' && sellipse '<{5d,0d},(280d, -8d),90d>'; - ?column? ----------- - t -(1 row) - --- path is a line , ellipse is a real ellipse -SELECT spath '{(280d, -8d),(280d, -9d)}' @ sellipse '<{10d,5d},(280d,-20d),90d>'; - ?column? ----------- - f -(1 row) - -SELECT spath '{(280d, -8d),(280d, -9d)}' @ sellipse '<{10d,5d},(280d, -8d),90d>'; - ?column? ----------- - t -(1 row) - -SELECT spath '{(280d, -8d),(280d, -9d)}' && sellipse '<{10d,5d},(280d,-20d),90d>'; - ?column? ----------- - f -(1 row) - -SELECT spath '{(280d, -8d),(280d, -9d)}' && sellipse '<{10d,5d},(280d, -8d),90d>'; - ?column? ----------- - t -(1 row) - --- --- ellipse and polygon --- --- negators , commutator @,&& -SELECT spoly '{(280d, -9d),(280d, -8d),(279d, -8d)}' @ sellipse '<{10d,5d},(280d,-20d),90d>'; - ?column? ----------- - f -(1 row) - -SELECT spoly '{(280d, -9d),(280d,-12d),(279d, -8d)}' @ sellipse '<{10d,5d},(280d,-20d),90d>'; - ?column? ----------- - f -(1 row) - -SELECT spoly '{(280d,-11d),(280d,-12d),(279d, -12d)}' @ sellipse '<{10d,5d},(280d,-20d),90d>'; - ?column? ----------- - t -(1 row) - -SELECT spoly '{(280d, -9d),(280d, -8d),(279d, -8d)}' && sellipse '<{10d,5d},(280d,-20d),90d>'; - ?column? ----------- - f -(1 row) - -SELECT spoly '{(280d, -9d),(280d,-12d),(279d, -8d)}' && sellipse '<{10d,5d},(280d,-20d),90d>'; - ?column? ----------- - t -(1 row) - -SELECT spoly '{(280d,-11d),(280d,-12d),(279d, -12d)}' && sellipse '<{10d,5d},(280d,-20d),90d>'; - ?column? ----------- - t -(1 row) - -SELECT spoly '{(280d, -9d),(280d, -8d),(279d, -8d)}' !@ sellipse '<{10d,5d},(280d,-20d),90d>'; - ?column? ----------- - t -(1 row) - -SELECT spoly '{(280d, -9d),(280d,-12d),(279d, -8d)}' !@ sellipse '<{10d,5d},(280d,-20d),90d>'; - ?column? ----------- - t -(1 row) - -SELECT spoly '{(280d,-11d),(280d,-12d),(279d, -12d)}' !@ sellipse '<{10d,5d},(280d,-20d),90d>'; - ?column? ----------- - f -(1 row) - -SELECT spoly '{(280d, -9d),(280d, -8d),(279d, -8d)}' !&& sellipse '<{10d,5d},(280d,-20d),90d>'; - ?column? ----------- - t -(1 row) - -SELECT spoly '{(280d, -9d),(280d,-12d),(279d, -8d)}' !&& sellipse '<{10d,5d},(280d,-20d),90d>'; - ?column? ----------- - f -(1 row) - -SELECT spoly '{(280d,-11d),(280d,-12d),(279d, -12d)}' !&& sellipse '<{10d,5d},(280d,-20d),90d>'; - ?column? ----------- - f -(1 row) - -SELECT sellipse '<{10d,5d},(280d,-20d),90d>' ~ spoly '{(280d, -9d),(280d, -8d),(279d, -8d)}'; - ?column? ----------- - f -(1 row) - -SELECT sellipse '<{10d,5d},(280d,-20d),90d>' ~ spoly '{(280d, -9d),(280d,-12d),(279d, -8d)}'; - ?column? ----------- - f -(1 row) - -SELECT sellipse '<{10d,5d},(280d,-20d),90d>' ~ spoly '{(280d,-11d),(280d,-12d),(279d, -12d)}'; - ?column? ----------- - t -(1 row) - -SELECT sellipse '<{10d,5d},(280d,-20d),90d>' && spoly '{(280d, -9d),(280d, -8d),(279d, -8d)}'; - ?column? ----------- - f -(1 row) - -SELECT sellipse '<{10d,5d},(280d,-20d),90d>' && spoly '{(280d, -9d),(280d,-12d),(279d, -8d)}'; - ?column? ----------- - t -(1 row) - -SELECT sellipse '<{10d,5d},(280d,-20d),90d>' && spoly '{(280d,-11d),(280d,-12d),(279d, -12d)}'; - ?column? ----------- - t -(1 row) - -SELECT sellipse '<{10d,5d},(280d,-20d),90d>' !~ spoly '{(280d, -9d),(280d, -8d),(279d, -8d)}'; - ?column? ----------- - t -(1 row) - -SELECT sellipse '<{10d,5d},(280d,-20d),90d>' !~ spoly '{(280d, -9d),(280d,-12d),(279d, -8d)}'; - ?column? ----------- - t -(1 row) - -SELECT sellipse '<{10d,5d},(280d,-20d),90d>' !~ spoly '{(280d,-11d),(280d,-12d),(279d, -12d)}'; - ?column? ----------- - f -(1 row) - -SELECT sellipse '<{10d,5d},(280d,-20d),90d>' !&& spoly '{(280d, -9d),(280d, -8d),(279d, -8d)}'; - ?column? ----------- - t -(1 row) - -SELECT sellipse '<{10d,5d},(280d,-20d),90d>' !&& spoly '{(280d, -9d),(280d,-12d),(279d, -8d)}'; - ?column? ----------- - f -(1 row) - -SELECT sellipse '<{10d,5d},(280d,-20d),90d>' !&& spoly '{(280d,-11d),(280d,-12d),(279d, -12d)}'; - ?column? ----------- - f -(1 row) - --- ellipse is point -SELECT spoly '{(280d, -9d),(280d, -8d),(279d, -8d)}' @ sellipse '<{0d,0d},(280d,-20d),90d>'; - ?column? ----------- - f -(1 row) - -SELECT spoly '{(280d,-11d),(280d,-20d),(279d, -12d)}' @ sellipse '<{0d,0d},(280d,-20d),90d>'; - ?column? ----------- - f -(1 row) - -SELECT spoly '{(280d, -9d),(280d, -8d),(279d, -8d)}' && sellipse '<{0d,0d},(280d,-20d),90d>'; - ?column? ----------- - f -(1 row) - -SELECT spoly '{(280d,-11d),(280d,-20d),(279d, -12d)}' && sellipse '<{0d,0d},(280d,-20d),90d>'; - ?column? ----------- - t -(1 row) - -SELECT sellipse '<{0d,0d},(280d,-20d),90d>' @ spoly '{(280d, -9d),(280d, -8d),(279d, -8d)}' ; - ?column? ----------- - f -(1 row) - -SELECT sellipse '<{0d,0d},(280d,-20d),90d>' @ spoly '{(280d,-11d),(280d,-20d),(279d, -12d)}'; - ?column? ----------- - t -(1 row) - -SELECT sellipse '<{0d,0d},(280d,-20d),90d>' && spoly '{(280d, -9d),(280d, -8d),(279d, -8d)}' ; - ?column? ----------- - f -(1 row) - -SELECT sellipse '<{0d,0d},(280d,-20d),90d>' && spoly '{(280d,-11d),(280d,-20d),(279d, -12d)}'; - ?column? ----------- - t -(1 row) - --- ellipse is circle -SELECT spoly '{(280d, -9d),(280d, -8d),(279d, -8d)}' @ sellipse '<{5d,5d},(280d,-20d),90d>'; - ?column? ----------- - f -(1 row) - -SELECT spoly '{(280d,-10d),(290d,-30d),(270d, -30d)}' @ sellipse '<{2d,2d},(280d,-20d),90d>'; - ?column? ----------- - f -(1 row) - -SELECT spoly '{(280d, -9d),(280d, -8d),(279d, -8d)}' && sellipse '<{5d,5d},(280d,-20d),90d>'; - ?column? ----------- - f -(1 row) - -SELECT spoly '{(280d,-11d),(280d,-20d),(279d, -12d)}' && sellipse '<{5d,5d},(280d,-20d),90d>'; - ?column? ----------- - t -(1 row) - -SELECT sellipse '<{5d,5d},(280d,-20d),90d>' @ spoly '{(280d, -9d),(280d, -8d),(279d, -8d)}' ; - ?column? ----------- - f -(1 row) - -SELECT sellipse '<{2d,2d},(280d,-20d),90d>' @ spoly '{(280d,-10d),(290d,-30d),(270d, -30d)}'; - ?column? ----------- - t -(1 row) - -SELECT sellipse '<{5d,5d},(280d,-20d),90d>' && spoly '{(280d, -9d),(280d, -8d),(279d, -8d)}' ; - ?column? ----------- - f -(1 row) - -SELECT sellipse '<{5d,5d},(280d,-20d),90d>' && spoly '{(280d,-11d),(280d,-18d),(279d, -12d)}'; - ?column? ----------- - t -(1 row) - --- ellipse is line -SELECT spoly '{(280d, -9d),(280d, -8d),(279d, -8d)}' @ sellipse '<{5d,0d},(280d,-20d),90d>'; - ?column? ----------- - f -(1 row) - -SELECT spoly '{(280d,-10d),(290d,-30d),(270d, -30d)}' @ sellipse '<{2d,0d},(280d,-20d),90d>'; - ?column? ----------- - f -(1 row) - -SELECT spoly '{(280d, -9d),(280d, -8d),(279d, -8d)}' && sellipse '<{5d,0d},(280d,-20d),90d>'; - ?column? ----------- - f -(1 row) - -SELECT spoly '{(280d,-11d),(280d,-20d),(279d, -12d)}' && sellipse '<{5d,0d},(280d,-20d),90d>'; - ?column? ----------- - t -(1 row) - -SELECT sellipse '<{5d,0d},(280d,-20d),90d>' @ spoly '{(280d, -9d),(280d, -8d),(279d, -8d)}' ; - ?column? ----------- - f -(1 row) - -SELECT sellipse '<{2d,0d},(280d,-20d),90d>' @ spoly '{(280d,-10d),(290d,-30d),(270d, -30d)}'; - ?column? ----------- - t -(1 row) - -SELECT sellipse '<{5d,0d},(280d,-20d),90d>' && spoly '{(280d, -9d),(280d, -8d),(279d, -8d)}' ; - ?column? ----------- - f -(1 row) - -SELECT sellipse '<{5d,0d},(280d,-20d),90d>' && spoly '{(280d,-11d),(280d,-18d),(279d, -12d)}'; - ?column? ----------- - t -(1 row) - --- ellipse is a real ellipse -SELECT spoly '{(280d, -9d),(280d, -8d),(279d, -8d)}' @ sellipse '<{5d,2d},(280d,-20d),90d>'; - ?column? ----------- - f -(1 row) - -SELECT spoly '{(280d,-10d),(290d,-30d),(270d, -30d)}' @ sellipse '<{2d,1d},(280d,-20d),90d>'; - ?column? ----------- - f -(1 row) - -SELECT spoly '{(280d, -9d),(280d, -8d),(279d, -8d)}' && sellipse '<{5d,2d},(280d,-20d),90d>'; - ?column? ----------- - f -(1 row) - -SELECT spoly '{(280d,-11d),(280d,-20d),(279d, -12d)}' && sellipse '<{5d,2d},(280d,-20d),90d>'; - ?column? ----------- - t -(1 row) - -SELECT sellipse '<{5d,2d},(280d,-20d),90d>' @ spoly '{(280d, -9d),(280d, -8d),(279d, -8d)}' ; - ?column? ----------- - f -(1 row) - -SELECT sellipse '<{2d,1d},(280d,-20d),90d>' @ spoly '{(280d,-10d),(290d,-30d),(270d, -30d)}'; - ?column? ----------- - t -(1 row) - -SELECT sellipse '<{5d,2d},(280d,-20d),90d>' && spoly '{(280d, -9d),(280d, -8d),(279d, -8d)}' ; - ?column? ----------- - f -(1 row) - -SELECT sellipse '<{5d,2d},(280d,-20d),90d>' && spoly '{(280d,-11d),(280d,-18d),(279d, -12d)}'; - ?column? ----------- - t -(1 row) - --- --- ellipse and ellipse --- --- check @ -SELECT sellipse '<{10d, 5d},(300d,0d), 0d>' @ sellipse '<{10d,5d},(300d,0d),0d>'; - ?column? ----------- - t -(1 row) - -SELECT sellipse '<{10d, 5d},(300d,0d), 90d>' @ sellipse '<{10d,5d},(300d,0d),0d>'; - ?column? ----------- - f -(1 row) - -SELECT sellipse '<{10d, 5d},(300d,0d),180d>' @ sellipse '<{10d,5d},(300d,0d),0d>'; - ?column? ----------- - t -(1 row) - -SELECT sellipse '<{10d, 5d},(300d,0d),270d>' @ sellipse '<{10d,5d},(300d,0d),0d>'; - ?column? ----------- - f -(1 row) - -SELECT sellipse '<{ 2d, 1d},( 52d,6d), 0d>' @ sellipse '<{10d,5d},(50d,5d),45d>'; - ?column? ----------- - t -(1 row) - --- negators , commutator @,&& -SELECT sellipse '<{ 2d, 1d},( 52d,6d), 0d>' @ sellipse '<{10d,5d},(50d,5d),45d>'; - ?column? ----------- - t -(1 row) - -SELECT sellipse '<{10d, 5d},( 52d,6d), 0d>' @ sellipse '<{10d,5d},(50d,5d),45d>'; - ?column? ----------- - f -(1 row) - -SELECT sellipse '<{10d, 5d},( 90d,9d), 0d>' @ sellipse '<{10d,5d},(50d,5d),45d>'; - ?column? ----------- - f -(1 row) - -SELECT sellipse '<{ 2d, 1d},( 52d,6d), 0d>' && sellipse '<{10d,5d},(50d,5d),45d>'; - ?column? ----------- - t -(1 row) - -SELECT sellipse '<{10d, 5d},( 52d,6d), 0d>' && sellipse '<{10d,5d},(50d,5d),45d>'; - ?column? ----------- - t -(1 row) - -SELECT sellipse '<{10d, 5d},( 90d,9d), 0d>' && sellipse '<{10d,5d},(50d,5d),45d>'; - ?column? ----------- - f -(1 row) - -SELECT sellipse '<{ 2d, 1d},( 52d,6d), 0d>' !@ sellipse '<{10d,5d},(50d,5d),45d>'; - ?column? ----------- - f -(1 row) - -SELECT sellipse '<{10d, 5d},( 52d,6d), 0d>' !@ sellipse '<{10d,5d},(50d,5d),45d>'; - ?column? ----------- - t -(1 row) - -SELECT sellipse '<{10d, 5d},( 90d,9d), 0d>' !@ sellipse '<{10d,5d},(50d,5d),45d>'; - ?column? ----------- - t -(1 row) - -SELECT sellipse '<{ 2d, 1d},( 52d,6d), 0d>' !&& sellipse '<{10d,5d},(50d,5d),45d>'; - ?column? ----------- - f -(1 row) - -SELECT sellipse '<{10d, 5d},( 52d,6d), 0d>' !&& sellipse '<{10d,5d},(50d,5d),45d>'; - ?column? ----------- - f -(1 row) - -SELECT sellipse '<{10d, 5d},( 90d,9d), 0d>' !&& sellipse '<{10d,5d},(50d,5d),45d>'; - ?column? ----------- - t -(1 row) - -SELECT sellipse '<{10d,5d},(50d,5d),45d>' ~ sellipse '<{ 2d, 1d},( 52d,6d), 0d>'; - ?column? ----------- - t -(1 row) - -SELECT sellipse '<{10d,5d},(50d,5d),45d>' ~ sellipse '<{10d, 5d},( 52d,6d), 0d>'; - ?column? ----------- - f -(1 row) - -SELECT sellipse '<{10d,5d},(50d,5d),45d>' ~ sellipse '<{10d, 5d},( 90d,9d), 0d>'; - ?column? ----------- - f -(1 row) - -SELECT sellipse '<{10d,5d},(50d,5d),45d>' && sellipse '<{ 2d, 1d},( 52d,6d), 0d>'; - ?column? ----------- - t -(1 row) - -SELECT sellipse '<{10d,5d},(50d,5d),45d>' && sellipse '<{10d, 5d},( 52d,6d), 0d>'; - ?column? ----------- - t -(1 row) - -SELECT sellipse '<{10d,5d},(50d,5d),45d>' && sellipse '<{10d, 5d},( 90d,9d), 0d>'; - ?column? ----------- - f -(1 row) - -SELECT sellipse '<{10d,5d},(50d,5d),45d>' !~ sellipse '<{ 2d, 1d},( 52d,6d), 0d>'; - ?column? ----------- - f -(1 row) - -SELECT sellipse '<{10d,5d},(50d,5d),45d>' !~ sellipse '<{10d, 5d},( 52d,6d), 0d>'; - ?column? ----------- - t -(1 row) - -SELECT sellipse '<{10d,5d},(50d,5d),45d>' !~ sellipse '<{10d, 5d},( 90d,9d), 0d>'; - ?column? ----------- - t -(1 row) - -SELECT sellipse '<{10d,5d},(50d,5d),45d>' !&& sellipse '<{ 2d, 1d},( 52d,6d), 0d>'; - ?column? ----------- - f -(1 row) - -SELECT sellipse '<{10d,5d},(50d,5d),45d>' !&& sellipse '<{10d, 5d},( 52d,6d), 0d>'; - ?column? ----------- - f -(1 row) - -SELECT sellipse '<{10d,5d},(50d,5d),45d>' !&& sellipse '<{10d, 5d},( 90d,9d), 0d>'; - ?column? ----------- - t -(1 row) - --- left ellipse is point right ellipse is point -SELECT sellipse '<{ 0d, 0d},( 50d,-5d), 0d>' @ sellipse '<{0d,0d},(50d,-5d),45d>'; - ?column? ----------- - t -(1 row) - -SELECT sellipse '<{ 0d, 0d},( 50d,-6d), 0d>' @ sellipse '<{0d,0d},(50d,-5d),45d>'; - ?column? ----------- - f -(1 row) - -SELECT sellipse '<{ 0d, 0d},( 50d,-5d), 0d>' && sellipse '<{0d,0d},(50d,-5d),45d>'; - ?column? ----------- - t -(1 row) - -SELECT sellipse '<{ 0d, 0d},( 50d,-6d), 0d>' && sellipse '<{0d,0d},(50d,-5d),45d>'; - ?column? ----------- - f -(1 row) - --- left ellipse is line right ellipse is point -SELECT sellipse '<{ 5d, 0d},( 50d, -2d), 90d>' @ sellipse '<{0d,0d},(50d,-5d),0d>'; - ?column? ----------- - f -(1 row) - -SELECT sellipse '<{ 5d, 0d},( 50d,-12d), 90d>' @ sellipse '<{0d,0d},(50d,-5d),0d>'; - ?column? ----------- - f -(1 row) - -SELECT sellipse '<{ 5d, 0d},( 50d, -2d), 90d>' && sellipse '<{0d,0d},(50d,-5d),0d>'; - ?column? ----------- - t -(1 row) - -SELECT sellipse '<{ 5d, 0d},( 50d,-12d), 90d>' && sellipse '<{0d,0d},(50d,-5d),0d>'; - ?column? ----------- - f -(1 row) - --- left ellipse is circle right ellipse is point -SELECT sellipse '<{ 5d, 5d},( 50d, -2d), 90d>' @ sellipse '<{0d,0d},(50d,-5d),0d>'; - ?column? ----------- - f -(1 row) - -SELECT sellipse '<{ 5d, 5d},( 50d,-12d), 90d>' @ sellipse '<{0d,0d},(50d,-5d),0d>'; - ?column? ----------- - f -(1 row) - -SELECT sellipse '<{ 5d, 5d},( 50d, -2d), 90d>' && sellipse '<{0d,0d},(50d,-5d),0d>'; - ?column? ----------- - t -(1 row) - -SELECT sellipse '<{ 5d, 5d},( 50d,-12d), 90d>' && sellipse '<{0d,0d},(50d,-5d),0d>'; - ?column? ----------- - f -(1 row) - --- left ellipse is real ellipse right ellipse is point -SELECT sellipse '<{ 5d, 3d},( 50d, -2d), 90d>' @ sellipse '<{0d,0d},(50d,-5d),0d>'; - ?column? ----------- - f -(1 row) - -SELECT sellipse '<{ 5d, 3d},( 50d,-12d), 90d>' @ sellipse '<{0d,0d},(50d,-5d),0d>'; - ?column? ----------- - f -(1 row) - -SELECT sellipse '<{ 5d, 3d},( 50d, -2d), 90d>' && sellipse '<{0d,0d},(50d,-5d),0d>'; - ?column? ----------- - t -(1 row) - -SELECT sellipse '<{ 5d, 3d},( 50d,-12d), 90d>' && sellipse '<{0d,0d},(50d,-5d),0d>'; - ?column? ----------- - f -(1 row) - --- left ellipse is point right ellipse is line -SELECT sellipse '<{ 0d, 0d},( 50d,-5d), 0d>' @ sellipse '<{5d,0d},(50d,-5d),90d>'; - ?column? ----------- - t -(1 row) - -SELECT sellipse '<{ 0d, 0d},( 50d,-6d), 0d>' @ sellipse '<{5d,0d},(50d,-5d),90d>'; - ?column? ----------- - t -(1 row) - -SELECT sellipse '<{ 0d, 0d},( 50d, 6d), 0d>' @ sellipse '<{5d,0d},(50d,-5d),90d>'; - ?column? ----------- - f -(1 row) - -SELECT sellipse '<{ 0d, 0d},( 50d,-5d), 0d>' && sellipse '<{5d,0d},(50d,-5d),90d>'; - ?column? ----------- - t -(1 row) - -SELECT sellipse '<{ 0d, 0d},( 50d,-6d), 0d>' && sellipse '<{5d,0d},(50d,-5d),90d>'; - ?column? ----------- - t -(1 row) - -SELECT sellipse '<{ 0d, 0d},( 50d, 6d), 0d>' && sellipse '<{5d,0d},(50d,-5d),90d>'; - ?column? ----------- - f -(1 row) - --- left ellipse is line right ellipse is line -SELECT sellipse '<{ 3d, 0d},( 50d,-5d), 90d>' @ sellipse '<{5d,0d},(50d,-5d),90d>'; - ?column? ----------- - t -(1 row) - -SELECT sellipse '<{ 3d, 0d},( 50d,-8d), 90d>' @ sellipse '<{5d,0d},(50d,-5d),90d>'; - ?column? ----------- - f -(1 row) - -SELECT sellipse '<{ 3d, 0d},( 50d,-6d), 0d>' @ sellipse '<{5d,0d},(50d,-5d),90d>'; - ?column? ----------- - f -(1 row) - -SELECT sellipse '<{ 3d, 0d},( 50d, 6d), 90d>' @ sellipse '<{5d,0d},(50d,-5d),90d>'; - ?column? ----------- - f -(1 row) - -SELECT sellipse '<{ 3d, 0d},( 50d,-5d), 90d>' && sellipse '<{5d,0d},(50d,-5d),90d>'; - ?column? ----------- - t -(1 row) - -SELECT sellipse '<{ 3d, 0d},( 50d,-8d), 90d>' && sellipse '<{5d,0d},(50d,-5d),90d>'; - ?column? ----------- - t -(1 row) - -SELECT sellipse '<{ 3d, 0d},( 50d,-6d), 0d>' && sellipse '<{5d,0d},(50d,-5d),90d>'; - ?column? ----------- - t -(1 row) - -SELECT sellipse '<{ 3d, 0d},( 50d, 6d), 90d>' && sellipse '<{5d,0d},(50d,-5d),90d>'; - ?column? ----------- - f -(1 row) - --- left ellipse is circle right ellipse is line -SELECT sellipse '<{ 3d, 3d},( 50d,-5d), 90d>' @ sellipse '<{5d,0d},(50d,-5d),90d>'; - ?column? ----------- - f -(1 row) - -SELECT sellipse '<{ 3d, 3d},( 50d,-8d), 90d>' @ sellipse '<{5d,0d},(50d,-5d),90d>'; - ?column? ----------- - f -(1 row) - -SELECT sellipse '<{ 3d, 3d},( 50d,-6d), 0d>' @ sellipse '<{5d,0d},(50d,-5d),90d>'; - ?column? ----------- - f -(1 row) - -SELECT sellipse '<{ 3d, 3d},( 50d, 6d), 90d>' @ sellipse '<{5d,0d},(50d,-5d),90d>'; - ?column? ----------- - f -(1 row) - -SELECT sellipse '<{ 3d, 3d},( 50d,-5d), 90d>' && sellipse '<{5d,0d},(50d,-5d),90d>'; - ?column? ----------- - t -(1 row) - -SELECT sellipse '<{ 3d, 3d},( 50d,-8d), 90d>' && sellipse '<{5d,0d},(50d,-5d),90d>'; - ?column? ----------- - t -(1 row) - -SELECT sellipse '<{ 3d, 3d},( 50d,-6d), 0d>' && sellipse '<{5d,0d},(50d,-5d),90d>'; - ?column? ----------- - t -(1 row) - -SELECT sellipse '<{ 3d, 3d},( 50d, 6d), 90d>' && sellipse '<{5d,0d},(50d,-5d),90d>'; - ?column? ----------- - f -(1 row) - --- left ellipse is point right ellipse is circle -SELECT sellipse '<{ 0d, 0d},( 50d,-5d), 0d>' @ sellipse '<{5d,5d},(50d,-5d),90d>'; - ?column? ----------- - t -(1 row) - -SELECT sellipse '<{ 0d, 0d},( 50d,-6d), 0d>' @ sellipse '<{5d,5d},(50d,-5d),90d>'; - ?column? ----------- - t -(1 row) - -SELECT sellipse '<{ 0d, 0d},( 50d, 6d), 0d>' @ sellipse '<{5d,5d},(50d,-5d),90d>'; - ?column? ----------- - f -(1 row) - -SELECT sellipse '<{ 0d, 0d},( 50d,-5d), 0d>' && sellipse '<{5d,5d},(50d,-5d),90d>'; - ?column? ----------- - t -(1 row) - -SELECT sellipse '<{ 0d, 0d},( 50d,-6d), 0d>' && sellipse '<{5d,5d},(50d,-5d),90d>'; - ?column? ----------- - t -(1 row) - -SELECT sellipse '<{ 0d, 0d},( 50d, 6d), 0d>' && sellipse '<{5d,5d},(50d,-5d),90d>'; - ?column? ----------- - f -(1 row) - --- left ellipse is line right ellipse is circle -SELECT sellipse '<{ 5d, 0d},( 50d,-5d), 90d>' @ sellipse '<{5d,5d},(50d,-5d),90d>'; - ?column? ----------- - t -(1 row) - -SELECT sellipse '<{ 5d, 0d},( 50d,-6d), 90d>' @ sellipse '<{5d,5d},(50d,-5d),90d>'; - ?column? ----------- - f -(1 row) - -SELECT sellipse '<{ 5d, 0d},( 50d, 6d), 90d>' @ sellipse '<{5d,5d},(50d,-5d),90d>'; - ?column? ----------- - f -(1 row) - -SELECT sellipse '<{ 5d, 0d},( 50d,-5d), 90d>' && sellipse '<{5d,5d},(50d,-5d),90d>'; - ?column? ----------- - t -(1 row) - -SELECT sellipse '<{ 5d, 0d},( 50d,-6d), 90d>' && sellipse '<{5d,5d},(50d,-5d),90d>'; - ?column? ----------- - t -(1 row) - -SELECT sellipse '<{ 5d, 0d},( 50d, 6d), 90d>' && sellipse '<{5d,5d},(50d,-5d),90d>'; - ?column? ----------- - f -(1 row) - --- left ellipse is circle right ellipse is circle -SELECT sellipse '<{ 3d, 3d},( 50d,-4d), 90d>' @ sellipse '<{5d,5d},(50d,-5d),90d>'; - ?column? ----------- - t -(1 row) - -SELECT sellipse '<{ 5d, 5d},( 50d,-5d), 90d>' @ sellipse '<{5d,5d},(50d,-5d),90d>'; - ?column? ----------- - t -(1 row) - -SELECT sellipse '<{ 5d, 5d},( 50d,-6d), 90d>' @ sellipse '<{5d,5d},(50d,-5d),90d>'; - ?column? ----------- - f -(1 row) - -SELECT sellipse '<{ 5d, 5d},( 50d, 6d), 90d>' @ sellipse '<{5d,5d},(50d,-5d),90d>'; - ?column? ----------- - f -(1 row) - -SELECT sellipse '<{ 3d, 3d},( 50d,-4d), 90d>' && sellipse '<{5d,5d},(50d,-5d),90d>'; - ?column? ----------- - t -(1 row) - -SELECT sellipse '<{ 5d, 5d},( 50d,-5d), 90d>' && sellipse '<{5d,5d},(50d,-5d),90d>'; - ?column? ----------- - t -(1 row) - -SELECT sellipse '<{ 5d, 5d},( 50d,-6d), 90d>' && sellipse '<{5d,5d},(50d,-5d),90d>'; - ?column? ----------- - t -(1 row) - -SELECT sellipse '<{ 5d, 5d},( 50d, 6d), 90d>' && sellipse '<{5d,5d},(50d,-5d),90d>'; - ?column? ----------- - f -(1 row) - --- index tests -CREATE TABLE spheretmp1 (p spoint); -\copy spheretmp1 from 'data/test_spherepoint.data' -\copy spheretmp1 from 'data/test_spherepoint.data' -\copy spheretmp1 from 'data/test_spherepoint.data' -\copy spheretmp1 from 'data/test_spherepoint.data' -CREATE TABLE spheretmp2 (c scircle); -\copy spheretmp2 from 'data/test_spherecircle.data' -\copy spheretmp2 from 'data/test_spherecircle.data' -\copy spheretmp2 from 'data/test_spherecircle.data' -\copy spheretmp2 from 'data/test_spherecircle.data' -CREATE TABLE spheretmp4 AS - SELECT sline ( p , p - strans '-15d,-15d,-15d,ZXZ' ) AS l - FROM spheretmp1; --- checking input -SELECT count(*) FROM spheretmp1 WHERE p @ scircle '< ( 180d 1m 10s , -2d 23m 59s ) , 10d >'; - count -------- - 32 -(1 row) - --- without idx -SELECT count(*) FROM spheretmp1 WHERE p @ scircle '<(1,1),0.3>'; - count -------- - 32 -(1 row) - -SELECT count(*) FROM spheretmp2 WHERE c @ scircle '<(1,1),0.3>'; - count -------- - 12 -(1 row) - -SELECT count(*) FROM spheretmp2 WHERE c && scircle '<(1,1),0.3>'; - count -------- - 48 -(1 row) - -SELECT count(*) FROM spheretmp4 WHERE l @ scircle '<(1,1),0.3>'; - count -------- - 8 -(1 row) - -SELECT count(*) FROM spheretmp4 WHERE l && scircle '<(1,1),0.3>'; - count -------- - 40 -(1 row) - -SELECT count(*) FROM spheretmp1 WHERE p = spoint '(3.09 , 1.25)' ; - count -------- - 4 -(1 row) - --- create idx -CREATE INDEX aaaidx ON spheretmp1 USING gist ( p ); -CREATE INDEX bbbidx ON spheretmp2 USING gist ( c ); -CREATE INDEX cccidx ON spheretmp4 USING gist ( l ); ---with idx -SET enable_seqscan = OFF ; -SELECT count(*) FROM spheretmp1 WHERE p @ scircle '<(1,1),0.3>' ; - count -------- - 32 -(1 row) - -SELECT count(*) FROM spheretmp2 WHERE c @ scircle '<(1,1),0.3>' ; - count -------- - 12 -(1 row) - -SELECT count(*) FROM spheretmp2 WHERE c && scircle '<(1,1),0.3>' ; - count -------- - 48 -(1 row) - -SELECT count(*) FROM spheretmp4 WHERE l @ scircle '<(1,1),0.3>' ; - count -------- - 8 -(1 row) - -SELECT count(*) FROM spheretmp4 WHERE l && scircle '<(1,1),0.3>' ; - count -------- - 40 -(1 row) - -SELECT count(*) FROM spheretmp1 WHERE p = spoint '(3.09 , 1.25)' ; - count -------- - 4 -(1 row) - diff --git a/expected/point.out b/expected/point.out deleted file mode 100644 index d6aa4c2..0000000 --- a/expected/point.out +++ /dev/null @@ -1,240 +0,0 @@ --- radian input -SELECT spoint (-3*pi(), 0); - spoint ------------------------- - (3.14159265358979 , 0) -(1 row) - -SELECT spoint ( 3*pi(), 0); - spoint ------------------------- - (3.14159265358979 , 0) -(1 row) - -SELECT spoint ( 0, pi()); - spoint ------------------------- - (3.14159265358979 , 0) -(1 row) - -SELECT spoint ( 0, -pi()); - spoint ------------------------- - (3.14159265358979 , 0) -(1 row) - -SELECT spoint ( 2*pi(), 2*pi()); - spoint ---------- - (0 , 0) -(1 row) - -SELECT spoint ( pi(), 2*pi()); - spoint ------------------------- - (3.14159265358979 , 0) -(1 row) - -SELECT spoint ( 0, pi()/2); - spoint ------------------------ - (0 , 1.5707963267949) -(1 row) - -SELECT spoint ( 0, -pi()/2); - spoint ------------------------- - (0 , -1.5707963267949) -(1 row) - --- degree input -SELECT spoint '(-540d, 0d)'; - spoint ------------------------- - (3.14159265358979 , 0) -(1 row) - -SELECT spoint '( 540d, 0d)'; - spoint ------------------------- - (3.14159265358979 , 0) -(1 row) - -SELECT spoint '( 0d, 180d)'; - spoint ------------------------- - (3.14159265358979 , 0) -(1 row) - -SELECT spoint '( 0d, -180d)'; - spoint ------------------------- - (3.14159265358979 , 0) -(1 row) - -SELECT spoint '( 360d, 360d)'; - spoint ---------- - (0 , 0) -(1 row) - -SELECT spoint '( 180d, 360d)'; - spoint ------------------------- - (3.14159265358979 , 0) -(1 row) - -SELECT spoint '( 0d, 90d)'; - spoint ------------------------ - (0 , 1.5707963267949) -(1 row) - -SELECT spoint '( 0d, -90d)'; - spoint ------------------------- - (0 , -1.5707963267949) -(1 row) - --- dms input -SELECT spoint '( 0.0d 0m 0s, 0d 0m 0s)'; -ERROR: parsing: syntax error -SELECT spoint '( 0d 60m 0s, 0d 0m 0s)'; -ERROR: parsing: minutes or seconds invalid (min:60.000000 sec:0.000000) -SELECT spoint '( 0d 0m 60s, 0d 0m 0s)'; -ERROR: parsing: minutes or seconds invalid (min:0.000000 sec:60.000000) -SELECT spoint '( 539d 59m 59.9999s, 0d 0m 0s)'; - spoint ------------------------- - (3.14159265310498 , 0) -(1 row) - -SELECT spoint '( 0d 0m 0s, 180d 0m 0s)'; - spoint ------------------------- - (3.14159265358979 , 0) -(1 row) - -SELECT spoint '( 0d 0m 0s, -180d 0m 0s)'; - spoint ------------------------- - (3.14159265358979 , 0) -(1 row) - -SELECT spoint '( 360d 0m 0s, 360d 0m 0s)'; - spoint ---------- - (0 , 0) -(1 row) - -SELECT spoint '( 180d 0m 0s, 360d 0m 0s)'; - spoint ------------------------- - (3.14159265358979 , 0) -(1 row) - -SELECT spoint '( 0d 0m 0s, 90d 0m 0s)'; - spoint ------------------------ - (0 , 1.5707963267949) -(1 row) - -SELECT spoint '( 0d 0m 0s, -90d 0m 0s)'; - spoint ------------------------- - (0 , -1.5707963267949) -(1 row) - --- hms input for latitude -SELECT spoint '( 0.0h 0m 0s, 0)'; -ERROR: parsing: syntax error -SELECT spoint '( 0h 60m 0s, 0)'; -ERROR: parsing: minutes or seconds invalid (min:60.000000 sec:0.000000) -SELECT spoint '( 0h 0m 60s, 0)'; -ERROR: parsing: minutes or seconds invalid (min:0.000000 sec:60.000000) -SELECT spoint '( 35h 59m 59.9999s, 0d 0m 0s)'; - spoint ------------------------- - (3.14159264631759 , 0) -(1 row) - -SELECT spoint '( 0h 0m 0s, 180d 0m 0s)'; - spoint ------------------------- - (3.14159265358979 , 0) -(1 row) - -SELECT spoint '( 0h 0m 0s, -180d 0m 0s)'; - spoint ------------------------- - (3.14159265358979 , 0) -(1 row) - -SELECT spoint '( 24h 0m 0s, 360d 0m 0s)'; - spoint ---------- - (0 , 0) -(1 row) - -SELECT spoint '( 12h 0m 0s, 360d 0m 0s)'; - spoint ------------------------- - (3.14159265358979 , 0) -(1 row) - -SELECT spoint '( 0h 0m 0s, 90d 0m 0s)'; - spoint ------------------------ - (0 , 1.5707963267949) -(1 row) - -SELECT spoint '( 0h 0m 0s, -90d 0m 0s)'; - spoint ------------------------- - (0 , -1.5707963267949) -(1 row) - --- mixed input --- operators -SELECT spoint '(0, 90d)' = spoint '(0, 90d)'; - ?column? ----------- - t -(1 row) - -SELECT spoint '(0, 90d)' = spoint '(0,-90d)'; - ?column? ----------- - f -(1 row) - -SELECT spoint '(0,-90d)' = spoint '(0,-90d)'; - ?column? ----------- - t -(1 row) - -SELECT spoint '(0, 90d)' != spoint '(0, 90d)'; - ?column? ----------- - f -(1 row) - -SELECT spoint '(0, 90d)' != spoint '(0,-90d)'; - ?column? ----------- - t -(1 row) - -SELECT spoint '(0,-90d)' != spoint '(0,-90d)'; - ?column? ----------- - f -(1 row) - -SELECT spoint '(0d, 0)' = spoint '(360d,0)'; - ?column? ----------- - t -(1 row) - From 65217de6e51a229737b793f24ab63a24349a3043 Mon Sep 17 00:00:00 2001 From: Christoph Berg Date: Thu, 27 Jul 2023 18:02:20 +0200 Subject: [PATCH 47/87] Implement restriction selectivity estimators for <@(spoint, scircle) This implements restriction selectivity estimation for the <@ @> !<@ !@> family of operators on spoint and scircle. The selectivity is estimated to be (area of sphere circle) / (4 pi). Queries like `select * from sky where sky.star <@ scircle(const, radius)` will be able to properly estimate if using an index is appropriate depending on the size of radius. Secondly, a function spoint_dwithin(p1 spoint, p2 spoint, radius float8) is added that effectively returns `p1 <-> p2 <= radius`. But other than this two-operator expression, it has GIST index support so the optimizer can rewrite it to either `p1 <@ scircle(p2, radius)` or `p2 <@ scircle(p1, radius)`, i.e. it is symmetric in the first two arguments. This allows efficient matching queries without the user having to encode the join ordering in the query. On PostgreSQL 10/11, the spoint_dwithin function is created, but without the GIST support since that only appeared in PG12. The file expected/selectivity_1.out is used on PG10/11; it has <@ flipped around to @> in some plans. --- Makefile | 24 ++-- doc/functions.sgm | 35 ++++++ expected/gist_support.out | 155 ++++++++++++++++++++++++++ expected/index.out | 2 +- expected/points.out | 16 +++ expected/selectivity.out | 124 +++++++++++++++++++++ expected/selectivity_1.out | 124 +++++++++++++++++++++ pgs_circle_sel.sql.in | 109 ++++++++++++++++++ pgs_gist_support.sql.in | 12 ++ sql/gist_support.sql | 26 +++++ sql/index.sql | 2 +- sql/points.sql | 9 ++ sql/selectivity.sql | 36 ++++++ src/circle.c | 2 +- src/circle_sel.c | 218 ++++++++++++++++++++++++++++++++++++ src/gist_support.c | 223 +++++++++++++++++++++++++++++++++++++ src/pgs_util.h | 13 +++ src/point.c | 12 ++ 18 files changed, 1132 insertions(+), 10 deletions(-) create mode 100644 expected/gist_support.out create mode 100644 expected/selectivity.out create mode 100644 expected/selectivity_1.out create mode 100644 pgs_circle_sel.sql.in create mode 100644 pgs_gist_support.sql.in create mode 100644 sql/gist_support.sql create mode 100644 sql/selectivity.sql create mode 100644 src/circle_sel.c create mode 100644 src/gist_support.c diff --git a/Makefile b/Makefile index 5f428ea..1e9805f 100644 --- a/Makefile +++ b/Makefile @@ -10,8 +10,8 @@ SRC_DIR = $(shell basename $(shell pwd)) MODULE_big = pg_sphere OBJS = src/sscan.o src/sparse.o src/sbuffer.o src/vector3d.o src/point.o \ - src/euler.o src/circle.o src/line.o src/ellipse.o src/polygon.o \ - src/path.o src/box.o src/output.o src/gq_cache.o src/gist.o \ + src/euler.o src/circle.o src/circle_sel.o src/line.o src/ellipse.o src/polygon.o \ + src/path.o src/box.o src/output.o src/gq_cache.o src/gist.o src/gist_support.o \ src/key.o src/gnomo.o src/epochprop.o src/brin.o ifneq ($(USE_HEALPIX),0) @@ -35,11 +35,11 @@ DATA_built = $(RELEASE_SQL) \ DOCS = README.pg_sphere COPYRIGHT.pg_sphere REGRESS = init tables points euler circle line ellipse poly path box index \ contains_ops contains_ops_compat bounding_box_gist gnomo epochprop \ - contains overlaps spoint_brin sbox_brin + contains overlaps spoint_brin sbox_brin selectivity TESTS = init_test tables points euler circle line ellipse poly path box \ index contains_ops contains_ops_compat bounding_box_gist gnomo \ - epochprop contains overlaps spoint_brin sbox_brin + epochprop contains overlaps spoint_brin sbox_brin selectivity PG_CFLAGS += -DPGSPHERE_VERSION=$(PGSPHERE_VERSION) PG_CPPFLAGS += -DPGSPHERE_VERSION=$(PGSPHERE_VERSION) @@ -58,7 +58,7 @@ CRUSH_TESTS = init_extended circle_extended PGS_SQL = pgs_types.sql pgs_point.sql pgs_euler.sql pgs_circle.sql \ pgs_line.sql pgs_ellipse.sql pgs_polygon.sql pgs_path.sql \ pgs_box.sql pgs_contains_ops.sql pgs_contains_ops_compat.sql \ - pgs_gist.sql gnomo.sql pgs_brin.sql + pgs_gist.sql gnomo.sql pgs_brin.sql pgs_circle_sel.sql ifneq ($(USE_HEALPIX),0) REGRESS += healpix moc moc1 moc100 mocautocast @@ -102,10 +102,17 @@ healpix_bare/healpix_bare.o : healpix_bare/healpix_bare.c $(COMPILE.c) -Wno-declaration-after-statement -o $@ $^ pg_version := $(word 2,$(shell $(PG_CONFIG) --version)) +has_support_functions = $(if $(filter-out 9.% 10.% 11.%,$(pg_version)),y,n) crushtest: REGRESS += $(CRUSH_TESTS) crushtest: installcheck +ifeq ($(has_support_functions),y) +PGS_SQL += pgs_gist_support.sql +REGRESS += gist_support +TESTS += gist_support +endif + test: pg_sphere.test.sql $(pg_regress_installcheck) --temp-instance=tmp_check $(REGRESS_OPTS) $(TESTS) @@ -180,8 +187,11 @@ pg_sphere--1.2.3--1.3.0.sql: pgs_brin.sql.in pg_sphere--1.3.0--1.3.1.sql: cat upgrade_scripts/$@.in > $@ -pg_sphere--1.3.1--1.3.2.sql: - cat upgrade_scripts/$@.in > $@ +ifeq ($(has_support_functions),y) +pg_sphere--1.3.1--1.3.2.sql: pgs_gist_support.sql.in +endif +pg_sphere--1.3.1--1.3.2.sql: pgs_circle_sel.sql.in + cat upgrade_scripts/$@.in $^ > $@ # end of local stuff diff --git a/doc/functions.sgm b/doc/functions.sgm index b65f8c0..232b755 100644 --- a/doc/functions.sgm +++ b/doc/functions.sgm @@ -149,6 +149,41 @@ + + Codestin Search App + + The function + + + + spoint_dwithin + spoint p1 + spoint p2 + float8 radius + + + + returns a boolean value that signifies whether the points + p1 and p2 + lie within distance radius (in radians) of each other, i.e. + it computes the boolean expression p1 <-> p2 <= radius. + On PostgreSQL 12 and later, the function has GiST + support and the PostgreSQL optimizer will transform it to either + p1 <@ scircle(p2, radius) or + p2 <@ scircle(p1, radius) where appropriate. + + + Codestin Search App + + SELECT * FROM stars1 JOIN stars2 WHERE spoint_dwithin(stars1.s, stars2.s, 1e-5);]]> + + + + diff --git a/expected/gist_support.out b/expected/gist_support.out new file mode 100644 index 0000000..dead655 --- /dev/null +++ b/expected/gist_support.out @@ -0,0 +1,155 @@ +-- spoint_dwithin function selectivity +set jit = off; -- suppress extra planning output +select explain('select * from spoint10k where spoint_dwithin(star, spoint(1,1), 1)'); + explain +----------------------------------------------------------------------------------------------- + Bitmap Heap Scan on spoint10k (rows=2298 width=16) (actual rows=3009 loops=1) + Filter: spoint_dwithin(star, '(1 , 1)'::spoint, '1'::double precision) + Rows Removed by Filter: 1560 + Heap Blocks: exact=55 + -> Bitmap Index Scan on spoint10k_star_idx (rows=2298 width=0) (actual rows=4569 loops=1) + Index Cond: (star <@ '<(1 , 1) , 1>'::scircle) +(6 rows) + +select explain('select * from spoint10k where spoint_dwithin(star, spoint(1,1), .1)'); + explain +------------------------------------------------------------------------------------------- + Bitmap Heap Scan on spoint10k (rows=25 width=16) (actual rows=29 loops=1) + Filter: spoint_dwithin(star, '(1 , 1)'::spoint, '0.1'::double precision) + Rows Removed by Filter: 19 + Heap Blocks: exact=32 + -> Bitmap Index Scan on spoint10k_star_idx (rows=25 width=0) (actual rows=48 loops=1) + Index Cond: (star <@ '<(1 , 1) , 0.1>'::scircle) +(6 rows) + +select explain('select * from spoint10k where spoint_dwithin(star, spoint(1,1), .01)'); + explain +--------------------------------------------------------------------------------------------- + Index Scan using spoint10k_star_idx on spoint10k (rows=1 width=16) (actual rows=1 loops=1) + Index Cond: (star <@ '<(1 , 1) , 0.01>'::scircle) +(2 rows) + +select explain('select * from spoint10k where spoint_dwithin(spoint(1,1), star, 1)'); + explain +----------------------------------------------------------------------------------------------- + Bitmap Heap Scan on spoint10k (rows=2298 width=16) (actual rows=3009 loops=1) + Filter: spoint_dwithin('(1 , 1)'::spoint, star, '1'::double precision) + Rows Removed by Filter: 1560 + Heap Blocks: exact=55 + -> Bitmap Index Scan on spoint10k_star_idx (rows=2298 width=0) (actual rows=4569 loops=1) + Index Cond: (star <@ '<(1 , 1) , 1>'::scircle) +(6 rows) + +select explain('select * from spoint10k where spoint_dwithin(spoint(1,1), star, .1)'); + explain +------------------------------------------------------------------------------------------- + Bitmap Heap Scan on spoint10k (rows=25 width=16) (actual rows=29 loops=1) + Filter: spoint_dwithin('(1 , 1)'::spoint, star, '0.1'::double precision) + Rows Removed by Filter: 19 + Heap Blocks: exact=32 + -> Bitmap Index Scan on spoint10k_star_idx (rows=25 width=0) (actual rows=48 loops=1) + Index Cond: (star <@ '<(1 , 1) , 0.1>'::scircle) +(6 rows) + +select explain('select * from spoint10k where spoint_dwithin(spoint(1,1), star, .01)'); + explain +--------------------------------------------------------------------------------------------- + Index Scan using spoint10k_star_idx on spoint10k (rows=1 width=16) (actual rows=1 loops=1) + Index Cond: (star <@ '<(1 , 1) , 0.01>'::scircle) +(2 rows) + +select explain('select * from spoint10k a join spoint10k b on spoint_dwithin(a.star, b.star, 1)', do_analyze := 'false'); + explain +--------------------------------------------------------------------------------------- + Nested Loop (rows=22984885 width=32) + -> Seq Scan on spoint10k a (rows=10000 width=16) + -> Index Scan using spoint10k_star_idx on spoint10k b (rows=2298 width=16) + Index Cond: (star OPERATOR(public.<@) scircle(a.star, '1'::double precision)) +(4 rows) + +select explain('select * from spoint10k a join spoint10k b on spoint_dwithin(a.star, b.star, .1)'); + explain +----------------------------------------------------------------------------------------------------------- + Nested Loop (rows=249792 width=32) (actual rows=505342 loops=1) + -> Seq Scan on spoint10k a (rows=10000 width=16) (actual rows=10000 loops=1) + -> Index Scan using spoint10k_star_idx on spoint10k b (rows=25 width=16) (actual rows=51 loops=10000) + Index Cond: (star OPERATOR(public.<@) scircle(a.star, '0.1'::double precision)) + Rows Removed by Index Recheck: 31 +(5 rows) + +select explain('select * from spoint10k a join spoint10k b on spoint_dwithin(a.star, b.star, .01)'); + explain +--------------------------------------------------------------------------------------------------------- + Nested Loop (rows=2500 width=32) (actual rows=17614 loops=1) + -> Seq Scan on spoint10k a (rows=10000 width=16) (actual rows=10000 loops=1) + -> Index Scan using spoint10k_star_idx on spoint10k b (rows=1 width=16) (actual rows=2 loops=10000) + Index Cond: (star OPERATOR(public.<@) scircle(a.star, '0.01'::double precision)) + Rows Removed by Index Recheck: 1 +(5 rows) + +-- spoint_dwithin is symmetric in the first two arguments +select explain('select * from spoint10k a join spoint10k b on spoint_dwithin(a.star, b.star, .01) + where spoint_dwithin(a.star, spoint(1,1), .1)'); + explain +------------------------------------------------------------------------------------------------------ + Nested Loop (rows=6 width=32) (actual rows=33 loops=1) + -> Bitmap Heap Scan on spoint10k a (rows=25 width=16) (actual rows=29 loops=1) + Filter: spoint_dwithin(star, '(1 , 1)'::spoint, '0.1'::double precision) + Rows Removed by Filter: 19 + Heap Blocks: exact=32 + -> Bitmap Index Scan on spoint10k_star_idx (rows=25 width=0) (actual rows=48 loops=1) + Index Cond: (star <@ '<(1 , 1) , 0.1>'::scircle) + -> Index Scan using spoint10k_star_idx on spoint10k b (rows=1 width=16) (actual rows=1 loops=29) + Index Cond: (star OPERATOR(public.<@) scircle(a.star, '0.01'::double precision)) + Rows Removed by Index Recheck: 0 +(10 rows) + +select explain('select * from spoint10k a join spoint10k b on spoint_dwithin(b.star, a.star, .01) + where spoint_dwithin(a.star, spoint(1,1), .1)'); + explain +------------------------------------------------------------------------------------------------------ + Nested Loop (rows=6 width=32) (actual rows=33 loops=1) + -> Bitmap Heap Scan on spoint10k a (rows=25 width=16) (actual rows=29 loops=1) + Filter: spoint_dwithin(star, '(1 , 1)'::spoint, '0.1'::double precision) + Rows Removed by Filter: 19 + Heap Blocks: exact=32 + -> Bitmap Index Scan on spoint10k_star_idx (rows=25 width=0) (actual rows=48 loops=1) + Index Cond: (star <@ '<(1 , 1) , 0.1>'::scircle) + -> Index Scan using spoint10k_star_idx on spoint10k b (rows=1 width=16) (actual rows=1 loops=29) + Index Cond: (star OPERATOR(public.<@) scircle(a.star, '0.01'::double precision)) + Rows Removed by Index Recheck: 0 +(10 rows) + +-- both sides indexable, check if the planner figures out the better choice +select explain('select * from spoint10k a join spoint10k b on spoint_dwithin(a.star, b.star, .01) + where spoint_dwithin(a.star, spoint(1,1), .1) and spoint_dwithin(b.star, spoint(1,1), .05)'); + explain +------------------------------------------------------------------------------------------------------------------------------------- + Nested Loop (rows=1 width=32) (actual rows=16 loops=1) + -> Bitmap Heap Scan on spoint10k b (rows=6 width=16) (actual rows=12 loops=1) + Filter: spoint_dwithin(star, '(1 , 1)'::spoint, '0.05'::double precision) + Rows Removed by Filter: 4 + Heap Blocks: exact=14 + -> Bitmap Index Scan on spoint10k_star_idx (rows=6 width=0) (actual rows=16 loops=1) + Index Cond: (star <@ '<(1 , 1) , 0.05>'::scircle) + -> Index Scan using spoint10k_star_idx on spoint10k a (rows=1 width=16) (actual rows=1 loops=12) + Index Cond: ((star OPERATOR(public.<@) scircle(b.star, '0.01'::double precision)) AND (star <@ '<(1 , 1) , 0.1>'::scircle)) + Rows Removed by Index Recheck: 0 +(10 rows) + +select explain('select * from spoint10k a join spoint10k b on spoint_dwithin(a.star, b.star, .01) + where spoint_dwithin(a.star, spoint(1,1), .05) and spoint_dwithin(b.star, spoint(1,1), .1)'); + explain +------------------------------------------------------------------------------------------------------------------------------------- + Nested Loop (rows=1 width=32) (actual rows=16 loops=1) + -> Bitmap Heap Scan on spoint10k a (rows=6 width=16) (actual rows=12 loops=1) + Filter: spoint_dwithin(star, '(1 , 1)'::spoint, '0.05'::double precision) + Rows Removed by Filter: 4 + Heap Blocks: exact=14 + -> Bitmap Index Scan on spoint10k_star_idx (rows=6 width=0) (actual rows=16 loops=1) + Index Cond: (star <@ '<(1 , 1) , 0.05>'::scircle) + -> Index Scan using spoint10k_star_idx on spoint10k b (rows=1 width=16) (actual rows=1 loops=12) + Index Cond: ((star OPERATOR(public.<@) scircle(a.star, '0.01'::double precision)) AND (star <@ '<(1 , 1) , 0.1>'::scircle)) + Rows Removed by Index Recheck: 0 +(10 rows) + diff --git a/expected/index.out b/expected/index.out index 8c67155..eefa5c6 100644 --- a/expected/index.out +++ b/expected/index.out @@ -55,6 +55,7 @@ SELECT count(*) FROM spheretmp4 WHERE l && scircle '<(1,1),0.3>'; -- create idx CREATE TABLE spheretmp1b AS TABLE spheretmp1; +ANALYZE spheretmp1; CREATE INDEX aaaidx ON spheretmp1 USING gist ( p ); CREATE INDEX spoint3_idx ON spheretmp1b USING gist (p spoint3); CREATE INDEX bbbidx ON spheretmp2 USING gist ( c ); @@ -165,7 +166,6 @@ EXPLAIN (COSTS OFF) SELECT count(*) FROM spheretmp1b WHERE p = spoint '(3.09 , 1 4 (1 row) -SET enable_bitmapscan = ON; SET enable_indexonlyscan = OFF; EXPLAIN (COSTS OFF) SELECT count(*) FROM spheretmp1b WHERE p <@ scircle '<(1,1),0.3>'; QUERY PLAN diff --git a/expected/points.out b/expected/points.out index 6fb3c17..f3a0713 100644 --- a/expected/points.out +++ b/expected/points.out @@ -666,3 +666,19 @@ SELECT '( 0h 2m 30s , -90d 0m 0s)'::spoint<->'( 12h 2m 30s , -90d 0m 0s)'::spoin 0 (1 row) +-- spoint_dwithin function ---------- +SELECT a, b, radius, a <-> b AS "<->", spoint_dwithin(a, b, radius) +FROM (VALUES + ('(0, 0)'::spoint, '(0, 0)'::spoint, 0), + ('(0, 0)', '(0, 1)', 1), + ('(0, 0)', '(0.1, 0.1)', 0.14), + ('(0, 0)', '(0.1, 0.1)', 0.15) + ) sub (a, b, radius); + a | b | radius | <-> | spoint_dwithin +---------+-------------+--------+-----------------+---------------- + (0 , 0) | (0 , 0) | 0 | 0 | t + (0 , 0) | (0 , 1) | 1 | 1 | t + (0 , 0) | (0.1 , 0.1) | 0.14 | 0.1413032986961 | f + (0 , 0) | (0.1 , 0.1) | 0.15 | 0.1413032986961 | t +(4 rows) + diff --git a/expected/selectivity.out b/expected/selectivity.out new file mode 100644 index 0000000..e694f0f --- /dev/null +++ b/expected/selectivity.out @@ -0,0 +1,124 @@ +-- test selectivity estimator functions +create table spoint10k (star spoint); +insert into spoint10k select spoint(i, i*i) from generate_series(1, 10000) g(i); +create index on spoint10k using gist (star); +analyze spoint10k; +-- "explain analyze" wrapper that removes 'cost=...' since it varies across architectures +-- (we can't use "costs off" since that also removes the estimated row count) +create or replace function explain(query text, do_analyze text default 'true') returns setof text language plpgsql as $$ +declare + line text; +begin + for line in execute format('explain (analyze %s, timing off, summary off) %s', do_analyze, query) loop + return next regexp_replace(line, 'cost=\S+ ', ''); + end loop; + return; +end; +$$; +-- <@ operator selectivity +select explain('select * from spoint10k where star <@ scircle(spoint(1,1), 1)'); + explain +----------------------------------------------------------------------------------------------- + Bitmap Heap Scan on spoint10k (rows=2298 width=16) (actual rows=3009 loops=1) + Recheck Cond: (star <@ '<(1 , 1) , 1>'::scircle) + Rows Removed by Index Recheck: 1560 + Heap Blocks: exact=55 + -> Bitmap Index Scan on spoint10k_star_idx (rows=2298 width=0) (actual rows=4569 loops=1) + Index Cond: (star <@ '<(1 , 1) , 1>'::scircle) +(6 rows) + +select explain('select * from spoint10k where star <@ scircle(spoint(1,1), .1)'); + explain +------------------------------------------------------------------------------------------- + Bitmap Heap Scan on spoint10k (rows=25 width=16) (actual rows=29 loops=1) + Recheck Cond: (star <@ '<(1 , 1) , 0.1>'::scircle) + Rows Removed by Index Recheck: 19 + Heap Blocks: exact=32 + -> Bitmap Index Scan on spoint10k_star_idx (rows=25 width=0) (actual rows=48 loops=1) + Index Cond: (star <@ '<(1 , 1) , 0.1>'::scircle) +(6 rows) + +select explain('select * from spoint10k where star <@ scircle(spoint(1,1), .01)'); + explain +--------------------------------------------------------------------------------------------- + Index Scan using spoint10k_star_idx on spoint10k (rows=1 width=16) (actual rows=1 loops=1) + Index Cond: (star <@ '<(1 , 1) , 0.01>'::scircle) +(2 rows) + +select explain('select * from spoint10k where scircle(spoint(1,1), 1) @> star'); + explain +----------------------------------------------------------------------------------------------- + Bitmap Heap Scan on spoint10k (rows=2298 width=16) (actual rows=3009 loops=1) + Recheck Cond: ('<(1 , 1) , 1>'::scircle @> star) + Rows Removed by Index Recheck: 1560 + Heap Blocks: exact=55 + -> Bitmap Index Scan on spoint10k_star_idx (rows=2298 width=0) (actual rows=4569 loops=1) + Index Cond: (star <@ '<(1 , 1) , 1>'::scircle) +(6 rows) + +select explain('select * from spoint10k where scircle(spoint(1,1), .1) @> star'); + explain +------------------------------------------------------------------------------------------- + Bitmap Heap Scan on spoint10k (rows=25 width=16) (actual rows=29 loops=1) + Recheck Cond: ('<(1 , 1) , 0.1>'::scircle @> star) + Rows Removed by Index Recheck: 19 + Heap Blocks: exact=32 + -> Bitmap Index Scan on spoint10k_star_idx (rows=25 width=0) (actual rows=48 loops=1) + Index Cond: (star <@ '<(1 , 1) , 0.1>'::scircle) +(6 rows) + +select explain('select * from spoint10k where scircle(spoint(1,1), .01) @> star'); + explain +--------------------------------------------------------------------------------------------- + Index Scan using spoint10k_star_idx on spoint10k (rows=1 width=16) (actual rows=1 loops=1) + Index Cond: (star <@ '<(1 , 1) , 0.01>'::scircle) +(2 rows) + +select explain('select * from spoint10k where star !<@ scircle(spoint(1,1), 1)'); + explain +------------------------------------------------------------------------ + Seq Scan on spoint10k (rows=7702 width=16) (actual rows=6991 loops=1) + Filter: (star !<@ '<(1 , 1) , 1>'::scircle) + Rows Removed by Filter: 3009 +(3 rows) + +select explain('select * from spoint10k where star !<@ scircle(spoint(1,1), .1)'); + explain +------------------------------------------------------------------------ + Seq Scan on spoint10k (rows=9975 width=16) (actual rows=9971 loops=1) + Filter: (star !<@ '<(1 , 1) , 0.1>'::scircle) + Rows Removed by Filter: 29 +(3 rows) + +select explain('select * from spoint10k where star !<@ scircle(spoint(1,1), .01)'); + explain +------------------------------------------------------------------------- + Seq Scan on spoint10k (rows=10000 width=16) (actual rows=9999 loops=1) + Filter: (star !<@ '<(1 , 1) , 0.01>'::scircle) + Rows Removed by Filter: 1 +(3 rows) + +select explain('select * from spoint10k where scircle(spoint(1,1), 1) !@> star'); + explain +------------------------------------------------------------------------ + Seq Scan on spoint10k (rows=7702 width=16) (actual rows=6991 loops=1) + Filter: ('<(1 , 1) , 1>'::scircle !@> star) + Rows Removed by Filter: 3009 +(3 rows) + +select explain('select * from spoint10k where scircle(spoint(1,1), .1) !@> star'); + explain +------------------------------------------------------------------------ + Seq Scan on spoint10k (rows=9975 width=16) (actual rows=9971 loops=1) + Filter: ('<(1 , 1) , 0.1>'::scircle !@> star) + Rows Removed by Filter: 29 +(3 rows) + +select explain('select * from spoint10k where scircle(spoint(1,1), .01) !@> star'); + explain +------------------------------------------------------------------------- + Seq Scan on spoint10k (rows=10000 width=16) (actual rows=9999 loops=1) + Filter: ('<(1 , 1) , 0.01>'::scircle !@> star) + Rows Removed by Filter: 1 +(3 rows) + diff --git a/expected/selectivity_1.out b/expected/selectivity_1.out new file mode 100644 index 0000000..08cd8f7 --- /dev/null +++ b/expected/selectivity_1.out @@ -0,0 +1,124 @@ +-- test selectivity estimator functions +create table spoint10k (star spoint); +insert into spoint10k select spoint(i, i*i) from generate_series(1, 10000) g(i); +create index on spoint10k using gist (star); +analyze spoint10k; +-- "explain analyze" wrapper that removes 'cost=...' since it varies across architectures +-- (we can't use "costs off" since that also removes the estimated row count) +create or replace function explain(query text, do_analyze text default 'true') returns setof text language plpgsql as $$ +declare + line text; +begin + for line in execute format('explain (analyze %s, timing off, summary off) %s', do_analyze, query) loop + return next regexp_replace(line, 'cost=\S+ ', ''); + end loop; + return; +end; +$$; +-- <@ operator selectivity +select explain('select * from spoint10k where star <@ scircle(spoint(1,1), 1)'); + explain +----------------------------------------------------------------------------------------------- + Bitmap Heap Scan on spoint10k (rows=2298 width=16) (actual rows=3009 loops=1) + Recheck Cond: (star <@ '<(1 , 1) , 1>'::scircle) + Rows Removed by Index Recheck: 1560 + Heap Blocks: exact=55 + -> Bitmap Index Scan on spoint10k_star_idx (rows=2298 width=0) (actual rows=4569 loops=1) + Index Cond: (star <@ '<(1 , 1) , 1>'::scircle) +(6 rows) + +select explain('select * from spoint10k where star <@ scircle(spoint(1,1), .1)'); + explain +------------------------------------------------------------------------------------------- + Bitmap Heap Scan on spoint10k (rows=25 width=16) (actual rows=29 loops=1) + Recheck Cond: (star <@ '<(1 , 1) , 0.1>'::scircle) + Rows Removed by Index Recheck: 19 + Heap Blocks: exact=32 + -> Bitmap Index Scan on spoint10k_star_idx (rows=25 width=0) (actual rows=48 loops=1) + Index Cond: (star <@ '<(1 , 1) , 0.1>'::scircle) +(6 rows) + +select explain('select * from spoint10k where star <@ scircle(spoint(1,1), .01)'); + explain +--------------------------------------------------------------------------------------------- + Index Scan using spoint10k_star_idx on spoint10k (rows=1 width=16) (actual rows=1 loops=1) + Index Cond: (star <@ '<(1 , 1) , 0.01>'::scircle) +(2 rows) + +select explain('select * from spoint10k where scircle(spoint(1,1), 1) @> star'); + explain +----------------------------------------------------------------------------------------------- + Bitmap Heap Scan on spoint10k (rows=2298 width=16) (actual rows=3009 loops=1) + Recheck Cond: ('<(1 , 1) , 1>'::scircle @> star) + Rows Removed by Index Recheck: 1560 + Heap Blocks: exact=55 + -> Bitmap Index Scan on spoint10k_star_idx (rows=2298 width=0) (actual rows=4569 loops=1) + Index Cond: ('<(1 , 1) , 1>'::scircle @> star) +(6 rows) + +select explain('select * from spoint10k where scircle(spoint(1,1), .1) @> star'); + explain +------------------------------------------------------------------------------------------- + Bitmap Heap Scan on spoint10k (rows=25 width=16) (actual rows=29 loops=1) + Recheck Cond: ('<(1 , 1) , 0.1>'::scircle @> star) + Rows Removed by Index Recheck: 19 + Heap Blocks: exact=32 + -> Bitmap Index Scan on spoint10k_star_idx (rows=25 width=0) (actual rows=48 loops=1) + Index Cond: ('<(1 , 1) , 0.1>'::scircle @> star) +(6 rows) + +select explain('select * from spoint10k where scircle(spoint(1,1), .01) @> star'); + explain +--------------------------------------------------------------------------------------------- + Index Scan using spoint10k_star_idx on spoint10k (rows=1 width=16) (actual rows=1 loops=1) + Index Cond: ('<(1 , 1) , 0.01>'::scircle @> star) +(2 rows) + +select explain('select * from spoint10k where star !<@ scircle(spoint(1,1), 1)'); + explain +------------------------------------------------------------------------ + Seq Scan on spoint10k (rows=7702 width=16) (actual rows=6991 loops=1) + Filter: (star !<@ '<(1 , 1) , 1>'::scircle) + Rows Removed by Filter: 3009 +(3 rows) + +select explain('select * from spoint10k where star !<@ scircle(spoint(1,1), .1)'); + explain +------------------------------------------------------------------------ + Seq Scan on spoint10k (rows=9975 width=16) (actual rows=9971 loops=1) + Filter: (star !<@ '<(1 , 1) , 0.1>'::scircle) + Rows Removed by Filter: 29 +(3 rows) + +select explain('select * from spoint10k where star !<@ scircle(spoint(1,1), .01)'); + explain +------------------------------------------------------------------------- + Seq Scan on spoint10k (rows=10000 width=16) (actual rows=9999 loops=1) + Filter: (star !<@ '<(1 , 1) , 0.01>'::scircle) + Rows Removed by Filter: 1 +(3 rows) + +select explain('select * from spoint10k where scircle(spoint(1,1), 1) !@> star'); + explain +------------------------------------------------------------------------ + Seq Scan on spoint10k (rows=7702 width=16) (actual rows=6991 loops=1) + Filter: ('<(1 , 1) , 1>'::scircle !@> star) + Rows Removed by Filter: 3009 +(3 rows) + +select explain('select * from spoint10k where scircle(spoint(1,1), .1) !@> star'); + explain +------------------------------------------------------------------------ + Seq Scan on spoint10k (rows=9975 width=16) (actual rows=9971 loops=1) + Filter: ('<(1 , 1) , 0.1>'::scircle !@> star) + Rows Removed by Filter: 29 +(3 rows) + +select explain('select * from spoint10k where scircle(spoint(1,1), .01) !@> star'); + explain +------------------------------------------------------------------------- + Seq Scan on spoint10k (rows=10000 width=16) (actual rows=9999 loops=1) + Filter: ('<(1 , 1) , 0.01>'::scircle !@> star) + Rows Removed by Filter: 1 +(3 rows) + diff --git a/pgs_circle_sel.sql.in b/pgs_circle_sel.sql.in new file mode 100644 index 0000000..d1e9c7e --- /dev/null +++ b/pgs_circle_sel.sql.in @@ -0,0 +1,109 @@ +CREATE FUNCTION spoint_contained_by_circle_sel(internal, oid, internal, integer) + RETURNS double precision + AS 'MODULE_PATHNAME' , 'spherepoint_in_circle_sel' + LANGUAGE C + IMMUTABLE STRICT PARALLEL SAFE; + +COMMENT ON FUNCTION spoint_contained_by_circle_sel(internal, oid, internal, integer) IS + 'selectivity estimator function for spoint_contained_by_circle'; + +CREATE FUNCTION spoint_contained_by_circle_joinsel(internal, oid, internal, smallint, internal) + RETURNS double precision + AS 'MODULE_PATHNAME' , 'spherepoint_in_circle_joinsel' + LANGUAGE C + IMMUTABLE STRICT PARALLEL SAFE; + +COMMENT ON FUNCTION spoint_contained_by_circle_joinsel(internal, oid, internal, smallint, internal) IS + 'join selectivity estimator function for spoint_contained_by_circle'; + + +CREATE FUNCTION spoint_contained_by_circle_neg_sel(internal, oid, internal, integer) + RETURNS double precision + AS 'MODULE_PATHNAME' , 'spherepoint_in_circle_neg_sel' + LANGUAGE C + IMMUTABLE STRICT PARALLEL SAFE; + +COMMENT ON FUNCTION spoint_contained_by_circle_neg_sel(internal, oid, internal, integer) IS + 'selectivity estimator function for spoint_contained_by_circle_neg'; + +CREATE FUNCTION spoint_contained_by_circle_neg_joinsel(internal, oid, internal, smallint, internal) + RETURNS double precision + AS 'MODULE_PATHNAME' , 'spherepoint_in_circle_neg_joinsel' + LANGUAGE C + IMMUTABLE STRICT PARALLEL SAFE; + +COMMENT ON FUNCTION spoint_contained_by_circle_neg_joinsel(internal, oid, internal, smallint, internal) IS + 'join selectivity estimator function for spoint_contained_by_circle_neg'; + + +CREATE FUNCTION spoint_contained_by_circle_com_sel(internal, oid, internal, integer) + RETURNS double precision + AS 'MODULE_PATHNAME' , 'spherepoint_in_circle_com_sel' + LANGUAGE C + IMMUTABLE STRICT PARALLEL SAFE; + +COMMENT ON FUNCTION spoint_contained_by_circle_com_sel(internal, oid, internal, integer) IS + 'selectivity estimator function for spoint_contained_by_circle_com'; + +CREATE FUNCTION spoint_contained_by_circle_com_joinsel(internal, oid, internal, smallint, internal) + RETURNS double precision + AS 'MODULE_PATHNAME' , 'spherepoint_in_circle_com_joinsel' + LANGUAGE C + IMMUTABLE STRICT PARALLEL SAFE; + +COMMENT ON FUNCTION spoint_contained_by_circle_com_joinsel(internal, oid, internal, smallint, internal) IS + 'join selectivity estimator function for spoint_contained_by_circle_com'; + + +CREATE FUNCTION spoint_contained_by_circle_com_neg_sel(internal, oid, internal, integer) + RETURNS double precision + AS 'MODULE_PATHNAME' , 'spherepoint_in_circle_com_neg_sel' + LANGUAGE C + IMMUTABLE STRICT PARALLEL SAFE; + +COMMENT ON FUNCTION spoint_contained_by_circle_com_neg_sel(internal, oid, internal, integer) IS + 'selectivity estimator function for spoint_contained_by_circle_com_neg'; + +CREATE FUNCTION spoint_contained_by_circle_com_neg_joinsel(internal, oid, internal, smallint, internal) + RETURNS double precision + AS 'MODULE_PATHNAME' , 'spherepoint_in_circle_com_neg_joinsel' + LANGUAGE C + IMMUTABLE STRICT PARALLEL SAFE; + +COMMENT ON FUNCTION spoint_contained_by_circle_com_neg_joinsel(internal, oid, internal, smallint, internal) IS + 'join selectivity estimator function for spoint_contained_by_circle_com_neg'; + + +ALTER OPERATOR @> (scircle, spoint) +SET ( + RESTRICT = spoint_contained_by_circle_com_sel, + JOIN = spoint_contained_by_circle_com_joinsel +); + +ALTER OPERATOR <@ (spoint, scircle) +SET ( + RESTRICT = spoint_contained_by_circle_sel, + JOIN = spoint_contained_by_circle_joinsel +); + +ALTER OPERATOR !@> (scircle, spoint) +SET ( + RESTRICT = spoint_contained_by_circle_com_neg_sel, + JOIN = spoint_contained_by_circle_com_neg_joinsel +); + +ALTER OPERATOR !<@ (spoint, scircle) +SET ( + RESTRICT = spoint_contained_by_circle_neg_sel, + JOIN = spoint_contained_by_circle_neg_joinsel +); + + +CREATE FUNCTION spoint_dwithin(spoint, spoint, float8) + RETURNS boolean + AS 'MODULE_PATHNAME', 'spherepoint_dwithin' + LANGUAGE C + IMMUTABLE STRICT PARALLEL SAFE; + +COMMENT ON FUNCTION spoint_dwithin(spoint, spoint, float8) IS + 'predicate matching spherical points less than a given distance apart'; diff --git a/pgs_gist_support.sql.in b/pgs_gist_support.sql.in new file mode 100644 index 0000000..97b4059 --- /dev/null +++ b/pgs_gist_support.sql.in @@ -0,0 +1,12 @@ +-- PG12+ has support functions + +CREATE FUNCTION spoint_dwithin_supportfn (internal) + RETURNS internal + AS 'MODULE_PATHNAME', 'spherepoint_dwithin_supportfn' + LANGUAGE 'c'; + +COMMENT ON FUNCTION spoint_dwithin_supportfn(internal) IS + 'support function for spoint_dwithin'; + +ALTER FUNCTION spoint_dwithin(spoint, spoint, float8) + SUPPORT spoint_dwithin_supportfn; diff --git a/sql/gist_support.sql b/sql/gist_support.sql new file mode 100644 index 0000000..361b3d6 --- /dev/null +++ b/sql/gist_support.sql @@ -0,0 +1,26 @@ +-- spoint_dwithin function selectivity +set jit = off; -- suppress extra planning output + +select explain('select * from spoint10k where spoint_dwithin(star, spoint(1,1), 1)'); +select explain('select * from spoint10k where spoint_dwithin(star, spoint(1,1), .1)'); +select explain('select * from spoint10k where spoint_dwithin(star, spoint(1,1), .01)'); + +select explain('select * from spoint10k where spoint_dwithin(spoint(1,1), star, 1)'); +select explain('select * from spoint10k where spoint_dwithin(spoint(1,1), star, .1)'); +select explain('select * from spoint10k where spoint_dwithin(spoint(1,1), star, .01)'); + +select explain('select * from spoint10k a join spoint10k b on spoint_dwithin(a.star, b.star, 1)', do_analyze := 'false'); +select explain('select * from spoint10k a join spoint10k b on spoint_dwithin(a.star, b.star, .1)'); +select explain('select * from spoint10k a join spoint10k b on spoint_dwithin(a.star, b.star, .01)'); + +-- spoint_dwithin is symmetric in the first two arguments +select explain('select * from spoint10k a join spoint10k b on spoint_dwithin(a.star, b.star, .01) + where spoint_dwithin(a.star, spoint(1,1), .1)'); +select explain('select * from spoint10k a join spoint10k b on spoint_dwithin(b.star, a.star, .01) + where spoint_dwithin(a.star, spoint(1,1), .1)'); + +-- both sides indexable, check if the planner figures out the better choice +select explain('select * from spoint10k a join spoint10k b on spoint_dwithin(a.star, b.star, .01) + where spoint_dwithin(a.star, spoint(1,1), .1) and spoint_dwithin(b.star, spoint(1,1), .05)'); +select explain('select * from spoint10k a join spoint10k b on spoint_dwithin(a.star, b.star, .01) + where spoint_dwithin(a.star, spoint(1,1), .05) and spoint_dwithin(b.star, spoint(1,1), .1)'); diff --git a/sql/index.sql b/sql/index.sql index fb3730a..8713106 100644 --- a/sql/index.sql +++ b/sql/index.sql @@ -24,6 +24,7 @@ SELECT count(*) FROM spheretmp4 WHERE l && scircle '<(1,1),0.3>'; -- create idx CREATE TABLE spheretmp1b AS TABLE spheretmp1; +ANALYZE spheretmp1; CREATE INDEX aaaidx ON spheretmp1 USING gist ( p ); @@ -69,7 +70,6 @@ EXPLAIN (COSTS OFF) SELECT count(*) FROM spheretmp1b WHERE p <@ scircle '<(1,1), EXPLAIN (COSTS OFF) SELECT count(*) FROM spheretmp1b WHERE p = spoint '(3.09 , 1.25)'; SELECT count(*) FROM spheretmp1b WHERE p = spoint '(3.09 , 1.25)'; -SET enable_bitmapscan = ON; SET enable_indexonlyscan = OFF; EXPLAIN (COSTS OFF) SELECT count(*) FROM spheretmp1b WHERE p <@ scircle '<(1,1),0.3>'; diff --git a/sql/points.sql b/sql/points.sql index 5e63260..b34ae6e 100644 --- a/sql/points.sql +++ b/sql/points.sql @@ -240,3 +240,12 @@ SELECT '( 0h 2m 30s , 90d 0m 0s)'::spoint<->'( 12h 2m 30s , 90d 0m 0s)'::spoint; SELECT '( 0h 2m 30s , -90d 0m 0s)'::spoint<->'( 12h 2m 30s , -90d 0m 0s)'::spoint; +-- spoint_dwithin function ---------- + +SELECT a, b, radius, a <-> b AS "<->", spoint_dwithin(a, b, radius) +FROM (VALUES + ('(0, 0)'::spoint, '(0, 0)'::spoint, 0), + ('(0, 0)', '(0, 1)', 1), + ('(0, 0)', '(0.1, 0.1)', 0.14), + ('(0, 0)', '(0.1, 0.1)', 0.15) + ) sub (a, b, radius); diff --git a/sql/selectivity.sql b/sql/selectivity.sql new file mode 100644 index 0000000..d0f1d6e --- /dev/null +++ b/sql/selectivity.sql @@ -0,0 +1,36 @@ +-- test selectivity estimator functions + +create table spoint10k (star spoint); +insert into spoint10k select spoint(i, i*i) from generate_series(1, 10000) g(i); +create index on spoint10k using gist (star); +analyze spoint10k; + +-- "explain analyze" wrapper that removes 'cost=...' since it varies across architectures +-- (we can't use "costs off" since that also removes the estimated row count) +create or replace function explain(query text, do_analyze text default 'true') returns setof text language plpgsql as $$ +declare + line text; +begin + for line in execute format('explain (analyze %s, timing off, summary off) %s', do_analyze, query) loop + return next regexp_replace(line, 'cost=\S+ ', ''); + end loop; + return; +end; +$$; + +-- <@ operator selectivity +select explain('select * from spoint10k where star <@ scircle(spoint(1,1), 1)'); +select explain('select * from spoint10k where star <@ scircle(spoint(1,1), .1)'); +select explain('select * from spoint10k where star <@ scircle(spoint(1,1), .01)'); + +select explain('select * from spoint10k where scircle(spoint(1,1), 1) @> star'); +select explain('select * from spoint10k where scircle(spoint(1,1), .1) @> star'); +select explain('select * from spoint10k where scircle(spoint(1,1), .01) @> star'); + +select explain('select * from spoint10k where star !<@ scircle(spoint(1,1), 1)'); +select explain('select * from spoint10k where star !<@ scircle(spoint(1,1), .1)'); +select explain('select * from spoint10k where star !<@ scircle(spoint(1,1), .01)'); + +select explain('select * from spoint10k where scircle(spoint(1,1), 1) !@> star'); +select explain('select * from spoint10k where scircle(spoint(1,1), .1) !@> star'); +select explain('select * from spoint10k where scircle(spoint(1,1), .01) !@> star'); diff --git a/src/circle.c b/src/circle.c index e28fe0c..577ac3c 100644 --- a/src/circle.c +++ b/src/circle.c @@ -391,7 +391,7 @@ spherecircle_area(PG_FUNCTION_ARGS) { SCIRCLE *c = (SCIRCLE *) PG_GETARG_POINTER(0); - PG_RETURN_FLOAT8(PID * (1 - cos(c->radius))); + PG_RETURN_FLOAT8(spherecircle_area_float(c->radius)); } Datum diff --git a/src/circle_sel.c b/src/circle_sel.c new file mode 100644 index 0000000..d7bd843 --- /dev/null +++ b/src/circle_sel.c @@ -0,0 +1,218 @@ +#include "circle.h" +#include +#include + +/* Circle selectivity functions */ + +PG_FUNCTION_INFO_V1(spherepoint_in_circle_sel); +PG_FUNCTION_INFO_V1(spherepoint_in_circle_joinsel); +PG_FUNCTION_INFO_V1(spherepoint_in_circle_neg_sel); +PG_FUNCTION_INFO_V1(spherepoint_in_circle_neg_joinsel); +PG_FUNCTION_INFO_V1(spherepoint_in_circle_com_sel); +PG_FUNCTION_INFO_V1(spherepoint_in_circle_com_joinsel); +PG_FUNCTION_INFO_V1(spherepoint_in_circle_com_neg_sel); +PG_FUNCTION_INFO_V1(spherepoint_in_circle_com_neg_joinsel); + +/* + * Common code for spherepoint_in_circle_sel() + */ +static double +spherepoint_in_circle_sel_funcexpr(Node *other) +{ + FuncExpr *ofunc = (FuncExpr *)other; + char *func_name = get_func_name(ofunc->funcid); + Const *arg2; + double radius; + double selec; + + /* + * Safety checks: are we called on a function called scircle that takes a + * const double as 2nd argument? + */ + if (strcmp(func_name, "scircle") != 0) + { + ereport(DEBUG1, (errmsg("<@ selectivity called on function that is not scircle"))); + return DEFAULT_SCIRCLE_SEL; + } + if (list_length(ofunc->args) != 2) + { + ereport(DEBUG1, (errmsg("<@ selectivity called on function that does not have 2 arguments"))); + return DEFAULT_SCIRCLE_SEL; + } + if (!IsA(lsecond(ofunc->args), Const)) + { + ereport(DEBUG1, (errmsg("<@ selectivity called on scircle() with non-const 2nd arg"))); + return DEFAULT_SCIRCLE_SEL; + } + arg2 = (Const *) lsecond(ofunc->args); + if (arg2->consttype != FLOAT8OID) + { + ereport(DEBUG1, (errmsg("<@ selectivity called on scircle() with non-float8 2nd arg"))); + return DEFAULT_SCIRCLE_SEL; + } + + radius = DatumGetFloat8(arg2->constvalue); + selec = spherecircle_area_float(radius) / SPHERE_SURFACE; + CLAMP_PROBABILITY(selec); + + return selec; +} + +static double +spherepoint_in_circle_sel_internal(PG_FUNCTION_ARGS, bool commute, bool negate) +{ + PlannerInfo *root = (PlannerInfo *) PG_GETARG_POINTER(0); + Oid operator = PG_GETARG_OID(1); + List *args = (List *) PG_GETARG_POINTER(2); + int varRelid = PG_GETARG_INT32(3); + //Oid collation = PG_GET_COLLATION(); + VariableStatData vardata; + Node *other; + bool varonleft; + double selec; + + /* + * When asked about <>, we do the estimation using the corresponding = + * operator, then convert to <> via "1.0 - eq_selectivity - nullfrac". + */ + if (negate) + { + operator = get_negator(operator); + if (!OidIsValid(operator)) + { + /* Use default selectivity (should we raise an error instead?) */ + return 1.0 - DEFAULT_SCIRCLE_SEL; + } + } + + /* + * If expression is not variable = something or something = variable, then + * punt and return a default estimate. + */ + if (!get_restriction_variable(root, args, varRelid, + &vardata, &other, &varonleft)) + return negate ? (1.0 - DEFAULT_SCIRCLE_SEL) : DEFAULT_SCIRCLE_SEL; + + /* + * We can do a lot better if the something is a constant. (Note: the + * Const might result from estimation rather than being a simple constant + * in the query.) + * Look only at var op circle_const, not var op point_const. + */ + if (IsA(other, Const) && varonleft != commute) + { + Const *constnode = (Const *) other; + SCIRCLE *c; + + Assert(!constnode->constisnull); /* operators are strict, shouldn't have NULLs here */ + c = (SCIRCLE *) constnode->constvalue; + selec = spherecircle_area_float(c->radius) / SPHERE_SURFACE; + CLAMP_PROBABILITY(selec); + } + /* + * Check for <@ scircle(..., radius) + */ + else if (IsA(other, FuncExpr) && varonleft != commute) + { + selec = spherepoint_in_circle_sel_funcexpr(other); + // p *((double * )&((*(Const *)((((FuncExpr*) other)->args->elements)[1].ptr_value)).constvalue)) + } + else + { + ereport(DEBUG1, (errmsg("<@ selectivity not const, other node tag %i", other->type))); + selec = DEFAULT_SCIRCLE_SEL; + } + + ReleaseVariableStats(vardata); + + return negate ? (1.0 - selec) : selec; +} + +/* + * Common code for spherepoint_in_circle_joinsel() + */ +static double +spherepoint_in_circle_joinsel_internal(PG_FUNCTION_ARGS, bool commute) +{ +#ifdef NOT_USED + PlannerInfo *root = (PlannerInfo *) PG_GETARG_POINTER(0); + Oid operator = PG_GETARG_OID(1); + List *args = (List *) PG_GETARG_POINTER(2); + + JoinType jointype = (JoinType) PG_GETARG_INT16(3); + SpecialJoinInfo *sjinfo = (SpecialJoinInfo *) PG_GETARG_POINTER(4); + Oid collation = PG_GET_COLLATION(); + double selec; + double selec_inner; + VariableStatData vardata1; + VariableStatData vardata2; + double nd1; + double nd2; + bool isdefault1; + bool isdefault2; + Oid opfuncoid; + AttStatsSlot sslot1; + AttStatsSlot sslot2; + bool join_is_reversed; + RelOptInfo *inner_rel; + + get_join_variables(root, args, sjinfo, + &vardata1, &vardata2, &join_is_reversed); + + ReleaseVariableStats(vardata1); + ReleaseVariableStats(vardata2); +#endif + + /* return a constant default for now; practically joins should use the + * spoint_dwithin function instead which has join support with the + * additional advantage that it's symmetric */ + return DEFAULT_SCIRCLE_SEL; +} + +Datum +spherepoint_in_circle_sel(PG_FUNCTION_ARGS) +{ + PG_RETURN_FLOAT8(spherepoint_in_circle_sel_internal(fcinfo, false, false)); +} + +Datum +spherepoint_in_circle_joinsel(PG_FUNCTION_ARGS) +{ + PG_RETURN_FLOAT8(spherepoint_in_circle_joinsel_internal(fcinfo, false)); +} + +Datum +spherepoint_in_circle_neg_sel(PG_FUNCTION_ARGS) +{ + PG_RETURN_FLOAT8(spherepoint_in_circle_sel_internal(fcinfo, false, true)); +} + +Datum +spherepoint_in_circle_neg_joinsel(PG_FUNCTION_ARGS) +{ + PG_RETURN_FLOAT8(DEFAULT_INEQ_SEL); +} + +Datum +spherepoint_in_circle_com_sel(PG_FUNCTION_ARGS) +{ + PG_RETURN_FLOAT8(spherepoint_in_circle_sel_internal(fcinfo, true, false)); +} + +Datum +spherepoint_in_circle_com_joinsel(PG_FUNCTION_ARGS) +{ + PG_RETURN_FLOAT8(spherepoint_in_circle_joinsel_internal(fcinfo, true)); +} + +Datum +spherepoint_in_circle_com_neg_sel(PG_FUNCTION_ARGS) +{ + PG_RETURN_FLOAT8(spherepoint_in_circle_sel_internal(fcinfo, true, true)); +} + +Datum +spherepoint_in_circle_com_neg_joinsel(PG_FUNCTION_ARGS) +{ + PG_RETURN_FLOAT8(DEFAULT_INEQ_SEL); +} diff --git a/src/gist_support.c b/src/gist_support.c new file mode 100644 index 0000000..95aa65c --- /dev/null +++ b/src/gist_support.c @@ -0,0 +1,223 @@ +/********************************************************************** + * + * pgsphere gist_support.c + * based on gserialized_supportfn.c from PostGIS + * + * PostGIS - Spatial Types for PostgreSQL + * http://postgis.net + * + * PostGIS is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 2 of the License, or + * (at your option) any later version. + * + * PostGIS is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with PostGIS. If not, see . + * + **********************************************************************/ + + +/* PostgreSQL */ +#include "postgres.h" +#if PG_VERSION_NUM >= 120000 +#include "funcapi.h" +#include "access/htup_details.h" +#include "access/stratnum.h" +#include "catalog/namespace.h" +#include "catalog/pg_opfamily.h" +#include "catalog/pg_type_d.h" +#include "catalog/pg_am_d.h" +#include "nodes/supportnodes.h" +#include "nodes/nodeFuncs.h" +#include "nodes/makefuncs.h" +#include "optimizer/optimizer.h" +#include "parser/parse_func.h" +#include "parser/parse_type.h" +#include "utils/array.h" +#include "utils/builtins.h" +#include "utils/lsyscache.h" +#include "utils/numeric.h" +#include "utils/selfuncs.h" +#include "utils/syscache.h" + +#include "point.h" +#include "circle.h" + +static Oid +scircleTypeOid(Oid callingfunc) +{ + /* type must be in same namespace as the caller */ + char *nspname = get_namespace_name(get_func_namespace(callingfunc)); + List *type_name_list = list_make2(makeString(nspname), makeString("scircle")); + TypeName *type_name = makeTypeNameFromNameList(type_name_list); + Oid type_oid = LookupTypeNameOid(NULL, type_name, true); + if (type_oid == InvalidOid) + elog(ERROR, "%s: unable to lookup type 'scircle'", __func__); + return type_oid; +} + +static Oid +scircleFunctionOid(Oid geotype, Oid callingfunc) +{ + const Oid radiustype = FLOAT8OID; /* Should always be FLOAT8OID */ + const Oid scircle_function_args[2] = {geotype, radiustype}; + const bool noError = true; + /* Expand function must be in same namespace as the caller */ + char *nspname = get_namespace_name(get_func_namespace(callingfunc)); + List *scircle_function_name = list_make2(makeString(nspname), makeString("scircle")); + Oid scircle_function_oid = LookupFuncName(scircle_function_name, 2, scircle_function_args, noError); + if (scircle_function_oid == InvalidOid) + elog(ERROR, "%s: unable to lookup 'scircle(Oid[%u], Oid[%u])'", __func__, geotype, radiustype); + return scircle_function_oid; +} + +PG_FUNCTION_INFO_V1(spherepoint_dwithin_supportfn); +Datum spherepoint_dwithin_supportfn(PG_FUNCTION_ARGS) +{ + Node *rawreq = (Node *) PG_GETARG_POINTER(0); + Node *ret = NULL; + + if (IsA(rawreq, SupportRequestSelectivity)) + { + SupportRequestSelectivity *req = (SupportRequestSelectivity *) rawreq; + Node *radiusarg = (Node *) list_nth(req->args, 2); + float8 selec; + ereport(DEBUG1, (errmsg("spherepoint_dwithin_supportfn sel called on %d", req->funcid))); + + /* + * If the radius is a constant, compute the circle constant. + */ + if (IsA(radiusarg, Const)) + { + Const *constarg = (Const *) radiusarg; + float8 radius = DatumGetFloat8(constarg->constvalue); + selec = spherecircle_area_float(radius) / SPHERE_SURFACE; + ereport(DEBUG1, (errmsg("spherepoint_dwithin_supportfn const radius %g", radius))); + } + else + { + selec = DEFAULT_SCIRCLE_SEL; + ereport(DEBUG1, (errmsg("spherepoint_dwithin_supportfn non-const radius"))); + } + + if (req->is_join) + { + req->selectivity = selec; + } + else + { + req->selectivity = selec; + } + CLAMP_PROBABILITY(req->selectivity); + ereport(DEBUG1, (errmsg("spherepoint_dwithin_supportfn selectivity %g is_join %d", req->selectivity, req->is_join))); + ret = rawreq; + } + + else if (IsA(rawreq, SupportRequestIndexCondition)) + { + SupportRequestIndexCondition *req = (SupportRequestIndexCondition *) rawreq; + + FuncExpr *clause = (FuncExpr *) req->node; + Oid funcid = clause->funcid; + Oid opfamilyoid = req->opfamily; /* OPERATOR FAMILY of the index */ + + Node *leftarg, *rightarg, *radiusarg; + Oid leftdatatype, oproid; + + Oid scircle_type_oid = scircleTypeOid(funcid); + Expr *scircle_expr; + Expr *expr; + + /* + * Extract "leftarg" as the arg matching the index and "rightarg" as + * the other, even if they were in the opposite order in the call. + */ + if (req->indexarg == 0) + { + leftarg = linitial(clause->args); + rightarg = lsecond(clause->args); + } + else if (req->indexarg == 1) + { + rightarg = linitial(clause->args); + leftarg = lsecond(clause->args); + } + else + PG_RETURN_POINTER((Node *)NULL); + + leftdatatype = exprType(leftarg); + Assert(leftdatatype == exprType(rightarg)); /* expect spoint, spoint */ + + radiusarg = (Node *) list_nth(clause->args, 2); + + /* + * Given the index operator family and the arguments and the desired + * strategy number we can now lookup the operator we want. + */ + oproid = get_opfamily_member(opfamilyoid, + leftdatatype, + scircle_type_oid, + 37); /* spoint <@ scircle */ + if (!OidIsValid(oproid)) + elog(ERROR, + "no spatial operator found for '%s': opfamily %u types %d %d strategy %d", + "scircle", + opfamilyoid, + leftdatatype, + scircle_type_oid, + 37); + + /* + * If both the right argument and the radius are a constant, compute + * the circle constant. (makeFuncExpr won't constify by itself + * unfortunately.) + */ + if (IsA(rightarg, Const) && IsA(radiusarg, Const)) + { + Datum center = ((Const *) rightarg)->constvalue; + Datum radius = ((Const *) radiusarg)->constvalue; + Datum circle = DirectFunctionCall2(spherecircle_by_center, center, radius); + scircle_expr = (Expr *) makeConst(scircle_type_oid, -1, InvalidOid, + sizeof(SCIRCLE), circle, false, false); + ereport(DEBUG1, (errmsg("spherepoint_dwithin_supportfn index condition const"))); + } + else + { + Oid scircle_function_oid = scircleFunctionOid(leftdatatype, clause->funcid); + scircle_expr = (Expr *) makeFuncExpr(scircle_function_oid, leftdatatype, + list_make2(rightarg, radiusarg), + InvalidOid, InvalidOid, COERCE_EXPLICIT_CALL); + ereport(DEBUG1, (errmsg("spherepoint_dwithin_supportfn index condition function"))); + } + + /* + * The comparison expression has to be a pseudo constant, + * (not volatile or dependent on the target index table) + */ +#if PG_VERSION_NUM >= 140000 + if (!is_pseudo_constant_for_index(req->root, (Node*)scircle_expr, req->index)) +#else + if (!is_pseudo_constant_for_index((Node*)scircle_expr, req->index)) +#endif + PG_RETURN_POINTER((Node*)NULL); + + /* OK, we can make an index expression */ + expr = make_opclause(oproid, BOOLOID, false, + (Expr *) leftarg, scircle_expr, + InvalidOid, InvalidOid); + + ret = (Node *)(list_make1(expr)); + + /* This is an exact index lookup */ + req->lossy = false; + } + + PG_RETURN_POINTER(ret); +} + +#endif /* PG_VERSION_NUM */ diff --git a/src/pgs_util.h b/src/pgs_util.h index b79170b..1b3ad76 100644 --- a/src/pgs_util.h +++ b/src/pgs_util.h @@ -14,6 +14,10 @@ #endif #define EPSILON 1.0E-09 /* precision of floating point values */ +/* spherical circle constants */ +#define SPHERE_SURFACE (4 * PI) +#define DEFAULT_SCIRCLE_SEL 1e-7 + /* convert pg_sphere theta [pi/2 .. -pi/2] to healpix theta [0 .. pi] ([north .. south pole]) */ static inline double conv_theta(double x) @@ -31,4 +35,13 @@ static inline double deg_to_rad(double in) return in * PI / 180; } +/* + * Area of circle on sphere + */ +static inline double +spherecircle_area_float(double radius) +{ + return PID * (1 - cos(radius)); +} + #endif diff --git a/src/point.c b/src/point.c index 0cbfa00..498ee5e 100644 --- a/src/point.c +++ b/src/point.c @@ -8,6 +8,7 @@ PG_FUNCTION_INFO_V1(spherepoint_in); PG_FUNCTION_INFO_V1(spherepoint_from_long_lat); PG_FUNCTION_INFO_V1(spherepoint_from_long_lat_deg); PG_FUNCTION_INFO_V1(spherepoint_distance); +PG_FUNCTION_INFO_V1(spherepoint_dwithin); PG_FUNCTION_INFO_V1(spherepoint_long); PG_FUNCTION_INFO_V1(spherepoint_lat); PG_FUNCTION_INFO_V1(spherepoint_x); @@ -223,6 +224,17 @@ spherepoint_distance(PG_FUNCTION_ARGS) } +Datum +spherepoint_dwithin(PG_FUNCTION_ARGS) +{ + SPoint *p1 = (SPoint *) PG_GETARG_POINTER(0); + SPoint *p2 = (SPoint *) PG_GETARG_POINTER(1); + float8 within = PG_GETARG_FLOAT8(2); + float8 dist = spoint_dist(p1, p2); + + PG_RETURN_BOOL(FPle(dist, within)); +} + Datum spherepoint_long(PG_FUNCTION_ARGS) { From 24daa229ab48f8cd4fa4099c72c5bede6ee01bb7 Mon Sep 17 00:00:00 2001 From: Christoph Berg Date: Mon, 23 Oct 2023 12:23:03 +0200 Subject: [PATCH 48/87] Maintain only one list of tests Make evaluates "=" variables lazily, so we can add items to TESTS later in the file and still have them show up in REGRESS. --- Makefile | 14 +++++--------- 1 file changed, 5 insertions(+), 9 deletions(-) diff --git a/Makefile b/Makefile index 1e9805f..6c648d9 100644 --- a/Makefile +++ b/Makefile @@ -33,13 +33,10 @@ DATA_built = $(RELEASE_SQL) \ pg_sphere--1.3.1--1.3.2.sql DOCS = README.pg_sphere COPYRIGHT.pg_sphere -REGRESS = init tables points euler circle line ellipse poly path box index \ - contains_ops contains_ops_compat bounding_box_gist gnomo epochprop \ - contains overlaps spoint_brin sbox_brin selectivity - -TESTS = init_test tables points euler circle line ellipse poly path box \ +TESTS = tables points euler circle line ellipse poly path box \ index contains_ops contains_ops_compat bounding_box_gist gnomo \ epochprop contains overlaps spoint_brin sbox_brin selectivity +REGRESS = init $(TESTS) PG_CFLAGS += -DPGSPHERE_VERSION=$(PGSPHERE_VERSION) PG_CPPFLAGS += -DPGSPHERE_VERSION=$(PGSPHERE_VERSION) @@ -61,7 +58,6 @@ PGS_SQL = pgs_types.sql pgs_point.sql pgs_euler.sql pgs_circle.sql \ pgs_gist.sql gnomo.sql pgs_brin.sql pgs_circle_sel.sql ifneq ($(USE_HEALPIX),0) -REGRESS += healpix moc moc1 moc100 mocautocast TESTS += healpix moc moc1 moc100 mocautocast PGS_SQL += healpix.sql endif @@ -104,17 +100,17 @@ healpix_bare/healpix_bare.o : healpix_bare/healpix_bare.c pg_version := $(word 2,$(shell $(PG_CONFIG) --version)) has_support_functions = $(if $(filter-out 9.% 10.% 11.%,$(pg_version)),y,n) -crushtest: REGRESS += $(CRUSH_TESTS) +crushtest: TESTS += $(CRUSH_TESTS) crushtest: installcheck ifeq ($(has_support_functions),y) PGS_SQL += pgs_gist_support.sql -REGRESS += gist_support TESTS += gist_support endif +# "make test" uses a special initialization file that doesn't rely on "create extension" test: pg_sphere.test.sql - $(pg_regress_installcheck) --temp-instance=tmp_check $(REGRESS_OPTS) $(TESTS) + $(pg_regress_installcheck) --temp-instance=tmp_check $(REGRESS_OPTS) init_test $(TESTS) pg_sphere.test.sql: $(RELEASE_SQL) $(shlib) tail -n+3 $< | sed 's,MODULE_PATHNAME,$(realpath $(shlib)),g' >$@ From 9d0c414bda38a510c21bcdbeace97d4c48815665 Mon Sep 17 00:00:00 2001 From: Christoph Berg Date: Tue, 24 Oct 2023 12:02:20 +0200 Subject: [PATCH 49/87] Import .editorconfig from PostgreSQL This is the very same .editorconfig file that PostgreSQL is using. https://github.com/postgres/postgres/commit/ecb09cd5de5279ab9cfa20a58fd3da44f7df5779 --- .editorconfig | 14 ++++++++++++++ 1 file changed, 14 insertions(+) create mode 100644 .editorconfig diff --git a/.editorconfig b/.editorconfig new file mode 100644 index 0000000..d69a3d1 --- /dev/null +++ b/.editorconfig @@ -0,0 +1,14 @@ +root = true + +[*.{c,h,l,y,pl,pm}] +indent_style = tab +indent_size = tab +tab_width = 4 + +[*.{sgml,xml}] +indent_style = space +indent_size = 1 + +[*.xsl] +indent_style = space +indent_size = 2 From 686987793dda0aaf0ff71f408c01a4018a8f29c2 Mon Sep 17 00:00:00 2001 From: Christoph Berg Date: Tue, 24 Oct 2023 16:10:01 +0200 Subject: [PATCH 50/87] .gitignore: Ignore doc and "make test" artifacts --- .gitignore | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/.gitignore b/.gitignore index ff5e881..f726763 100644 --- a/.gitignore +++ b/.gitignore @@ -3,10 +3,17 @@ *.so /*.sql /doc/html/ +/doc/pg_sphere*.fo +/doc/pg_sphere-*.html +/doc/pg_sphere-*.pdf +/doc/pg_sphere-full.xml /doc/pg_sphere.dsl +/doc/version.xml +/log /results/ regression.out regression.diffs tags +/tmp_check buildpod .deps From b96b067c8f3fb062195d1f0fcabff745ed8deeab Mon Sep 17 00:00:00 2001 From: Christoph Berg Date: Tue, 24 Oct 2023 22:35:21 +0200 Subject: [PATCH 51/87] Configurable smoc_gin_ops index resolution Back when smoc GIN indexes were implemented, indexes did not support opclass options yet; that was added only later in PG 13. Add an "order" parameter on the smoc_gin_ops opclass to allow picking the smoc index granularity between level 0 and 12. (Larger levels do not fit into the internal int32 datatype anymore.) Example: `create index on sky using gin (coverage smoc_gin_ops (order = 8))` --- Makefile | 13 +++++++++++++ doc/indices.sgm | 21 +++++++++++++++------ expected/moc_options.out | 40 ++++++++++++++++++++++++++++++++++++++++ pgs_moc_ops.sql.in | 1 + pgs_moc_options.sql.in | 12 ++++++++++++ sql/moc_options.sql | 14 ++++++++++++++ src/moc.c | 29 +++++++++++++++++++++++++---- src/pgs_moc.h | 19 ++++++++++++++++++- 8 files changed, 138 insertions(+), 11 deletions(-) create mode 100644 expected/moc_options.out create mode 100644 pgs_moc_options.sql.in create mode 100644 sql/moc_options.sql diff --git a/Makefile b/Makefile index 6c648d9..5782814 100644 --- a/Makefile +++ b/Makefile @@ -99,6 +99,7 @@ healpix_bare/healpix_bare.o : healpix_bare/healpix_bare.c pg_version := $(word 2,$(shell $(PG_CONFIG) --version)) has_support_functions = $(if $(filter-out 9.% 10.% 11.%,$(pg_version)),y,n) +has_index_options = $(if $(filter-out 9.% 10.% 11.% 12.%,$(pg_version)),y,n) crushtest: TESTS += $(CRUSH_TESTS) crushtest: installcheck @@ -108,6 +109,13 @@ PGS_SQL += pgs_gist_support.sql TESTS += gist_support endif +ifneq ($(USE_HEALPIX),0) +ifeq ($(has_index_options),y) +PGS_SQL += pgs_moc_options.sql +TESTS += moc_options +endif +endif + # "make test" uses a special initialization file that doesn't rely on "create extension" test: pg_sphere.test.sql $(pg_regress_installcheck) --temp-instance=tmp_check $(REGRESS_OPTS) init_test $(TESTS) @@ -186,6 +194,11 @@ pg_sphere--1.3.0--1.3.1.sql: ifeq ($(has_support_functions),y) pg_sphere--1.3.1--1.3.2.sql: pgs_gist_support.sql.in endif +ifneq ($(USE_HEALPIX),0) +ifeq ($(has_index_options),y) +pg_sphere--1.3.1--1.3.2.sql: pgs_moc_options.sql.in +endif +endif pg_sphere--1.3.1--1.3.2.sql: pgs_circle_sel.sql.in cat upgrade_scripts/$@.in $^ > $@ diff --git a/doc/indices.sgm b/doc/indices.sgm index 0ef179f..b3a9c69 100644 --- a/doc/indices.sgm +++ b/doc/indices.sgm @@ -121,14 +121,20 @@ The index works by casting all contained smocs to a fixed level, and for each pixel at that level, storing which smocs overlap with that pixel. This is especially beneficial for "overlaps" queries using - the && operator. Two levels of granularity - are provided: the default opclass smoc_gin_ops - works on level 5 with a resolution of 12288 pixels, while the - opclass smoc_gin_ops_fine works on level 8 with - 786432 pixels. The downside of that approach is that storing large + the && operator. + The downside of that approach is that storing large smocs like "all sky" (0/0-11) produces a large number of index entries. + + The default opclass smoc_gin_ops defaults to + working on level 5 with a resolution of 12288 pixels (12 * 4^5). + An alternative granularity can be selected by setting the + order parameter on the opclass (integer value + between 0 and 12; option only available on PG 13 and later). + The alternative smoc_gin_ops_fine opclass works + on level 8 with 786432 pixels. + Codestin Search App @@ -136,8 +142,11 @@ + - + + + diff --git a/expected/moc_options.out b/expected/moc_options.out new file mode 100644 index 0000000..2342b79 --- /dev/null +++ b/expected/moc_options.out @@ -0,0 +1,40 @@ +create table moc_opt (m smoc); +insert into moc_opt select format('9/%s', i)::smoc from generate_series(1, 1000) g(i); +analyze moc_opt; +create index moc_opt5 on moc_opt using gin (m); +explain (analyze, costs off, timing off, summary off) select * from moc_opt where m && '9/1'; + QUERY PLAN +--------------------------------------------------------------- + Bitmap Heap Scan on moc_opt (actual rows=1 loops=1) + Recheck Cond: (m && '9/1'::smoc) + Rows Removed by Index Recheck: 254 + Heap Blocks: exact=4 + -> Bitmap Index Scan on moc_opt5 (actual rows=255 loops=1) + Index Cond: (m && '9/1'::smoc) +(6 rows) + +drop index moc_opt5; +create index moc_opt8 on moc_opt using gin (m smoc_gin_ops_fine); +explain (analyze, costs off, timing off, summary off) select * from moc_opt where m && '9/1'; + QUERY PLAN +------------------------------------------------------------- + Bitmap Heap Scan on moc_opt (actual rows=1 loops=1) + Recheck Cond: (m && '9/1'::smoc) + Rows Removed by Index Recheck: 2 + Heap Blocks: exact=1 + -> Bitmap Index Scan on moc_opt8 (actual rows=3 loops=1) + Index Cond: (m && '9/1'::smoc) +(6 rows) + +drop index moc_opt8; +create index moc_opt9 on moc_opt using gin (m smoc_gin_ops (order = 9)); +explain (analyze, costs off, timing off, summary off) select * from moc_opt where m && '9/1'; + QUERY PLAN +------------------------------------------------------------- + Bitmap Heap Scan on moc_opt (actual rows=1 loops=1) + Recheck Cond: (m && '9/1'::smoc) + Heap Blocks: exact=1 + -> Bitmap Index Scan on moc_opt9 (actual rows=1 loops=1) + Index Cond: (m && '9/1'::smoc) +(5 rows) + diff --git a/pgs_moc_ops.sql.in b/pgs_moc_ops.sql.in index 1319f5b..4e71af3 100644 --- a/pgs_moc_ops.sql.in +++ b/pgs_moc_ops.sql.in @@ -354,6 +354,7 @@ CREATE OPERATOR CLASS smoc_gin_ops FUNCTION 4 smoc_gin_consistent (internal, int2, smoc, int4, internal, internal, internal, internal), --FUNCTION 5 smoc_gin_compare_partial (), --FUNCTION 6 smoc_gin_tri_consistent (), + --FUNCTION 7 (smoc) smoc_gin_options (internal), -- needs PG13 STORAGE int4; CREATE OPERATOR CLASS smoc_gin_ops_fine diff --git a/pgs_moc_options.sql.in b/pgs_moc_options.sql.in new file mode 100644 index 0000000..e2b8e84 --- /dev/null +++ b/pgs_moc_options.sql.in @@ -0,0 +1,12 @@ +-- GIN opclass options + +CREATE FUNCTION smoc_gin_options (internal) + RETURNS void + AS 'MODULE_PATHNAME' + LANGUAGE C + PARALLEL SAFE + IMMUTABLE + STRICT; + +ALTER OPERATOR FAMILY smoc_gin_ops USING gin + ADD FUNCTION 7 (smoc) smoc_gin_options (internal); diff --git a/sql/moc_options.sql b/sql/moc_options.sql new file mode 100644 index 0000000..5041f65 --- /dev/null +++ b/sql/moc_options.sql @@ -0,0 +1,14 @@ +create table moc_opt (m smoc); +insert into moc_opt select format('9/%s', i)::smoc from generate_series(1, 1000) g(i); +analyze moc_opt; + +create index moc_opt5 on moc_opt using gin (m); +explain (analyze, costs off, timing off, summary off) select * from moc_opt where m && '9/1'; +drop index moc_opt5; + +create index moc_opt8 on moc_opt using gin (m smoc_gin_ops_fine); +explain (analyze, costs off, timing off, summary off) select * from moc_opt where m && '9/1'; +drop index moc_opt8; + +create index moc_opt9 on moc_opt using gin (m smoc_gin_ops (order = 9)); +explain (analyze, costs off, timing off, summary off) select * from moc_opt where m && '9/1'; diff --git a/src/moc.c b/src/moc.c index 6f1cbaf..4457aa6 100644 --- a/src/moc.c +++ b/src/moc.c @@ -3,7 +3,8 @@ #include #include -#include +#include "access/gin.h" +#include "access/reloptions.h" #include "circle.h" #include "polygon.h" @@ -45,6 +46,7 @@ PG_FUNCTION_INFO_V1(smoc_gin_extract_value_fine); PG_FUNCTION_INFO_V1(smoc_gin_extract_query); PG_FUNCTION_INFO_V1(smoc_gin_extract_query_fine); PG_FUNCTION_INFO_V1(smoc_gin_consistent); +PG_FUNCTION_INFO_V1(smoc_gin_options); int32 smoc_output_type = 0; @@ -1079,7 +1081,6 @@ smoc_gin_extract_internal(Smoc *moc_a, int32 *nkeys, int gin_order) if (*nkeys >= nalloc) { nalloc *= 2; - Assert(nalloc < 2000000); keys = repalloc(keys, nalloc * sizeof(Datum)); } keys[(*nkeys)++] = Int32GetDatum(p); @@ -1094,8 +1095,9 @@ smoc_gin_extract_value(PG_FUNCTION_ARGS) { Smoc* moc_a = (Smoc *) PG_DETOAST_DATUM(PG_GETARG_DATUM(0)); int32* nkeys = (int32 *) PG_GETARG_POINTER(1); + int order = SMOC_GIN_GET_ORDER(); - PG_RETURN_DATUM(smoc_gin_extract_internal(moc_a, nkeys, MOC_GIN_ORDER)); + PG_RETURN_DATUM(smoc_gin_extract_internal(moc_a, nkeys, order)); } Datum @@ -1114,13 +1116,14 @@ smoc_gin_extract_query(PG_FUNCTION_ARGS) int32* nkeys = (int32 *) PG_GETARG_POINTER(1); StrategyNumber st = PG_GETARG_UINT16(2); int32* searchmode = (int32 *) PG_GETARG_POINTER(6); + int order = SMOC_GIN_GET_ORDER(); if (st == MOC_GIN_STRATEGY_SUBSET || (st == MOC_GIN_STRATEGY_EQUAL && moc_a->area == 0)) *searchmode = GIN_SEARCH_MODE_INCLUDE_EMPTY; else if (st == MOC_GIN_STRATEGY_UNEQUAL) *searchmode = GIN_SEARCH_MODE_ALL; - PG_RETURN_DATUM(smoc_gin_extract_internal(moc_a, nkeys, MOC_GIN_ORDER)); + PG_RETURN_DATUM(smoc_gin_extract_internal(moc_a, nkeys, order)); } Datum @@ -1202,3 +1205,21 @@ smoc_gin_consistent(PG_FUNCTION_ARGS) /* not reached */ PG_RETURN_NULL(); } + +#if PG_VERSION_NUM >= 130000 +Datum +smoc_gin_options(PG_FUNCTION_ARGS) +{ + local_relopts *relopts = (local_relopts *) PG_GETARG_POINTER(0); + + init_local_reloptions(relopts, sizeof(SMocGinOptions)); + add_local_int_reloption(relopts, "order", + "smoc order to store in index", + MOC_GIN_ORDER_DEFAULT, + 0, + 12, /* maximum order fitting into 32bit */ + offsetof(SMocGinOptions, order)); + + PG_RETURN_VOID(); +} +#endif diff --git a/src/pgs_moc.h b/src/pgs_moc.h index 6bad1ae..68116d0 100644 --- a/src/pgs_moc.h +++ b/src/pgs_moc.h @@ -122,7 +122,7 @@ next_interval(int32 a) #define MOC_AREA_ALL_SKY 3458764513820540928 -#define MOC_GIN_ORDER 5 /* order 5 has 12 * 4^5 = 12288 pixels */ +#define MOC_GIN_ORDER_DEFAULT 5 /* order 5 has 12 * 4^5 = 12288 pixels */ #define MOC_GIN_ORDER_FINE 8 /* order 8 has 12 * 4^8 = 786432 pixels */ #define MOC_GIN_STRATEGY_INTERSECTS 1 #define MOC_GIN_STRATEGY_SUBSET 2 @@ -130,4 +130,21 @@ next_interval(int32 a) #define MOC_GIN_STRATEGY_EQUAL 4 #define MOC_GIN_STRATEGY_UNEQUAL 5 +/* smoc_gin_ops opclass options */ +#if PG_VERSION_NUM >= 130000 +Datum smoc_gin_options(PG_FUNCTION_ARGS); + +typedef struct +{ + int32 vl_len_; /* varlena header (do not touch directly!) */ + int order; /* smoc order to store in index (default 5) */ +} SMocGinOptions; + +#define SMOC_GIN_GET_ORDER() (PG_HAS_OPCLASS_OPTIONS() ? \ + ((SMocGinOptions *) PG_GET_OPCLASS_OPTIONS())->order : \ + MOC_GIN_ORDER_DEFAULT) +#else +#define SMOC_GIN_GET_ORDER() MOC_GIN_ORDER_DEFAULT +#endif + #endif From 1dc181ae0ac97c9a557ca5b6029683ace392e90a Mon Sep 17 00:00:00 2001 From: Christoph Berg Date: Mon, 23 Oct 2023 16:56:57 +0200 Subject: [PATCH 52/87] Use explain() function in moc100 test The interesting part of the moc100 test are the row counts and "Rows Removed by Filter". Remove all other noise. This also lets us get rid of the moc100_N alternative output files. --- expected/moc100.out | 251 ++++++++++++++-------------------- expected/moc100_1.out | 263 ----------------------------------- expected/moc100_2.out | 297 ---------------------------------------- expected/moc100_3.out | 297 ---------------------------------------- expected/moc100_4.out | 309 ------------------------------------------ expected/moc100_5.out | 309 ------------------------------------------ sql/moc100.sql | 88 ++++-------- 7 files changed, 132 insertions(+), 1682 deletions(-) delete mode 100644 expected/moc100_1.out delete mode 100644 expected/moc100_2.out delete mode 100644 expected/moc100_3.out delete mode 100644 expected/moc100_4.out delete mode 100644 expected/moc100_5.out diff --git a/expected/moc100.out b/expected/moc100.out index 51d668b..c74fb6e 100644 --- a/expected/moc100.out +++ b/expected/moc100.out @@ -1,20 +1,10 @@ -\set ECHO none - outputfile_for_majorversion ------------------------------ - 10, 11, 12 -(1 row) - - outputfile_for_arch_bits --------------------------- - 64-bit -(1 row) - CREATE TABLE moc100 ( ivoid text, coverage smoc, ref_system_name text ); COPY moc100 FROM STDIN; +ANALYZE moc100; CREATE INDEX ON moc100 USING GIN (coverage); SELECT ivoid FROM moc100 WHERE coverage && '4/0' ORDER BY ivoid; ivoid @@ -56,208 +46,175 @@ SELECT ivoid FROM moc100 WHERE coverage && '4/0' ORDER BY ivoid; ivo://vopdc.obspm/luth/hess (35 rows) -EXPLAIN (ANALYZE, BUFFERS, TIMING OFF, SUMMARY OFF) - SELECT * FROM moc100 WHERE coverage && '0/'; - QUERY PLAN ----------------------------------------------------------------------------------------------------------- - Bitmap Heap Scan on moc100 (cost=0.00..4.01 rows=1 width=96) (actual rows=0 loops=1) +-- PG 10 does not have JIT, ignore errors on SET +DO $$ + begin + set jit = off; + exception + when undefined_object then null; + when others then raise; + end; +$$; +SELECT explain ($$SELECT * FROM moc100 WHERE coverage && '0/'$$); + explain +------------------------------------------------------------------------------------------ + Bitmap Heap Scan on moc100 (rows=1 width=341) (actual rows=0 loops=1) Recheck Cond: (coverage && '0/'::smoc) - -> Bitmap Index Scan on moc100_coverage_idx (cost=0.00..0.00 rows=1 width=0) (actual rows=0 loops=1) + -> Bitmap Index Scan on moc100_coverage_idx (rows=1 width=0) (actual rows=0 loops=1) Index Cond: (coverage && '0/'::smoc) (4 rows) -EXPLAIN (ANALYZE, BUFFERS, TIMING OFF, SUMMARY OFF) - SELECT * FROM moc100 WHERE coverage && '4/0'; - QUERY PLAN --------------------------------------------------------------------------------- - Seq Scan on moc100 (cost=0.00..6.26 rows=1 width=96) (actual rows=35 loops=1) +SELECT explain ($$SELECT * FROM moc100 WHERE coverage && '4/0'$$); + explain +----------------------------------------------------------------- + Seq Scan on moc100 (rows=1 width=341) (actual rows=35 loops=1) Filter: (coverage && '4/0'::smoc) Rows Removed by Filter: 66 - Buffers: shared hit=114 -(4 rows) +(3 rows) -EXPLAIN (ANALYZE, BUFFERS, TIMING OFF, SUMMARY OFF) - SELECT * FROM moc100 WHERE coverage = '0/0-11'; - QUERY PLAN --------------------------------------------------------------------------------- - Seq Scan on moc100 (cost=0.00..6.26 rows=1 width=96) (actual rows=23 loops=1) +SELECT explain ($$SELECT * FROM moc100 WHERE coverage = '0/0-11'$$); + explain +----------------------------------------------------------------- + Seq Scan on moc100 (rows=1 width=341) (actual rows=23 loops=1) Filter: (coverage = '0/0-11'::smoc) Rows Removed by Filter: 78 - Buffers: shared hit=59 -(4 rows) +(3 rows) -EXPLAIN (ANALYZE, BUFFERS, TIMING OFF, SUMMARY OFF) - SELECT * FROM moc100 WHERE coverage = '6/43225,43227'; - QUERY PLAN -------------------------------------------------------------------------------- - Seq Scan on moc100 (cost=0.00..6.26 rows=1 width=96) (actual rows=1 loops=1) +SELECT explain ($$SELECT * FROM moc100 WHERE coverage = '6/43225,43227'$$); + explain +---------------------------------------------------------------- + Seq Scan on moc100 (rows=1 width=341) (actual rows=1 loops=1) Filter: (coverage = '6/43225 43227'::smoc) Rows Removed by Filter: 100 - Buffers: shared hit=59 -(4 rows) +(3 rows) -EXPLAIN (ANALYZE, BUFFERS, TIMING OFF, SUMMARY OFF) - SELECT * FROM moc100 WHERE coverage = '0/'; - QUERY PLAN -------------------------------------------------------------------------------- - Seq Scan on moc100 (cost=0.00..6.26 rows=1 width=96) (actual rows=1 loops=1) +SELECT explain ($$SELECT * FROM moc100 WHERE coverage = '0/'$$); + explain +---------------------------------------------------------------- + Seq Scan on moc100 (rows=1 width=341) (actual rows=1 loops=1) Filter: (coverage = '0/'::smoc) Rows Removed by Filter: 100 - Buffers: shared hit=59 -(4 rows) +(3 rows) -EXPLAIN (ANALYZE, BUFFERS, TIMING OFF, SUMMARY OFF) - SELECT * FROM moc100 WHERE coverage <> '0/0-11'; - QUERY PLAN ----------------------------------------------------------------------------------- - Seq Scan on moc100 (cost=0.00..6.26 rows=100 width=96) (actual rows=78 loops=1) +SELECT explain ($$SELECT * FROM moc100 WHERE coverage <> '0/0-11'$$); + explain +------------------------------------------------------------------- + Seq Scan on moc100 (rows=100 width=341) (actual rows=78 loops=1) Filter: (coverage <> '0/0-11'::smoc) Rows Removed by Filter: 23 - Buffers: shared hit=59 -(4 rows) +(3 rows) -EXPLAIN (ANALYZE, BUFFERS, TIMING OFF, SUMMARY OFF) - SELECT * FROM moc100 WHERE coverage <> '6/43225,43227'; - QUERY PLAN ------------------------------------------------------------------------------------ - Seq Scan on moc100 (cost=0.00..6.26 rows=100 width=96) (actual rows=100 loops=1) +SELECT explain ($$SELECT * FROM moc100 WHERE coverage <> '6/43225,43227'$$); + explain +-------------------------------------------------------------------- + Seq Scan on moc100 (rows=100 width=341) (actual rows=100 loops=1) Filter: (coverage <> '6/43225 43227'::smoc) Rows Removed by Filter: 1 - Buffers: shared hit=59 -(4 rows) +(3 rows) -EXPLAIN (ANALYZE, BUFFERS, TIMING OFF, SUMMARY OFF) - SELECT * FROM moc100 WHERE coverage <> '0/'; - QUERY PLAN ------------------------------------------------------------------------------------ - Seq Scan on moc100 (cost=0.00..6.26 rows=100 width=96) (actual rows=100 loops=1) +SELECT explain ($$SELECT * FROM moc100 WHERE coverage <> '0/'$$); + explain +-------------------------------------------------------------------- + Seq Scan on moc100 (rows=100 width=341) (actual rows=100 loops=1) Filter: (coverage <> '0/'::smoc) Rows Removed by Filter: 1 - Buffers: shared hit=59 -(4 rows) +(3 rows) SET enable_seqscan = off; -EXPLAIN (ANALYZE, BUFFERS, TIMING OFF, SUMMARY OFF) - SELECT * FROM moc100 WHERE coverage && '4/0'; - QUERY PLAN ------------------------------------------------------------------------------------------------------------- - Bitmap Heap Scan on moc100 (cost=36.00..40.01 rows=1 width=96) (actual rows=35 loops=1) +SELECT explain ($$SELECT * FROM moc100 WHERE coverage && '4/0'$$); + explain +------------------------------------------------------------------------------------------- + Bitmap Heap Scan on moc100 (rows=1 width=341) (actual rows=35 loops=1) Recheck Cond: (coverage && '4/0'::smoc) Heap Blocks: exact=5 - Buffers: shared hit=85 - -> Bitmap Index Scan on moc100_coverage_idx (cost=0.00..36.00 rows=1 width=0) (actual rows=35 loops=1) + -> Bitmap Index Scan on moc100_coverage_idx (rows=1 width=0) (actual rows=35 loops=1) Index Cond: (coverage && '4/0'::smoc) - Buffers: shared hit=9 -(7 rows) +(5 rows) -EXPLAIN (ANALYZE, BUFFERS, TIMING OFF, SUMMARY OFF) - SELECT * FROM moc100 WHERE coverage <@ '4/0'; - QUERY PLAN ------------------------------------------------------------------------------------------------------------- - Bitmap Heap Scan on moc100 (cost=44.00..48.01 rows=1 width=96) (actual rows=1 loops=1) +SELECT explain ($$SELECT * FROM moc100 WHERE coverage <@ '4/0'$$); + explain +------------------------------------------------------------------------------------------- + Bitmap Heap Scan on moc100 (rows=1 width=341) (actual rows=1 loops=1) Recheck Cond: (coverage <@ '4/0'::smoc) Rows Removed by Index Recheck: 35 Heap Blocks: exact=5 - Buffers: shared hit=33 - -> Bitmap Index Scan on moc100_coverage_idx (cost=0.00..44.00 rows=1 width=0) (actual rows=36 loops=1) + -> Bitmap Index Scan on moc100_coverage_idx (rows=1 width=0) (actual rows=36 loops=1) Index Cond: (coverage <@ '4/0'::smoc) - Buffers: shared hit=12 -(8 rows) +(6 rows) -EXPLAIN (ANALYZE, BUFFERS, TIMING OFF, SUMMARY OFF) - SELECT * FROM moc100 WHERE coverage @> '4/0'; - QUERY PLAN ------------------------------------------------------------------------------------------------------------- - Bitmap Heap Scan on moc100 (cost=36.00..40.01 rows=1 width=96) (actual rows=28 loops=1) +SELECT explain ($$SELECT * FROM moc100 WHERE coverage @> '4/0'$$); + explain +------------------------------------------------------------------------------------------- + Bitmap Heap Scan on moc100 (rows=1 width=341) (actual rows=28 loops=1) Recheck Cond: (coverage @> '4/0'::smoc) Rows Removed by Index Recheck: 1 Heap Blocks: exact=4 - Buffers: shared hit=36 - -> Bitmap Index Scan on moc100_coverage_idx (cost=0.00..36.00 rows=1 width=0) (actual rows=29 loops=1) + -> Bitmap Index Scan on moc100_coverage_idx (rows=1 width=0) (actual rows=29 loops=1) Index Cond: (coverage @> '4/0'::smoc) - Buffers: shared hit=9 -(8 rows) +(6 rows) -EXPLAIN (ANALYZE, BUFFERS, TIMING OFF, SUMMARY OFF) - SELECT * FROM moc100 WHERE coverage = '0/0-11'; - QUERY PLAN ---------------------------------------------------------------------------------------------------------------- - Bitmap Heap Scan on moc100 (cost=98308.01..98312.02 rows=1 width=96) (actual rows=23 loops=1) +SELECT explain ($$SELECT * FROM moc100 WHERE coverage = '0/0-11'$$); + explain +------------------------------------------------------------------------------------------- + Bitmap Heap Scan on moc100 (rows=1 width=341) (actual rows=23 loops=1) Recheck Cond: (coverage = '0/0-11'::smoc) Rows Removed by Index Recheck: 1 Heap Blocks: exact=2 - Buffers: shared hit=24581 - -> Bitmap Index Scan on moc100_coverage_idx (cost=0.00..98308.01 rows=1 width=0) (actual rows=24 loops=1) + -> Bitmap Index Scan on moc100_coverage_idx (rows=1 width=0) (actual rows=24 loops=1) Index Cond: (coverage = '0/0-11'::smoc) - Buffers: shared hit=24577 -(8 rows) +(6 rows) -EXPLAIN (ANALYZE, BUFFERS, TIMING OFF, SUMMARY OFF) - SELECT * FROM moc100 WHERE coverage = '6/43225,43227'; - QUERY PLAN ------------------------------------------------------------------------------------------------------------- - Bitmap Heap Scan on moc100 (cost=12.01..16.02 rows=1 width=96) (actual rows=1 loops=1) +SELECT explain ($$SELECT * FROM moc100 WHERE coverage = '6/43225,43227'$$); + explain +------------------------------------------------------------------------------------------- + Bitmap Heap Scan on moc100 (rows=1 width=341) (actual rows=1 loops=1) Recheck Cond: (coverage = '6/43225 43227'::smoc) Rows Removed by Index Recheck: 28 Heap Blocks: exact=3 - Buffers: shared hit=12 - -> Bitmap Index Scan on moc100_coverage_idx (cost=0.00..12.01 rows=1 width=0) (actual rows=29 loops=1) + -> Bitmap Index Scan on moc100_coverage_idx (rows=1 width=0) (actual rows=29 loops=1) Index Cond: (coverage = '6/43225 43227'::smoc) - Buffers: shared hit=3 -(8 rows) +(6 rows) -EXPLAIN (ANALYZE, BUFFERS, TIMING OFF, SUMMARY OFF) - SELECT * FROM moc100 WHERE coverage = '0/'; - QUERY PLAN ------------------------------------------------------------------------------------------------------------ - Bitmap Heap Scan on moc100 (cost=12.01..16.02 rows=1 width=96) (actual rows=1 loops=1) +SELECT explain ($$SELECT * FROM moc100 WHERE coverage = '0/'$$); + explain +------------------------------------------------------------------------------------------ + Bitmap Heap Scan on moc100 (rows=1 width=341) (actual rows=1 loops=1) Recheck Cond: (coverage = '0/'::smoc) Heap Blocks: exact=1 - Buffers: shared hit=5 - -> Bitmap Index Scan on moc100_coverage_idx (cost=0.00..12.01 rows=1 width=0) (actual rows=1 loops=1) + -> Bitmap Index Scan on moc100_coverage_idx (rows=1 width=0) (actual rows=1 loops=1) Index Cond: (coverage = '0/'::smoc) - Buffers: shared hit=4 -(7 rows) +(5 rows) -EXPLAIN (ANALYZE, BUFFERS, TIMING OFF, SUMMARY OFF) - SELECT * FROM moc100 WHERE coverage <> '0/0-11'; - QUERY PLAN ------------------------------------------------------------------------------------------------------------------- - Bitmap Heap Scan on moc100 (cost=98316.77..98323.02 rows=100 width=96) (actual rows=78 loops=1) +SELECT explain ($$SELECT * FROM moc100 WHERE coverage <> '0/0-11'$$); + explain +---------------------------------------------------------------------------------------------- + Bitmap Heap Scan on moc100 (rows=100 width=341) (actual rows=78 loops=1) Recheck Cond: (coverage <> '0/0-11'::smoc) Rows Removed by Index Recheck: 23 Heap Blocks: exact=5 - Buffers: shared hit=24821 - -> Bitmap Index Scan on moc100_coverage_idx (cost=0.00..98316.75 rows=100 width=0) (actual rows=101 loops=1) + -> Bitmap Index Scan on moc100_coverage_idx (rows=100 width=0) (actual rows=101 loops=1) Index Cond: (coverage <> '0/0-11'::smoc) - Buffers: shared hit=24762 -(8 rows) +(6 rows) -EXPLAIN (ANALYZE, BUFFERS, TIMING OFF, SUMMARY OFF) - SELECT * FROM moc100 WHERE coverage <> '6/43225,43227'; - QUERY PLAN ------------------------------------------------------------------------------------------------------------------- - Bitmap Heap Scan on moc100 (cost=98316.77..98323.02 rows=100 width=96) (actual rows=100 loops=1) +SELECT explain ($$SELECT * FROM moc100 WHERE coverage <> '6/43225,43227'$$); + explain +---------------------------------------------------------------------------------------------- + Bitmap Heap Scan on moc100 (rows=100 width=341) (actual rows=100 loops=1) Recheck Cond: (coverage <> '6/43225 43227'::smoc) Rows Removed by Index Recheck: 1 Heap Blocks: exact=5 - Buffers: shared hit=247 - -> Bitmap Index Scan on moc100_coverage_idx (cost=0.00..98316.75 rows=100 width=0) (actual rows=101 loops=1) + -> Bitmap Index Scan on moc100_coverage_idx (rows=100 width=0) (actual rows=101 loops=1) Index Cond: (coverage <> '6/43225 43227'::smoc) - Buffers: shared hit=188 -(8 rows) +(6 rows) -EXPLAIN (ANALYZE, BUFFERS, TIMING OFF, SUMMARY OFF) - SELECT * FROM moc100 WHERE coverage <> '0/'; - QUERY PLAN ------------------------------------------------------------------------------------------------------------------- - Bitmap Heap Scan on moc100 (cost=98316.77..98323.02 rows=100 width=96) (actual rows=100 loops=1) +SELECT explain ($$SELECT * FROM moc100 WHERE coverage <> '0/'$$); + explain +---------------------------------------------------------------------------------------------- + Bitmap Heap Scan on moc100 (rows=100 width=341) (actual rows=100 loops=1) Recheck Cond: (coverage <> '0/'::smoc) Rows Removed by Index Recheck: 1 Heap Blocks: exact=5 - Buffers: shared hit=245 - -> Bitmap Index Scan on moc100_coverage_idx (cost=0.00..98316.75 rows=100 width=0) (actual rows=101 loops=1) + -> Bitmap Index Scan on moc100_coverage_idx (rows=100 width=0) (actual rows=101 loops=1) Index Cond: (coverage <> '0/'::smoc) - Buffers: shared hit=186 -(8 rows) +(6 rows) diff --git a/expected/moc100_1.out b/expected/moc100_1.out deleted file mode 100644 index c7d6255..0000000 --- a/expected/moc100_1.out +++ /dev/null @@ -1,263 +0,0 @@ -\set ECHO none - outputfile_for_majorversion ------------------------------ - 10, 11, 12 -(1 row) - - outputfile_for_arch_bits --------------------------- - 32-bit -(1 row) - -CREATE TABLE moc100 ( - ivoid text, - coverage smoc, - ref_system_name text -); -COPY moc100 FROM STDIN; -CREATE INDEX ON moc100 USING GIN (coverage); -SELECT ivoid FROM moc100 WHERE coverage && '4/0' ORDER BY ivoid; - ivoid ------------------------------------------- - ivo://byu.arvo/dfbsspec/q/getssa - ivo://cadc.nrc.ca/archive/cfht - ivo://cadc.nrc.ca/archive/hst - ivo://cds.vizier/b/assocdata - ivo://cds.vizier/b/swift - ivo://cds.vizier/i/241 - ivo://cds.vizier/iv/12 - ivo://cds.vizier/ix/13 - ivo://cds.vizier/j/a+a/316/147 - ivo://cds.vizier/j/a+as/105/311 - ivo://cds.vizier/j/a+as/122/235 - ivo://chivo/gaia/q/dr1 - ivo://chivo/openngc/q/data - ivo://cxc.harvard.edu/csc - ivo://irsa.ipac/2mass/catalog/psc - ivo://irsa.ipac/2mass/catalog/xsc - ivo://irsa.ipac/2mass/images/asky-ql - ivo://irsa.ipac/cosmos/images - ivo://irsa.ipac/iras/images/issa - ivo://irsa.ipac/mast/scrapbook - ivo://irsa.ipac/spitzer/images/swire - ivo://mssl.ucl.ac.uk/xmmsuss_dsa/xmmsuss - ivo://ned.ipac/sia - ivo://ned.ipac/tap - ivo://svo.cab/cat/gbs - ivo://svo.cab/cat/uves - ivo://svo.cab/cat/xshooter - ivo://vopdc.iap/fss - ivo://vopdc.obspm/imcce/m4ast - ivo://vopdc.obspm/imcce/miriade - ivo://vopdc.obspm/imcce/skybot - ivo://vopdc.obspm/lesia/bestars/besc - ivo://vopdc.obspm/lesia/bestars/bess - ivo://vopdc.obspm/luth/exoplanet - ivo://vopdc.obspm/luth/hess -(35 rows) - -EXPLAIN (ANALYZE, BUFFERS, TIMING OFF, SUMMARY OFF) - SELECT * FROM moc100 WHERE coverage && '0/'; - QUERY PLAN ----------------------------------------------------------------------------------------------------------- - Bitmap Heap Scan on moc100 (cost=0.00..4.01 rows=1 width=96) (actual rows=0 loops=1) - Recheck Cond: (coverage && '0/'::smoc) - -> Bitmap Index Scan on moc100_coverage_idx (cost=0.00..0.00 rows=1 width=0) (actual rows=0 loops=1) - Index Cond: (coverage && '0/'::smoc) -(4 rows) - -EXPLAIN (ANALYZE, BUFFERS, TIMING OFF, SUMMARY OFF) - SELECT * FROM moc100 WHERE coverage && '4/0'; - QUERY PLAN --------------------------------------------------------------------------------- - Seq Scan on moc100 (cost=0.00..6.26 rows=1 width=96) (actual rows=35 loops=1) - Filter: (coverage && '4/0'::smoc) - Rows Removed by Filter: 66 - Buffers: shared hit=115 -(4 rows) - -EXPLAIN (ANALYZE, BUFFERS, TIMING OFF, SUMMARY OFF) - SELECT * FROM moc100 WHERE coverage = '0/0-11'; - QUERY PLAN --------------------------------------------------------------------------------- - Seq Scan on moc100 (cost=0.00..6.26 rows=1 width=96) (actual rows=23 loops=1) - Filter: (coverage = '0/0-11'::smoc) - Rows Removed by Filter: 78 - Buffers: shared hit=59 -(4 rows) - -EXPLAIN (ANALYZE, BUFFERS, TIMING OFF, SUMMARY OFF) - SELECT * FROM moc100 WHERE coverage = '6/43225,43227'; - QUERY PLAN -------------------------------------------------------------------------------- - Seq Scan on moc100 (cost=0.00..6.26 rows=1 width=96) (actual rows=1 loops=1) - Filter: (coverage = '6/43225 43227'::smoc) - Rows Removed by Filter: 100 - Buffers: shared hit=59 -(4 rows) - -EXPLAIN (ANALYZE, BUFFERS, TIMING OFF, SUMMARY OFF) - SELECT * FROM moc100 WHERE coverage = '0/'; - QUERY PLAN -------------------------------------------------------------------------------- - Seq Scan on moc100 (cost=0.00..6.26 rows=1 width=96) (actual rows=1 loops=1) - Filter: (coverage = '0/'::smoc) - Rows Removed by Filter: 100 - Buffers: shared hit=59 -(4 rows) - -EXPLAIN (ANALYZE, BUFFERS, TIMING OFF, SUMMARY OFF) - SELECT * FROM moc100 WHERE coverage <> '0/0-11'; - QUERY PLAN ----------------------------------------------------------------------------------- - Seq Scan on moc100 (cost=0.00..6.26 rows=100 width=96) (actual rows=78 loops=1) - Filter: (coverage <> '0/0-11'::smoc) - Rows Removed by Filter: 23 - Buffers: shared hit=59 -(4 rows) - -EXPLAIN (ANALYZE, BUFFERS, TIMING OFF, SUMMARY OFF) - SELECT * FROM moc100 WHERE coverage <> '6/43225,43227'; - QUERY PLAN ------------------------------------------------------------------------------------ - Seq Scan on moc100 (cost=0.00..6.26 rows=100 width=96) (actual rows=100 loops=1) - Filter: (coverage <> '6/43225 43227'::smoc) - Rows Removed by Filter: 1 - Buffers: shared hit=59 -(4 rows) - -EXPLAIN (ANALYZE, BUFFERS, TIMING OFF, SUMMARY OFF) - SELECT * FROM moc100 WHERE coverage <> '0/'; - QUERY PLAN ------------------------------------------------------------------------------------ - Seq Scan on moc100 (cost=0.00..6.26 rows=100 width=96) (actual rows=100 loops=1) - Filter: (coverage <> '0/'::smoc) - Rows Removed by Filter: 1 - Buffers: shared hit=59 -(4 rows) - -SET enable_seqscan = off; -EXPLAIN (ANALYZE, BUFFERS, TIMING OFF, SUMMARY OFF) - SELECT * FROM moc100 WHERE coverage && '4/0'; - QUERY PLAN ------------------------------------------------------------------------------------------------------------- - Bitmap Heap Scan on moc100 (cost=36.00..40.01 rows=1 width=96) (actual rows=35 loops=1) - Recheck Cond: (coverage && '4/0'::smoc) - Heap Blocks: exact=5 - Buffers: shared hit=86 - -> Bitmap Index Scan on moc100_coverage_idx (cost=0.00..36.00 rows=1 width=0) (actual rows=35 loops=1) - Index Cond: (coverage && '4/0'::smoc) - Buffers: shared hit=9 -(7 rows) - -EXPLAIN (ANALYZE, BUFFERS, TIMING OFF, SUMMARY OFF) - SELECT * FROM moc100 WHERE coverage <@ '4/0'; - QUERY PLAN ------------------------------------------------------------------------------------------------------------- - Bitmap Heap Scan on moc100 (cost=44.00..48.01 rows=1 width=96) (actual rows=1 loops=1) - Recheck Cond: (coverage <@ '4/0'::smoc) - Rows Removed by Index Recheck: 35 - Heap Blocks: exact=5 - Buffers: shared hit=33 - -> Bitmap Index Scan on moc100_coverage_idx (cost=0.00..44.00 rows=1 width=0) (actual rows=36 loops=1) - Index Cond: (coverage <@ '4/0'::smoc) - Buffers: shared hit=12 -(8 rows) - -EXPLAIN (ANALYZE, BUFFERS, TIMING OFF, SUMMARY OFF) - SELECT * FROM moc100 WHERE coverage @> '4/0'; - QUERY PLAN ------------------------------------------------------------------------------------------------------------- - Bitmap Heap Scan on moc100 (cost=36.00..40.01 rows=1 width=96) (actual rows=28 loops=1) - Recheck Cond: (coverage @> '4/0'::smoc) - Rows Removed by Index Recheck: 1 - Heap Blocks: exact=4 - Buffers: shared hit=36 - -> Bitmap Index Scan on moc100_coverage_idx (cost=0.00..36.00 rows=1 width=0) (actual rows=29 loops=1) - Index Cond: (coverage @> '4/0'::smoc) - Buffers: shared hit=9 -(8 rows) - -EXPLAIN (ANALYZE, BUFFERS, TIMING OFF, SUMMARY OFF) - SELECT * FROM moc100 WHERE coverage = '0/0-11'; - QUERY PLAN ---------------------------------------------------------------------------------------------------------------- - Bitmap Heap Scan on moc100 (cost=98308.01..98312.02 rows=1 width=96) (actual rows=23 loops=1) - Recheck Cond: (coverage = '0/0-11'::smoc) - Rows Removed by Index Recheck: 1 - Heap Blocks: exact=2 - Buffers: shared hit=24581 - -> Bitmap Index Scan on moc100_coverage_idx (cost=0.00..98308.01 rows=1 width=0) (actual rows=24 loops=1) - Index Cond: (coverage = '0/0-11'::smoc) - Buffers: shared hit=24577 -(8 rows) - -EXPLAIN (ANALYZE, BUFFERS, TIMING OFF, SUMMARY OFF) - SELECT * FROM moc100 WHERE coverage = '6/43225,43227'; - QUERY PLAN ------------------------------------------------------------------------------------------------------------- - Bitmap Heap Scan on moc100 (cost=12.01..16.02 rows=1 width=96) (actual rows=1 loops=1) - Recheck Cond: (coverage = '6/43225 43227'::smoc) - Rows Removed by Index Recheck: 28 - Heap Blocks: exact=3 - Buffers: shared hit=12 - -> Bitmap Index Scan on moc100_coverage_idx (cost=0.00..12.01 rows=1 width=0) (actual rows=29 loops=1) - Index Cond: (coverage = '6/43225 43227'::smoc) - Buffers: shared hit=3 -(8 rows) - -EXPLAIN (ANALYZE, BUFFERS, TIMING OFF, SUMMARY OFF) - SELECT * FROM moc100 WHERE coverage = '0/'; - QUERY PLAN ------------------------------------------------------------------------------------------------------------ - Bitmap Heap Scan on moc100 (cost=12.01..16.02 rows=1 width=96) (actual rows=1 loops=1) - Recheck Cond: (coverage = '0/'::smoc) - Heap Blocks: exact=1 - Buffers: shared hit=5 - -> Bitmap Index Scan on moc100_coverage_idx (cost=0.00..12.01 rows=1 width=0) (actual rows=1 loops=1) - Index Cond: (coverage = '0/'::smoc) - Buffers: shared hit=4 -(7 rows) - -EXPLAIN (ANALYZE, BUFFERS, TIMING OFF, SUMMARY OFF) - SELECT * FROM moc100 WHERE coverage <> '0/0-11'; - QUERY PLAN ------------------------------------------------------------------------------------------------------------------- - Bitmap Heap Scan on moc100 (cost=98316.77..98323.02 rows=100 width=96) (actual rows=78 loops=1) - Recheck Cond: (coverage <> '0/0-11'::smoc) - Rows Removed by Index Recheck: 23 - Heap Blocks: exact=5 - Buffers: shared hit=24804 - -> Bitmap Index Scan on moc100_coverage_idx (cost=0.00..98316.75 rows=100 width=0) (actual rows=101 loops=1) - Index Cond: (coverage <> '0/0-11'::smoc) - Buffers: shared hit=24745 -(8 rows) - -EXPLAIN (ANALYZE, BUFFERS, TIMING OFF, SUMMARY OFF) - SELECT * FROM moc100 WHERE coverage <> '6/43225,43227'; - QUERY PLAN ------------------------------------------------------------------------------------------------------------------- - Bitmap Heap Scan on moc100 (cost=98316.77..98323.02 rows=100 width=96) (actual rows=100 loops=1) - Recheck Cond: (coverage <> '6/43225 43227'::smoc) - Rows Removed by Index Recheck: 1 - Heap Blocks: exact=5 - Buffers: shared hit=230 - -> Bitmap Index Scan on moc100_coverage_idx (cost=0.00..98316.75 rows=100 width=0) (actual rows=101 loops=1) - Index Cond: (coverage <> '6/43225 43227'::smoc) - Buffers: shared hit=171 -(8 rows) - -EXPLAIN (ANALYZE, BUFFERS, TIMING OFF, SUMMARY OFF) - SELECT * FROM moc100 WHERE coverage <> '0/'; - QUERY PLAN ------------------------------------------------------------------------------------------------------------------- - Bitmap Heap Scan on moc100 (cost=98316.77..98323.02 rows=100 width=96) (actual rows=100 loops=1) - Recheck Cond: (coverage <> '0/'::smoc) - Rows Removed by Index Recheck: 1 - Heap Blocks: exact=5 - Buffers: shared hit=228 - -> Bitmap Index Scan on moc100_coverage_idx (cost=0.00..98316.75 rows=100 width=0) (actual rows=101 loops=1) - Index Cond: (coverage <> '0/'::smoc) - Buffers: shared hit=169 -(8 rows) - diff --git a/expected/moc100_2.out b/expected/moc100_2.out deleted file mode 100644 index 0f511a8..0000000 --- a/expected/moc100_2.out +++ /dev/null @@ -1,297 +0,0 @@ -\set ECHO none - outputfile_for_majorversion ------------------------------ - 13, 14, 15 -(1 row) - - outputfile_for_arch_bits --------------------------- - 64-bit -(1 row) - -CREATE TABLE moc100 ( - ivoid text, - coverage smoc, - ref_system_name text -); -COPY moc100 FROM STDIN; -CREATE INDEX ON moc100 USING GIN (coverage); -SELECT ivoid FROM moc100 WHERE coverage && '4/0' ORDER BY ivoid; - ivoid ------------------------------------------- - ivo://byu.arvo/dfbsspec/q/getssa - ivo://cadc.nrc.ca/archive/cfht - ivo://cadc.nrc.ca/archive/hst - ivo://cds.vizier/b/assocdata - ivo://cds.vizier/b/swift - ivo://cds.vizier/i/241 - ivo://cds.vizier/iv/12 - ivo://cds.vizier/ix/13 - ivo://cds.vizier/j/a+a/316/147 - ivo://cds.vizier/j/a+as/105/311 - ivo://cds.vizier/j/a+as/122/235 - ivo://chivo/gaia/q/dr1 - ivo://chivo/openngc/q/data - ivo://cxc.harvard.edu/csc - ivo://irsa.ipac/2mass/catalog/psc - ivo://irsa.ipac/2mass/catalog/xsc - ivo://irsa.ipac/2mass/images/asky-ql - ivo://irsa.ipac/cosmos/images - ivo://irsa.ipac/iras/images/issa - ivo://irsa.ipac/mast/scrapbook - ivo://irsa.ipac/spitzer/images/swire - ivo://mssl.ucl.ac.uk/xmmsuss_dsa/xmmsuss - ivo://ned.ipac/sia - ivo://ned.ipac/tap - ivo://svo.cab/cat/gbs - ivo://svo.cab/cat/uves - ivo://svo.cab/cat/xshooter - ivo://vopdc.iap/fss - ivo://vopdc.obspm/imcce/m4ast - ivo://vopdc.obspm/imcce/miriade - ivo://vopdc.obspm/imcce/skybot - ivo://vopdc.obspm/lesia/bestars/besc - ivo://vopdc.obspm/lesia/bestars/bess - ivo://vopdc.obspm/luth/exoplanet - ivo://vopdc.obspm/luth/hess -(35 rows) - -EXPLAIN (ANALYZE, BUFFERS, TIMING OFF, SUMMARY OFF) - SELECT * FROM moc100 WHERE coverage && '0/'; - QUERY PLAN ----------------------------------------------------------------------------------------------------------- - Bitmap Heap Scan on moc100 (cost=0.00..4.01 rows=1 width=96) (actual rows=0 loops=1) - Recheck Cond: (coverage && '0/'::smoc) - -> Bitmap Index Scan on moc100_coverage_idx (cost=0.00..0.00 rows=1 width=0) (actual rows=0 loops=1) - Index Cond: (coverage && '0/'::smoc) - Planning: - Buffers: shared hit=5 -(6 rows) - -EXPLAIN (ANALYZE, BUFFERS, TIMING OFF, SUMMARY OFF) - SELECT * FROM moc100 WHERE coverage && '4/0'; - QUERY PLAN --------------------------------------------------------------------------------- - Seq Scan on moc100 (cost=0.00..6.26 rows=1 width=96) (actual rows=35 loops=1) - Filter: (coverage && '4/0'::smoc) - Rows Removed by Filter: 66 - Buffers: shared hit=114 - Planning: - Buffers: shared hit=1 -(6 rows) - -EXPLAIN (ANALYZE, BUFFERS, TIMING OFF, SUMMARY OFF) - SELECT * FROM moc100 WHERE coverage = '0/0-11'; - QUERY PLAN --------------------------------------------------------------------------------- - Seq Scan on moc100 (cost=0.00..6.26 rows=1 width=96) (actual rows=23 loops=1) - Filter: (coverage = '0/0-11'::smoc) - Rows Removed by Filter: 78 - Buffers: shared hit=59 - Planning: - Buffers: shared hit=4 -(6 rows) - -EXPLAIN (ANALYZE, BUFFERS, TIMING OFF, SUMMARY OFF) - SELECT * FROM moc100 WHERE coverage = '6/43225,43227'; - QUERY PLAN -------------------------------------------------------------------------------- - Seq Scan on moc100 (cost=0.00..6.26 rows=1 width=96) (actual rows=1 loops=1) - Filter: (coverage = '6/43225 43227'::smoc) - Rows Removed by Filter: 100 - Buffers: shared hit=59 - Planning: - Buffers: shared hit=1 -(6 rows) - -EXPLAIN (ANALYZE, BUFFERS, TIMING OFF, SUMMARY OFF) - SELECT * FROM moc100 WHERE coverage = '0/'; - QUERY PLAN -------------------------------------------------------------------------------- - Seq Scan on moc100 (cost=0.00..6.26 rows=1 width=96) (actual rows=1 loops=1) - Filter: (coverage = '0/'::smoc) - Rows Removed by Filter: 100 - Buffers: shared hit=59 - Planning: - Buffers: shared hit=1 -(6 rows) - -EXPLAIN (ANALYZE, BUFFERS, TIMING OFF, SUMMARY OFF) - SELECT * FROM moc100 WHERE coverage <> '0/0-11'; - QUERY PLAN ----------------------------------------------------------------------------------- - Seq Scan on moc100 (cost=0.00..6.26 rows=100 width=96) (actual rows=78 loops=1) - Filter: (coverage <> '0/0-11'::smoc) - Rows Removed by Filter: 23 - Buffers: shared hit=59 - Planning: - Buffers: shared hit=4 -(6 rows) - -EXPLAIN (ANALYZE, BUFFERS, TIMING OFF, SUMMARY OFF) - SELECT * FROM moc100 WHERE coverage <> '6/43225,43227'; - QUERY PLAN ------------------------------------------------------------------------------------ - Seq Scan on moc100 (cost=0.00..6.26 rows=100 width=96) (actual rows=100 loops=1) - Filter: (coverage <> '6/43225 43227'::smoc) - Rows Removed by Filter: 1 - Buffers: shared hit=59 - Planning: - Buffers: shared hit=1 -(6 rows) - -EXPLAIN (ANALYZE, BUFFERS, TIMING OFF, SUMMARY OFF) - SELECT * FROM moc100 WHERE coverage <> '0/'; - QUERY PLAN ------------------------------------------------------------------------------------ - Seq Scan on moc100 (cost=0.00..6.26 rows=100 width=96) (actual rows=100 loops=1) - Filter: (coverage <> '0/'::smoc) - Rows Removed by Filter: 1 - Buffers: shared hit=59 - Planning: - Buffers: shared hit=1 -(6 rows) - -SET enable_seqscan = off; -EXPLAIN (ANALYZE, BUFFERS, TIMING OFF, SUMMARY OFF) - SELECT * FROM moc100 WHERE coverage && '4/0'; - QUERY PLAN ------------------------------------------------------------------------------------------------------------- - Bitmap Heap Scan on moc100 (cost=36.00..40.01 rows=1 width=96) (actual rows=35 loops=1) - Recheck Cond: (coverage && '4/0'::smoc) - Heap Blocks: exact=5 - Buffers: shared hit=85 - -> Bitmap Index Scan on moc100_coverage_idx (cost=0.00..36.00 rows=1 width=0) (actual rows=35 loops=1) - Index Cond: (coverage && '4/0'::smoc) - Buffers: shared hit=9 - Planning: - Buffers: shared hit=1 -(9 rows) - -EXPLAIN (ANALYZE, BUFFERS, TIMING OFF, SUMMARY OFF) - SELECT * FROM moc100 WHERE coverage <@ '4/0'; - QUERY PLAN ------------------------------------------------------------------------------------------------------------- - Bitmap Heap Scan on moc100 (cost=44.00..48.01 rows=1 width=96) (actual rows=1 loops=1) - Recheck Cond: (coverage <@ '4/0'::smoc) - Rows Removed by Index Recheck: 35 - Heap Blocks: exact=5 - Buffers: shared hit=33 - -> Bitmap Index Scan on moc100_coverage_idx (cost=0.00..44.00 rows=1 width=0) (actual rows=36 loops=1) - Index Cond: (coverage <@ '4/0'::smoc) - Buffers: shared hit=12 - Planning: - Buffers: shared hit=4 -(10 rows) - -EXPLAIN (ANALYZE, BUFFERS, TIMING OFF, SUMMARY OFF) - SELECT * FROM moc100 WHERE coverage @> '4/0'; - QUERY PLAN ------------------------------------------------------------------------------------------------------------- - Bitmap Heap Scan on moc100 (cost=36.00..40.01 rows=1 width=96) (actual rows=28 loops=1) - Recheck Cond: (coverage @> '4/0'::smoc) - Rows Removed by Index Recheck: 1 - Heap Blocks: exact=4 - Buffers: shared hit=36 - -> Bitmap Index Scan on moc100_coverage_idx (cost=0.00..36.00 rows=1 width=0) (actual rows=29 loops=1) - Index Cond: (coverage @> '4/0'::smoc) - Buffers: shared hit=9 - Planning: - Buffers: shared hit=4 -(10 rows) - -EXPLAIN (ANALYZE, BUFFERS, TIMING OFF, SUMMARY OFF) - SELECT * FROM moc100 WHERE coverage = '0/0-11'; - QUERY PLAN ---------------------------------------------------------------------------------------------------------------- - Bitmap Heap Scan on moc100 (cost=98308.01..98312.02 rows=1 width=96) (actual rows=23 loops=1) - Recheck Cond: (coverage = '0/0-11'::smoc) - Rows Removed by Index Recheck: 1 - Heap Blocks: exact=2 - Buffers: shared hit=24581 - -> Bitmap Index Scan on moc100_coverage_idx (cost=0.00..98308.01 rows=1 width=0) (actual rows=24 loops=1) - Index Cond: (coverage = '0/0-11'::smoc) - Buffers: shared hit=24577 - Planning: - Buffers: shared hit=1 -(10 rows) - -EXPLAIN (ANALYZE, BUFFERS, TIMING OFF, SUMMARY OFF) - SELECT * FROM moc100 WHERE coverage = '6/43225,43227'; - QUERY PLAN ------------------------------------------------------------------------------------------------------------- - Bitmap Heap Scan on moc100 (cost=12.01..16.02 rows=1 width=96) (actual rows=1 loops=1) - Recheck Cond: (coverage = '6/43225 43227'::smoc) - Rows Removed by Index Recheck: 28 - Heap Blocks: exact=3 - Buffers: shared hit=12 - -> Bitmap Index Scan on moc100_coverage_idx (cost=0.00..12.01 rows=1 width=0) (actual rows=29 loops=1) - Index Cond: (coverage = '6/43225 43227'::smoc) - Buffers: shared hit=3 - Planning: - Buffers: shared hit=1 -(10 rows) - -EXPLAIN (ANALYZE, BUFFERS, TIMING OFF, SUMMARY OFF) - SELECT * FROM moc100 WHERE coverage = '0/'; - QUERY PLAN ------------------------------------------------------------------------------------------------------------ - Bitmap Heap Scan on moc100 (cost=12.01..16.02 rows=1 width=96) (actual rows=1 loops=1) - Recheck Cond: (coverage = '0/'::smoc) - Heap Blocks: exact=1 - Buffers: shared hit=5 - -> Bitmap Index Scan on moc100_coverage_idx (cost=0.00..12.01 rows=1 width=0) (actual rows=1 loops=1) - Index Cond: (coverage = '0/'::smoc) - Buffers: shared hit=4 - Planning: - Buffers: shared hit=1 -(9 rows) - -EXPLAIN (ANALYZE, BUFFERS, TIMING OFF, SUMMARY OFF) - SELECT * FROM moc100 WHERE coverage <> '0/0-11'; - QUERY PLAN ------------------------------------------------------------------------------------------------------------------- - Bitmap Heap Scan on moc100 (cost=98316.77..98323.02 rows=100 width=96) (actual rows=78 loops=1) - Recheck Cond: (coverage <> '0/0-11'::smoc) - Rows Removed by Index Recheck: 23 - Heap Blocks: exact=5 - Buffers: shared hit=24821 - -> Bitmap Index Scan on moc100_coverage_idx (cost=0.00..98316.75 rows=100 width=0) (actual rows=101 loops=1) - Index Cond: (coverage <> '0/0-11'::smoc) - Buffers: shared hit=24762 - Planning: - Buffers: shared hit=1 -(10 rows) - -EXPLAIN (ANALYZE, BUFFERS, TIMING OFF, SUMMARY OFF) - SELECT * FROM moc100 WHERE coverage <> '6/43225,43227'; - QUERY PLAN ------------------------------------------------------------------------------------------------------------------- - Bitmap Heap Scan on moc100 (cost=98316.77..98323.02 rows=100 width=96) (actual rows=100 loops=1) - Recheck Cond: (coverage <> '6/43225 43227'::smoc) - Rows Removed by Index Recheck: 1 - Heap Blocks: exact=5 - Buffers: shared hit=247 - -> Bitmap Index Scan on moc100_coverage_idx (cost=0.00..98316.75 rows=100 width=0) (actual rows=101 loops=1) - Index Cond: (coverage <> '6/43225 43227'::smoc) - Buffers: shared hit=188 - Planning: - Buffers: shared hit=1 -(10 rows) - -EXPLAIN (ANALYZE, BUFFERS, TIMING OFF, SUMMARY OFF) - SELECT * FROM moc100 WHERE coverage <> '0/'; - QUERY PLAN ------------------------------------------------------------------------------------------------------------------- - Bitmap Heap Scan on moc100 (cost=98316.77..98323.02 rows=100 width=96) (actual rows=100 loops=1) - Recheck Cond: (coverage <> '0/'::smoc) - Rows Removed by Index Recheck: 1 - Heap Blocks: exact=5 - Buffers: shared hit=245 - -> Bitmap Index Scan on moc100_coverage_idx (cost=0.00..98316.75 rows=100 width=0) (actual rows=101 loops=1) - Index Cond: (coverage <> '0/'::smoc) - Buffers: shared hit=186 - Planning: - Buffers: shared hit=1 -(10 rows) - diff --git a/expected/moc100_3.out b/expected/moc100_3.out deleted file mode 100644 index c650501..0000000 --- a/expected/moc100_3.out +++ /dev/null @@ -1,297 +0,0 @@ -\set ECHO none - outputfile_for_majorversion ------------------------------ - 13, 14, 15 -(1 row) - - outputfile_for_arch_bits --------------------------- - 32-bit -(1 row) - -CREATE TABLE moc100 ( - ivoid text, - coverage smoc, - ref_system_name text -); -COPY moc100 FROM STDIN; -CREATE INDEX ON moc100 USING GIN (coverage); -SELECT ivoid FROM moc100 WHERE coverage && '4/0' ORDER BY ivoid; - ivoid ------------------------------------------- - ivo://byu.arvo/dfbsspec/q/getssa - ivo://cadc.nrc.ca/archive/cfht - ivo://cadc.nrc.ca/archive/hst - ivo://cds.vizier/b/assocdata - ivo://cds.vizier/b/swift - ivo://cds.vizier/i/241 - ivo://cds.vizier/iv/12 - ivo://cds.vizier/ix/13 - ivo://cds.vizier/j/a+a/316/147 - ivo://cds.vizier/j/a+as/105/311 - ivo://cds.vizier/j/a+as/122/235 - ivo://chivo/gaia/q/dr1 - ivo://chivo/openngc/q/data - ivo://cxc.harvard.edu/csc - ivo://irsa.ipac/2mass/catalog/psc - ivo://irsa.ipac/2mass/catalog/xsc - ivo://irsa.ipac/2mass/images/asky-ql - ivo://irsa.ipac/cosmos/images - ivo://irsa.ipac/iras/images/issa - ivo://irsa.ipac/mast/scrapbook - ivo://irsa.ipac/spitzer/images/swire - ivo://mssl.ucl.ac.uk/xmmsuss_dsa/xmmsuss - ivo://ned.ipac/sia - ivo://ned.ipac/tap - ivo://svo.cab/cat/gbs - ivo://svo.cab/cat/uves - ivo://svo.cab/cat/xshooter - ivo://vopdc.iap/fss - ivo://vopdc.obspm/imcce/m4ast - ivo://vopdc.obspm/imcce/miriade - ivo://vopdc.obspm/imcce/skybot - ivo://vopdc.obspm/lesia/bestars/besc - ivo://vopdc.obspm/lesia/bestars/bess - ivo://vopdc.obspm/luth/exoplanet - ivo://vopdc.obspm/luth/hess -(35 rows) - -EXPLAIN (ANALYZE, BUFFERS, TIMING OFF, SUMMARY OFF) - SELECT * FROM moc100 WHERE coverage && '0/'; - QUERY PLAN ----------------------------------------------------------------------------------------------------------- - Bitmap Heap Scan on moc100 (cost=0.00..4.01 rows=1 width=96) (actual rows=0 loops=1) - Recheck Cond: (coverage && '0/'::smoc) - -> Bitmap Index Scan on moc100_coverage_idx (cost=0.00..0.00 rows=1 width=0) (actual rows=0 loops=1) - Index Cond: (coverage && '0/'::smoc) - Planning: - Buffers: shared hit=5 -(6 rows) - -EXPLAIN (ANALYZE, BUFFERS, TIMING OFF, SUMMARY OFF) - SELECT * FROM moc100 WHERE coverage && '4/0'; - QUERY PLAN --------------------------------------------------------------------------------- - Seq Scan on moc100 (cost=0.00..6.26 rows=1 width=96) (actual rows=35 loops=1) - Filter: (coverage && '4/0'::smoc) - Rows Removed by Filter: 66 - Buffers: shared hit=115 - Planning: - Buffers: shared hit=1 -(6 rows) - -EXPLAIN (ANALYZE, BUFFERS, TIMING OFF, SUMMARY OFF) - SELECT * FROM moc100 WHERE coverage = '0/0-11'; - QUERY PLAN --------------------------------------------------------------------------------- - Seq Scan on moc100 (cost=0.00..6.26 rows=1 width=96) (actual rows=23 loops=1) - Filter: (coverage = '0/0-11'::smoc) - Rows Removed by Filter: 78 - Buffers: shared hit=59 - Planning: - Buffers: shared hit=4 -(6 rows) - -EXPLAIN (ANALYZE, BUFFERS, TIMING OFF, SUMMARY OFF) - SELECT * FROM moc100 WHERE coverage = '6/43225,43227'; - QUERY PLAN -------------------------------------------------------------------------------- - Seq Scan on moc100 (cost=0.00..6.26 rows=1 width=96) (actual rows=1 loops=1) - Filter: (coverage = '6/43225 43227'::smoc) - Rows Removed by Filter: 100 - Buffers: shared hit=59 - Planning: - Buffers: shared hit=1 -(6 rows) - -EXPLAIN (ANALYZE, BUFFERS, TIMING OFF, SUMMARY OFF) - SELECT * FROM moc100 WHERE coverage = '0/'; - QUERY PLAN -------------------------------------------------------------------------------- - Seq Scan on moc100 (cost=0.00..6.26 rows=1 width=96) (actual rows=1 loops=1) - Filter: (coverage = '0/'::smoc) - Rows Removed by Filter: 100 - Buffers: shared hit=59 - Planning: - Buffers: shared hit=1 -(6 rows) - -EXPLAIN (ANALYZE, BUFFERS, TIMING OFF, SUMMARY OFF) - SELECT * FROM moc100 WHERE coverage <> '0/0-11'; - QUERY PLAN ----------------------------------------------------------------------------------- - Seq Scan on moc100 (cost=0.00..6.26 rows=100 width=96) (actual rows=78 loops=1) - Filter: (coverage <> '0/0-11'::smoc) - Rows Removed by Filter: 23 - Buffers: shared hit=59 - Planning: - Buffers: shared hit=4 -(6 rows) - -EXPLAIN (ANALYZE, BUFFERS, TIMING OFF, SUMMARY OFF) - SELECT * FROM moc100 WHERE coverage <> '6/43225,43227'; - QUERY PLAN ------------------------------------------------------------------------------------ - Seq Scan on moc100 (cost=0.00..6.26 rows=100 width=96) (actual rows=100 loops=1) - Filter: (coverage <> '6/43225 43227'::smoc) - Rows Removed by Filter: 1 - Buffers: shared hit=59 - Planning: - Buffers: shared hit=1 -(6 rows) - -EXPLAIN (ANALYZE, BUFFERS, TIMING OFF, SUMMARY OFF) - SELECT * FROM moc100 WHERE coverage <> '0/'; - QUERY PLAN ------------------------------------------------------------------------------------ - Seq Scan on moc100 (cost=0.00..6.26 rows=100 width=96) (actual rows=100 loops=1) - Filter: (coverage <> '0/'::smoc) - Rows Removed by Filter: 1 - Buffers: shared hit=59 - Planning: - Buffers: shared hit=1 -(6 rows) - -SET enable_seqscan = off; -EXPLAIN (ANALYZE, BUFFERS, TIMING OFF, SUMMARY OFF) - SELECT * FROM moc100 WHERE coverage && '4/0'; - QUERY PLAN ------------------------------------------------------------------------------------------------------------- - Bitmap Heap Scan on moc100 (cost=36.00..40.01 rows=1 width=96) (actual rows=35 loops=1) - Recheck Cond: (coverage && '4/0'::smoc) - Heap Blocks: exact=5 - Buffers: shared hit=86 - -> Bitmap Index Scan on moc100_coverage_idx (cost=0.00..36.00 rows=1 width=0) (actual rows=35 loops=1) - Index Cond: (coverage && '4/0'::smoc) - Buffers: shared hit=9 - Planning: - Buffers: shared hit=1 -(9 rows) - -EXPLAIN (ANALYZE, BUFFERS, TIMING OFF, SUMMARY OFF) - SELECT * FROM moc100 WHERE coverage <@ '4/0'; - QUERY PLAN ------------------------------------------------------------------------------------------------------------- - Bitmap Heap Scan on moc100 (cost=44.00..48.01 rows=1 width=96) (actual rows=1 loops=1) - Recheck Cond: (coverage <@ '4/0'::smoc) - Rows Removed by Index Recheck: 35 - Heap Blocks: exact=5 - Buffers: shared hit=33 - -> Bitmap Index Scan on moc100_coverage_idx (cost=0.00..44.00 rows=1 width=0) (actual rows=36 loops=1) - Index Cond: (coverage <@ '4/0'::smoc) - Buffers: shared hit=12 - Planning: - Buffers: shared hit=4 -(10 rows) - -EXPLAIN (ANALYZE, BUFFERS, TIMING OFF, SUMMARY OFF) - SELECT * FROM moc100 WHERE coverage @> '4/0'; - QUERY PLAN ------------------------------------------------------------------------------------------------------------- - Bitmap Heap Scan on moc100 (cost=36.00..40.01 rows=1 width=96) (actual rows=28 loops=1) - Recheck Cond: (coverage @> '4/0'::smoc) - Rows Removed by Index Recheck: 1 - Heap Blocks: exact=4 - Buffers: shared hit=36 - -> Bitmap Index Scan on moc100_coverage_idx (cost=0.00..36.00 rows=1 width=0) (actual rows=29 loops=1) - Index Cond: (coverage @> '4/0'::smoc) - Buffers: shared hit=9 - Planning: - Buffers: shared hit=4 -(10 rows) - -EXPLAIN (ANALYZE, BUFFERS, TIMING OFF, SUMMARY OFF) - SELECT * FROM moc100 WHERE coverage = '0/0-11'; - QUERY PLAN ---------------------------------------------------------------------------------------------------------------- - Bitmap Heap Scan on moc100 (cost=98308.01..98312.02 rows=1 width=96) (actual rows=23 loops=1) - Recheck Cond: (coverage = '0/0-11'::smoc) - Rows Removed by Index Recheck: 1 - Heap Blocks: exact=2 - Buffers: shared hit=24581 - -> Bitmap Index Scan on moc100_coverage_idx (cost=0.00..98308.01 rows=1 width=0) (actual rows=24 loops=1) - Index Cond: (coverage = '0/0-11'::smoc) - Buffers: shared hit=24577 - Planning: - Buffers: shared hit=1 -(10 rows) - -EXPLAIN (ANALYZE, BUFFERS, TIMING OFF, SUMMARY OFF) - SELECT * FROM moc100 WHERE coverage = '6/43225,43227'; - QUERY PLAN ------------------------------------------------------------------------------------------------------------- - Bitmap Heap Scan on moc100 (cost=12.01..16.02 rows=1 width=96) (actual rows=1 loops=1) - Recheck Cond: (coverage = '6/43225 43227'::smoc) - Rows Removed by Index Recheck: 28 - Heap Blocks: exact=3 - Buffers: shared hit=12 - -> Bitmap Index Scan on moc100_coverage_idx (cost=0.00..12.01 rows=1 width=0) (actual rows=29 loops=1) - Index Cond: (coverage = '6/43225 43227'::smoc) - Buffers: shared hit=3 - Planning: - Buffers: shared hit=1 -(10 rows) - -EXPLAIN (ANALYZE, BUFFERS, TIMING OFF, SUMMARY OFF) - SELECT * FROM moc100 WHERE coverage = '0/'; - QUERY PLAN ------------------------------------------------------------------------------------------------------------ - Bitmap Heap Scan on moc100 (cost=12.01..16.02 rows=1 width=96) (actual rows=1 loops=1) - Recheck Cond: (coverage = '0/'::smoc) - Heap Blocks: exact=1 - Buffers: shared hit=5 - -> Bitmap Index Scan on moc100_coverage_idx (cost=0.00..12.01 rows=1 width=0) (actual rows=1 loops=1) - Index Cond: (coverage = '0/'::smoc) - Buffers: shared hit=4 - Planning: - Buffers: shared hit=1 -(9 rows) - -EXPLAIN (ANALYZE, BUFFERS, TIMING OFF, SUMMARY OFF) - SELECT * FROM moc100 WHERE coverage <> '0/0-11'; - QUERY PLAN ------------------------------------------------------------------------------------------------------------------- - Bitmap Heap Scan on moc100 (cost=98316.77..98323.02 rows=100 width=96) (actual rows=78 loops=1) - Recheck Cond: (coverage <> '0/0-11'::smoc) - Rows Removed by Index Recheck: 23 - Heap Blocks: exact=5 - Buffers: shared hit=24804 - -> Bitmap Index Scan on moc100_coverage_idx (cost=0.00..98316.75 rows=100 width=0) (actual rows=101 loops=1) - Index Cond: (coverage <> '0/0-11'::smoc) - Buffers: shared hit=24745 - Planning: - Buffers: shared hit=1 -(10 rows) - -EXPLAIN (ANALYZE, BUFFERS, TIMING OFF, SUMMARY OFF) - SELECT * FROM moc100 WHERE coverage <> '6/43225,43227'; - QUERY PLAN ------------------------------------------------------------------------------------------------------------------- - Bitmap Heap Scan on moc100 (cost=98316.77..98323.02 rows=100 width=96) (actual rows=100 loops=1) - Recheck Cond: (coverage <> '6/43225 43227'::smoc) - Rows Removed by Index Recheck: 1 - Heap Blocks: exact=5 - Buffers: shared hit=230 - -> Bitmap Index Scan on moc100_coverage_idx (cost=0.00..98316.75 rows=100 width=0) (actual rows=101 loops=1) - Index Cond: (coverage <> '6/43225 43227'::smoc) - Buffers: shared hit=171 - Planning: - Buffers: shared hit=1 -(10 rows) - -EXPLAIN (ANALYZE, BUFFERS, TIMING OFF, SUMMARY OFF) - SELECT * FROM moc100 WHERE coverage <> '0/'; - QUERY PLAN ------------------------------------------------------------------------------------------------------------------- - Bitmap Heap Scan on moc100 (cost=98316.77..98323.02 rows=100 width=96) (actual rows=100 loops=1) - Recheck Cond: (coverage <> '0/'::smoc) - Rows Removed by Index Recheck: 1 - Heap Blocks: exact=5 - Buffers: shared hit=228 - -> Bitmap Index Scan on moc100_coverage_idx (cost=0.00..98316.75 rows=100 width=0) (actual rows=101 loops=1) - Index Cond: (coverage <> '0/'::smoc) - Buffers: shared hit=169 - Planning: - Buffers: shared hit=1 -(10 rows) - diff --git a/expected/moc100_4.out b/expected/moc100_4.out deleted file mode 100644 index 0dc26bd..0000000 --- a/expected/moc100_4.out +++ /dev/null @@ -1,309 +0,0 @@ -\set ECHO none - outputfile_for_majorversion ------------------------------ - 16+ -(1 row) - - outputfile_for_arch_bits --------------------------- - 64-bit -(1 row) - -CREATE TABLE moc100 ( - ivoid text, - coverage smoc, - ref_system_name text -); -COPY moc100 FROM STDIN; -CREATE INDEX ON moc100 USING GIN (coverage); -SELECT ivoid FROM moc100 WHERE coverage && '4/0' ORDER BY ivoid; - ivoid ------------------------------------------- - ivo://byu.arvo/dfbsspec/q/getssa - ivo://cadc.nrc.ca/archive/cfht - ivo://cadc.nrc.ca/archive/hst - ivo://cds.vizier/b/assocdata - ivo://cds.vizier/b/swift - ivo://cds.vizier/i/241 - ivo://cds.vizier/iv/12 - ivo://cds.vizier/ix/13 - ivo://cds.vizier/j/a+a/316/147 - ivo://cds.vizier/j/a+as/105/311 - ivo://cds.vizier/j/a+as/122/235 - ivo://chivo/gaia/q/dr1 - ivo://chivo/openngc/q/data - ivo://cxc.harvard.edu/csc - ivo://irsa.ipac/2mass/catalog/psc - ivo://irsa.ipac/2mass/catalog/xsc - ivo://irsa.ipac/2mass/images/asky-ql - ivo://irsa.ipac/cosmos/images - ivo://irsa.ipac/iras/images/issa - ivo://irsa.ipac/mast/scrapbook - ivo://irsa.ipac/spitzer/images/swire - ivo://mssl.ucl.ac.uk/xmmsuss_dsa/xmmsuss - ivo://ned.ipac/sia - ivo://ned.ipac/tap - ivo://svo.cab/cat/gbs - ivo://svo.cab/cat/uves - ivo://svo.cab/cat/xshooter - ivo://vopdc.iap/fss - ivo://vopdc.obspm/imcce/m4ast - ivo://vopdc.obspm/imcce/miriade - ivo://vopdc.obspm/imcce/skybot - ivo://vopdc.obspm/lesia/bestars/besc - ivo://vopdc.obspm/lesia/bestars/bess - ivo://vopdc.obspm/luth/exoplanet - ivo://vopdc.obspm/luth/hess -(35 rows) - -EXPLAIN (ANALYZE, BUFFERS, TIMING OFF, SUMMARY OFF) - SELECT * FROM moc100 WHERE coverage && '0/'; - QUERY PLAN ----------------------------------------------------------------------------------------------------------- - Bitmap Heap Scan on moc100 (cost=0.00..4.01 rows=1 width=96) (actual rows=0 loops=1) - Recheck Cond: (coverage && '0/'::smoc) - -> Bitmap Index Scan on moc100_coverage_idx (cost=0.00..0.00 rows=1 width=0) (actual rows=0 loops=1) - Index Cond: (coverage && '0/'::smoc) - Planning: - Buffers: shared hit=5 -(6 rows) - -EXPLAIN (ANALYZE, BUFFERS, TIMING OFF, SUMMARY OFF) - SELECT * FROM moc100 WHERE coverage && '4/0'; - QUERY PLAN --------------------------------------------------------------------------------- - Seq Scan on moc100 (cost=0.00..7.26 rows=1 width=96) (actual rows=35 loops=1) - Filter: (coverage && '4/0'::smoc) - Rows Removed by Filter: 66 - Buffers: shared hit=115 - Planning: - Buffers: shared hit=1 -(6 rows) - -EXPLAIN (ANALYZE, BUFFERS, TIMING OFF, SUMMARY OFF) - SELECT * FROM moc100 WHERE coverage = '0/0-11'; - QUERY PLAN --------------------------------------------------------------------------------- - Seq Scan on moc100 (cost=0.00..7.26 rows=1 width=96) (actual rows=23 loops=1) - Filter: (coverage = '0/0-11'::smoc) - Rows Removed by Filter: 78 - Buffers: shared hit=60 - Planning: - Buffers: shared hit=4 -(6 rows) - -EXPLAIN (ANALYZE, BUFFERS, TIMING OFF, SUMMARY OFF) - SELECT * FROM moc100 WHERE coverage = '6/43225,43227'; - QUERY PLAN -------------------------------------------------------------------------------- - Seq Scan on moc100 (cost=0.00..7.26 rows=1 width=96) (actual rows=1 loops=1) - Filter: (coverage = '6/43225 43227'::smoc) - Rows Removed by Filter: 100 - Buffers: shared hit=60 - Planning: - Buffers: shared hit=1 -(6 rows) - -EXPLAIN (ANALYZE, BUFFERS, TIMING OFF, SUMMARY OFF) - SELECT * FROM moc100 WHERE coverage = '0/'; - QUERY PLAN -------------------------------------------------------------------------------- - Seq Scan on moc100 (cost=0.00..7.26 rows=1 width=96) (actual rows=1 loops=1) - Filter: (coverage = '0/'::smoc) - Rows Removed by Filter: 100 - Buffers: shared hit=60 - Planning: - Buffers: shared hit=1 -(6 rows) - -EXPLAIN (ANALYZE, BUFFERS, TIMING OFF, SUMMARY OFF) - SELECT * FROM moc100 WHERE coverage <> '0/0-11'; - QUERY PLAN ----------------------------------------------------------------------------------- - Seq Scan on moc100 (cost=0.00..7.26 rows=100 width=96) (actual rows=78 loops=1) - Filter: (coverage <> '0/0-11'::smoc) - Rows Removed by Filter: 23 - Buffers: shared hit=60 - Planning: - Buffers: shared hit=4 -(6 rows) - -EXPLAIN (ANALYZE, BUFFERS, TIMING OFF, SUMMARY OFF) - SELECT * FROM moc100 WHERE coverage <> '6/43225,43227'; - QUERY PLAN ------------------------------------------------------------------------------------ - Seq Scan on moc100 (cost=0.00..7.26 rows=100 width=96) (actual rows=100 loops=1) - Filter: (coverage <> '6/43225 43227'::smoc) - Rows Removed by Filter: 1 - Buffers: shared hit=60 - Planning: - Buffers: shared hit=1 -(6 rows) - -EXPLAIN (ANALYZE, BUFFERS, TIMING OFF, SUMMARY OFF) - SELECT * FROM moc100 WHERE coverage <> '0/'; - QUERY PLAN ------------------------------------------------------------------------------------ - Seq Scan on moc100 (cost=0.00..7.26 rows=100 width=96) (actual rows=100 loops=1) - Filter: (coverage <> '0/'::smoc) - Rows Removed by Filter: 1 - Buffers: shared hit=60 - Planning: - Buffers: shared hit=1 -(6 rows) - -SET enable_seqscan = off; -EXPLAIN (ANALYZE, BUFFERS, TIMING OFF, SUMMARY OFF) - SELECT * FROM moc100 WHERE coverage && '4/0'; - QUERY PLAN ------------------------------------------------------------------------------------------------------------- - Bitmap Heap Scan on moc100 (cost=38.92..42.93 rows=1 width=96) (actual rows=35 loops=1) - Recheck Cond: (coverage && '4/0'::smoc) - Heap Blocks: exact=5 - Buffers: shared hit=85 - -> Bitmap Index Scan on moc100_coverage_idx (cost=0.00..38.92 rows=1 width=0) (actual rows=35 loops=1) - Index Cond: (coverage && '4/0'::smoc) - Buffers: shared hit=9 - Planning: - Buffers: shared hit=1 -(9 rows) - -EXPLAIN (ANALYZE, BUFFERS, TIMING OFF, SUMMARY OFF) - SELECT * FROM moc100 WHERE coverage <@ '4/0'; - QUERY PLAN ------------------------------------------------------------------------------------------------------------- - Bitmap Heap Scan on moc100 (cost=47.61..51.63 rows=1 width=96) (actual rows=1 loops=1) - Recheck Cond: (coverage <@ '4/0'::smoc) - Rows Removed by Index Recheck: 35 - Heap Blocks: exact=5 - Buffers: shared hit=33 - -> Bitmap Index Scan on moc100_coverage_idx (cost=0.00..47.61 rows=1 width=0) (actual rows=36 loops=1) - Index Cond: (coverage <@ '4/0'::smoc) - Buffers: shared hit=12 - Planning: - Buffers: shared hit=4 -(10 rows) - -EXPLAIN (ANALYZE, BUFFERS, TIMING OFF, SUMMARY OFF) - SELECT * FROM moc100 WHERE coverage @> '4/0'; - QUERY PLAN ------------------------------------------------------------------------------------------------------------- - Bitmap Heap Scan on moc100 (cost=38.92..42.93 rows=1 width=96) (actual rows=28 loops=1) - Recheck Cond: (coverage @> '4/0'::smoc) - Rows Removed by Index Recheck: 1 - Heap Blocks: exact=4 - Buffers: shared hit=36 - -> Bitmap Index Scan on moc100_coverage_idx (cost=0.00..38.92 rows=1 width=0) (actual rows=29 loops=1) - Index Cond: (coverage @> '4/0'::smoc) - Buffers: shared hit=9 - Planning: - Buffers: shared hit=4 -(10 rows) - -EXPLAIN (ANALYZE, BUFFERS, TIMING OFF, SUMMARY OFF) - SELECT * FROM moc100 WHERE coverage = '0/0-11'; - QUERY PLAN ----------------------------------------------------------------------------------------------------------------- - Bitmap Heap Scan on moc100 (cost=106879.01..106883.02 rows=1 width=96) (actual rows=23 loops=1) - Recheck Cond: (coverage = '0/0-11'::smoc) - Rows Removed by Index Recheck: 1 - Heap Blocks: exact=2 - Buffers: shared hit=24581 - -> Bitmap Index Scan on moc100_coverage_idx (cost=0.00..106879.01 rows=1 width=0) (actual rows=24 loops=1) - Index Cond: (coverage = '0/0-11'::smoc) - Buffers: shared hit=24577 - Planning: - Buffers: shared hit=1 - JIT: - Functions: 2 - Options: Inlining false, Optimization false, Expressions true, Deforming true -(13 rows) - -EXPLAIN (ANALYZE, BUFFERS, TIMING OFF, SUMMARY OFF) - SELECT * FROM moc100 WHERE coverage = '6/43225,43227'; - QUERY PLAN ------------------------------------------------------------------------------------------------------------- - Bitmap Heap Scan on moc100 (cost=12.83..16.84 rows=1 width=96) (actual rows=1 loops=1) - Recheck Cond: (coverage = '6/43225 43227'::smoc) - Rows Removed by Index Recheck: 28 - Heap Blocks: exact=3 - Buffers: shared hit=12 - -> Bitmap Index Scan on moc100_coverage_idx (cost=0.00..12.83 rows=1 width=0) (actual rows=29 loops=1) - Index Cond: (coverage = '6/43225 43227'::smoc) - Buffers: shared hit=3 - Planning: - Buffers: shared hit=1 -(10 rows) - -EXPLAIN (ANALYZE, BUFFERS, TIMING OFF, SUMMARY OFF) - SELECT * FROM moc100 WHERE coverage = '0/'; - QUERY PLAN ------------------------------------------------------------------------------------------------------------ - Bitmap Heap Scan on moc100 (cost=12.83..16.84 rows=1 width=96) (actual rows=1 loops=1) - Recheck Cond: (coverage = '0/'::smoc) - Heap Blocks: exact=1 - Buffers: shared hit=5 - -> Bitmap Index Scan on moc100_coverage_idx (cost=0.00..12.83 rows=1 width=0) (actual rows=1 loops=1) - Index Cond: (coverage = '0/'::smoc) - Buffers: shared hit=4 - Planning: - Buffers: shared hit=1 -(9 rows) - -EXPLAIN (ANALYZE, BUFFERS, TIMING OFF, SUMMARY OFF) - SELECT * FROM moc100 WHERE coverage <> '0/0-11'; - QUERY PLAN -------------------------------------------------------------------------------------------------------------------- - Bitmap Heap Scan on moc100 (cost=106888.23..106895.48 rows=100 width=96) (actual rows=78 loops=1) - Recheck Cond: (coverage <> '0/0-11'::smoc) - Rows Removed by Index Recheck: 23 - Heap Blocks: exact=5 - Buffers: shared hit=24821 - -> Bitmap Index Scan on moc100_coverage_idx (cost=0.00..106888.20 rows=100 width=0) (actual rows=101 loops=1) - Index Cond: (coverage <> '0/0-11'::smoc) - Buffers: shared hit=24762 - Planning: - Buffers: shared hit=1 - JIT: - Functions: 2 - Options: Inlining false, Optimization false, Expressions true, Deforming true -(13 rows) - -EXPLAIN (ANALYZE, BUFFERS, TIMING OFF, SUMMARY OFF) - SELECT * FROM moc100 WHERE coverage <> '6/43225,43227'; - QUERY PLAN -------------------------------------------------------------------------------------------------------------------- - Bitmap Heap Scan on moc100 (cost=106888.23..106895.48 rows=100 width=96) (actual rows=100 loops=1) - Recheck Cond: (coverage <> '6/43225 43227'::smoc) - Rows Removed by Index Recheck: 1 - Heap Blocks: exact=5 - Buffers: shared hit=247 - -> Bitmap Index Scan on moc100_coverage_idx (cost=0.00..106888.20 rows=100 width=0) (actual rows=101 loops=1) - Index Cond: (coverage <> '6/43225 43227'::smoc) - Buffers: shared hit=188 - Planning: - Buffers: shared hit=1 - JIT: - Functions: 2 - Options: Inlining false, Optimization false, Expressions true, Deforming true -(13 rows) - -EXPLAIN (ANALYZE, BUFFERS, TIMING OFF, SUMMARY OFF) - SELECT * FROM moc100 WHERE coverage <> '0/'; - QUERY PLAN -------------------------------------------------------------------------------------------------------------------- - Bitmap Heap Scan on moc100 (cost=106888.23..106895.48 rows=100 width=96) (actual rows=100 loops=1) - Recheck Cond: (coverage <> '0/'::smoc) - Rows Removed by Index Recheck: 1 - Heap Blocks: exact=5 - Buffers: shared hit=245 - -> Bitmap Index Scan on moc100_coverage_idx (cost=0.00..106888.20 rows=100 width=0) (actual rows=101 loops=1) - Index Cond: (coverage <> '0/'::smoc) - Buffers: shared hit=186 - Planning: - Buffers: shared hit=1 - JIT: - Functions: 2 - Options: Inlining false, Optimization false, Expressions true, Deforming true -(13 rows) - diff --git a/expected/moc100_5.out b/expected/moc100_5.out deleted file mode 100644 index 3fb98a4..0000000 --- a/expected/moc100_5.out +++ /dev/null @@ -1,309 +0,0 @@ -\set ECHO none - outputfile_for_majorversion ------------------------------ - 16+ -(1 row) - - outputfile_for_arch_bits --------------------------- - 32-bit -(1 row) - -CREATE TABLE moc100 ( - ivoid text, - coverage smoc, - ref_system_name text -); -COPY moc100 FROM STDIN; -CREATE INDEX ON moc100 USING GIN (coverage); -SELECT ivoid FROM moc100 WHERE coverage && '4/0' ORDER BY ivoid; - ivoid ------------------------------------------- - ivo://byu.arvo/dfbsspec/q/getssa - ivo://cadc.nrc.ca/archive/cfht - ivo://cadc.nrc.ca/archive/hst - ivo://cds.vizier/b/assocdata - ivo://cds.vizier/b/swift - ivo://cds.vizier/i/241 - ivo://cds.vizier/iv/12 - ivo://cds.vizier/ix/13 - ivo://cds.vizier/j/a+a/316/147 - ivo://cds.vizier/j/a+as/105/311 - ivo://cds.vizier/j/a+as/122/235 - ivo://chivo/gaia/q/dr1 - ivo://chivo/openngc/q/data - ivo://cxc.harvard.edu/csc - ivo://irsa.ipac/2mass/catalog/psc - ivo://irsa.ipac/2mass/catalog/xsc - ivo://irsa.ipac/2mass/images/asky-ql - ivo://irsa.ipac/cosmos/images - ivo://irsa.ipac/iras/images/issa - ivo://irsa.ipac/mast/scrapbook - ivo://irsa.ipac/spitzer/images/swire - ivo://mssl.ucl.ac.uk/xmmsuss_dsa/xmmsuss - ivo://ned.ipac/sia - ivo://ned.ipac/tap - ivo://svo.cab/cat/gbs - ivo://svo.cab/cat/uves - ivo://svo.cab/cat/xshooter - ivo://vopdc.iap/fss - ivo://vopdc.obspm/imcce/m4ast - ivo://vopdc.obspm/imcce/miriade - ivo://vopdc.obspm/imcce/skybot - ivo://vopdc.obspm/lesia/bestars/besc - ivo://vopdc.obspm/lesia/bestars/bess - ivo://vopdc.obspm/luth/exoplanet - ivo://vopdc.obspm/luth/hess -(35 rows) - -EXPLAIN (ANALYZE, BUFFERS, TIMING OFF, SUMMARY OFF) - SELECT * FROM moc100 WHERE coverage && '0/'; - QUERY PLAN ----------------------------------------------------------------------------------------------------------- - Bitmap Heap Scan on moc100 (cost=0.00..4.01 rows=1 width=96) (actual rows=0 loops=1) - Recheck Cond: (coverage && '0/'::smoc) - -> Bitmap Index Scan on moc100_coverage_idx (cost=0.00..0.00 rows=1 width=0) (actual rows=0 loops=1) - Index Cond: (coverage && '0/'::smoc) - Planning: - Buffers: shared hit=5 -(6 rows) - -EXPLAIN (ANALYZE, BUFFERS, TIMING OFF, SUMMARY OFF) - SELECT * FROM moc100 WHERE coverage && '4/0'; - QUERY PLAN --------------------------------------------------------------------------------- - Seq Scan on moc100 (cost=0.00..6.26 rows=1 width=96) (actual rows=35 loops=1) - Filter: (coverage && '4/0'::smoc) - Rows Removed by Filter: 66 - Buffers: shared hit=115 - Planning: - Buffers: shared hit=1 -(6 rows) - -EXPLAIN (ANALYZE, BUFFERS, TIMING OFF, SUMMARY OFF) - SELECT * FROM moc100 WHERE coverage = '0/0-11'; - QUERY PLAN --------------------------------------------------------------------------------- - Seq Scan on moc100 (cost=0.00..6.26 rows=1 width=96) (actual rows=23 loops=1) - Filter: (coverage = '0/0-11'::smoc) - Rows Removed by Filter: 78 - Buffers: shared hit=59 - Planning: - Buffers: shared hit=4 -(6 rows) - -EXPLAIN (ANALYZE, BUFFERS, TIMING OFF, SUMMARY OFF) - SELECT * FROM moc100 WHERE coverage = '6/43225,43227'; - QUERY PLAN -------------------------------------------------------------------------------- - Seq Scan on moc100 (cost=0.00..6.26 rows=1 width=96) (actual rows=1 loops=1) - Filter: (coverage = '6/43225 43227'::smoc) - Rows Removed by Filter: 100 - Buffers: shared hit=59 - Planning: - Buffers: shared hit=1 -(6 rows) - -EXPLAIN (ANALYZE, BUFFERS, TIMING OFF, SUMMARY OFF) - SELECT * FROM moc100 WHERE coverage = '0/'; - QUERY PLAN -------------------------------------------------------------------------------- - Seq Scan on moc100 (cost=0.00..6.26 rows=1 width=96) (actual rows=1 loops=1) - Filter: (coverage = '0/'::smoc) - Rows Removed by Filter: 100 - Buffers: shared hit=59 - Planning: - Buffers: shared hit=1 -(6 rows) - -EXPLAIN (ANALYZE, BUFFERS, TIMING OFF, SUMMARY OFF) - SELECT * FROM moc100 WHERE coverage <> '0/0-11'; - QUERY PLAN ----------------------------------------------------------------------------------- - Seq Scan on moc100 (cost=0.00..6.26 rows=100 width=96) (actual rows=78 loops=1) - Filter: (coverage <> '0/0-11'::smoc) - Rows Removed by Filter: 23 - Buffers: shared hit=59 - Planning: - Buffers: shared hit=4 -(6 rows) - -EXPLAIN (ANALYZE, BUFFERS, TIMING OFF, SUMMARY OFF) - SELECT * FROM moc100 WHERE coverage <> '6/43225,43227'; - QUERY PLAN ------------------------------------------------------------------------------------ - Seq Scan on moc100 (cost=0.00..6.26 rows=100 width=96) (actual rows=100 loops=1) - Filter: (coverage <> '6/43225 43227'::smoc) - Rows Removed by Filter: 1 - Buffers: shared hit=59 - Planning: - Buffers: shared hit=1 -(6 rows) - -EXPLAIN (ANALYZE, BUFFERS, TIMING OFF, SUMMARY OFF) - SELECT * FROM moc100 WHERE coverage <> '0/'; - QUERY PLAN ------------------------------------------------------------------------------------ - Seq Scan on moc100 (cost=0.00..6.26 rows=100 width=96) (actual rows=100 loops=1) - Filter: (coverage <> '0/'::smoc) - Rows Removed by Filter: 1 - Buffers: shared hit=59 - Planning: - Buffers: shared hit=1 -(6 rows) - -SET enable_seqscan = off; -EXPLAIN (ANALYZE, BUFFERS, TIMING OFF, SUMMARY OFF) - SELECT * FROM moc100 WHERE coverage && '4/0'; - QUERY PLAN ------------------------------------------------------------------------------------------------------------- - Bitmap Heap Scan on moc100 (cost=38.92..42.93 rows=1 width=96) (actual rows=35 loops=1) - Recheck Cond: (coverage && '4/0'::smoc) - Heap Blocks: exact=5 - Buffers: shared hit=86 - -> Bitmap Index Scan on moc100_coverage_idx (cost=0.00..38.92 rows=1 width=0) (actual rows=35 loops=1) - Index Cond: (coverage && '4/0'::smoc) - Buffers: shared hit=9 - Planning: - Buffers: shared hit=1 -(9 rows) - -EXPLAIN (ANALYZE, BUFFERS, TIMING OFF, SUMMARY OFF) - SELECT * FROM moc100 WHERE coverage <@ '4/0'; - QUERY PLAN ------------------------------------------------------------------------------------------------------------- - Bitmap Heap Scan on moc100 (cost=47.61..51.63 rows=1 width=96) (actual rows=1 loops=1) - Recheck Cond: (coverage <@ '4/0'::smoc) - Rows Removed by Index Recheck: 35 - Heap Blocks: exact=5 - Buffers: shared hit=33 - -> Bitmap Index Scan on moc100_coverage_idx (cost=0.00..47.61 rows=1 width=0) (actual rows=36 loops=1) - Index Cond: (coverage <@ '4/0'::smoc) - Buffers: shared hit=12 - Planning: - Buffers: shared hit=4 -(10 rows) - -EXPLAIN (ANALYZE, BUFFERS, TIMING OFF, SUMMARY OFF) - SELECT * FROM moc100 WHERE coverage @> '4/0'; - QUERY PLAN ------------------------------------------------------------------------------------------------------------- - Bitmap Heap Scan on moc100 (cost=38.92..42.93 rows=1 width=96) (actual rows=28 loops=1) - Recheck Cond: (coverage @> '4/0'::smoc) - Rows Removed by Index Recheck: 1 - Heap Blocks: exact=4 - Buffers: shared hit=36 - -> Bitmap Index Scan on moc100_coverage_idx (cost=0.00..38.92 rows=1 width=0) (actual rows=29 loops=1) - Index Cond: (coverage @> '4/0'::smoc) - Buffers: shared hit=9 - Planning: - Buffers: shared hit=4 -(10 rows) - -EXPLAIN (ANALYZE, BUFFERS, TIMING OFF, SUMMARY OFF) - SELECT * FROM moc100 WHERE coverage = '0/0-11'; - QUERY PLAN ----------------------------------------------------------------------------------------------------------------- - Bitmap Heap Scan on moc100 (cost=106879.01..106883.02 rows=1 width=96) (actual rows=23 loops=1) - Recheck Cond: (coverage = '0/0-11'::smoc) - Rows Removed by Index Recheck: 1 - Heap Blocks: exact=2 - Buffers: shared hit=24581 - -> Bitmap Index Scan on moc100_coverage_idx (cost=0.00..106879.01 rows=1 width=0) (actual rows=24 loops=1) - Index Cond: (coverage = '0/0-11'::smoc) - Buffers: shared hit=24577 - Planning: - Buffers: shared hit=1 - JIT: - Functions: 2 - Options: Inlining false, Optimization false, Expressions true, Deforming true -(13 rows) - -EXPLAIN (ANALYZE, BUFFERS, TIMING OFF, SUMMARY OFF) - SELECT * FROM moc100 WHERE coverage = '6/43225,43227'; - QUERY PLAN ------------------------------------------------------------------------------------------------------------- - Bitmap Heap Scan on moc100 (cost=12.83..16.84 rows=1 width=96) (actual rows=1 loops=1) - Recheck Cond: (coverage = '6/43225 43227'::smoc) - Rows Removed by Index Recheck: 28 - Heap Blocks: exact=3 - Buffers: shared hit=12 - -> Bitmap Index Scan on moc100_coverage_idx (cost=0.00..12.83 rows=1 width=0) (actual rows=29 loops=1) - Index Cond: (coverage = '6/43225 43227'::smoc) - Buffers: shared hit=3 - Planning: - Buffers: shared hit=1 -(10 rows) - -EXPLAIN (ANALYZE, BUFFERS, TIMING OFF, SUMMARY OFF) - SELECT * FROM moc100 WHERE coverage = '0/'; - QUERY PLAN ------------------------------------------------------------------------------------------------------------ - Bitmap Heap Scan on moc100 (cost=12.83..16.84 rows=1 width=96) (actual rows=1 loops=1) - Recheck Cond: (coverage = '0/'::smoc) - Heap Blocks: exact=1 - Buffers: shared hit=5 - -> Bitmap Index Scan on moc100_coverage_idx (cost=0.00..12.83 rows=1 width=0) (actual rows=1 loops=1) - Index Cond: (coverage = '0/'::smoc) - Buffers: shared hit=4 - Planning: - Buffers: shared hit=1 -(9 rows) - -EXPLAIN (ANALYZE, BUFFERS, TIMING OFF, SUMMARY OFF) - SELECT * FROM moc100 WHERE coverage <> '0/0-11'; - QUERY PLAN -------------------------------------------------------------------------------------------------------------------- - Bitmap Heap Scan on moc100 (cost=106888.23..106894.48 rows=100 width=96) (actual rows=78 loops=1) - Recheck Cond: (coverage <> '0/0-11'::smoc) - Rows Removed by Index Recheck: 23 - Heap Blocks: exact=5 - Buffers: shared hit=24804 - -> Bitmap Index Scan on moc100_coverage_idx (cost=0.00..106888.20 rows=100 width=0) (actual rows=101 loops=1) - Index Cond: (coverage <> '0/0-11'::smoc) - Buffers: shared hit=24745 - Planning: - Buffers: shared hit=1 - JIT: - Functions: 2 - Options: Inlining false, Optimization false, Expressions true, Deforming true -(13 rows) - -EXPLAIN (ANALYZE, BUFFERS, TIMING OFF, SUMMARY OFF) - SELECT * FROM moc100 WHERE coverage <> '6/43225,43227'; - QUERY PLAN -------------------------------------------------------------------------------------------------------------------- - Bitmap Heap Scan on moc100 (cost=106888.23..106894.48 rows=100 width=96) (actual rows=100 loops=1) - Recheck Cond: (coverage <> '6/43225 43227'::smoc) - Rows Removed by Index Recheck: 1 - Heap Blocks: exact=5 - Buffers: shared hit=230 - -> Bitmap Index Scan on moc100_coverage_idx (cost=0.00..106888.20 rows=100 width=0) (actual rows=101 loops=1) - Index Cond: (coverage <> '6/43225 43227'::smoc) - Buffers: shared hit=171 - Planning: - Buffers: shared hit=1 - JIT: - Functions: 2 - Options: Inlining false, Optimization false, Expressions true, Deforming true -(13 rows) - -EXPLAIN (ANALYZE, BUFFERS, TIMING OFF, SUMMARY OFF) - SELECT * FROM moc100 WHERE coverage <> '0/'; - QUERY PLAN -------------------------------------------------------------------------------------------------------------------- - Bitmap Heap Scan on moc100 (cost=106888.23..106894.48 rows=100 width=96) (actual rows=100 loops=1) - Recheck Cond: (coverage <> '0/'::smoc) - Rows Removed by Index Recheck: 1 - Heap Blocks: exact=5 - Buffers: shared hit=228 - -> Bitmap Index Scan on moc100_coverage_idx (cost=0.00..106888.20 rows=100 width=0) (actual rows=101 loops=1) - Index Cond: (coverage <> '0/'::smoc) - Buffers: shared hit=169 - Planning: - Buffers: shared hit=1 - JIT: - Functions: 2 - Options: Inlining false, Optimization false, Expressions true, Deforming true -(13 rows) - diff --git a/sql/moc100.sql b/sql/moc100.sql index 8c700b1..93afd1e 100644 --- a/sql/moc100.sql +++ b/sql/moc100.sql @@ -1,14 +1,3 @@ -\set ECHO none -SELECT CASE - WHEN setting::int/10000 IN (10, 11, 12) THEN '10, 11, 12' -- moc100 - WHEN setting::int/10000 IN (13, 14, 15) THEN '13, 14, 15' -- moc100_2 - ELSE '16+' -END AS outputfile_for_majorversion -FROM pg_settings WHERE name = 'server_version_num'; - -SELECT (regexp_matches(version(), '..-bit'))[1] outputfile_for_arch_bits; -\set ECHO queries - CREATE TABLE moc100 ( ivoid text, coverage smoc, @@ -119,59 +108,38 @@ ivo://cds.vizier/j/a+as/124/353 6/24603,24796,25383,26065,27212,29368,29399,3101 empty 0/ \N \. +ANALYZE moc100; CREATE INDEX ON moc100 USING GIN (coverage); SELECT ivoid FROM moc100 WHERE coverage && '4/0' ORDER BY ivoid; -EXPLAIN (ANALYZE, BUFFERS, TIMING OFF, SUMMARY OFF) - SELECT * FROM moc100 WHERE coverage && '0/'; - -EXPLAIN (ANALYZE, BUFFERS, TIMING OFF, SUMMARY OFF) - SELECT * FROM moc100 WHERE coverage && '4/0'; - -EXPLAIN (ANALYZE, BUFFERS, TIMING OFF, SUMMARY OFF) - SELECT * FROM moc100 WHERE coverage = '0/0-11'; - -EXPLAIN (ANALYZE, BUFFERS, TIMING OFF, SUMMARY OFF) - SELECT * FROM moc100 WHERE coverage = '6/43225,43227'; - -EXPLAIN (ANALYZE, BUFFERS, TIMING OFF, SUMMARY OFF) - SELECT * FROM moc100 WHERE coverage = '0/'; - -EXPLAIN (ANALYZE, BUFFERS, TIMING OFF, SUMMARY OFF) - SELECT * FROM moc100 WHERE coverage <> '0/0-11'; - -EXPLAIN (ANALYZE, BUFFERS, TIMING OFF, SUMMARY OFF) - SELECT * FROM moc100 WHERE coverage <> '6/43225,43227'; - -EXPLAIN (ANALYZE, BUFFERS, TIMING OFF, SUMMARY OFF) - SELECT * FROM moc100 WHERE coverage <> '0/'; +-- PG 10 does not have JIT, ignore errors on SET +DO $$ + begin + set jit = off; + exception + when undefined_object then null; + when others then raise; + end; +$$; + +SELECT explain ($$SELECT * FROM moc100 WHERE coverage && '0/'$$); +SELECT explain ($$SELECT * FROM moc100 WHERE coverage && '4/0'$$); +SELECT explain ($$SELECT * FROM moc100 WHERE coverage = '0/0-11'$$); +SELECT explain ($$SELECT * FROM moc100 WHERE coverage = '6/43225,43227'$$); +SELECT explain ($$SELECT * FROM moc100 WHERE coverage = '0/'$$); +SELECT explain ($$SELECT * FROM moc100 WHERE coverage <> '0/0-11'$$); +SELECT explain ($$SELECT * FROM moc100 WHERE coverage <> '6/43225,43227'$$); +SELECT explain ($$SELECT * FROM moc100 WHERE coverage <> '0/'$$); SET enable_seqscan = off; -EXPLAIN (ANALYZE, BUFFERS, TIMING OFF, SUMMARY OFF) - SELECT * FROM moc100 WHERE coverage && '4/0'; - -EXPLAIN (ANALYZE, BUFFERS, TIMING OFF, SUMMARY OFF) - SELECT * FROM moc100 WHERE coverage <@ '4/0'; - -EXPLAIN (ANALYZE, BUFFERS, TIMING OFF, SUMMARY OFF) - SELECT * FROM moc100 WHERE coverage @> '4/0'; - -EXPLAIN (ANALYZE, BUFFERS, TIMING OFF, SUMMARY OFF) - SELECT * FROM moc100 WHERE coverage = '0/0-11'; - -EXPLAIN (ANALYZE, BUFFERS, TIMING OFF, SUMMARY OFF) - SELECT * FROM moc100 WHERE coverage = '6/43225,43227'; - -EXPLAIN (ANALYZE, BUFFERS, TIMING OFF, SUMMARY OFF) - SELECT * FROM moc100 WHERE coverage = '0/'; - -EXPLAIN (ANALYZE, BUFFERS, TIMING OFF, SUMMARY OFF) - SELECT * FROM moc100 WHERE coverage <> '0/0-11'; - -EXPLAIN (ANALYZE, BUFFERS, TIMING OFF, SUMMARY OFF) - SELECT * FROM moc100 WHERE coverage <> '6/43225,43227'; - -EXPLAIN (ANALYZE, BUFFERS, TIMING OFF, SUMMARY OFF) - SELECT * FROM moc100 WHERE coverage <> '0/'; +SELECT explain ($$SELECT * FROM moc100 WHERE coverage && '4/0'$$); +SELECT explain ($$SELECT * FROM moc100 WHERE coverage <@ '4/0'$$); +SELECT explain ($$SELECT * FROM moc100 WHERE coverage @> '4/0'$$); +SELECT explain ($$SELECT * FROM moc100 WHERE coverage = '0/0-11'$$); +SELECT explain ($$SELECT * FROM moc100 WHERE coverage = '6/43225,43227'$$); +SELECT explain ($$SELECT * FROM moc100 WHERE coverage = '0/'$$); +SELECT explain ($$SELECT * FROM moc100 WHERE coverage <> '0/0-11'$$); +SELECT explain ($$SELECT * FROM moc100 WHERE coverage <> '6/43225,43227'$$); +SELECT explain ($$SELECT * FROM moc100 WHERE coverage <> '0/'$$); From e810f5ddd827881b06a92a303c5c9fbf997b892e Mon Sep 17 00:00:00 2001 From: Christoph Berg Date: Thu, 26 Oct 2023 12:01:10 +0200 Subject: [PATCH 53/87] Drop obsolete compatibility @({bigint,spoint}, smoc) operators These were required by GAVO DaCHS, but are not used anymore. Furthermore, PG17 will forbid declaring commutators and negators relations with operators that themselves have relations to different operators. We delete pgs_moc_compat.sql.in and remove it from the old pg_sphere--1.1.5beta2gavo--1.1.5beta4gavo.sql upgrade script. This is ok to do since dropping the operators uses "if exists". Discussion: https://www.postgresql.org/message-id/flat/ZTfL1G1fBPQHVPWV%40msg.df7cb.de#ce3801c084bcf05b6b976cb2d0e25b2d Close #85. --- Makefile | 4 ++-- pgs_moc_compat.sql.in | 22 ------------------- .../pg_sphere--1.3.1--1.3.2.sql.in | 4 ++++ 3 files changed, 6 insertions(+), 24 deletions(-) delete mode 100644 pgs_moc_compat.sql.in diff --git a/Makefile b/Makefile index 5782814..2a685d3 100644 --- a/Makefile +++ b/Makefile @@ -65,7 +65,7 @@ endif PGS_SQL += pgs_gist_spoint3.sql ifneq ($(USE_HEALPIX),0) -PGS_SQL += pgs_moc_type.sql pgs_moc_compat.sql pgs_moc_ops.sql \ +PGS_SQL += pgs_moc_type.sql pgs_moc_ops.sql \ pgs_moc_geo_casts.sql endif @@ -154,7 +154,7 @@ ifneq ($(USE_HEALPIX),0) pg_sphere--1.1.5beta0gavo--1.1.5beta2gavo.sql: pgs_moc_type.sql.in cat upgrade_scripts/$@.in $^ > $@ -pg_sphere--1.1.5beta2gavo--1.1.5beta4gavo.sql: pgs_moc_compat.sql.in +pg_sphere--1.1.5beta2gavo--1.1.5beta4gavo.sql: cat upgrade_scripts/$@.in $^ > $@ pg_sphere--1.1.5beta4gavo--1.2.0.sql: pgs_moc_ops.sql.in diff --git a/pgs_moc_compat.sql.in b/pgs_moc_compat.sql.in deleted file mode 100644 index 212b4f3..0000000 --- a/pgs_moc_compat.sql.in +++ /dev/null @@ -1,22 +0,0 @@ --- a minimal set of backwards-compatible operators for GAVO DaCHS, --- see http://soft.g-vo.org/dachs - -CREATE OPERATOR @ ( - LEFTARG = bigint, - RIGHTARG = smoc, - PROCEDURE = healpix_subset_smoc, - COMMUTATOR = '@>', - NEGATOR = '!<@', - RESTRICT = contsel, - JOIN = contjoinsel -); - -CREATE OPERATOR @ ( - LEFTARG = spoint, - RIGHTARG = smoc, - PROCEDURE = spoint_subset_smoc, - COMMUTATOR = '@>', - NEGATOR = '!<@', - RESTRICT = contsel, - JOIN = contjoinsel -); diff --git a/upgrade_scripts/pg_sphere--1.3.1--1.3.2.sql.in b/upgrade_scripts/pg_sphere--1.3.1--1.3.2.sql.in index 1ada066..bdad0c2 100644 --- a/upgrade_scripts/pg_sphere--1.3.1--1.3.2.sql.in +++ b/upgrade_scripts/pg_sphere--1.3.1--1.3.2.sql.in @@ -12,3 +12,7 @@ EXCEPTION WHEN OTHERS THEN RAISE; END; $$; + +-- remove legacy spellings of operators +DROP OPERATOR IF EXISTS @(bigint, smoc); +DROP OPERATOR IF EXISTS @(spoint, smoc); From 2ce76ba5cd08794e3438202975067ae464c86198 Mon Sep 17 00:00:00 2001 From: Christoph Berg Date: Mon, 30 Oct 2023 10:48:24 +0100 Subject: [PATCH 54/87] Add *.cpp to .editorconfig src/process_moc.cpp is C++. --- .editorconfig | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.editorconfig b/.editorconfig index d69a3d1..993a1d1 100644 --- a/.editorconfig +++ b/.editorconfig @@ -1,6 +1,6 @@ root = true -[*.{c,h,l,y,pl,pm}] +[*.{c,cpp,h,l,y,pl,pm}] indent_style = tab indent_size = tab tab_width = 4 From 0fcfa3631972c84b83baf856eda07b5e31eb42e8 Mon Sep 17 00:00:00 2001 From: Ed Sabol Date: Sat, 28 Oct 2023 18:55:00 -0400 Subject: [PATCH 55/87] Add function to create spoly from an array of numbers in radians. --- expected/poly.out | 26 ++++++ pgs_polygon.sql.in | 41 ++++++---- sql/poly.sql | 14 ++++ src/polygon.c | 82 ++++++++++++++++--- src/polygon.h | 9 +- .../pg_sphere--1.3.1--1.3.2.sql.in | 17 ++++ 6 files changed, 160 insertions(+), 29 deletions(-) diff --git a/expected/poly.out b/expected/poly.out index 50e510e..2d622b5 100644 --- a/expected/poly.out +++ b/expected/poly.out @@ -318,6 +318,18 @@ SELECT spoly '{(10d,0d),(10d,1d),(15d,0d)}'; {(10d , 0d),(10d , 1d),(15d , 0d)} (1 row) +SELECT spoly(ARRAY[0.017453292519943295, 0.03490658503988659, 0.05235987755982988, 0.06981317007977318, 0.08726646259971647, 0.10471975511965977]); + spoly +--------------------------------- + {(1d , 2d),(3d , 4d),(5d , 6d)} +(1 row) + +SELECT spoly(ARRAY[0.17453292519943295, 0.0, 0.17453292519943295, 0.017453292519943295, 0.2617993877991494, 0.0]); + spoly +------------------------------------ + {(10d , 0d),(10d , 1d),(15d , 0d)} +(1 row) + SELECT spoly_deg(ARRAY[1.0, 2.0, 3.0, 4.0, 5.0, 6.0]); spoly_deg --------------------------------- @@ -335,8 +347,22 @@ SELECT spoly '{(10d,0d),(10d,1d)}'; ERROR: spherepoly_in: more than two points needed LINE 1: SELECT spoly '{(10d,0d),(10d,1d)}'; ^ +SELECT spoly(ARRAY[1.0, 2.0, 3.0, 4.0, 5.0]); +ERROR: spherepoly_rad: invalid number of arguments (must be even and >= 6) +SELECT spoly(ARRAY[1.0, 2.0, 3.0, NULL, 5.0, 6.0]); +ERROR: spherepoly_rad: input array is invalid because it has null values +SELECT spoly(ARRAY[]::float8[]); +ERROR: spherepoly_rad: invalid number of arguments (must be even and >= 6) +SELECT spoly(NULL::float8[]); + spoly +------- + +(1 row) + SELECT spoly_deg(ARRAY[1.0, 2.0, 3.0, 4.0, 5.0]); ERROR: spherepoly_deg: invalid number of arguments (must be even and >= 6) +SELECT spoly_deg(ARRAY[1.0, 2.0, 3.0, NULL, 5.0, 6.0]); +ERROR: spherepoly_deg: input array is invalid because it has null values SELECT spoly_deg(ARRAY[]::float8[]); ERROR: spherepoly_deg: invalid number of arguments (must be even and >= 6) SELECT spoly_deg(NULL::float8[]); diff --git a/pgs_polygon.sql.in b/pgs_polygon.sql.in index fdd4277..3a5d801 100644 --- a/pgs_polygon.sql.in +++ b/pgs_polygon.sql.in @@ -1,6 +1,8 @@ - +-- ************************** +-- -- spherical polygon functions - +-- +-- ************************** CREATE FUNCTION npoints(spoly) RETURNS INT4 @@ -933,6 +935,29 @@ COMMENT ON OPERATOR !&& (sellipse, spoly) IS 'true if spherical ellipse does not overlap spherical polygon'; +-- +-- Functions to create a polygon from arrays +-- + +CREATE FUNCTION spoly(float8[]) + RETURNS spoly + AS 'MODULE_PATHNAME', 'spherepoly_rad' + LANGUAGE 'c' + IMMUTABLE STRICT PARALLEL SAFE; + +COMMENT ON FUNCTION spoly(float8[]) IS + 'creates spoly from array of numbers in radians'; + +CREATE FUNCTION spoly_deg(float8[]) + RETURNS spoly + AS 'MODULE_PATHNAME', 'spherepoly_deg' + LANGUAGE 'c' + IMMUTABLE STRICT PARALLEL SAFE; + +COMMENT ON FUNCTION spoly_deg(float8[]) IS + 'creates spoly from array of numbers in degrees'; + + -- -- Aggregate functions to add points to polygon -- @@ -946,18 +971,6 @@ CREATE FUNCTION spoly_add_point_aggr (spoly, spoint) COMMENT ON FUNCTION spoly_add_point_aggr (spoly, spoint) IS 'adds a spherical point to spherical polygon. Do not use it standalone!'; -CREATE FUNCTION spoly_deg(float8[]) - RETURNS spoly - AS 'MODULE_PATHNAME', 'spherepoly_deg' - LANGUAGE 'c' - IMMUTABLE STRICT; - -COMMENT ON FUNCTION spoly_deg(float8[]) IS - ' Create spoly from array of points. - Two consecutive numbers among those present - refer to the same occurrence and cover its - latitude and longitude, respectively.'; - CREATE FUNCTION spoly_add_points_fin_aggr (spoly) RETURNS spoly AS 'MODULE_PATHNAME', 'spherepoly_add_points_finalize' diff --git a/sql/poly.sql b/sql/poly.sql index 2281aba..a3f36d4 100644 --- a/sql/poly.sql +++ b/sql/poly.sql @@ -78,6 +78,10 @@ SELECT spoly '{(359d,0d),(359d,1d),(4d,0d)}'; SELECT spoly '{(10d,0d),(10d,1d),(15d,0d)}'; +SELECT spoly(ARRAY[0.017453292519943295, 0.03490658503988659, 0.05235987755982988, 0.06981317007977318, 0.08726646259971647, 0.10471975511965977]); + +SELECT spoly(ARRAY[0.17453292519943295, 0.0, 0.17453292519943295, 0.017453292519943295, 0.2617993877991494, 0.0]); + SELECT spoly_deg(ARRAY[1.0, 2.0, 3.0, 4.0, 5.0, 6.0]); SELECT spoly_deg(ARRAY[10.0, 0.0, 10.0, 1.0, 15.0, 0.0]); @@ -86,8 +90,18 @@ SELECT spoly_deg(ARRAY[10.0, 0.0, 10.0, 1.0, 15.0, 0.0]); SELECT spoly '{(10d,0d),(10d,1d)}'; +SELECT spoly(ARRAY[1.0, 2.0, 3.0, 4.0, 5.0]); + +SELECT spoly(ARRAY[1.0, 2.0, 3.0, NULL, 5.0, 6.0]); + +SELECT spoly(ARRAY[]::float8[]); + +SELECT spoly(NULL::float8[]); + SELECT spoly_deg(ARRAY[1.0, 2.0, 3.0, 4.0, 5.0]); +SELECT spoly_deg(ARRAY[1.0, 2.0, 3.0, NULL, 5.0, 6.0]); + SELECT spoly_deg(ARRAY[]::float8[]); SELECT spoly_deg(NULL::float8[]); diff --git a/src/polygon.c b/src/polygon.c index 57786b8..0ed6191 100644 --- a/src/polygon.c +++ b/src/polygon.c @@ -6,6 +6,7 @@ PG_FUNCTION_INFO_V1(spherepoly_in); PG_FUNCTION_INFO_V1(spherepoly_deg); +PG_FUNCTION_INFO_V1(spherepoly_rad); PG_FUNCTION_INFO_V1(spherepoly_equal); PG_FUNCTION_INFO_V1(spherepoly_equal_neg); PG_FUNCTION_INFO_V1(spherepoly_circ); @@ -906,6 +907,56 @@ spherepoly_in(PG_FUNCTION_ARGS) PG_RETURN_POINTER(poly); } +Datum +spherepoly_rad(PG_FUNCTION_ARGS) +{ + int i, + np; + ArrayType *float_vector = PG_GETARG_ARRAYTYPE_P(0); + float8 *array_data; + SPoint *points; + + np = ArrayGetNItems(ARR_NDIM(float_vector), ARR_DIMS(float_vector)); + + if (ARR_HASNULL(float_vector)) + { + elog(ERROR, + "spherepoly_rad: input array is invalid because it has null values" + ); + PG_RETURN_NULL(); + } + + if (np < 6 || np % 2 != 0) + { + elog(ERROR, + "spherepoly_rad: invalid number of arguments (must be even and >= 6)" + ); + PG_RETURN_NULL(); + } + + np /= 2; + + points = (SPoint *) palloc(np * sizeof(SPoint)); + if (points == NULL) + { + elog(ERROR, + "spherepoly_rad: failed to allocate memory for points array" + ); + PG_RETURN_NULL(); + } + + array_data = (float8 *) ARR_DATA_PTR(float_vector); + + for (i = 0; i < np; i++) + { + create_spherepoint_from_long_lat(&points[i], + array_data[2 * i], + array_data[2 * i + 1] + ); + } + PG_RETURN_POINTER(spherepoly_from_array(points, np)); +} + Datum spherepoly_deg(PG_FUNCTION_ARGS) { @@ -917,12 +968,19 @@ spherepoly_deg(PG_FUNCTION_ARGS) np = ArrayGetNItems(ARR_NDIM(float_vector), ARR_DIMS(float_vector)); + if (ARR_HASNULL(float_vector)) + { + elog(ERROR, + "spherepoly_deg: input array is invalid because it has null values" + ); + PG_RETURN_NULL(); + } + if (np < 6 || np % 2 != 0) { - elog( - ERROR, - "spherepoly_deg: invalid number of arguments (must be even and >= 6)" - ); + elog(ERROR, + "spherepoly_deg: invalid number of arguments (must be even and >= 6)" + ); PG_RETURN_NULL(); } @@ -931,10 +989,9 @@ spherepoly_deg(PG_FUNCTION_ARGS) points = (SPoint *) palloc(np * sizeof(SPoint)); if (points == NULL) { - elog( - ERROR, - "spherepoly_deg: failed for allocate memory for points array" - ); + elog(ERROR, + "spherepoly_deg: failed to allocate memory for points array" + ); PG_RETURN_NULL(); } @@ -942,11 +999,10 @@ spherepoly_deg(PG_FUNCTION_ARGS) for (i = 0; i < np; i++) { - create_spherepoint_from_long_lat( - &points[i], - deg_to_rad(array_data[2 * i]), - deg_to_rad(array_data[2 * i + 1]) - ); + create_spherepoint_from_long_lat(&points[i], + deg_to_rad(array_data[2 * i]), + deg_to_rad(array_data[2 * i + 1]) + ); } PG_RETURN_POINTER(spherepoly_from_array(points, np)); } diff --git a/src/polygon.h b/src/polygon.h index d52a9c6..e90b7c5 100644 --- a/src/polygon.h +++ b/src/polygon.h @@ -87,9 +87,14 @@ Datum spherepoly_get_point(PG_FUNCTION_ARGS); int8 poly_line_pos(const SPOLY *poly, const SLine *line); /* - * Input of a spherical from sequence of pairconsecutive numbers(lng, lat). + * Input of a spherical from array of pair-consecutive numbers (lng, lat), in radians. */ -Datum spherepoly_deg(PG_FUNCTION_ARGS); +Datum spherepoly_rad(PG_FUNCTION_ARGS); + +/* + * Input of a spherical from array of pair-consecutive numbers (lng, lat), in degrees. + */ +Datum spherepoly_deg(PG_FUNCTION_ARGS); /* * Input of a spherical polygon. diff --git a/upgrade_scripts/pg_sphere--1.3.1--1.3.2.sql.in b/upgrade_scripts/pg_sphere--1.3.1--1.3.2.sql.in index bdad0c2..3a80bc7 100644 --- a/upgrade_scripts/pg_sphere--1.3.1--1.3.2.sql.in +++ b/upgrade_scripts/pg_sphere--1.3.1--1.3.2.sql.in @@ -16,3 +16,20 @@ $$; -- remove legacy spellings of operators DROP OPERATOR IF EXISTS @(bigint, smoc); DROP OPERATOR IF EXISTS @(spoint, smoc); + +-- add spoly function that takes an array of float8 values in radians +CREATE FUNCTION spoly(float8[]) + RETURNS spoly + AS 'MODULE_PATHNAME', 'spherepoly_rad' + LANGUAGE 'c' + IMMUTABLE STRICT PARALLEL SAFE; + +COMMENT ON FUNCTION spoly(float8[]) IS + 'creates spoly from array of numbers in radians'; + +-- add PARALLEL SAFE to spoly_deg(float8[]) +ALTER FUNCTION spoly_deg(float8[]) IMMUTABLE STRICT PARALLEL SAFE; + +-- update comment on spoly_deg function +COMMENT ON FUNCTION spoly_deg(float8[]) IS + 'creates spoly from array of numbers in degrees'; From 9d5fa49c37206cc2cabea0bf85abf35a9c26a246 Mon Sep 17 00:00:00 2001 From: Vitaly Davydov Date: Wed, 1 Nov 2023 16:30:35 +0300 Subject: [PATCH 56/87] Add spoly(spoint[]) constructor function --- expected/poly.out | 76 ++++++++++++------- pgs_polygon.sql.in | 10 ++- sql/poly.sql | 66 +++++++++------- src/polygon.c | 28 ++++++- .../pg_sphere--1.3.1--1.3.2.sql.in | 9 +++ 5 files changed, 135 insertions(+), 54 deletions(-) diff --git a/expected/poly.out b/expected/poly.out index 2d622b5..a695915 100644 --- a/expected/poly.out +++ b/expected/poly.out @@ -12,25 +12,25 @@ SELECT spoint '(0.15,0.10)' @ :poly; -- point inside polygon t (1 row) -SELECT spoint '(0.20,0.00)' @ :poly; -- point contained polygon +SELECT spoint '(0.20,0.00)' @ :poly; -- point contained polygon ?column? ---------- t (1 row) -SELECT spoint '(0.10,0.10)' @ :poly; -- point contained polygon +SELECT spoint '(0.10,0.10)' @ :poly; -- point contained polygon ?column? ---------- t (1 row) -SELECT spoint '(0.25,0.50)' @ :poly; -- point outside polygon +SELECT spoint '(0.25,0.50)' @ :poly; -- point outside polygon ?column? ---------- f (1 row) -SELECT spoint '(0.25,0.00)' @ :poly; -- point outside polygon +SELECT spoint '(0.25,0.00)' @ :poly; -- point outside polygon ?column? ---------- f @@ -42,13 +42,13 @@ SELECT scircle '<(0.15,0.10),0.03>' @ :poly; -- circle inside polygon t (1 row) -SELECT scircle '<(0.20,0.00),0.00>' @ :poly; -- circle contained polygon +SELECT scircle '<(0.20,0.00),0.00>' @ :poly; -- circle contained polygon ?column? ---------- t (1 row) -SELECT scircle '<(0.20,0.30),0.05>' @ :poly; -- circle outside polygon +SELECT scircle '<(0.20,0.30),0.05>' @ :poly; -- circle outside polygon ?column? ---------- f @@ -72,13 +72,13 @@ SELECT scircle '<(0.15,0.10),0.03>' && :poly; -- circle inside polygon t (1 row) -SELECT scircle '<(0.20,0.00),0.00>' && :poly; -- circle contained polygon +SELECT scircle '<(0.20,0.00),0.00>' && :poly; -- circle contained polygon ?column? ---------- t (1 row) -SELECT scircle '<(0.20,0.30),0.05>' && :poly; -- circle outside polygon +SELECT scircle '<(0.20,0.30),0.05>' && :poly; -- circle outside polygon ?column? ---------- f @@ -96,13 +96,13 @@ SELECT scircle '<(0.25,0.00),0.10>' && :poly; -- circle overlaps polyg t (1 row) -SELECT sline ( spoint '(0.00, 0.00)', spoint '(0.10,0.20)' ) @ :poly; -- line touches polygon +SELECT sline ( spoint '(0.00, 0.00)', spoint '(0.10,0.20)' ) @ :poly; -- line touches polygon ?column? ---------- f (1 row) -SELECT sline ( spoint '(0.00, 0.10)', spoint '(0.10,0.10)' ) @ :poly; -- line touches polygon +SELECT sline ( spoint '(0.00, 0.10)', spoint '(0.10,0.10)' ) @ :poly; -- line touches polygon ?column? ---------- f @@ -114,7 +114,7 @@ SELECT sline ( spoint '(0.50, 0.00)', spoint '(0.50,0.20)' ) @ :poly; -- line f (1 row) -SELECT sline ( spoint '(0.10, 0.20)', spoint '(0.20,0.00)' ) @ :poly; -- line touches and inside polygon +SELECT sline ( spoint '(0.10, 0.20)', spoint '(0.20,0.00)' ) @ :poly; -- line touches and inside polygon ?column? ---------- t @@ -138,13 +138,13 @@ SELECT sline ( spoint '(0.24, 0.17)', spoint '(0.25,0.14)' ) @ :poly; -- line t (1 row) -SELECT sline ( spoint '(0.00, 0.00)', spoint '(0.10,0.20)' ) && :poly; -- line touches polygon +SELECT sline ( spoint '(0.00, 0.00)', spoint '(0.10,0.20)' ) && :poly; -- line touches polygon ?column? ---------- t (1 row) -SELECT sline ( spoint '(0.00, 0.10)', spoint '(0.10,0.10)' ) && :poly; -- line touches polygon +SELECT sline ( spoint '(0.00, 0.10)', spoint '(0.10,0.10)' ) && :poly; -- line touches polygon ?column? ---------- t @@ -156,7 +156,7 @@ SELECT sline ( spoint '(0.50, 0.00)', spoint '(0.50,0.20)' ) && :poly; -- line t (1 row) -SELECT sline ( spoint '(0.10, 0.20)', spoint '(0.20,0.00)' ) && :poly; -- line touches and inside polygon +SELECT sline ( spoint '(0.10, 0.20)', spoint '(0.20,0.00)' ) && :poly; -- line touches and inside polygon ?column? ---------- t @@ -342,7 +342,32 @@ SELECT spoly_deg(ARRAY[10.0, 0.0, 10.0, 1.0, 15.0, 0.0]); {(10d , 0d),(10d , 1d),(15d , 0d)} (1 row) --- incorrect input ----- +--- Constructors +SELECT spoly(NULL::spoint[]); + spoly +------- + +(1 row) + +SELECT spoly(ARRAY[]::spoint[]); +ERROR: spoly_deg: invalid number of arguments (must be >= 3) +SELECT spoly(ARRAY[spoint_deg(0, 0)]); +ERROR: spoly_deg: invalid number of arguments (must be >= 3) +SELECT spoly(ARRAY[spoint_deg(0, 0), spoint_deg(10, 0)]); +ERROR: spoly_deg: invalid number of arguments (must be >= 3) +SELECT spoly(ARRAY[spoint_deg(0, 0), spoint_deg(10, 0), spoint_deg(10,10)]); + spoly +------------------------------------ + {(0d , 0d),(10d , 0d),(10d , 10d)} +(1 row) + +SELECT spoly(ARRAY[spoint_deg(0, 0), spoint_deg(10, 0), spoint_deg(10,10), spoint_deg(0, 10)]); + spoly +----------------------------------------------- + {(0d , 0d),(10d , 0d),(10d , 10d),(0d , 10d)} +(1 row) + +--- incorrect input ----- SELECT spoly '{(10d,0d),(10d,1d)}'; ERROR: spherepoly_in: more than two points needed LINE 1: SELECT spoly '{(10d,0d),(10d,1d)}'; @@ -1211,7 +1236,7 @@ SELECT spoly '{(0d,-88d),(90d,-88d),(180d,-88d),(270d,-88d)}' @ spoly '{(0d,89d) (1 row) --- spoly ~ spoly ---- should be true +--- should be true SELECT spoly '{(-1d,-1d),(-1d,1d),(1d,1d),(1d,-1d)}' ~ spoly '{(0d,0d),(0d,0.5d),(0.5d,0.5d),(0.5d,0d)}'; ?column? ---------- @@ -1280,7 +1305,7 @@ SELECT spoly '{(0d,89d),(90d,89d),(180d,89d),(270d,89d)}' ~ spoly '{(0d,-88d),(9 (1 row) --- spoly && spoly ---- should be true +--- should be true SELECT spoly '{(0d,0d),(0d,0.5d),(0.5d,0.5d),(0.5d,0d)}' && spoly '{(-1d,-1d),(-1d,1d),(1d,1d),(1d,-1d)}'; ?column? ---------- @@ -1417,7 +1442,6 @@ SELECT spoly '{(-1d,-1d),(-1d,1d),(1d,1d),(1d,-1d)}' && spoly '{(179d,-1d),(179d -- -- ellipse and polygon -- - -- negators , commutator @,&& SELECT spoly '{(280d, -9d),(280d, -8d),(279d, -8d)}' @ sellipse '<{10d,5d},(280d,-20d),90d>'; ?column? @@ -1564,49 +1588,49 @@ SELECT sellipse '<{10d,5d},(280d,-20d),90d>' !&& spoly '{(280d,-11d),(280d,-12 (1 row) -- ellipse is point -SELECT spoly '{(280d, -9d),(280d, -8d),(279d, -8d)}' @ sellipse '<{0d,0d},(280d,-20d),90d>'; +SELECT spoly '{(280d, -9d),(280d, -8d),(279d, -8d)}' @ sellipse '<{0d,0d},(280d,-20d),90d>'; ?column? ---------- f (1 row) -SELECT spoly '{(280d,-11d),(280d,-20d),(279d, -12d)}' @ sellipse '<{0d,0d},(280d,-20d),90d>'; +SELECT spoly '{(280d,-11d),(280d,-20d),(279d, -12d)}' @ sellipse '<{0d,0d},(280d,-20d),90d>'; ?column? ---------- f (1 row) -SELECT spoly '{(280d, -9d),(280d, -8d),(279d, -8d)}' && sellipse '<{0d,0d},(280d,-20d),90d>'; +SELECT spoly '{(280d, -9d),(280d, -8d),(279d, -8d)}' && sellipse '<{0d,0d},(280d,-20d),90d>'; ?column? ---------- f (1 row) -SELECT spoly '{(280d,-11d),(280d,-20d),(279d, -12d)}' && sellipse '<{0d,0d},(280d,-20d),90d>'; +SELECT spoly '{(280d,-11d),(280d,-20d),(279d, -12d)}' && sellipse '<{0d,0d},(280d,-20d),90d>'; ?column? ---------- t (1 row) -SELECT sellipse '<{0d,0d},(280d,-20d),90d>' @ spoly '{(280d, -9d),(280d, -8d),(279d, -8d)}' ; +SELECT sellipse '<{0d,0d},(280d,-20d),90d>' @ spoly '{(280d, -9d),(280d, -8d),(279d, -8d)}' ; ?column? ---------- f (1 row) -SELECT sellipse '<{0d,0d},(280d,-20d),90d>' @ spoly '{(280d,-11d),(280d,-20d),(279d, -12d)}'; +SELECT sellipse '<{0d,0d},(280d,-20d),90d>' @ spoly '{(280d,-11d),(280d,-20d),(279d, -12d)}'; ?column? ---------- t (1 row) -SELECT sellipse '<{0d,0d},(280d,-20d),90d>' && spoly '{(280d, -9d),(280d, -8d),(279d, -8d)}' ; +SELECT sellipse '<{0d,0d},(280d,-20d),90d>' && spoly '{(280d, -9d),(280d, -8d),(279d, -8d)}' ; ?column? ---------- f (1 row) -SELECT sellipse '<{0d,0d},(280d,-20d),90d>' && spoly '{(280d,-11d),(280d,-20d),(279d, -12d)}'; +SELECT sellipse '<{0d,0d},(280d,-20d),90d>' && spoly '{(280d,-11d),(280d,-20d),(279d, -12d)}'; ?column? ---------- t diff --git a/pgs_polygon.sql.in b/pgs_polygon.sql.in index 3a5d801..0e73bec 100644 --- a/pgs_polygon.sql.in +++ b/pgs_polygon.sql.in @@ -948,6 +948,15 @@ CREATE FUNCTION spoly(float8[]) COMMENT ON FUNCTION spoly(float8[]) IS 'creates spoly from array of numbers in radians'; +CREATE FUNCTION spoly(spoint[]) + RETURNS spoly + AS 'MODULE_PATHNAME', 'spherepoly_from_point_array' + LANGUAGE 'c' + IMMUTABLE STRICT PARALLEL SAFE; + +COMMENT ON FUNCTION spoly(spoint[]) IS + 'creates spoly from an array of points'; + CREATE FUNCTION spoly_deg(float8[]) RETURNS spoly AS 'MODULE_PATHNAME', 'spherepoly_deg' @@ -987,7 +996,6 @@ CREATE AGGREGATE spoly ( finalfunc = spoly_add_points_fin_aggr ); - -- -- polygon is convex -- diff --git a/sql/poly.sql b/sql/poly.sql index a3f36d4..0fb992b 100644 --- a/sql/poly.sql +++ b/sql/poly.sql @@ -7,31 +7,31 @@ SET extra_float_digits = 0; \set poly 'spoly \'{(0.1,0),(0.2,0),(0.2,0.1),(0.3,0.1),(0.3,-0.1),(0.4,-0.1),(0.5,0.1),(0.4,0.2),(0.1,0.2)}\'' SELECT spoint '(0.15,0.10)' @ :poly; -- point inside polygon -SELECT spoint '(0.20,0.00)' @ :poly; -- point contained polygon -SELECT spoint '(0.10,0.10)' @ :poly; -- point contained polygon -SELECT spoint '(0.25,0.50)' @ :poly; -- point outside polygon -SELECT spoint '(0.25,0.00)' @ :poly; -- point outside polygon +SELECT spoint '(0.20,0.00)' @ :poly; -- point contained polygon +SELECT spoint '(0.10,0.10)' @ :poly; -- point contained polygon +SELECT spoint '(0.25,0.50)' @ :poly; -- point outside polygon +SELECT spoint '(0.25,0.00)' @ :poly; -- point outside polygon SELECT scircle '<(0.15,0.10),0.03>' @ :poly; -- circle inside polygon -SELECT scircle '<(0.20,0.00),0.00>' @ :poly; -- circle contained polygon -SELECT scircle '<(0.20,0.30),0.05>' @ :poly; -- circle outside polygon +SELECT scircle '<(0.20,0.00),0.00>' @ :poly; -- circle contained polygon +SELECT scircle '<(0.20,0.30),0.05>' @ :poly; -- circle outside polygon SELECT scircle '<(0.25,0.00),0.05>' @ :poly; -- circle overlaps polygon SELECT scircle '<(0.25,0.00),0.10>' @ :poly; -- circle overlaps polygon SELECT scircle '<(0.15,0.10),0.03>' && :poly; -- circle inside polygon -SELECT scircle '<(0.20,0.00),0.00>' && :poly; -- circle contained polygon -SELECT scircle '<(0.20,0.30),0.05>' && :poly; -- circle outside polygon +SELECT scircle '<(0.20,0.00),0.00>' && :poly; -- circle contained polygon +SELECT scircle '<(0.20,0.30),0.05>' && :poly; -- circle outside polygon SELECT scircle '<(0.25,0.00),0.05>' && :poly; -- circle overlaps polygon SELECT scircle '<(0.25,0.00),0.10>' && :poly; -- circle overlaps polygon -SELECT sline ( spoint '(0.00, 0.00)', spoint '(0.10,0.20)' ) @ :poly; -- line touches polygon -SELECT sline ( spoint '(0.00, 0.10)', spoint '(0.10,0.10)' ) @ :poly; -- line touches polygon +SELECT sline ( spoint '(0.00, 0.00)', spoint '(0.10,0.20)' ) @ :poly; -- line touches polygon +SELECT sline ( spoint '(0.00, 0.10)', spoint '(0.10,0.10)' ) @ :poly; -- line touches polygon SELECT sline ( spoint '(0.50, 0.00)', spoint '(0.50,0.20)' ) @ :poly; -- line touches polygon -SELECT sline ( spoint '(0.10, 0.20)', spoint '(0.20,0.00)' ) @ :poly; -- line touches and inside polygon +SELECT sline ( spoint '(0.10, 0.20)', spoint '(0.20,0.00)' ) @ :poly; -- line touches and inside polygon SELECT sline ( spoint '(0.45,-0.20)', spoint '(0.45,0.20)' ) @ :poly; -- line overlaps polygon SELECT sline ( spoint '(0.45, 0.10)', spoint '(0.45,0.20)' ) @ :poly; -- line overlaps polygon SELECT sline ( spoint '(0.24, 0.17)', spoint '(0.25,0.14)' ) @ :poly; -- line inside polygon -SELECT sline ( spoint '(0.00, 0.00)', spoint '(0.10,0.20)' ) && :poly; -- line touches polygon -SELECT sline ( spoint '(0.00, 0.10)', spoint '(0.10,0.10)' ) && :poly; -- line touches polygon +SELECT sline ( spoint '(0.00, 0.00)', spoint '(0.10,0.20)' ) && :poly; -- line touches polygon +SELECT sline ( spoint '(0.00, 0.10)', spoint '(0.10,0.10)' ) && :poly; -- line touches polygon SELECT sline ( spoint '(0.50, 0.00)', spoint '(0.50,0.20)' ) && :poly; -- line touches polygon -SELECT sline ( spoint '(0.10, 0.20)', spoint '(0.20,0.00)' ) && :poly; -- line touches and inside polygon +SELECT sline ( spoint '(0.10, 0.20)', spoint '(0.20,0.00)' ) && :poly; -- line touches and inside polygon SELECT sline ( spoint '(0.45,-0.20)', spoint '(0.45,0.20)' ) && :poly; -- line overlaps polygon SELECT sline ( spoint '(0.45, 0.10)', spoint '(0.45,0.20)' ) && :poly; -- line overlaps polygon SELECT sline ( spoint '(0.24, 0.17)', spoint '(0.25,0.14)' ) && :poly; -- line inside polygon @@ -86,7 +86,21 @@ SELECT spoly_deg(ARRAY[1.0, 2.0, 3.0, 4.0, 5.0, 6.0]); SELECT spoly_deg(ARRAY[10.0, 0.0, 10.0, 1.0, 15.0, 0.0]); --- incorrect input ----- +--- Constructors + +SELECT spoly(NULL::spoint[]); + +SELECT spoly(ARRAY[]::spoint[]); + +SELECT spoly(ARRAY[spoint_deg(0, 0)]); + +SELECT spoly(ARRAY[spoint_deg(0, 0), spoint_deg(10, 0)]); + +SELECT spoly(ARRAY[spoint_deg(0, 0), spoint_deg(10, 0), spoint_deg(10,10)]); + +SELECT spoly(ARRAY[spoint_deg(0, 0), spoint_deg(10, 0), spoint_deg(10,10), spoint_deg(0, 10)]); + +--- incorrect input ----- SELECT spoly '{(10d,0d),(10d,1d)}'; @@ -457,7 +471,7 @@ SELECT spoly '{(0d,-88d),(90d,-88d),(180d,-88d),(270d,-88d)}' @ spoly '{(0d,89d) --- spoly ~ spoly ---- should be true +--- should be true SELECT spoly '{(-1d,-1d),(-1d,1d),(1d,1d),(1d,-1d)}' ~ spoly '{(0d,0d),(0d,0.5d),(0.5d,0.5d),(0.5d,0d)}'; @@ -485,7 +499,7 @@ SELECT spoly '{(0d,89d),(90d,89d),(180d,89d),(270d,89d)}' ~ spoly '{(0d,-88d),(9 --- spoly && spoly ---- should be true +--- should be true SELECT spoly '{(0d,0d),(0d,0.5d),(0.5d,0.5d),(0.5d,0d)}' && spoly '{(-1d,-1d),(-1d,1d),(1d,1d),(1d,-1d)}'; @@ -536,7 +550,7 @@ SELECT spoly '{(-1d,-1d),(-1d,1d),(1d,1d),(1d,-1d)}' && spoly '{(179d,-1d),(179d -- -- ellipse and polygon -- - + -- negators , commutator @,&& SELECT spoly '{(280d, -9d),(280d, -8d),(279d, -8d)}' @ sellipse '<{10d,5d},(280d,-20d),90d>'; @@ -565,14 +579,14 @@ SELECT sellipse '<{10d,5d},(280d,-20d),90d>' !&& spoly '{(280d, -9d),(280d,-12 SELECT sellipse '<{10d,5d},(280d,-20d),90d>' !&& spoly '{(280d,-11d),(280d,-12d),(279d, -12d)}'; -- ellipse is point -SELECT spoly '{(280d, -9d),(280d, -8d),(279d, -8d)}' @ sellipse '<{0d,0d},(280d,-20d),90d>'; -SELECT spoly '{(280d,-11d),(280d,-20d),(279d, -12d)}' @ sellipse '<{0d,0d},(280d,-20d),90d>'; -SELECT spoly '{(280d, -9d),(280d, -8d),(279d, -8d)}' && sellipse '<{0d,0d},(280d,-20d),90d>'; -SELECT spoly '{(280d,-11d),(280d,-20d),(279d, -12d)}' && sellipse '<{0d,0d},(280d,-20d),90d>'; -SELECT sellipse '<{0d,0d},(280d,-20d),90d>' @ spoly '{(280d, -9d),(280d, -8d),(279d, -8d)}' ; -SELECT sellipse '<{0d,0d},(280d,-20d),90d>' @ spoly '{(280d,-11d),(280d,-20d),(279d, -12d)}'; -SELECT sellipse '<{0d,0d},(280d,-20d),90d>' && spoly '{(280d, -9d),(280d, -8d),(279d, -8d)}' ; -SELECT sellipse '<{0d,0d},(280d,-20d),90d>' && spoly '{(280d,-11d),(280d,-20d),(279d, -12d)}'; +SELECT spoly '{(280d, -9d),(280d, -8d),(279d, -8d)}' @ sellipse '<{0d,0d},(280d,-20d),90d>'; +SELECT spoly '{(280d,-11d),(280d,-20d),(279d, -12d)}' @ sellipse '<{0d,0d},(280d,-20d),90d>'; +SELECT spoly '{(280d, -9d),(280d, -8d),(279d, -8d)}' && sellipse '<{0d,0d},(280d,-20d),90d>'; +SELECT spoly '{(280d,-11d),(280d,-20d),(279d, -12d)}' && sellipse '<{0d,0d},(280d,-20d),90d>'; +SELECT sellipse '<{0d,0d},(280d,-20d),90d>' @ spoly '{(280d, -9d),(280d, -8d),(279d, -8d)}' ; +SELECT sellipse '<{0d,0d},(280d,-20d),90d>' @ spoly '{(280d,-11d),(280d,-20d),(279d, -12d)}'; +SELECT sellipse '<{0d,0d},(280d,-20d),90d>' && spoly '{(280d, -9d),(280d, -8d),(279d, -8d)}' ; +SELECT sellipse '<{0d,0d},(280d,-20d),90d>' && spoly '{(280d,-11d),(280d,-20d),(279d, -12d)}'; -- ellipse is circle SELECT spoly '{(280d, -9d),(280d, -8d),(279d, -8d)}' @ sellipse '<{5d,5d},(280d,-20d),90d>'; diff --git a/src/polygon.c b/src/polygon.c index 0ed6191..98e8aa0 100644 --- a/src/polygon.c +++ b/src/polygon.c @@ -61,7 +61,7 @@ PG_FUNCTION_INFO_V1(spheretrans_poly_inverse); PG_FUNCTION_INFO_V1(spherepoly_add_point); PG_FUNCTION_INFO_V1(spherepoly_add_points_finalize); PG_FUNCTION_INFO_V1(spherepoly_is_convex); - +PG_FUNCTION_INFO_V1(spherepoly_from_point_array); /* * Writes "center" of a polygon into 'v'. @@ -1007,6 +1007,32 @@ spherepoly_deg(PG_FUNCTION_ARGS) PG_RETURN_POINTER(spherepoly_from_array(points, np)); } +Datum +spherepoly_from_point_array(PG_FUNCTION_ARGS) +{ + int np; + ArrayType *inarr = PG_GETARG_ARRAYTYPE_P(0); + SPoint *points; + + np = ArrayGetNItems(ARR_NDIM(inarr), ARR_DIMS(inarr)); + + if (np < 3) + { + elog(ERROR, "spoly_deg: invalid number of arguments (must be >= 3)"); + PG_RETURN_NULL(); + } + + if (ARR_HASNULL(inarr)) + { + elog(ERROR, "spoly_deg: input array is invalid because if has null values"); + PG_RETURN_NULL(); + } + + points = (SPoint *) ARR_DATA_PTR(inarr); + + PG_RETURN_POINTER(spherepoly_from_array(points, np)); +} + Datum spherepoly_equal(PG_FUNCTION_ARGS) { diff --git a/upgrade_scripts/pg_sphere--1.3.1--1.3.2.sql.in b/upgrade_scripts/pg_sphere--1.3.1--1.3.2.sql.in index 3a80bc7..70f9506 100644 --- a/upgrade_scripts/pg_sphere--1.3.1--1.3.2.sql.in +++ b/upgrade_scripts/pg_sphere--1.3.1--1.3.2.sql.in @@ -27,6 +27,15 @@ CREATE FUNCTION spoly(float8[]) COMMENT ON FUNCTION spoly(float8[]) IS 'creates spoly from array of numbers in radians'; +CREATE FUNCTION spoly(spoint[]) + RETURNS spoly + AS 'MODULE_PATHNAME', 'spherepoly_from_point_array' + LANGUAGE 'c' + IMMUTABLE STRICT PARALLEL SAFE; + +COMMENT ON FUNCTION spoly(spoint[]) IS + 'creates spoly from an array of points'; + -- add PARALLEL SAFE to spoly_deg(float8[]) ALTER FUNCTION spoly_deg(float8[]) IMMUTABLE STRICT PARALLEL SAFE; From 595ecc9849675d29f36085ce489bc3eee43f0b5a Mon Sep 17 00:00:00 2001 From: Vitaly Davydov Date: Fri, 3 Nov 2023 15:05:00 +0300 Subject: [PATCH 57/87] Fix found problems after review --- expected/poly.out | 10 +++++----- sql/poly.sql | 4 ++-- src/polygon.c | 12 ++++++------ src/polygon.h | 11 +++++++++-- 4 files changed, 22 insertions(+), 15 deletions(-) diff --git a/expected/poly.out b/expected/poly.out index a695915..1ce3963 100644 --- a/expected/poly.out +++ b/expected/poly.out @@ -350,18 +350,18 @@ SELECT spoly(NULL::spoint[]); (1 row) SELECT spoly(ARRAY[]::spoint[]); -ERROR: spoly_deg: invalid number of arguments (must be >= 3) +ERROR: spherepoly_from_point_array: invalid number of arguments (must be >= 3) SELECT spoly(ARRAY[spoint_deg(0, 0)]); -ERROR: spoly_deg: invalid number of arguments (must be >= 3) +ERROR: spherepoly_from_point_array: invalid number of arguments (must be >= 3) SELECT spoly(ARRAY[spoint_deg(0, 0), spoint_deg(10, 0)]); -ERROR: spoly_deg: invalid number of arguments (must be >= 3) -SELECT spoly(ARRAY[spoint_deg(0, 0), spoint_deg(10, 0), spoint_deg(10,10)]); +ERROR: spherepoly_from_point_array: invalid number of arguments (must be >= 3) +SELECT spoly(ARRAY[spoint_deg(0, 0), spoint_deg(10, 0), spoint_deg(10, 10)]); spoly ------------------------------------ {(0d , 0d),(10d , 0d),(10d , 10d)} (1 row) -SELECT spoly(ARRAY[spoint_deg(0, 0), spoint_deg(10, 0), spoint_deg(10,10), spoint_deg(0, 10)]); +SELECT spoly(ARRAY[spoint_deg(0, 0), spoint_deg(10, 0), spoint_deg(10, 10), spoint_deg(0, 10)]); spoly ----------------------------------------------- {(0d , 0d),(10d , 0d),(10d , 10d),(0d , 10d)} diff --git a/sql/poly.sql b/sql/poly.sql index 0fb992b..972674e 100644 --- a/sql/poly.sql +++ b/sql/poly.sql @@ -96,9 +96,9 @@ SELECT spoly(ARRAY[spoint_deg(0, 0)]); SELECT spoly(ARRAY[spoint_deg(0, 0), spoint_deg(10, 0)]); -SELECT spoly(ARRAY[spoint_deg(0, 0), spoint_deg(10, 0), spoint_deg(10,10)]); +SELECT spoly(ARRAY[spoint_deg(0, 0), spoint_deg(10, 0), spoint_deg(10, 10)]); -SELECT spoly(ARRAY[spoint_deg(0, 0), spoint_deg(10, 0), spoint_deg(10,10), spoint_deg(0, 10)]); +SELECT spoly(ARRAY[spoint_deg(0, 0), spoint_deg(10, 0), spoint_deg(10, 10), spoint_deg(0, 10)]); --- incorrect input ----- diff --git a/src/polygon.c b/src/polygon.c index 98e8aa0..ac91c6e 100644 --- a/src/polygon.c +++ b/src/polygon.c @@ -1010,21 +1010,21 @@ spherepoly_deg(PG_FUNCTION_ARGS) Datum spherepoly_from_point_array(PG_FUNCTION_ARGS) { - int np; - ArrayType *inarr = PG_GETARG_ARRAYTYPE_P(0); SPoint *points; - - np = ArrayGetNItems(ARR_NDIM(inarr), ARR_DIMS(inarr)); + ArrayType *inarr = PG_GETARG_ARRAYTYPE_P(0); + const int np = ArrayGetNItems(ARR_NDIM(inarr), ARR_DIMS(inarr)); if (np < 3) { - elog(ERROR, "spoly_deg: invalid number of arguments (must be >= 3)"); + elog(ERROR, "spherepoly_from_point_array: " + "invalid number of arguments (must be >= 3)"); PG_RETURN_NULL(); } if (ARR_HASNULL(inarr)) { - elog(ERROR, "spoly_deg: input array is invalid because if has null values"); + elog(ERROR, "spherepoly_from_point_array: " + "input array is invalid because it has null values"); PG_RETURN_NULL(); } diff --git a/src/polygon.h b/src/polygon.h index e90b7c5..b8c754d 100644 --- a/src/polygon.h +++ b/src/polygon.h @@ -87,15 +87,22 @@ Datum spherepoly_get_point(PG_FUNCTION_ARGS); int8 poly_line_pos(const SPOLY *poly, const SLine *line); /* - * Input of a spherical from array of pair-consecutive numbers (lng, lat), in radians. + * Creates a spherical polygon (spoly) from an array of pair-consecutive + * numbers (lng, lat), in radians. */ Datum spherepoly_rad(PG_FUNCTION_ARGS); /* - * Input of a spherical from array of pair-consecutive numbers (lng, lat), in degrees. + * Creates a spherical polygon (spoly) from an array of pair-consecutive + * numbers (lng, lat), in degrees. */ Datum spherepoly_deg(PG_FUNCTION_ARGS); +/* + * Creates a spherical polygon (spoly) from an array of spoint elements. + */ +Datum spherepoly_from_point_array(PG_FUNCTION_ARGS); + /* * Input of a spherical polygon. */ From 4d8e97dfbd5f65c424a92c19e87a1a57f9c1bcc9 Mon Sep 17 00:00:00 2001 From: Vitaly Davydov Date: Fri, 3 Nov 2023 20:58:09 +0300 Subject: [PATCH 58/87] Update the doc with spoly, spoly_deg function descriptions --- doc/constructors.sgm | 47 +++++++++++++++++++++++++++++++++----------- 1 file changed, 35 insertions(+), 12 deletions(-) diff --git a/doc/constructors.sgm b/doc/constructors.sgm index e14dd3f..4f87651 100644 --- a/doc/constructors.sgm +++ b/doc/constructors.sgm @@ -268,22 +268,45 @@ Codestin Search App + - The aggregate function + The functions spoly and spoly_deg + can be used to create spherical polygons. Function spoly + is overloaded and can accept arrays of float8 or spoint elements. + There are the same restrictions as for using the input function of + spherical polygon (see ). - - - spoly - spoint edge - - + - can be used to create a polygon from a set of spherical points. - There are the same restrictions as for using the input function of - spherical polygon (see ). The function - returns - NULL, if the polygon couldn't be created. + Create a spherical polygon from an array of pair-consecutive + numbers (lng, lat). The coordinates are specified in radians. + + SELECT spoly(ARRAY[0, 0, 0, 0.5, 0.5, 0.5, 0.5, 0])]]> + + + + Create a spherical polygon from an array of spoint elements. + + SELECT spoly(ARRAY[spoint(0, 0), spoint(0, 0.5), spoint(0.5, 0.5), spoint(0.5, 0)])]]> + + + + + Create a spherical polygon from an array of pair-consecutive + numbers (lng, lat). The coordinates are specified in degrees. + + SELECT spoly_deg(ARRAY[0, 0, 0, 10, 10, 10, 10, 0])]]> + + + + + The aggregate function spoly can be used to + create a polygon from a set of spherical points. The function + returns NULL, if the polygon could not be + created. + + Codestin Search App + + Values of type spoint can be indexed using a + HASH index, supporting the + = operator. + The spoint_hash_ops operator class also enables + DISTINCT queries on spoint. + + + Codestin Search App + + + + + + + + + + + + diff --git a/expected/index.out b/expected/index.out index eefa5c6..f63cff8 100644 --- a/expected/index.out +++ b/expected/index.out @@ -195,3 +195,39 @@ EXPLAIN (COSTS OFF) SELECT count(*) FROM spheretmp1b WHERE p = spoint '(3.09 , 1 4 (1 row) +-- test hash opclass +CREATE TABLE spheretmp1c AS TABLE spheretmp1; +SELECT p FROM spheretmp1c WHERE p <@ scircle '<(1,1),0.2>' ORDER BY p::text; + p +--------------- + (0.67 , 0.97) + (0.67 , 0.97) + (0.67 , 0.97) + (0.67 , 0.97) + (1.07 , 1.09) + (1.07 , 1.09) + (1.07 , 1.09) + (1.07 , 1.09) + (1.24 , 0.95) + (1.24 , 0.95) + (1.24 , 0.95) + (1.24 , 0.95) +(12 rows) + +WITH points AS (SELECT DISTINCT p FROM spheretmp1c WHERE p <@ scircle '<(1,1),0.2>') + SELECT p FROM points ORDER BY p::text; + p +--------------- + (0.67 , 0.97) + (1.07 , 1.09) + (1.24 , 0.95) +(3 rows) + +CREATE INDEX spheretmp1c_hash_idx ON spheretmp1c USING hash(p); +EXPLAIN (COSTS OFF) SELECT * FROM spheretmp1c WHERE p = '(0.67 , 0.97)'; + QUERY PLAN +------------------------------------------------------ + Index Scan using spheretmp1c_hash_idx on spheretmp1c + Index Cond: (p = '(0.67 , 0.97)'::spoint) +(2 rows) + diff --git a/pgs_hash.sql.in b/pgs_hash.sql.in new file mode 100644 index 0000000..52fd1ed --- /dev/null +++ b/pgs_hash.sql.in @@ -0,0 +1,19 @@ +CREATE FUNCTION spoint_hash32 (spoint) + RETURNS int + IMMUTABLE STRICT + PARALLEL SAFE + LANGUAGE C + AS 'MODULE_PATHNAME', 'spherepoint_hash32'; + +UPDATE pg_operator + SET oprcanhash = true + WHERE oprname = '=' AND + oprleft = 'spoint'::regtype AND oprright = 'spoint'::regtype; + +/* PG17: ALTER OPERATOR = (spoint, spoint) SET (HASHES); */ + +CREATE OPERATOR CLASS spoint_hash_ops + DEFAULT FOR TYPE spoint USING hash + AS + OPERATOR 1 = (spoint, spoint), + FUNCTION 1 spoint_hash32(spoint); diff --git a/sql/index.sql b/sql/index.sql index 8713106..19d537b 100644 --- a/sql/index.sql +++ b/sql/index.sql @@ -76,3 +76,14 @@ EXPLAIN (COSTS OFF) SELECT count(*) FROM spheretmp1b WHERE p <@ scircle '<(1,1), SELECT count(*) FROM spheretmp1b WHERE p <@ scircle '<(1,1),0.3>'; EXPLAIN (COSTS OFF) SELECT count(*) FROM spheretmp1b WHERE p = spoint '(3.09 , 1.25)'; SELECT count(*) FROM spheretmp1b WHERE p = spoint '(3.09 , 1.25)'; + +-- test hash opclass + +CREATE TABLE spheretmp1c AS TABLE spheretmp1; + +SELECT p FROM spheretmp1c WHERE p <@ scircle '<(1,1),0.2>' ORDER BY p::text; +WITH points AS (SELECT DISTINCT p FROM spheretmp1c WHERE p <@ scircle '<(1,1),0.2>') + SELECT p FROM points ORDER BY p::text; + +CREATE INDEX spheretmp1c_hash_idx ON spheretmp1c USING hash(p); +EXPLAIN (COSTS OFF) SELECT * FROM spheretmp1c WHERE p = '(0.67 , 0.97)'; diff --git a/src/point.c b/src/point.c index 498ee5e..f4df15c 100644 --- a/src/point.c +++ b/src/point.c @@ -16,6 +16,7 @@ PG_FUNCTION_INFO_V1(spherepoint_y); PG_FUNCTION_INFO_V1(spherepoint_z); PG_FUNCTION_INFO_V1(spherepoint_xyz); PG_FUNCTION_INFO_V1(spherepoint_equal); +PG_FUNCTION_INFO_V1(spherepoint_hash32); static Oid point_id = InvalidOid; @@ -309,3 +310,13 @@ spherepoint_equal(PG_FUNCTION_ARGS) PG_RETURN_BOOL(spoint_eq(p1, p2)); } + +Datum +spherepoint_hash32(PG_FUNCTION_ARGS) +{ + SPoint *p1 = (SPoint *) PG_GETARG_POINTER(0); + Datum h1 = DirectFunctionCall1(hashfloat8, p1->lat); + Datum h2 = DirectFunctionCall1(hashfloat8, p1->lng); + + PG_RETURN_INT32(DatumGetInt32(h1) ^ DatumGetInt32(h2)); +} diff --git a/src/point.h b/src/point.h index 9269cf7..d7af228 100644 --- a/src/point.h +++ b/src/point.h @@ -102,4 +102,9 @@ Datum spherepoint_xyz(PG_FUNCTION_ARGS); */ Datum spherepoint_equal(PG_FUNCTION_ARGS); +/* + * Compute a 32-bit hash value of a point. + */ +Datum spherepoint_hash32(PG_FUNCTION_ARGS); + #endif From 1f0f8e4772c58e6e3ccf0e60d39b2bbe7cc38231 Mon Sep 17 00:00:00 2001 From: Vitaly Davydov Date: Tue, 7 Nov 2023 20:58:16 +0300 Subject: [PATCH 60/87] Remove Travis-CI tests from the pipeline --- .travis.yml | 42 ------------------------------------------ 1 file changed, 42 deletions(-) delete mode 100644 .travis.yml diff --git a/.travis.yml b/.travis.yml deleted file mode 100644 index 0d199cf..0000000 --- a/.travis.yml +++ /dev/null @@ -1,42 +0,0 @@ -# run the testsuite on travis-ci.com ---- -# versions to run on -env: - - PG_SUPPORTED_VERSIONS=10 - - PG_SUPPORTED_VERSIONS=11 - - PG_SUPPORTED_VERSIONS=12 - - PG_SUPPORTED_VERSIONS=13 - - PG_SUPPORTED_VERSIONS=14 - - PG_SUPPORTED_VERSIONS=15 - - PG_SUPPORTED_VERSIONS=16 - -language: C -dist: focal - -before_install: - # extra apt.pg.o.sh options added in version 204, travis currently has 199 (2019-11-27) - - sudo apt-get -qq update - - sudo apt-get -y install postgresql-common libhealpix-cxx-dev docbook-xml docbook-xsl libxml2-utils xsltproc fop - -install: - - sudo /usr/share/postgresql-common/pgdg/apt.postgresql.org.sh -p -v $PG_SUPPORTED_VERSIONS -i - -script: - - make PROFILE="-Werror" - - sudo make install - - pg_virtualenv make installcheck - - if test -s regression.diffs; then cat regression.diffs; exit 1; fi - - pg_virtualenv make test - - if test -s regression.diffs; then cat regression.diffs; exit 1; fi - - pg_virtualenv make crushtest - - if test -s regression.diffs; then cat regression.diffs; exit 1; fi - - make clean - - make PROFILE="-Werror" USE_HEALPIX=0 - - sudo make USE_HEALPIX=0 install - - pg_virtualenv make USE_HEALPIX=0 installcheck - - if test -s regression.diffs; then cat regression.diffs; exit 1; fi - - pg_virtualenv make USE_HEALPIX=0 test - - if test -s regression.diffs; then cat regression.diffs; exit 1; fi - - pg_virtualenv make USE_HEALPIX=0 crushtest - - if test -s regression.diffs; then cat regression.diffs; exit 1; fi - - make -C doc From fcf6b4a19ee012f5bcb32d5f456eccb703d76bc8 Mon Sep 17 00:00:00 2001 From: Vitaly Davydov Date: Wed, 8 Nov 2023 13:32:07 +0300 Subject: [PATCH 61/87] Update copyright file to present --- COPYRIGHT.pg_sphere | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/COPYRIGHT.pg_sphere b/COPYRIGHT.pg_sphere index 61a2e1f..7753260 100644 --- a/COPYRIGHT.pg_sphere +++ b/COPYRIGHT.pg_sphere @@ -1,4 +1,4 @@ -Copyright (c) 2003-2017, pgSphere development team +Copyright (c) 2003-2023, pgSphere development team All rights reserved. Redistribution and use in source and binary forms, with or without @@ -24,4 +24,3 @@ INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - From c0f824b3b0791a7e396646a503c35c6254d739af Mon Sep 17 00:00:00 2001 From: Vitaly Date: Thu, 9 Nov 2023 11:12:59 +0300 Subject: [PATCH 62/87] Add "pgindent" rule for make to run pgindent (#71) Add "pgindent" rule for make to run pgindent --- Makefile | 28 ++++- pgindent-excludes.list | 1 + pgindent-typedefs.list | 236 +++++++++++++++++++++++++++++++++++++++++ 3 files changed, 264 insertions(+), 1 deletion(-) create mode 100644 pgindent-excludes.list create mode 100644 pgindent-typedefs.list diff --git a/Makefile b/Makefile index 20abe66..b8aca35 100644 --- a/Makefile +++ b/Makefile @@ -3,7 +3,9 @@ include Makefile.common.mk RELEASE_SQL = $(EXTENSION)--$(PGSPHERE_VERSION).sql USE_PGXS = 1 -USE_HEALPIX =? 1 +USE_HEALPIX ?= 1 +PGINDENT ?= pgindent +PGBSDINDENT ?= pg_bsd_indent # the base dir name may be changed depending on git clone command SRC_DIR = $(shell basename $(shell pwd)) @@ -223,3 +225,27 @@ endif dist : clean sparse.c sscan.c find . -name '*~' -type f -exec rm {} \; cd .. && tar --transform s/$(SRC_DIR)/pgsphere-$(PGSPHERE_VERSION)/ --exclude CVS --exclude .git -czf pgsphere-$(PGSPHERE_VERSION).tar.gz $(SRC_DIR) && cd - + +# To use pgindent, set the PATH environment variable to include the directories +# containing the binaries pgindent and pg_bsd_indent. It is important to +# utilize a specific version of pg_bsd_indent, which sources can be found +# in the /src/tools/pg_bsd_indent directory, where +# is the root directory of the PostgreSQL project source tree. +# +# The sources of the utilities can be found in the following directories: +# - /src/tools/pgindent +# - /src/tools/pg_bsd_indent +# +# pgindent-typedefs.list should be updated every time after implementing +# new types and introducing new typedefs in the code. For details how +# to update pgindent-typedefs.list and for other information about pgindent, +# please, read the doc: /src/tools/pgindent/README. +# +# pgindent-excludes.list is used to specify files to be ignored. +# +pgindent: + $(PGINDENT) \ + --typedefs=pgindent-typedefs.list \ + --excludes=pgindent-excludes.list \ + --indent=${PGBSDINDENT} \ + src diff --git a/pgindent-excludes.list b/pgindent-excludes.list new file mode 100644 index 0000000..c3add5c --- /dev/null +++ b/pgindent-excludes.list @@ -0,0 +1 @@ +pgs_process_moc.h diff --git a/pgindent-typedefs.list b/pgindent-typedefs.list new file mode 100644 index 0000000..7f2c8fe --- /dev/null +++ b/pgindent-typedefs.list @@ -0,0 +1,236 @@ +align_val_t +allocator_type +__alloc_rebind +ArrayType +AttrDefault +AttrNumber +_Base_ptr +BlockNumber +Box3D +BpChar +bpoint +BrinDesc +BrinOpcInfo +brin_serialize_callback_type +BrinValues +__builtin_va_list +_Char_alloc_type +char_type +CommonEntry +__compar_fn_t +ConsiderSplitContext +_Const_Base_ptr +__const_iterator +const_iterator +_Const_Link_type +const_pointer +ConstrCheck +const_reference +const_reverse_iterator +const_void_pointer +coord_t +CPoint +Datum +difference_type +_DistanceType +div_t +DomainConstraintCache +double_t +__dso_handle +__enable_if_t +false> +false_type +__FILE +FILE +first_type +flex_int16_t +flex_uint8_t +float4 +float8 +float_t +FmgrInfo +fmNodePtr +FormData_pg_attribute +__fpos_t +fpos_t +FunctionCallInfo +GISTENTRY +GistEntryVector +GISTPageOpaque +GISTPageOpaqueData +GIST_SPLITVEC +GiSTSPointKey +__gnuc_va_list +Healpix_Base2 +hpint64 +insert_return_type +int16 +__int16_t +int16_t +int32 +__int32_t +int32_t +int64 +__int64_t +int64_t +int8 +__int8_t +int8_t +int_fast16_t +int_fast32_t +int_fast64_t +int_fast8_t +__int_least16_t +int_least16_t +__int_least32_t +int_least32_t +__int_least64_t +int_least64_t +__int_least8_t +int_least8_t +__intmax_t +intmax_t +intptr_t +int_type +_IO_lock_t +iostate +ItemIdData +iterator +iterator_category +iterator_type +key_compare +key_type +layout_vec +ldiv_t +_Link_type +lldiv_t +LocationIndex +__make_not_void +map_const_iter +map_iterator +mapped_type +map_rev_iter +max_align_t +__mbstate_t +mbstate_t +MemoryContext +moc_interval +moc_map +moc_map_entry +moc_out_data +moc_tree_entry +NameData +_Node_allocator +NodeTag +node_type +NullableDatum +nullptr_t +__off64_t +OffsetNumber +__off_t +Oid +ostream +__ostream_type +other +output_map +Page +PageGistNSN +PageHeader +PageHeaderData +PageXLogRecPtr +Pg_finfo_record +PGFunction +Pg_magic_struct +pgs_error_handler +phasevec +Point +Point3D +__pointer +pointer +Pointer +ptrdiff_t +__ptr_rebind +rebind +rebind_alloc +reference +Relation +_Rep_type +reverse_iterator +rintv_iter +rnode_iter +rtype +SBOX +SCIRCLE +second_type +_Self +SELLIPSE +SEuler +Size +size_t +size_type +SLine +Smoc +SPATH +SplitInterval +SPoint +SPOLY +StrategyNumber +streamsize +string +__sv_type +t_ang +tdiff +text +_Tp_alloc_type +TransactionId +true_type +tsize +TupleConstr +TupleDesc +__type +type +TypeCacheEntry +uchar +uint16 +__uint16_t +uint16_t +uint32 +__uint32_t +uint32_t +uint64 +__uint64_t +uint64_t +uint8 +__uint8_t +uint8_t +uint_fast16_t +uint_fast32_t +uint_fast64_t +uint_fast8_t +__uint_least16_t +uint_least16_t +__uint_least32_t +uint_least32_t +__uint_least64_t +uint_least64_t +__uint_least8_t +uint_least8_t +__uintmax_t +uintmax_t +uintptr_t +va_list +value_type +varattrib_4b +vec3 +Vector3D +wctrans_t +wctype_t +wint_t +YY_BUFFER_STATE +YY_CHAR +yy_size_t +yy_state_type +YYSTYPE +yytype_int16 +yytype_int8 +yytype_uint8 From 94e498dfa013d13f55155c8b26c2150de1f41e9d Mon Sep 17 00:00:00 2001 From: Vitaly Date: Thu, 9 Nov 2023 12:33:51 +0300 Subject: [PATCH 63/87] Adjust release version 1.3.2 to 1.4.0 (#105) --- Makefile | 8 ++++---- Makefile.common.mk | 2 +- expected/init.out | 2 +- pg_sphere.control | 2 +- ...1.3.1--1.3.2.sql.in => pg_sphere--1.3.1--1.4.0.sql.in} | 0 5 files changed, 7 insertions(+), 7 deletions(-) rename upgrade_scripts/{pg_sphere--1.3.1--1.3.2.sql.in => pg_sphere--1.3.1--1.4.0.sql.in} (100%) diff --git a/Makefile b/Makefile index b8aca35..5b1c4e2 100644 --- a/Makefile +++ b/Makefile @@ -32,7 +32,7 @@ DATA_built = $(RELEASE_SQL) \ pg_sphere--1.2.2--1.2.3.sql \ pg_sphere--1.2.3--1.3.0.sql \ pg_sphere--1.3.0--1.3.1.sql \ - pg_sphere--1.3.1--1.3.2.sql + pg_sphere--1.3.1--1.4.0.sql DOCS = README.pg_sphere COPYRIGHT.pg_sphere TESTS = tables points euler circle line ellipse poly path box \ @@ -194,14 +194,14 @@ pg_sphere--1.3.0--1.3.1.sql: cat upgrade_scripts/$@.in > $@ ifeq ($(has_support_functions),y) -pg_sphere--1.3.1--1.3.2.sql: pgs_gist_support.sql.in +pg_sphere--1.3.1--1.4.0.sql: pgs_gist_support.sql.in endif ifneq ($(USE_HEALPIX),0) ifeq ($(has_index_options),y) -pg_sphere--1.3.1--1.3.2.sql: pgs_moc_options.sql.in +pg_sphere--1.3.1--1.4.0.sql: pgs_moc_options.sql.in endif endif -pg_sphere--1.3.1--1.3.2.sql: pgs_circle_sel.sql.in pgs_hash.sql.in +pg_sphere--1.3.1--1.4.0.sql: pgs_circle_sel.sql.in pgs_hash.sql.in cat upgrade_scripts/$@.in $^ > $@ # end of local stuff diff --git a/Makefile.common.mk b/Makefile.common.mk index 6387bea..aaaf096 100644 --- a/Makefile.common.mk +++ b/Makefile.common.mk @@ -5,4 +5,4 @@ #---------------------------------------------------------------------------- EXTENSION := pg_sphere -PGSPHERE_VERSION := 1.3.2 +PGSPHERE_VERSION := 1.4.0 diff --git a/expected/init.out b/expected/init.out index f5e092b..e4dcdfd 100644 --- a/expected/init.out +++ b/expected/init.out @@ -6,6 +6,6 @@ CREATE EXTENSION pg_sphere; select pg_sphere_version(); pg_sphere_version ------------------- - 1.3.2 + 1.4.0 (1 row) diff --git a/pg_sphere.control b/pg_sphere.control index d9f2ccc..41ae5a7 100644 --- a/pg_sphere.control +++ b/pg_sphere.control @@ -1,5 +1,5 @@ # pg_sphere extension comment = 'spherical objects with useful functions, operators and index support' -default_version = '1.3.2' +default_version = '1.4.0' module_pathname = '$libdir/pg_sphere' relocatable = true diff --git a/upgrade_scripts/pg_sphere--1.3.1--1.3.2.sql.in b/upgrade_scripts/pg_sphere--1.3.1--1.4.0.sql.in similarity index 100% rename from upgrade_scripts/pg_sphere--1.3.1--1.3.2.sql.in rename to upgrade_scripts/pg_sphere--1.3.1--1.4.0.sql.in From f229b2e1bbbb89bc742561c1c6bf8380e8aa1698 Mon Sep 17 00:00:00 2001 From: Christoph Berg Date: Wed, 22 Nov 2023 05:55:14 +0100 Subject: [PATCH 64/87] spherepoint_hash32: float8 needs wrapping into a Datum (#107) --- src/point.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/point.c b/src/point.c index f4df15c..26ae5f5 100644 --- a/src/point.c +++ b/src/point.c @@ -315,8 +315,8 @@ Datum spherepoint_hash32(PG_FUNCTION_ARGS) { SPoint *p1 = (SPoint *) PG_GETARG_POINTER(0); - Datum h1 = DirectFunctionCall1(hashfloat8, p1->lat); - Datum h2 = DirectFunctionCall1(hashfloat8, p1->lng); + Datum h1 = DirectFunctionCall1(hashfloat8, Float8GetDatum(p1->lat)); + Datum h2 = DirectFunctionCall1(hashfloat8, Float8GetDatum(p1->lng)); PG_RETURN_INT32(DatumGetInt32(h1) ^ DatumGetInt32(h2)); } From 902ba8da469da799dd18ca3b68b8915bd4d381b5 Mon Sep 17 00:00:00 2001 From: Vitaly Davydov Date: Wed, 22 Nov 2023 08:17:39 +0300 Subject: [PATCH 65/87] Add version.sql test Current version check was moved from init.sql into version.sql because init.sql it is not executed with the 'test' target. --- Makefile | 2 +- expected/init.out | 9 +-------- expected/version.out | 7 +++++++ sql/init.sql | 5 +---- sql/version.sql | 3 +++ 5 files changed, 13 insertions(+), 13 deletions(-) create mode 100644 expected/version.out create mode 100644 sql/version.sql diff --git a/Makefile b/Makefile index 5b1c4e2..249e1c2 100644 --- a/Makefile +++ b/Makefile @@ -35,7 +35,7 @@ DATA_built = $(RELEASE_SQL) \ pg_sphere--1.3.1--1.4.0.sql DOCS = README.pg_sphere COPYRIGHT.pg_sphere -TESTS = tables points euler circle line ellipse poly path box \ +TESTS = version tables points euler circle line ellipse poly path box \ index contains_ops contains_ops_compat bounding_box_gist gnomo \ epochprop contains overlaps spoint_brin sbox_brin selectivity REGRESS = init $(TESTS) diff --git a/expected/init.out b/expected/init.out index e4dcdfd..374e2a3 100644 --- a/expected/init.out +++ b/expected/init.out @@ -1,11 +1,4 @@ -- --- first, define the datatype. Turn off echoing so that expected file --- does not depend on contents of pg_sphere.sql. +-- Initialize the extension. -- CREATE EXTENSION pg_sphere; -select pg_sphere_version(); - pg_sphere_version -------------------- - 1.4.0 -(1 row) - diff --git a/expected/version.out b/expected/version.out new file mode 100644 index 0000000..075d008 --- /dev/null +++ b/expected/version.out @@ -0,0 +1,7 @@ +-- Check current pgsphere version +SELECT pg_sphere_version(); + pg_sphere_version +------------------- + 1.4.0 +(1 row) + diff --git a/sql/init.sql b/sql/init.sql index 05b3516..374e2a3 100644 --- a/sql/init.sql +++ b/sql/init.sql @@ -1,7 +1,4 @@ -- --- first, define the datatype. Turn off echoing so that expected file --- does not depend on contents of pg_sphere.sql. +-- Initialize the extension. -- CREATE EXTENSION pg_sphere; - -select pg_sphere_version(); diff --git a/sql/version.sql b/sql/version.sql new file mode 100644 index 0000000..89f6266 --- /dev/null +++ b/sql/version.sql @@ -0,0 +1,3 @@ +-- Check current pgsphere version +SELECT pg_sphere_version(); + From 2cb0c2869e3568ac400cda3af8bb42c246e18676 Mon Sep 17 00:00:00 2001 From: Vitaly Davydov Date: Wed, 22 Nov 2023 08:22:07 +0300 Subject: [PATCH 66/87] Increment the version number to 1.4.1 --- Makefile | 6 +++++- Makefile.common.mk | 2 +- expected/version.out | 2 +- pg_sphere.control | 2 +- upgrade_scripts/pg_sphere--1.4.0--1.4.1.sql.in | 1 + 5 files changed, 9 insertions(+), 4 deletions(-) create mode 100644 upgrade_scripts/pg_sphere--1.4.0--1.4.1.sql.in diff --git a/Makefile b/Makefile index 249e1c2..88c082b 100644 --- a/Makefile +++ b/Makefile @@ -32,7 +32,8 @@ DATA_built = $(RELEASE_SQL) \ pg_sphere--1.2.2--1.2.3.sql \ pg_sphere--1.2.3--1.3.0.sql \ pg_sphere--1.3.0--1.3.1.sql \ - pg_sphere--1.3.1--1.4.0.sql + pg_sphere--1.3.1--1.4.0.sql \ + pg_sphere--1.4.0--1.4.1.sql \ DOCS = README.pg_sphere COPYRIGHT.pg_sphere TESTS = version tables points euler circle line ellipse poly path box \ @@ -204,6 +205,9 @@ endif pg_sphere--1.3.1--1.4.0.sql: pgs_circle_sel.sql.in pgs_hash.sql.in cat upgrade_scripts/$@.in $^ > $@ +pg_sphere--1.4.0--1.4.1.sql: + cat upgrade_scripts/$@.in $^ > $@ + # end of local stuff src/sscan.o : src/sparse.c diff --git a/Makefile.common.mk b/Makefile.common.mk index aaaf096..42c2376 100644 --- a/Makefile.common.mk +++ b/Makefile.common.mk @@ -5,4 +5,4 @@ #---------------------------------------------------------------------------- EXTENSION := pg_sphere -PGSPHERE_VERSION := 1.4.0 +PGSPHERE_VERSION := 1.4.1 diff --git a/expected/version.out b/expected/version.out index 075d008..c05ab96 100644 --- a/expected/version.out +++ b/expected/version.out @@ -2,6 +2,6 @@ SELECT pg_sphere_version(); pg_sphere_version ------------------- - 1.4.0 + 1.4.1 (1 row) diff --git a/pg_sphere.control b/pg_sphere.control index 41ae5a7..fdf8f98 100644 --- a/pg_sphere.control +++ b/pg_sphere.control @@ -1,5 +1,5 @@ # pg_sphere extension comment = 'spherical objects with useful functions, operators and index support' -default_version = '1.4.0' +default_version = '1.4.1' module_pathname = '$libdir/pg_sphere' relocatable = true diff --git a/upgrade_scripts/pg_sphere--1.4.0--1.4.1.sql.in b/upgrade_scripts/pg_sphere--1.4.0--1.4.1.sql.in new file mode 100644 index 0000000..8ea3baa --- /dev/null +++ b/upgrade_scripts/pg_sphere--1.4.0--1.4.1.sql.in @@ -0,0 +1 @@ +-- Nothing to upgrade in the schema From 562f098854aa61ba15b84a1c409c3688d328835f Mon Sep 17 00:00:00 2001 From: Vitaly Davydov Date: Tue, 5 Dec 2023 07:39:12 +0300 Subject: [PATCH 67/87] Fix polygon validation function Some previous changes to improve the behaviour in case of degenerate poygons introduced a bug in the polygon validation function. The changes are rolled back. --- expected/poly.out | 49 +++++++++++++++++++++++++++++++++++++++++------ sql/poly.sql | 29 ++++++++++++++++++++++++++++ src/line.c | 18 ++++++++--------- 3 files changed, 81 insertions(+), 15 deletions(-) diff --git a/expected/poly.out b/expected/poly.out index 1ce3963..5f095a3 100644 --- a/expected/poly.out +++ b/expected/poly.out @@ -403,13 +403,17 @@ LINE 1: SELECT spoly '{(0d,0d),(10d,10d),(0d,10d),(10d,0d)}'; ^ --- degenerate polygons ----- SELECT spoly '{(0d,1d),(0d,2d),(0d,3d)}'; -ERROR: spherepoly_from_array: a line segment overlaps or polygon too large -LINE 1: SELECT spoly '{(0d,1d),(0d,2d),(0d,3d)}'; - ^ + spoly +--------------------------------- + {(0d , 1d),(0d , 2d),(0d , 3d)} +(1 row) + SELECT spoly '{(1d,0d),(2d,0d),(3d,0d)}'; -ERROR: spherepoly_from_array: a line segment overlaps or polygon too large -LINE 1: SELECT spoly '{(1d,0d),(2d,0d),(3d,0d)}'; - ^ + spoly +--------------------------------- + {(1d , 0d),(2d , 0d),(3d , 0d)} +(1 row) + --- functions SELECT npoints( spoly '{(10d,0d),(10d,1d),(15d,0d)}'); npoints @@ -1874,3 +1878,36 @@ SELECT spoly_is_convex(NULL); f (1 row) +-- Complex but valid polygon +SELECT '{ + (3.30474723646012 , 1.08600456205300), + (3.30341855309927 , 1.08577960186707), + (3.30341054542378 , 1.08578643990271), + (3.30297351563319 , 1.08633534556428), + (3.30357156120003 , 1.08643683957210), + (3.30358891855857 , 1.08643995044436), + (3.30360894676365 , 1.08644306147078), + (3.30361829343581 , 1.08644430596871), + (3.30362630482521 , 1.08644555030213), + (3.30364633346451 , 1.08644866102000), + (3.30365300940335 , 1.08645052692055), + (3.30366102096957 , 1.08645177113937), + (3.30367036769496 , 1.08645363721023), + (3.30367837934959 , 1.08645488137174), + (3.30368906174976 , 1.08645612569695), + (3.30370107936906 , 1.08645799183673), + (3.30370642025712 , 1.08645985750225), + (3.30373179124734 , 1.08646358962156), + (3.30374514456618 , 1.08646545561358), + (3.30410706158729 , 1.08652886672786), + (3.30427803417922 , 1.08655868846497), + (3.30429673329093 , 1.08655930694968), + (3.30432478121775 , 1.08655930174652), + (3.30433278932944 , 1.08655308246640), + (3.30446348355532 , 1.08638330933224) +}'::spoly; + spoly +--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- + {(3.3047472 , 1.0860046),(3.3034186 , 1.0857796),(3.3034105 , 1.0857864),(3.3029735 , 1.0863353),(3.3035716 , 1.0864368),(3.3035889 , 1.08644),(3.3036089 , 1.0864431),(3.3036183 , 1.0864443),(3.3036263 , 1.0864456),(3.3036463 , 1.0864487),(3.303653 , 1.0864505),(3.303661 , 1.0864518),(3.3036704 , 1.0864536),(3.3036784 , 1.0864549),(3.3036891 , 1.0864561),(3.3037011 , 1.086458),(3.3037064 , 1.0864599),(3.3037318 , 1.0864636),(3.3037451 , 1.0864655),(3.3041071 , 1.0865289),(3.304278 , 1.0865587),(3.3042967 , 1.0865593),(3.3043248 , 1.0865593),(3.3043328 , 1.0865531),(3.3044635 , 1.0863833)} +(1 row) + diff --git a/sql/poly.sql b/sql/poly.sql index 972674e..f742bf0 100644 --- a/sql/poly.sql +++ b/sql/poly.sql @@ -650,3 +650,32 @@ SELECT spoly_is_convex(spoly'{(53d 45m 35.0s, 37d 6m 30.0s), (52d 21m 36.0s, 41d SELECT spoly_is_convex(spoly'{(12d,32d),(34d,12d),(59d,21d),(69d,21d)}'); SELECT spoly_is_convex(spoly'{(12d,32d),(34d,12d),(59d,21d),(34d,40d)}'); SELECT spoly_is_convex(NULL); + +-- Complex but valid polygon +SELECT '{ + (3.30474723646012 , 1.08600456205300), + (3.30341855309927 , 1.08577960186707), + (3.30341054542378 , 1.08578643990271), + (3.30297351563319 , 1.08633534556428), + (3.30357156120003 , 1.08643683957210), + (3.30358891855857 , 1.08643995044436), + (3.30360894676365 , 1.08644306147078), + (3.30361829343581 , 1.08644430596871), + (3.30362630482521 , 1.08644555030213), + (3.30364633346451 , 1.08644866102000), + (3.30365300940335 , 1.08645052692055), + (3.30366102096957 , 1.08645177113937), + (3.30367036769496 , 1.08645363721023), + (3.30367837934959 , 1.08645488137174), + (3.30368906174976 , 1.08645612569695), + (3.30370107936906 , 1.08645799183673), + (3.30370642025712 , 1.08645985750225), + (3.30373179124734 , 1.08646358962156), + (3.30374514456618 , 1.08646545561358), + (3.30410706158729 , 1.08652886672786), + (3.30427803417922 , 1.08655868846497), + (3.30429673329093 , 1.08655930694968), + (3.30432478121775 , 1.08655930174652), + (3.30433278932944 , 1.08655308246640), + (3.30446348355532 , 1.08638330933224) +}'::spoly; diff --git a/src/line.c b/src/line.c index ad02575..59785f1 100644 --- a/src/line.c +++ b/src/line.c @@ -496,6 +496,15 @@ sline_sline_pos(const SLine *l1, const SLine *l2) vector3d_spoint(&p[2], &v[1][0]); vector3d_spoint(&p[3], &v[1][1]); + /* check connected lines */ + if (FPgt(il2->length, 0.0) && (vector3d_eq(&v[0][0], &v[1][0]) || + vector3d_eq(&v[0][0], &v[1][1]) || + vector3d_eq(&v[0][1], &v[1][0]) || + vector3d_eq(&v[0][1], &v[1][1]))) + { + return PGS_LINE_CONNECT; + } + /* Check, sl2 is at equator */ if (FPzero(p[2].lat) && FPzero(p[3].lat)) { @@ -520,15 +529,6 @@ sline_sline_pos(const SLine *l1, const SLine *l2) return PGS_LINE_AVOID; } - /* check connected lines */ - if (FPgt(il2->length, 0.0) && (vector3d_eq(&v[0][0], &v[1][0]) || - vector3d_eq(&v[0][0], &v[1][1]) || - vector3d_eq(&v[0][1], &v[1][0]) || - vector3d_eq(&v[0][1], &v[1][1]))) - { - return PGS_LINE_CONNECT; - } - /* Now sl2 is not at equator */ if (FPle(il2->length, seg_length)) From 0be5757aab717d7569236128b4f3592fcd60d28f Mon Sep 17 00:00:00 2001 From: Vitaly Davydov Date: Tue, 5 Dec 2023 08:47:22 +0300 Subject: [PATCH 68/87] Increment version patch number up to 1.4.2 An extra change is introduced as well: generate empty upgrade scripts without the need to create *.sql.in files in upgrade_script subdirectory. --- Makefile | 5 +++-- Makefile.common.mk | 2 +- expected/version.out | 2 +- pg_sphere.control | 2 +- upgrade_scripts/pg_sphere--1.4.0--1.4.1.sql.in | 1 - 5 files changed, 6 insertions(+), 6 deletions(-) delete mode 100644 upgrade_scripts/pg_sphere--1.4.0--1.4.1.sql.in diff --git a/Makefile b/Makefile index 88c082b..8a9dec7 100644 --- a/Makefile +++ b/Makefile @@ -34,6 +34,7 @@ DATA_built = $(RELEASE_SQL) \ pg_sphere--1.3.0--1.3.1.sql \ pg_sphere--1.3.1--1.4.0.sql \ pg_sphere--1.4.0--1.4.1.sql \ + pg_sphere--1.4.1--1.4.2.sql DOCS = README.pg_sphere COPYRIGHT.pg_sphere TESTS = version tables points euler circle line ellipse poly path box \ @@ -205,8 +206,8 @@ endif pg_sphere--1.3.1--1.4.0.sql: pgs_circle_sel.sql.in pgs_hash.sql.in cat upgrade_scripts/$@.in $^ > $@ -pg_sphere--1.4.0--1.4.1.sql: - cat upgrade_scripts/$@.in $^ > $@ +pg_sphere--1.4.0--1.4.1.sql pg_sphere--1.4.1--1.4.2.sql: + @echo "-- Nothing to upgrade in the schema" > $@ # end of local stuff diff --git a/Makefile.common.mk b/Makefile.common.mk index 42c2376..9a73710 100644 --- a/Makefile.common.mk +++ b/Makefile.common.mk @@ -5,4 +5,4 @@ #---------------------------------------------------------------------------- EXTENSION := pg_sphere -PGSPHERE_VERSION := 1.4.1 +PGSPHERE_VERSION := 1.4.2 diff --git a/expected/version.out b/expected/version.out index c05ab96..5e361bf 100644 --- a/expected/version.out +++ b/expected/version.out @@ -2,6 +2,6 @@ SELECT pg_sphere_version(); pg_sphere_version ------------------- - 1.4.1 + 1.4.2 (1 row) diff --git a/pg_sphere.control b/pg_sphere.control index fdf8f98..69ca772 100644 --- a/pg_sphere.control +++ b/pg_sphere.control @@ -1,5 +1,5 @@ # pg_sphere extension comment = 'spherical objects with useful functions, operators and index support' -default_version = '1.4.1' +default_version = '1.4.2' module_pathname = '$libdir/pg_sphere' relocatable = true diff --git a/upgrade_scripts/pg_sphere--1.4.0--1.4.1.sql.in b/upgrade_scripts/pg_sphere--1.4.0--1.4.1.sql.in deleted file mode 100644 index 8ea3baa..0000000 --- a/upgrade_scripts/pg_sphere--1.4.0--1.4.1.sql.in +++ /dev/null @@ -1 +0,0 @@ --- Nothing to upgrade in the schema From 597600eae6726bdffd1309627596d054da18c5ad Mon Sep 17 00:00:00 2001 From: Patrick Dowler Date: Wed, 6 Dec 2023 12:49:23 -0800 Subject: [PATCH 69/87] fix Makefile dist target the sparse.c and sscan.c files are now committed in src dir --- Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Makefile b/Makefile index 8a9dec7..c9c225f 100644 --- a/Makefile +++ b/Makefile @@ -227,7 +227,7 @@ else @$(missing) flex $< $@ endif -dist : clean sparse.c sscan.c +dist : clean find . -name '*~' -type f -exec rm {} \; cd .. && tar --transform s/$(SRC_DIR)/pgsphere-$(PGSPHERE_VERSION)/ --exclude CVS --exclude .git -czf pgsphere-$(PGSPHERE_VERSION).tar.gz $(SRC_DIR) && cd - From f2b6879704fc737aa020a26e7c1ad113bff83dd8 Mon Sep 17 00:00:00 2001 From: Ivan Panchenko Date: Sat, 9 Dec 2023 13:19:06 +0300 Subject: [PATCH 70/87] KNN support for spoints --- Makefile | 2 +- doc/indices.sgm | 13 ++++- expected/knn.out | 122 +++++++++++++++++++++++++++++++++++++++++++++ pgs_gist.sql.in | 7 ++- sql/knn.sql | 12 +++++ src/gist.c | 126 +++++++++++++++++++++++++++++++++++++++++++++++ 6 files changed, 279 insertions(+), 3 deletions(-) create mode 100644 expected/knn.out create mode 100644 sql/knn.sql diff --git a/Makefile b/Makefile index c9c225f..eb862f4 100644 --- a/Makefile +++ b/Makefile @@ -39,7 +39,7 @@ DATA_built = $(RELEASE_SQL) \ DOCS = README.pg_sphere COPYRIGHT.pg_sphere TESTS = version tables points euler circle line ellipse poly path box \ index contains_ops contains_ops_compat bounding_box_gist gnomo \ - epochprop contains overlaps spoint_brin sbox_brin selectivity + epochprop contains overlaps spoint_brin sbox_brin selectivity knn REGRESS = init $(TESTS) PG_CFLAGS += -DPGSPHERE_VERSION=$(PGSPHERE_VERSION) diff --git a/doc/indices.sgm b/doc/indices.sgm index 998b546..c27ef5e 100644 --- a/doc/indices.sgm +++ b/doc/indices.sgm @@ -68,6 +68,11 @@ + + GiST index can be used also for fast finding points closest to the given one + when ordering by an expression with the <-> operator + is used, as shown in an example below. + BRIN indexing supports just spherical points (spoint) and spherical coordinates range (sbox) at the moment. @@ -82,6 +87,13 @@ + + To find points closest to a given spherical position, use the <-> operator: + + + spoint (0.2, 0.3) LIMIT 10 ]]> + + BRIN index can be created through the following syntax: @@ -100,7 +112,6 @@ - diff --git a/expected/knn.out b/expected/knn.out new file mode 100644 index 0000000..49c8903 --- /dev/null +++ b/expected/knn.out @@ -0,0 +1,122 @@ +CREATE TABLE points (id int, p spoint, pos int); +INSERT INTO points (id, p) SELECT x, spoint(random()*6.28, (2*random()-1)*1.57) FROM generate_series(1,314159) x; +CREATE INDEX i ON points USING gist (p); +SET enable_indexscan = true; +EXPLAIN (costs off) SELECT p <-> spoint (0.2, 0.3) FROM points ORDER BY 1 LIMIT 100; + QUERY PLAN +------------------------------------------------- + Limit + -> Index Scan using i on points + Order By: (p <-> '(0.2 , 0.3)'::spoint) +(3 rows) + +UPDATE points SET pos = n FROM + (SELECT id, row_number() OVER (ORDER BY p <-> spoint (0.2, 0.3)) n FROM points ORDER BY p <-> spoint (0.2, 0.3) LIMIT 100) sel + WHERE points.id = sel.id; +SET enable_indexscan = false; +SELECT pos, row_number() OVER (ORDER BY p <-> spoint (0.2, 0.3)) n FROM points ORDER BY p <-> spoint (0.2, 0.3) LIMIT 100; + pos | n +-----+----- + 1 | 1 + 2 | 2 + 3 | 3 + 4 | 4 + 5 | 5 + 6 | 6 + 7 | 7 + 8 | 8 + 9 | 9 + 10 | 10 + 11 | 11 + 12 | 12 + 13 | 13 + 14 | 14 + 15 | 15 + 16 | 16 + 17 | 17 + 18 | 18 + 19 | 19 + 20 | 20 + 21 | 21 + 22 | 22 + 23 | 23 + 24 | 24 + 25 | 25 + 26 | 26 + 27 | 27 + 28 | 28 + 29 | 29 + 30 | 30 + 31 | 31 + 32 | 32 + 33 | 33 + 34 | 34 + 35 | 35 + 36 | 36 + 37 | 37 + 38 | 38 + 39 | 39 + 40 | 40 + 41 | 41 + 42 | 42 + 43 | 43 + 44 | 44 + 45 | 45 + 46 | 46 + 47 | 47 + 48 | 48 + 49 | 49 + 50 | 50 + 51 | 51 + 52 | 52 + 53 | 53 + 54 | 54 + 55 | 55 + 56 | 56 + 57 | 57 + 58 | 58 + 59 | 59 + 60 | 60 + 61 | 61 + 62 | 62 + 63 | 63 + 64 | 64 + 65 | 65 + 66 | 66 + 67 | 67 + 68 | 68 + 69 | 69 + 70 | 70 + 71 | 71 + 72 | 72 + 73 | 73 + 74 | 74 + 75 | 75 + 76 | 76 + 77 | 77 + 78 | 78 + 79 | 79 + 80 | 80 + 81 | 81 + 82 | 82 + 83 | 83 + 84 | 84 + 85 | 85 + 86 | 86 + 87 | 87 + 88 | 88 + 89 | 89 + 90 | 90 + 91 | 91 + 92 | 92 + 93 | 93 + 94 | 94 + 95 | 95 + 96 | 96 + 97 | 97 + 98 | 98 + 99 | 99 + 100 | 100 +(100 rows) + +DROP TABLE points; diff --git a/pgs_gist.sql.in b/pgs_gist.sql.in index e8ac119..3ac9971 100644 --- a/pgs_gist.sql.in +++ b/pgs_gist.sql.in @@ -98,12 +98,15 @@ CREATE FUNCTION g_spoint_compress(internal) AS 'MODULE_PATHNAME', 'g_spoint_compress' LANGUAGE 'c'; - CREATE FUNCTION g_spoint_consistent(internal, internal, int4, oid, internal) RETURNS internal AS 'MODULE_PATHNAME', 'g_spoint_consistent' LANGUAGE 'c'; +CREATE FUNCTION g_spoint_distance(internal, spoint, smallint, oid, internal) + RETURNS internal + AS 'MODULE_PATHNAME', 'g_spoint_distance' + LANGUAGE 'c'; CREATE OPERATOR CLASS spoint DEFAULT FOR TYPE spoint USING gist AS @@ -114,6 +117,7 @@ CREATE OPERATOR CLASS spoint OPERATOR 14 @ (spoint, spoly), OPERATOR 15 @ (spoint, sellipse), OPERATOR 16 @ (spoint, sbox), + OPERATOR 17 <-> (spoint, spoint) FOR ORDER BY float_ops, OPERATOR 37 <@ (spoint, scircle), OPERATOR 38 <@ (spoint, sline), OPERATOR 39 <@ (spoint, spath), @@ -127,6 +131,7 @@ CREATE OPERATOR CLASS spoint FUNCTION 5 g_spherekey_penalty (internal, internal, internal), FUNCTION 6 g_spherekey_picksplit (internal, internal), FUNCTION 7 g_spherekey_same (spherekey, spherekey, internal), + FUNCTION 8 g_spoint_distance (internal, spoint, smallint, oid, internal), STORAGE spherekey; diff --git a/sql/knn.sql b/sql/knn.sql new file mode 100644 index 0000000..0207c98 --- /dev/null +++ b/sql/knn.sql @@ -0,0 +1,12 @@ +CREATE TABLE points (id int, p spoint, pos int); +INSERT INTO points (id, p) SELECT x, spoint(random()*6.28, (2*random()-1)*1.57) FROM generate_series(1,314159) x; +CREATE INDEX i ON points USING gist (p); +SET enable_indexscan = true; +EXPLAIN (costs off) SELECT p <-> spoint (0.2, 0.3) FROM points ORDER BY 1 LIMIT 100; +UPDATE points SET pos = n FROM + (SELECT id, row_number() OVER (ORDER BY p <-> spoint (0.2, 0.3)) n FROM points ORDER BY p <-> spoint (0.2, 0.3) LIMIT 100) sel + WHERE points.id = sel.id; +SET enable_indexscan = false; +SELECT pos, row_number() OVER (ORDER BY p <-> spoint (0.2, 0.3)) n FROM points ORDER BY p <-> spoint (0.2, 0.3) LIMIT 100; +DROP TABLE points; + diff --git a/src/gist.c b/src/gist.c index b3223a5..f373448 100644 --- a/src/gist.c +++ b/src/gist.c @@ -36,6 +36,7 @@ PG_FUNCTION_INFO_V1(g_spherekey_penalty); PG_FUNCTION_INFO_V1(g_spherekey_picksplit); PG_FUNCTION_INFO_V1(g_spoint3_penalty); PG_FUNCTION_INFO_V1(g_spoint3_picksplit); +PG_FUNCTION_INFO_V1(g_spoint_distance); PG_FUNCTION_INFO_V1(g_spoint3_distance); PG_FUNCTION_INFO_V1(g_spoint3_fetch); @@ -681,6 +682,10 @@ g_spoint3_consistent(PG_FUNCTION_ARGS) PG_RETURN_BOOL(false); } +static double distance_vector_point_3d (Vector3D* v, double x, double y, double z) { + return acos ( (v->x * x + v->y * y + v->z * z) / sqrt( x*x + y*y + z*z ) ); // as v has length=1 by design +} + Datum g_spoint3_distance(PG_FUNCTION_ARGS) { @@ -1672,6 +1677,127 @@ fallbackSplit(Box3D *boxes, OffsetNumber maxoff, GIST_SPLITVEC *v) v->spl_ldatum_exists = v->spl_rdatum_exists = false; } + +Datum +g_spoint_distance(PG_FUNCTION_ARGS) +{ + GISTENTRY *entry = (GISTENTRY *) PG_GETARG_POINTER(0); + StrategyNumber strategy = (StrategyNumber) PG_GETARG_UINT16(2); + Box3D* box = (Box3D *) DatumGetPointer(entry->key); + double retval; + SPoint *point = (SPoint *) PG_GETARG_POINTER(1); + Vector3D v_point, v_low, v_high; + + switch (strategy) + { + case 17: + // Prepare data for calculation + spoint_vector3d(&v_point, point); + v_low.x = (double)box->low.coord[0] / MAXCVALUE; + v_low.y = (double)box->low.coord[1] / MAXCVALUE; + v_low.z = (double)box->low.coord[2] / MAXCVALUE; + v_high.x = (double)box->high.coord[0] / MAXCVALUE; + v_high.y = (double)box->high.coord[1] / MAXCVALUE; + v_high.z = (double)box->high.coord[2] / MAXCVALUE; + // a box splits space into 27 subspaces (6+12+8+1) with different distance calculation + if(v_point.x < v_low.x) { + if(v_point.y < v_low.y) { + if(v_point.z < v_low.z) { + retval = distance_vector_point_3d (&v_point, v_low.x, v_low.y, v_low.z); //point2point distance + } else if (v_point.z < v_high.z) { + retval = distance_vector_point_3d (&v_point, v_low.x, v_low.y, v_point.z); //point2line distance + } else { + retval = distance_vector_point_3d (&v_point, v_low.x, v_low.y, v_high.z); //point2point distance + } + } else if(v_point.y < v_high.y) { + if(v_point.z < v_low.z) { + retval = distance_vector_point_3d (&v_point, v_low.x, v_point.y , v_low.z); //point2line distance + } else if (v_point.z < v_high.z) { + retval = distance_vector_point_3d (&v_point, v_low.x, v_point.y , v_point.z); //point2plane distance + } else { + retval = distance_vector_point_3d (&v_point, v_low.x, v_point.y, v_high.z); //point2line distance + } + } else { + if(v_point.z < v_low.z) { + retval = distance_vector_point_3d (&v_point, v_low.x, v_high.y, v_low.z); //point2point distance + } else if (v_point.z < v_high.z) { + retval = distance_vector_point_3d (&v_point, v_low.x, v_high.y, v_point.z); //point2line distance + } else { + retval = distance_vector_point_3d (&v_point, v_low.x, v_high.y, v_high.z); //point2point distance + } + } + } else if(v_point.x < v_high.x) { + if(v_point.y < v_low.y) { + if(v_point.z < v_low.z) { + retval = distance_vector_point_3d (&v_point, v_point.x, v_low.y, v_low.z); //p2line distance + } else if (v_point.z < v_high.z) { + retval = distance_vector_point_3d (&v_point, v_point.x, v_low.y, v_point.z); //point2plane distance + } else { + retval = distance_vector_point_3d (&v_point, v_point.x, v_low.y, v_high.z); //point2line distance + } + } else if(v_point.y < v_high.y) { + if(v_point.z < v_low.z) { + retval = distance_vector_point_3d (&v_point, v_point.x, v_point.y , v_low.z); //point2plane distance + } else if (v_point.z < v_high.z) { + retval = 0; // inside cube + } else { + retval = distance_vector_point_3d (&v_point, v_point.x, v_point.y, v_high.z); //point2plane distance + } + } else { + if(v_point.z < v_low.z) { + retval = distance_vector_point_3d (&v_point, v_point.x, v_high.y, v_low.z); //point2line distance + } else if (v_point.z < v_high.z) { + retval = distance_vector_point_3d (&v_point, v_point.x, v_high.y, v_point.z); //point2plane distance + } else { + retval = distance_vector_point_3d (&v_point, v_point.x, v_high.y, v_high.z); //point2line distance + } + } + } else { + if(v_point.y < v_low.y) { + if(v_point.z < v_low.z) { + retval = distance_vector_point_3d (&v_point, v_high.x, v_low.y, v_low.z); //p2p distance + } else if (v_point.z < v_high.z) { + retval = distance_vector_point_3d (&v_point, v_high.x, v_low.y, v_point.z); //point2line distance + } else { + retval = distance_vector_point_3d (&v_point, v_high.x, v_low.y, v_high.z); //point2point distance + } + } else if(v_point.y < v_high.y) { + if(v_point.z < v_low.z) { + retval = distance_vector_point_3d (&v_point, v_high.x, v_point.y , v_low.z); //point2line distance + } else if (v_point.z < v_high.z) { + retval = distance_vector_point_3d (&v_point, v_high.x, v_point.y , v_point.z); //point2plane distance + } else { + retval = distance_vector_point_3d (&v_point, v_high.x, v_point.y, v_high.z); //point2line distance + } + } else { + if(v_point.z < v_low.z) { + retval = distance_vector_point_3d (&v_point, v_high.x, v_high.y, v_low.z); //point2point distance + } else if (v_point.z < v_high.z) { + retval = distance_vector_point_3d (&v_point, v_high.x, v_high.y, v_point.z); //point2line distance + } else { + retval = distance_vector_point_3d (&v_point, v_high.x, v_high.y, v_high.z); //point2point distance + } + } + } + + elog(DEBUG1, "distance (%lg,%lg,%lg %lg,%lg,%lg) <-> (%lg,%lg) = %lg", + v_low.x, v_low.y, v_low.z, + v_high.x, v_high.y, v_high.z, + point->lng, point->lat, + retval + ); + break; + + default: + elog(ERROR, "unrecognized cube strategy number: %d", strategy); + retval = 0; /* keep compiler quiet */ + break; + } + PG_RETURN_FLOAT8(retval); +} + + + /* * Represents information about an entry that can be placed to either group * without affecting overlap over selected axis ("common entry"). From f20a66474414c1ee8f5e14c066840eea51135517 Mon Sep 17 00:00:00 2001 From: Vitaly Davydov Date: Tue, 12 Dec 2023 16:47:59 +0300 Subject: [PATCH 71/87] Fix code formatting, bump release version up to 1.5.0 Raise the version up to 1.5.0, add upgrade script Fix issues found after the review --- Makefile | 6 +- Makefile.common.mk | 2 +- doc/indices.sgm | 9 +- expected/version.out | 2 +- pg_sphere.control | 2 +- pgs_gist.sql.in | 2 +- src/gist.c | 284 ++++++++++++------ .../pg_sphere--1.4.2--1.5.0.sql.in | 16 + 8 files changed, 222 insertions(+), 101 deletions(-) create mode 100644 upgrade_scripts/pg_sphere--1.4.2--1.5.0.sql.in diff --git a/Makefile b/Makefile index eb862f4..14350ec 100644 --- a/Makefile +++ b/Makefile @@ -34,7 +34,8 @@ DATA_built = $(RELEASE_SQL) \ pg_sphere--1.3.0--1.3.1.sql \ pg_sphere--1.3.1--1.4.0.sql \ pg_sphere--1.4.0--1.4.1.sql \ - pg_sphere--1.4.1--1.4.2.sql + pg_sphere--1.4.1--1.4.2.sql \ + pg_sphere--1.4.2--1.5.0.sql DOCS = README.pg_sphere COPYRIGHT.pg_sphere TESTS = version tables points euler circle line ellipse poly path box \ @@ -209,6 +210,9 @@ pg_sphere--1.3.1--1.4.0.sql: pgs_circle_sel.sql.in pgs_hash.sql.in pg_sphere--1.4.0--1.4.1.sql pg_sphere--1.4.1--1.4.2.sql: @echo "-- Nothing to upgrade in the schema" > $@ +pg_sphere--1.4.2--1.5.0.sql: + cat upgrade_scripts/$@.in $^ > $@ + # end of local stuff src/sscan.o : src/sparse.c diff --git a/Makefile.common.mk b/Makefile.common.mk index 9a73710..7764d84 100644 --- a/Makefile.common.mk +++ b/Makefile.common.mk @@ -5,4 +5,4 @@ #---------------------------------------------------------------------------- EXTENSION := pg_sphere -PGSPHERE_VERSION := 1.4.2 +PGSPHERE_VERSION := 1.5.0 diff --git a/doc/indices.sgm b/doc/indices.sgm index c27ef5e..6b874b0 100644 --- a/doc/indices.sgm +++ b/doc/indices.sgm @@ -69,9 +69,9 @@ - GiST index can be used also for fast finding points closest to the given one - when ordering by an expression with the <-> operator - is used, as shown in an example below. + A GiST index can be also used for quickly finding the points closest to the given one + when ordering by an expression with the <-> operator, + as shown in an example below. BRIN indexing supports just spherical points (spoint) @@ -88,7 +88,7 @@ - To find points closest to a given spherical position, use the <-> operator: + To find the points closest to a given spherical position, use the <-> operator: spoint (0.2, 0.3) LIMIT 10 ]]> @@ -112,6 +112,7 @@ + diff --git a/expected/version.out b/expected/version.out index 5e361bf..1d82d75 100644 --- a/expected/version.out +++ b/expected/version.out @@ -2,6 +2,6 @@ SELECT pg_sphere_version(); pg_sphere_version ------------------- - 1.4.2 + 1.5.0 (1 row) diff --git a/pg_sphere.control b/pg_sphere.control index 69ca772..4ecf4cd 100644 --- a/pg_sphere.control +++ b/pg_sphere.control @@ -1,5 +1,5 @@ # pg_sphere extension comment = 'spherical objects with useful functions, operators and index support' -default_version = '1.4.2' +default_version = '1.5.0' module_pathname = '$libdir/pg_sphere' relocatable = true diff --git a/pgs_gist.sql.in b/pgs_gist.sql.in index 3ac9971..fcd4f11 100644 --- a/pgs_gist.sql.in +++ b/pgs_gist.sql.in @@ -117,7 +117,7 @@ CREATE OPERATOR CLASS spoint OPERATOR 14 @ (spoint, spoly), OPERATOR 15 @ (spoint, sellipse), OPERATOR 16 @ (spoint, sbox), - OPERATOR 17 <-> (spoint, spoint) FOR ORDER BY float_ops, + OPERATOR 17 <-> (spoint, spoint) FOR ORDER BY float_ops, OPERATOR 37 <@ (spoint, scircle), OPERATOR 38 <@ (spoint, sline), OPERATOR 39 <@ (spoint, spath), diff --git a/src/gist.c b/src/gist.c index f373448..0fef2ac 100644 --- a/src/gist.c +++ b/src/gist.c @@ -511,7 +511,7 @@ g_spoint_consistent(PG_FUNCTION_ARGS) SCK_INTERLEAVE(SELLIPSE, sphereellipse_gen_key, 0); break; case 42: - SCK_INTERLEAVE(SBOX, spherebox_gen_key , 0); + SCK_INTERLEAVE(SBOX, spherebox_gen_key, 0); break; } @@ -682,8 +682,11 @@ g_spoint3_consistent(PG_FUNCTION_ARGS) PG_RETURN_BOOL(false); } -static double distance_vector_point_3d (Vector3D* v, double x, double y, double z) { - return acos ( (v->x * x + v->y * y + v->z * z) / sqrt( x*x + y*y + z*z ) ); // as v has length=1 by design +static double +distance_vector_point_3d(Vector3D *v, double x, double y, double z) +{ + /* as v has length = 1 by design */ + return acos((v->x * x + v->y * y + v->z * z) / sqrt(x * x + y * y + z * z)); } Datum @@ -1683,121 +1686,218 @@ g_spoint_distance(PG_FUNCTION_ARGS) { GISTENTRY *entry = (GISTENTRY *) PG_GETARG_POINTER(0); StrategyNumber strategy = (StrategyNumber) PG_GETARG_UINT16(2); - Box3D* box = (Box3D *) DatumGetPointer(entry->key); + Box3D *box = (Box3D *) DatumGetPointer(entry->key); double retval; SPoint *point = (SPoint *) PG_GETARG_POINTER(1); - Vector3D v_point, v_low, v_high; + Vector3D v_point, + v_low, + v_high; switch (strategy) { case 17: - // Prepare data for calculation + /* Prepare data for calculation */ spoint_vector3d(&v_point, point); - v_low.x = (double)box->low.coord[0] / MAXCVALUE; - v_low.y = (double)box->low.coord[1] / MAXCVALUE; - v_low.z = (double)box->low.coord[2] / MAXCVALUE; - v_high.x = (double)box->high.coord[0] / MAXCVALUE; - v_high.y = (double)box->high.coord[1] / MAXCVALUE; - v_high.z = (double)box->high.coord[2] / MAXCVALUE; - // a box splits space into 27 subspaces (6+12+8+1) with different distance calculation - if(v_point.x < v_low.x) { - if(v_point.y < v_low.y) { - if(v_point.z < v_low.z) { - retval = distance_vector_point_3d (&v_point, v_low.x, v_low.y, v_low.z); //point2point distance - } else if (v_point.z < v_high.z) { - retval = distance_vector_point_3d (&v_point, v_low.x, v_low.y, v_point.z); //point2line distance - } else { - retval = distance_vector_point_3d (&v_point, v_low.x, v_low.y, v_high.z); //point2point distance - } - } else if(v_point.y < v_high.y) { - if(v_point.z < v_low.z) { - retval = distance_vector_point_3d (&v_point, v_low.x, v_point.y , v_low.z); //point2line distance - } else if (v_point.z < v_high.z) { - retval = distance_vector_point_3d (&v_point, v_low.x, v_point.y , v_point.z); //point2plane distance - } else { - retval = distance_vector_point_3d (&v_point, v_low.x, v_point.y, v_high.z); //point2line distance + v_low.x = (double) box->low.coord[0] / MAXCVALUE; + v_low.y = (double) box->low.coord[1] / MAXCVALUE; + v_low.z = (double) box->low.coord[2] / MAXCVALUE; + v_high.x = (double) box->high.coord[0] / MAXCVALUE; + v_high.y = (double) box->high.coord[1] / MAXCVALUE; + v_high.z = (double) box->high.coord[2] / MAXCVALUE; + + /* + * a box splits space into 27 subspaces (6+12+8+1) with different + * distance calculation + */ + if (v_point.x < v_low.x) + { + if (v_point.y < v_low.y) + { + if (v_point.z < v_low.z) + { + /* point2point distance */ + retval = distance_vector_point_3d(&v_point, v_low.x, v_low.y, v_low.z); + } + else if (v_point.z < v_high.z) + { + /* point2line distance */ + retval = distance_vector_point_3d(&v_point, v_low.x, v_low.y, v_point.z); + } + else + { + /* point2point distance */ + retval = distance_vector_point_3d(&v_point, v_low.x, v_low.y, v_high.z); + } + } + else if (v_point.y < v_high.y) + { + if (v_point.z < v_low.z) + { + /* point2line distance */ + retval = distance_vector_point_3d(&v_point, v_low.x, v_point.y, v_low.z); + } + else if (v_point.z < v_high.z) + { + /* point2plane distance */ + retval = distance_vector_point_3d(&v_point, v_low.x, v_point.y, v_point.z); + } + else + { + /* point2line distance */ + retval = distance_vector_point_3d(&v_point, v_low.x, v_point.y, v_high.z); + } + } + else + { + if (v_point.z < v_low.z) + { + /* point2point distance */ + retval = distance_vector_point_3d(&v_point, v_low.x, v_high.y, v_low.z); + } + else if (v_point.z < v_high.z) + { + /* point2line distance */ + retval = distance_vector_point_3d(&v_point, v_low.x, v_high.y, v_point.z); + } + else + { + /* point2point distance */ + retval = distance_vector_point_3d(&v_point, v_low.x, v_high.y, v_high.z); + } + } + } + else if (v_point.x < v_high.x) + { + if (v_point.y < v_low.y) + { + if (v_point.z < v_low.z) + { + /* p2line distance */ + retval = distance_vector_point_3d(&v_point, v_point.x, v_low.y, v_low.z); + } + else if (v_point.z < v_high.z) + { + /* point2plane distance */ + retval = distance_vector_point_3d(&v_point, v_point.x, v_low.y, v_point.z); + } + else + { + /* point2line distance */ + retval = distance_vector_point_3d(&v_point, v_point.x, v_low.y, v_high.z); } - } else { - if(v_point.z < v_low.z) { - retval = distance_vector_point_3d (&v_point, v_low.x, v_high.y, v_low.z); //point2point distance - } else if (v_point.z < v_high.z) { - retval = distance_vector_point_3d (&v_point, v_low.x, v_high.y, v_point.z); //point2line distance - } else { - retval = distance_vector_point_3d (&v_point, v_low.x, v_high.y, v_high.z); //point2point distance + } + else if (v_point.y < v_high.y) + { + if (v_point.z < v_low.z) + { + /* point2plane distance */ + retval = distance_vector_point_3d(&v_point, v_point.x, v_point.y, v_low.z); + } + else if (v_point.z < v_high.z) + { + /* inside cube */ + retval = 0; + } + else + { + /* point2plane distance */ + retval = distance_vector_point_3d(&v_point, v_point.x, v_point.y, v_high.z); } } - } else if(v_point.x < v_high.x) { - if(v_point.y < v_low.y) { - if(v_point.z < v_low.z) { - retval = distance_vector_point_3d (&v_point, v_point.x, v_low.y, v_low.z); //p2line distance - } else if (v_point.z < v_high.z) { - retval = distance_vector_point_3d (&v_point, v_point.x, v_low.y, v_point.z); //point2plane distance - } else { - retval = distance_vector_point_3d (&v_point, v_point.x, v_low.y, v_high.z); //point2line distance - } - } else if(v_point.y < v_high.y) { - if(v_point.z < v_low.z) { - retval = distance_vector_point_3d (&v_point, v_point.x, v_point.y , v_low.z); //point2plane distance - } else if (v_point.z < v_high.z) { - retval = 0; // inside cube - } else { - retval = distance_vector_point_3d (&v_point, v_point.x, v_point.y, v_high.z); //point2plane distance + else + { + if (v_point.z < v_low.z) + { + /* point2line distance */ + retval = distance_vector_point_3d(&v_point, v_point.x, v_high.y, v_low.z); + } + else if (v_point.z < v_high.z) + { + /* point2plane distance */ + retval = distance_vector_point_3d(&v_point, v_point.x, v_high.y, v_point.z); } - } else { - if(v_point.z < v_low.z) { - retval = distance_vector_point_3d (&v_point, v_point.x, v_high.y, v_low.z); //point2line distance - } else if (v_point.z < v_high.z) { - retval = distance_vector_point_3d (&v_point, v_point.x, v_high.y, v_point.z); //point2plane distance - } else { - retval = distance_vector_point_3d (&v_point, v_point.x, v_high.y, v_high.z); //point2line distance + else + { + /* point2line distance */ + retval = distance_vector_point_3d(&v_point, v_point.x, v_high.y, v_high.z); } } - } else { - if(v_point.y < v_low.y) { - if(v_point.z < v_low.z) { - retval = distance_vector_point_3d (&v_point, v_high.x, v_low.y, v_low.z); //p2p distance - } else if (v_point.z < v_high.z) { - retval = distance_vector_point_3d (&v_point, v_high.x, v_low.y, v_point.z); //point2line distance - } else { - retval = distance_vector_point_3d (&v_point, v_high.x, v_low.y, v_high.z); //point2point distance - } - } else if(v_point.y < v_high.y) { - if(v_point.z < v_low.z) { - retval = distance_vector_point_3d (&v_point, v_high.x, v_point.y , v_low.z); //point2line distance - } else if (v_point.z < v_high.z) { - retval = distance_vector_point_3d (&v_point, v_high.x, v_point.y , v_point.z); //point2plane distance - } else { - retval = distance_vector_point_3d (&v_point, v_high.x, v_point.y, v_high.z); //point2line distance + } + else + { + if (v_point.y < v_low.y) + { + if (v_point.z < v_low.z) + { + /* p2p distance */ + retval = distance_vector_point_3d(&v_point, v_high.x, v_low.y, v_low.z); } - } else { - if(v_point.z < v_low.z) { - retval = distance_vector_point_3d (&v_point, v_high.x, v_high.y, v_low.z); //point2point distance - } else if (v_point.z < v_high.z) { - retval = distance_vector_point_3d (&v_point, v_high.x, v_high.y, v_point.z); //point2line distance - } else { - retval = distance_vector_point_3d (&v_point, v_high.x, v_high.y, v_high.z); //point2point distance + else if (v_point.z < v_high.z) + { + /* point2line distance */ + retval = distance_vector_point_3d(&v_point, v_high.x, v_low.y, v_point.z); + } + else + { + /* point2point distance */ + retval = distance_vector_point_3d(&v_point, v_high.x, v_low.y, v_high.z); + } + } + else if (v_point.y < v_high.y) + { + if (v_point.z < v_low.z) + { + /* point2line distance */ + retval = distance_vector_point_3d(&v_point, v_high.x, v_point.y, v_low.z); + } + else if (v_point.z < v_high.z) + { + /* point2plane distance */ + retval = distance_vector_point_3d(&v_point, v_high.x, v_point.y, v_point.z); + } + else + { + /* point2line distance */ + retval = distance_vector_point_3d(&v_point, v_high.x, v_point.y, v_high.z); + } + } + else + { + if (v_point.z < v_low.z) + { + /* point2point distance */ + retval = distance_vector_point_3d(&v_point, v_high.x, v_high.y, v_low.z); + } + else if (v_point.z < v_high.z) + { + /* point2line distance */ + retval = distance_vector_point_3d(&v_point, v_high.x, v_high.y, v_point.z); + } + else + { + /* point2point distance */ + retval = distance_vector_point_3d(&v_point, v_high.x, v_high.y, v_high.z); } } } - + elog(DEBUG1, "distance (%lg,%lg,%lg %lg,%lg,%lg) <-> (%lg,%lg) = %lg", - v_low.x, v_low.y, v_low.z, - v_high.x, v_high.y, v_high.z, - point->lng, point->lat, - retval - ); + v_low.x, v_low.y, v_low.z, + v_high.x, v_high.y, v_high.z, + point->lng, point->lat, + retval + ); break; default: elog(ERROR, "unrecognized cube strategy number: %d", strategy); - retval = 0; /* keep compiler quiet */ + retval = 0; /* keep compiler quiet */ break; } + PG_RETURN_FLOAT8(retval); } - - /* * Represents information about an entry that can be placed to either group * without affecting overlap over selected axis ("common entry"). @@ -2329,7 +2429,7 @@ do_picksplit(Box3D *boxes, OffsetNumber maxoff, GIST_SPLITVEC *v) { box = &boxes[i]; commonEntries[i].delta = fabs((unionSizeBox3D(leftBox, box) - leftBoxSize) - - (unionSizeBox3D(rightBox, box) - rightBoxSize)); + (unionSizeBox3D(rightBox, box) - rightBoxSize)); } /* diff --git a/upgrade_scripts/pg_sphere--1.4.2--1.5.0.sql.in b/upgrade_scripts/pg_sphere--1.4.2--1.5.0.sql.in new file mode 100644 index 0000000..35c964e --- /dev/null +++ b/upgrade_scripts/pg_sphere--1.4.2--1.5.0.sql.in @@ -0,0 +1,16 @@ +-- Upgrade: 1.4.2 -> 1.5.0 + +CREATE OR REPLACE FUNCTION g_spoint_distance(internal, spoint, smallint, oid, internal) + RETURNS internal + AS 'MODULE_PATHNAME', 'g_spoint_distance' + LANGUAGE 'c'; + +DO $$ +BEGIN + ALTER OPERATOR FAMILY spoint USING gist ADD + FUNCTION 8 (spoint, spoint) g_spoint_distance (internal, spoint, smallint, oid, internal); +EXCEPTION + WHEN duplicate_object THEN NULL; + WHEN OTHERS THEN RAISE; +END; +$$; From 2f7d791af0728ede689673b701ca6c215f23590d Mon Sep 17 00:00:00 2001 From: Vitaly Davydov Date: Tue, 19 Dec 2023 17:04:16 +0300 Subject: [PATCH 72/87] Fix indentation in headers with pgindent --- pgindent-excludes.list | 2 + src/box.h | 152 ++++++++++++++++++++--------------------- src/circle.h | 60 ++++++++-------- src/ellipse.h | 108 ++++++++++++++--------------- src/epochprop.h | 26 +++---- src/euler.c | 36 ++++++---- src/euler.h | 62 ++++++++--------- src/gist.h | 84 +++++++++++------------ src/gnomo.h | 4 +- src/key.h | 70 ++++++++++--------- src/line.h | 106 ++++++++++++++-------------- src/path.h | 118 ++++++++++++++++---------------- src/pg_sphere.h | 13 ++-- src/pgs_chealpix.h | 2 +- src/pgs_util.h | 18 ++--- src/point.h | 51 ++++++++------ src/polygon.h | 150 ++++++++++++++++++++-------------------- src/sbuffer.h | 72 +++++++++---------- src/vector3d.h | 23 ++++--- 19 files changed, 594 insertions(+), 563 deletions(-) diff --git a/pgindent-excludes.list b/pgindent-excludes.list index c3add5c..629df90 100644 --- a/pgindent-excludes.list +++ b/pgindent-excludes.list @@ -1 +1,3 @@ pgs_process_moc.h +pgs_healpix.h +pgs_moc.h diff --git a/src/box.h b/src/box.h index 7314ac0..6444a52 100644 --- a/src/box.h +++ b/src/box.h @@ -11,8 +11,8 @@ */ typedef struct { - SPoint sw; /* South-west value of a box */ - SPoint ne; /* North-east value of a box */ + SPoint sw; /* South-west value of a box */ + SPoint ne; /* North-east value of a box */ } SBOX; @@ -56,373 +56,373 @@ typedef struct /* * Checks whether two boxes are equal. */ -bool sbox_eq(SBOX *b1, SBOX *b2); +extern bool sbox_eq(SBOX *b1, SBOX *b2); /* * Checks whether a point is contained by a box. */ -bool sbox_cont_point(const SBOX *b, const SPoint *p); +extern bool sbox_cont_point(const SBOX *b, const SPoint *p); /* * Input function of a box. */ -Datum spherebox_in(PG_FUNCTION_ARGS); +extern Datum spherebox_in(PG_FUNCTION_ARGS); /* * Input function of a box from two points. The first point * is the south-west position, the second the north-east position. */ -Datum spherebox_in_from_points(PG_FUNCTION_ARGS); +extern Datum spherebox_in_from_points(PG_FUNCTION_ARGS); /* * Returns the south-west edge of a box. */ -Datum spherebox_sw(PG_FUNCTION_ARGS); +extern Datum spherebox_sw(PG_FUNCTION_ARGS); /* * Returns the north-east edge of a box. */ -Datum spherebox_ne(PG_FUNCTION_ARGS); +extern Datum spherebox_ne(PG_FUNCTION_ARGS); /* * Returns the south-east edge of a box. */ -Datum spherebox_se(PG_FUNCTION_ARGS); +extern Datum spherebox_se(PG_FUNCTION_ARGS); /* * Returns the north-west edge of a box. */ -Datum spherebox_nw(PG_FUNCTION_ARGS); +extern Datum spherebox_nw(PG_FUNCTION_ARGS); /* * Returns the area of a box. */ -Datum spherebox_area(PG_FUNCTION_ARGS); +extern Datum spherebox_area(PG_FUNCTION_ARGS); /* * Returns the circumference of a box. */ -Datum spherebox_circ(PG_FUNCTION_ARGS); +extern Datum spherebox_circ(PG_FUNCTION_ARGS); /* * Checks whether two boxes are equal. */ -Datum spherebox_equal(PG_FUNCTION_ARGS); +extern Datum spherebox_equal(PG_FUNCTION_ARGS); /* * Checks whether two boxes are not equal. */ -Datum spherebox_equal_neg(PG_FUNCTION_ARGS); +extern Datum spherebox_equal_neg(PG_FUNCTION_ARGS); /* * Checks whether a point is contained by a box. */ -Datum spherebox_cont_point(PG_FUNCTION_ARGS); +extern Datum spherebox_cont_point(PG_FUNCTION_ARGS); /* * Checks whether a point isn't contained by a box. */ -Datum spherebox_cont_point_neg(PG_FUNCTION_ARGS); +extern Datum spherebox_cont_point_neg(PG_FUNCTION_ARGS); /* * Checks whether a point is contained by a box. */ -Datum spherebox_cont_point_com(PG_FUNCTION_ARGS); +extern Datum spherebox_cont_point_com(PG_FUNCTION_ARGS); /* * Checks whether a point isn't contained by a box. */ -Datum spherebox_cont_point_com_neg(PG_FUNCTION_ARGS); +extern Datum spherebox_cont_point_com_neg(PG_FUNCTION_ARGS); /* * Checks whether a box contains a circle. */ -Datum spherebox_cont_circle(PG_FUNCTION_ARGS); +extern Datum spherebox_cont_circle(PG_FUNCTION_ARGS); /* * Checks whether a box doesn't contain a circle. */ -Datum spherebox_cont_circle_neg(PG_FUNCTION_ARGS); +extern Datum spherebox_cont_circle_neg(PG_FUNCTION_ARGS); /* * Checks whether a box contains a circle. */ -Datum spherebox_cont_circle_com(PG_FUNCTION_ARGS); +extern Datum spherebox_cont_circle_com(PG_FUNCTION_ARGS); /* * Checks whether a box doesn't contain a circle. */ -Datum spherebox_cont_circle_com_neg(PG_FUNCTION_ARGS); +extern Datum spherebox_cont_circle_com_neg(PG_FUNCTION_ARGS); /* * Checks whether a circle contains a box. */ -Datum spherecircle_cont_box(PG_FUNCTION_ARGS); +extern Datum spherecircle_cont_box(PG_FUNCTION_ARGS); /* * Checks whether a circle doesn't contain a box. */ -Datum spherecircle_cont_box_neg(PG_FUNCTION_ARGS); +extern Datum spherecircle_cont_box_neg(PG_FUNCTION_ARGS); /* * Checks whether a circle contains a box. */ -Datum spherecircle_cont_box_com(PG_FUNCTION_ARGS); +extern Datum spherecircle_cont_box_com(PG_FUNCTION_ARGS); /* * Checks whether a circle doesn't contain a box. */ -Datum spherecircle_cont_box_com_neg(PG_FUNCTION_ARGS); +extern Datum spherecircle_cont_box_com_neg(PG_FUNCTION_ARGS); /* * Checks whether a circle and a box overlap. */ -Datum spherebox_overlap_circle(PG_FUNCTION_ARGS); +extern Datum spherebox_overlap_circle(PG_FUNCTION_ARGS); /* * Checks whether a circle and a box don't overlap. */ -Datum spherebox_overlap_circle_neg(PG_FUNCTION_ARGS); +extern Datum spherebox_overlap_circle_neg(PG_FUNCTION_ARGS); /* * Checks whether a circle and a box overlap. */ -Datum spherebox_overlap_circle_com(PG_FUNCTION_ARGS); +extern Datum spherebox_overlap_circle_com(PG_FUNCTION_ARGS); /* * Checks whether a circle and a box don't overlap. */ -Datum spherebox_overlap_circle_com_neg(PG_FUNCTION_ARGS); +extern Datum spherebox_overlap_circle_com_neg(PG_FUNCTION_ARGS); /* * Checks whether a box contains a line. */ -Datum spherebox_cont_line(PG_FUNCTION_ARGS); +extern Datum spherebox_cont_line(PG_FUNCTION_ARGS); /* * Checks whether a box doesn't contain a line. */ -Datum spherebox_cont_line_neg(PG_FUNCTION_ARGS); +extern Datum spherebox_cont_line_neg(PG_FUNCTION_ARGS); /* * Checks whether a box contains a line. */ -Datum spherebox_cont_line_com(PG_FUNCTION_ARGS); +extern Datum spherebox_cont_line_com(PG_FUNCTION_ARGS); /* * Checks whether a box doesn't contain a line. */ -Datum spherebox_cont_line_com_neg(PG_FUNCTION_ARGS); +extern Datum spherebox_cont_line_com_neg(PG_FUNCTION_ARGS); /* * Checks whether a box and a line overlap. */ -Datum spherebox_overlap_line(PG_FUNCTION_ARGS); +extern Datum spherebox_overlap_line(PG_FUNCTION_ARGS); /* * Checks whether a box and a line don't overlap. */ -Datum spherebox_overlap_line_neg(PG_FUNCTION_ARGS); +extern Datum spherebox_overlap_line_neg(PG_FUNCTION_ARGS); /* * Checks whether a box and a line overlap. */ -Datum spherebox_overlap_line_com(PG_FUNCTION_ARGS); +extern Datum spherebox_overlap_line_com(PG_FUNCTION_ARGS); /* * Checks whether a box and a line don't overlap. */ -Datum spherebox_overlap_line_com_neg(PG_FUNCTION_ARGS); +extern Datum spherebox_overlap_line_com_neg(PG_FUNCTION_ARGS); /* * Checks whether a box contains a path. */ -Datum spherebox_cont_path(PG_FUNCTION_ARGS); +extern Datum spherebox_cont_path(PG_FUNCTION_ARGS); /* * Checks whether a box doesn't contain a path. */ -Datum spherebox_cont_path_neg(PG_FUNCTION_ARGS); +extern Datum spherebox_cont_path_neg(PG_FUNCTION_ARGS); /* * Checks whether a box contains a path. */ -Datum spherebox_cont_path_com(PG_FUNCTION_ARGS); +extern Datum spherebox_cont_path_com(PG_FUNCTION_ARGS); /* * Checks whether a box doesn't contain a path. */ -Datum spherebox_cont_path_com_neg(PG_FUNCTION_ARGS); +extern Datum spherebox_cont_path_com_neg(PG_FUNCTION_ARGS); /* * Checks whether a box and a path overlap. */ -Datum spherebox_overlap_path(PG_FUNCTION_ARGS); +extern Datum spherebox_overlap_path(PG_FUNCTION_ARGS); /* * Checks whether a box and a path don't overlap. */ -Datum spherebox_overlap_path_neg(PG_FUNCTION_ARGS); +extern Datum spherebox_overlap_path_neg(PG_FUNCTION_ARGS); /* * Checks whether a box and a path overlap. */ -Datum spherebox_overlap_path_com(PG_FUNCTION_ARGS); +extern Datum spherebox_overlap_path_com(PG_FUNCTION_ARGS); /* * Checks whether a box and a path don't overlap. */ -Datum spherebox_overlap_path_com_neg(PG_FUNCTION_ARGS); +extern Datum spherebox_overlap_path_com_neg(PG_FUNCTION_ARGS); /* * Checks whether a box contains a polygon. */ -Datum spherebox_cont_poly(PG_FUNCTION_ARGS); +extern Datum spherebox_cont_poly(PG_FUNCTION_ARGS); /* * Checks whether a box doesn't contain a polygon. */ -Datum spherebox_cont_poly_neg(PG_FUNCTION_ARGS); +extern Datum spherebox_cont_poly_neg(PG_FUNCTION_ARGS); /* * Checks whether a box contains a polygon. */ -Datum spherebox_cont_poly_com(PG_FUNCTION_ARGS); +extern Datum spherebox_cont_poly_com(PG_FUNCTION_ARGS); /* * Checks whether a box doesn't contain a polygon. */ -Datum spherebox_cont_poly_com_neg(PG_FUNCTION_ARGS); +extern Datum spherebox_cont_poly_com_neg(PG_FUNCTION_ARGS); /* * Checks whether a polygon contains a box. */ -Datum spherepoly_cont_box(PG_FUNCTION_ARGS); +extern Datum spherepoly_cont_box(PG_FUNCTION_ARGS); /* * Checks whether a polygon doesn't contain a box. */ -Datum spherepoly_cont_box_neg(PG_FUNCTION_ARGS); +extern Datum spherepoly_cont_box_neg(PG_FUNCTION_ARGS); /* * Checks whether a polygon contains a box. */ -Datum spherepoly_cont_box_com(PG_FUNCTION_ARGS); +extern Datum spherepoly_cont_box_com(PG_FUNCTION_ARGS); /* * Checks whether a polygon doesn't contain a box. */ -Datum spherepoly_cont_box_com_neg(PG_FUNCTION_ARGS); +extern Datum spherepoly_cont_box_com_neg(PG_FUNCTION_ARGS); /* * Checks whether a polygon and a box overlap. */ -Datum spherebox_overlap_poly(PG_FUNCTION_ARGS); +extern Datum spherebox_overlap_poly(PG_FUNCTION_ARGS); /* * Checks whether a polygon and a box don't overlap. */ -Datum spherebox_overlap_poly_neg(PG_FUNCTION_ARGS); +extern Datum spherebox_overlap_poly_neg(PG_FUNCTION_ARGS); /* * Checks whether a polygon and a box overlap. */ -Datum spherebox_overlap_poly_com(PG_FUNCTION_ARGS); +extern Datum spherebox_overlap_poly_com(PG_FUNCTION_ARGS); /* * Checks whether a polygon and a box don't overlap. */ -Datum spherebox_overlap_poly_com_neg(PG_FUNCTION_ARGS); +extern Datum spherebox_overlap_poly_com_neg(PG_FUNCTION_ARGS); /* * Checks whether a box contains an ellipse. */ -Datum spherebox_cont_ellipse(PG_FUNCTION_ARGS); +extern Datum spherebox_cont_ellipse(PG_FUNCTION_ARGS); /* * Checks whether a box doesn't contain an ellipse. */ -Datum spherebox_cont_ellipse_neg(PG_FUNCTION_ARGS); +extern Datum spherebox_cont_ellipse_neg(PG_FUNCTION_ARGS); /* * Checks whether a box contains an ellipse. */ -Datum spherebox_cont_ellipse_com(PG_FUNCTION_ARGS); +extern Datum spherebox_cont_ellipse_com(PG_FUNCTION_ARGS); /* * Checks whether a box doesn't contain an ellipse. */ -Datum spherebox_cont_ellipse_com_neg(PG_FUNCTION_ARGS); +extern Datum spherebox_cont_ellipse_com_neg(PG_FUNCTION_ARGS); /* * Checks whether an ellipse contains a box. */ -Datum sphereellipse_cont_box(PG_FUNCTION_ARGS); +extern Datum sphereellipse_cont_box(PG_FUNCTION_ARGS); /* * Checks whether an ellipse doesn't contain a box. */ -Datum sphereellipse_cont_box_neg(PG_FUNCTION_ARGS); +extern Datum sphereellipse_cont_box_neg(PG_FUNCTION_ARGS); /* * Checks whether an ellipse contains a box. */ -Datum sphereellipse_cont_box_com(PG_FUNCTION_ARGS); +extern Datum sphereellipse_cont_box_com(PG_FUNCTION_ARGS); /* * Checks whether an ellipse doesn't contain a box. */ -Datum sphereellipse_cont_box_com_neg(PG_FUNCTION_ARGS); +extern Datum sphereellipse_cont_box_com_neg(PG_FUNCTION_ARGS); /* * Checks whether an ellipse and a box overlap. */ -Datum spherebox_overlap_ellipse(PG_FUNCTION_ARGS); +extern Datum spherebox_overlap_ellipse(PG_FUNCTION_ARGS); /* * Checks whether an ellipse and a box don't overlap. */ -Datum spherebox_overlap_ellipse_neg(PG_FUNCTION_ARGS); +extern Datum spherebox_overlap_ellipse_neg(PG_FUNCTION_ARGS); /* * Checks whether an ellipse and a box overlap. */ -Datum spherebox_overlap_ellipse_com(PG_FUNCTION_ARGS); +extern Datum spherebox_overlap_ellipse_com(PG_FUNCTION_ARGS); /* * Checks whether an ellipse and a box don't overlap. */ -Datum spherebox_overlap_ellipse_com_neg(PG_FUNCTION_ARGS); +extern Datum spherebox_overlap_ellipse_com_neg(PG_FUNCTION_ARGS); /* * Checks whether a box contains another box. */ -Datum spherebox_cont_box(PG_FUNCTION_ARGS); +extern Datum spherebox_cont_box(PG_FUNCTION_ARGS); /* * Checks whether a box doesn't contain another box. */ -Datum spherebox_cont_box_neg(PG_FUNCTION_ARGS); +extern Datum spherebox_cont_box_neg(PG_FUNCTION_ARGS); /* * Checks whether a box contains another box. */ -Datum spherebox_cont_box_com(PG_FUNCTION_ARGS); +extern Datum spherebox_cont_box_com(PG_FUNCTION_ARGS); /* * Checks whether a box doesn't contain another box. */ -Datum spherebox_cont_box_com_neg(PG_FUNCTION_ARGS); +extern Datum spherebox_cont_box_com_neg(PG_FUNCTION_ARGS); /* * Checks whether two boxes overlap. */ -Datum spherebox_overlap_box(PG_FUNCTION_ARGS); +extern Datum spherebox_overlap_box(PG_FUNCTION_ARGS); /* * Checks whether two boxes don't overlap. */ -Datum spherebox_overlap_box_neg(PG_FUNCTION_ARGS); +extern Datum spherebox_overlap_box_neg(PG_FUNCTION_ARGS); #endif diff --git a/src/circle.h b/src/circle.h index b8aa520..614b0e8 100644 --- a/src/circle.h +++ b/src/circle.h @@ -10,151 +10,151 @@ */ typedef struct { - SPoint center; /* the center of circle */ - float8 radius; /* the circle radius in radians */ + SPoint center; /* the center of circle */ + float8 radius; /* the circle radius in radians */ } SCIRCLE; /* * Checks whether two circles are equal. */ -bool scircle_eq(const SCIRCLE *c1, const SCIRCLE *c2); +extern bool scircle_eq(const SCIRCLE *c1, const SCIRCLE *c2); /* * Checks whether a circle contains a point. */ -bool spoint_in_circle(const SPoint *p, const SCIRCLE *c); +extern bool spoint_in_circle(const SPoint *p, const SCIRCLE *c); /* * Transforms a circle using an Euler transformation. */ -void euler_scircle_trans(SCIRCLE *out, const SCIRCLE *in, const SEuler *se); +extern void euler_scircle_trans(SCIRCLE *out, const SCIRCLE *in, const SEuler *se); /* * Takes the input and stores it as a spherical circle. */ -Datum spherecircle_in(PG_FUNCTION_ARGS); +extern Datum spherecircle_in(PG_FUNCTION_ARGS); /* * Checks whether two circles are equal. */ -Datum spherecircle_equal(PG_FUNCTION_ARGS); +extern Datum spherecircle_equal(PG_FUNCTION_ARGS); /* * Checks whether two circles are not equal. */ -Datum spherecircle_equal_neg(PG_FUNCTION_ARGS); +extern Datum spherecircle_equal_neg(PG_FUNCTION_ARGS); /* * Calculate the distance of two circles. If they overlap, this function * returns 0.0. */ -Datum spherecircle_distance(PG_FUNCTION_ARGS); +extern Datum spherecircle_distance(PG_FUNCTION_ARGS); /* * Calculate the distance of a circle and a point. If a circle contains a point, * this function returns 0.0. */ -Datum spherecircle_point_distance(PG_FUNCTION_ARGS); +extern Datum spherecircle_point_distance(PG_FUNCTION_ARGS); /* * Calculate the distance of a point and a circle. If a circle contains a point, * this function returns 0.0. */ -Datum spherecircle_point_distance_com(PG_FUNCTION_ARGS); +extern Datum spherecircle_point_distance_com(PG_FUNCTION_ARGS); /* * Checks whether a circle contains a point. */ -Datum spherepoint_in_circle(PG_FUNCTION_ARGS); +extern Datum spherepoint_in_circle(PG_FUNCTION_ARGS); /* * Checks whether a circle doesn't contain a point. */ -Datum spherepoint_in_circle_neg(PG_FUNCTION_ARGS); +extern Datum spherepoint_in_circle_neg(PG_FUNCTION_ARGS); /* * Checks whether a circle contains a point. */ -Datum spherepoint_in_circle_com(PG_FUNCTION_ARGS); +extern Datum spherepoint_in_circle_com(PG_FUNCTION_ARGS); /* * Checks whether a circle doesn't contain a point. */ -Datum spherepoint_in_circle_com_neg(PG_FUNCTION_ARGS); +extern Datum spherepoint_in_circle_com_neg(PG_FUNCTION_ARGS); /* * Checks whether a circle is contained by other circle. */ -Datum spherecircle_in_circle(PG_FUNCTION_ARGS); +extern Datum spherecircle_in_circle(PG_FUNCTION_ARGS); /* * Checks whether a circle is not contained by other circle. */ -Datum spherecircle_in_circle_neg(PG_FUNCTION_ARGS); +extern Datum spherecircle_in_circle_neg(PG_FUNCTION_ARGS); /* * Checks whether a circle contains other circle. */ -Datum spherecircle_in_circle_com(PG_FUNCTION_ARGS); +extern Datum spherecircle_in_circle_com(PG_FUNCTION_ARGS); /* * Checks whether circle does not contain other circle. */ -Datum spherecircle_in_circle_com_neg(PG_FUNCTION_ARGS); +extern Datum spherecircle_in_circle_com_neg(PG_FUNCTION_ARGS); /* * Checks whether two circles overlap. */ -Datum spherecircle_overlap(PG_FUNCTION_ARGS); +extern Datum spherecircle_overlap(PG_FUNCTION_ARGS); /* * Checks whether two circles overlap. */ -Datum spherecircle_overlap_neg(PG_FUNCTION_ARGS); +extern Datum spherecircle_overlap_neg(PG_FUNCTION_ARGS); /* * Returns the center of a circle. */ -Datum spherecircle_center(PG_FUNCTION_ARGS); +extern Datum spherecircle_center(PG_FUNCTION_ARGS); /* * Returns the radius of a circle. */ -Datum spherecircle_radius(PG_FUNCTION_ARGS); +extern Datum spherecircle_radius(PG_FUNCTION_ARGS); /* * Converts a point to a circle. */ -Datum spherepoint_to_circle(PG_FUNCTION_ARGS); +extern Datum spherepoint_to_circle(PG_FUNCTION_ARGS); /* * Creates a circle from center and radius. */ -Datum spherecircle_by_center(PG_FUNCTION_ARGS); +extern Datum spherecircle_by_center(PG_FUNCTION_ARGS); /* * Creates a circle from center and radius(in degrees). */ -Datum spherecircle_by_center_deg(PG_FUNCTION_ARGS); +extern Datum spherecircle_by_center_deg(PG_FUNCTION_ARGS); /* * Calculates the area of a circle in square radians. */ -Datum spherecircle_area(PG_FUNCTION_ARGS); +extern Datum spherecircle_area(PG_FUNCTION_ARGS); /* * Calculates the circumference of a circle in radians. */ -Datum spherecircle_circ(PG_FUNCTION_ARGS); +extern Datum spherecircle_circ(PG_FUNCTION_ARGS); /* * Transforms a circle using an Euler transformation. */ -Datum spheretrans_circle(PG_FUNCTION_ARGS); +extern Datum spheretrans_circle(PG_FUNCTION_ARGS); /* * Inverse transformation of a circle using an Euler transformation. */ -Datum spheretrans_circle_inverse(PG_FUNCTION_ARGS); +extern Datum spheretrans_circle_inverse(PG_FUNCTION_ARGS); #endif diff --git a/src/ellipse.h b/src/ellipse.h index b27bc3b..f600936 100644 --- a/src/ellipse.h +++ b/src/ellipse.h @@ -18,9 +18,9 @@ typedef struct */ float8 rad[2]; - float8 phi, /* the first rotation angle around z axis */ - theta, /* the second rotation angle around x axis */ - psi; /* the last rotation angle around z axis */ + float8 phi, /* the first rotation angle around z axis */ + theta, /* the second rotation angle around x axis */ + psi; /* the last rotation angle around z axis */ } SELLIPSE; /* @@ -47,258 +47,258 @@ typedef struct /* * Checks whether two ellipses are equal . */ -bool sellipse_eq(const SELLIPSE *e1, const SELLIPSE *e2); +extern bool sellipse_eq(const SELLIPSE *e1, const SELLIPSE *e2); /* * Returns the center of an ellipse. */ -void sellipse_center(SPoint *sp, const SELLIPSE *e); +extern void sellipse_center(SPoint *sp, const SELLIPSE *e); /* * Checks whether a ellipse contains point. */ -bool sellipse_cont_point(const SELLIPSE *se, const SPoint *sp); +extern bool sellipse_cont_point(const SELLIPSE *se, const SPoint *sp); /* * Returns the large axis of an ellipse as line. */ -bool sellipse_line(SLine *sl, const SELLIPSE *e); +extern bool sellipse_line(SLine *sl, const SELLIPSE *e); /* * Relationship between a line and an ellipse as PGS_ELLIPSE_LINE_REL int8 value. */ -int8 sellipse_line_pos(const SELLIPSE *se, const SLine *sl); +extern int8 sellipse_line_pos(const SELLIPSE *se, const SLine *sl); /* * Relationship between a circle and an ellipse as PGS_ELLIPSE_CIRCLE_REL int8 value. */ -int8 sellipse_circle_pos(const SELLIPSE *se, const SCIRCLE *sc); +extern int8 sellipse_circle_pos(const SELLIPSE *se, const SCIRCLE *sc); /* * Returns the Euler transformation of an ellipse. */ -void sellipse_trans(SEuler *se, const SELLIPSE *e); +extern void sellipse_trans(SEuler *se, const SELLIPSE *e); /* * Input of the spherical ellipse. */ -Datum sphereellipse_in(PG_FUNCTION_ARGS); +extern Datum sphereellipse_in(PG_FUNCTION_ARGS); /* * Input of the spherical ellipse from center, axes and inclination. */ -Datum sphereellipse_infunc(PG_FUNCTION_ARGS); +extern Datum sphereellipse_infunc(PG_FUNCTION_ARGS); /* * Returns the inclination of an ellipse. */ -Datum sphereellipse_incl(PG_FUNCTION_ARGS); +extern Datum sphereellipse_incl(PG_FUNCTION_ARGS); /* * Returns the length of the major axis of an ellipse. */ -Datum sphereellipse_rad1(PG_FUNCTION_ARGS); +extern Datum sphereellipse_rad1(PG_FUNCTION_ARGS); /* * Returns the length of the minor axis of an ellipse. */ -Datum sphereellipse_rad2(PG_FUNCTION_ARGS); +extern Datum sphereellipse_rad2(PG_FUNCTION_ARGS); /* * Returns the center of an ellipse. */ -Datum sphereellipse_center(PG_FUNCTION_ARGS); +extern Datum sphereellipse_center(PG_FUNCTION_ARGS); /* * Returns the Euler transformation of an ellipse. */ -Datum sphereellipse_trans(PG_FUNCTION_ARGS); +extern Datum sphereellipse_trans(PG_FUNCTION_ARGS); /* * Casts a spherical ellipse as circle. The created circle is the boundary * circle of ellipse. The diameter of returned circle is equal to length of * major axis of ellipse. */ -Datum sphereellipse_circle(PG_FUNCTION_ARGS); +extern Datum sphereellipse_circle(PG_FUNCTION_ARGS); /* * Casts a spherical point to an ellipse. */ -Datum spherepoint_ellipse(PG_FUNCTION_ARGS); +extern Datum spherepoint_ellipse(PG_FUNCTION_ARGS); /* * Casts a spherical circle to an ellipse. */ -Datum spherecircle_ellipse(PG_FUNCTION_ARGS); +extern Datum spherecircle_ellipse(PG_FUNCTION_ARGS); /* * Checks whether two ellipses are equal. */ -Datum sphereellipse_equal(PG_FUNCTION_ARGS); +extern Datum sphereellipse_equal(PG_FUNCTION_ARGS); /* * Checks whether two ellipses are not equal. */ -Datum sphereellipse_equal_neg(PG_FUNCTION_ARGS); +extern Datum sphereellipse_equal_neg(PG_FUNCTION_ARGS); /* * Checks whether an ellipse contains a point. */ -Datum sphereellipse_cont_point(PG_FUNCTION_ARGS); +extern Datum sphereellipse_cont_point(PG_FUNCTION_ARGS); /* * Checks whether an ellipse doesn't contain a point. */ -Datum sphereellipse_cont_point_neg(PG_FUNCTION_ARGS); +extern Datum sphereellipse_cont_point_neg(PG_FUNCTION_ARGS); /* * Checks whether an ellipse contains a point. */ -Datum sphereellipse_cont_point_com(PG_FUNCTION_ARGS); +extern Datum sphereellipse_cont_point_com(PG_FUNCTION_ARGS); /* * Checks whether an ellipse doesn't contain a point. */ -Datum sphereellipse_cont_point_com_neg(PG_FUNCTION_ARGS); +extern Datum sphereellipse_cont_point_com_neg(PG_FUNCTION_ARGS); /* * Checks whether an ellipse contains a line. */ -Datum sphereellipse_cont_line(PG_FUNCTION_ARGS); +extern Datum sphereellipse_cont_line(PG_FUNCTION_ARGS); /* * Checks whether an ellipse doesn't contain a line. */ -Datum sphereellipse_cont_line_neg(PG_FUNCTION_ARGS); +extern Datum sphereellipse_cont_line_neg(PG_FUNCTION_ARGS); /* * Checks whether an ellipse contains a line. */ -Datum sphereellipse_cont_line_com(PG_FUNCTION_ARGS); +extern Datum sphereellipse_cont_line_com(PG_FUNCTION_ARGS); /* * Checks whether an ellipse doesn't contain a line. */ -Datum sphereellipse_cont_line_com_neg(PG_FUNCTION_ARGS); +extern Datum sphereellipse_cont_line_com_neg(PG_FUNCTION_ARGS); /* * Checks whether an ellipse and a line overlap. */ -Datum sphereellipse_overlap_line(PG_FUNCTION_ARGS); +extern Datum sphereellipse_overlap_line(PG_FUNCTION_ARGS); /* * Checks whether an ellipse and a line don't overlap. */ -Datum sphereellipse_overlap_line_neg(PG_FUNCTION_ARGS); +extern Datum sphereellipse_overlap_line_neg(PG_FUNCTION_ARGS); /* * Checks whether an ellipse and a line overlap. */ -Datum sphereellipse_overlap_line_com(PG_FUNCTION_ARGS); +extern Datum sphereellipse_overlap_line_com(PG_FUNCTION_ARGS); /* * Checks whether an ellipse and a line don't overlap. */ -Datum sphereellipse_overlap_line_com_neg(PG_FUNCTION_ARGS); +extern Datum sphereellipse_overlap_line_com_neg(PG_FUNCTION_ARGS); /* * Checks whether an ellipse contains a circle. */ -Datum sphereellipse_cont_circle(PG_FUNCTION_ARGS); +extern Datum sphereellipse_cont_circle(PG_FUNCTION_ARGS); /* * Checks whether an ellipse doesn't contain a circle. */ -Datum sphereellipse_cont_circle_neg(PG_FUNCTION_ARGS); +extern Datum sphereellipse_cont_circle_neg(PG_FUNCTION_ARGS); /* * Checks whether an ellipse contains a circle. */ -Datum sphereellipse_cont_circle_com(PG_FUNCTION_ARGS); +extern Datum sphereellipse_cont_circle_com(PG_FUNCTION_ARGS); /* * Checks whether an ellipse doesn't contain a circle. */ -Datum sphereellipse_cont_circle_com_neg(PG_FUNCTION_ARGS); +extern Datum sphereellipse_cont_circle_com_neg(PG_FUNCTION_ARGS); /* * Checks whether a circle contains an ellipse. */ -Datum spherecircle_cont_ellipse(PG_FUNCTION_ARGS); +extern Datum spherecircle_cont_ellipse(PG_FUNCTION_ARGS); /* * Checks whether a circle doesn't contain an ellipse. */ -Datum spherecircle_cont_ellipse_neg(PG_FUNCTION_ARGS); +extern Datum spherecircle_cont_ellipse_neg(PG_FUNCTION_ARGS); /* * Checks whether a circle contains an ellipse. */ -Datum spherecircle_cont_ellipse_com(PG_FUNCTION_ARGS); +extern Datum spherecircle_cont_ellipse_com(PG_FUNCTION_ARGS); /* * Checks whether a circle doesn't contain an ellipse. */ -Datum spherecircle_cont_ellipse_com_neg(PG_FUNCTION_ARGS); +extern Datum spherecircle_cont_ellipse_com_neg(PG_FUNCTION_ARGS); /* * Checks whether a circle and an ellipse overlap. */ -Datum sphereellipse_overlap_circle(PG_FUNCTION_ARGS); +extern Datum sphereellipse_overlap_circle(PG_FUNCTION_ARGS); /* * Checks whether a circle and an ellipse don't overlap. */ -Datum sphereellipse_overlap_circle_neg(PG_FUNCTION_ARGS); +extern Datum sphereellipse_overlap_circle_neg(PG_FUNCTION_ARGS); /* * Checks whether a circle and an ellipse overlap. */ -Datum sphereellipse_overlap_circle_com(PG_FUNCTION_ARGS); +extern Datum sphereellipse_overlap_circle_com(PG_FUNCTION_ARGS); /* * Checks whether a circle and an ellipse don't overlap. */ -Datum sphereellipse_overlap_circle_com_neg(PG_FUNCTION_ARGS); +extern Datum sphereellipse_overlap_circle_com_neg(PG_FUNCTION_ARGS); /* * Checks whether an ellipse contains other ellipse. */ -Datum sphereellipse_cont_ellipse(PG_FUNCTION_ARGS); +extern Datum sphereellipse_cont_ellipse(PG_FUNCTION_ARGS); /* * Checks whether an ellipse doesn't contain other ellipse. */ -Datum sphereellipse_cont_ellipse_neg(PG_FUNCTION_ARGS); +extern Datum sphereellipse_cont_ellipse_neg(PG_FUNCTION_ARGS); /* * Checks whether an ellipse is contained by other ellipse. */ -Datum sphereellipse_cont_ellipse_com(PG_FUNCTION_ARGS); +extern Datum sphereellipse_cont_ellipse_com(PG_FUNCTION_ARGS); /* * Checks whether an ellipse isn't contained by other ellipse. */ -Datum sphereellipse_cont_ellipse_com_neg(PG_FUNCTION_ARGS); +extern Datum sphereellipse_cont_ellipse_com_neg(PG_FUNCTION_ARGS); /* * Checks whether two ellipses overlap. */ -Datum sphereellipse_overlap_ellipse(PG_FUNCTION_ARGS); +extern Datum sphereellipse_overlap_ellipse(PG_FUNCTION_ARGS); /* * Checks whether two ellipses don't overlap. */ -Datum sphereellipse_overlap_ellipse_neg(PG_FUNCTION_ARGS); +extern Datum sphereellipse_overlap_ellipse_neg(PG_FUNCTION_ARGS); /* * Transforms an ellipse using an Euler transformation. */ -Datum spheretrans_ellipse(PG_FUNCTION_ARGS); +extern Datum spheretrans_ellipse(PG_FUNCTION_ARGS); /* * Transforms an ellipse using an Euler transformation. */ -Datum spheretrans_ellipse_inv(PG_FUNCTION_ARGS); +extern Datum spheretrans_ellipse_inv(PG_FUNCTION_ARGS); #endif diff --git a/src/epochprop.h b/src/epochprop.h index 9e1b87e..a93e4c3 100644 --- a/src/epochprop.h +++ b/src/epochprop.h @@ -3,24 +3,24 @@ #include -Datum epoch_prop(PG_FUNCTION_ARGS); +extern Datum epoch_prop(PG_FUNCTION_ARGS); /* a cartesian point; this is like geo_decl's point, but you can't have both geo_decls and pg_sphere right now (both define a type Point, not to mention they have different ideas on EPSILON */ -typedef struct s_cpoint { - double x, y; +typedef struct s_cpoint +{ + double x, + y; } CPoint; -typedef struct s_phasevec { - SPoint pos; /* Position as an SPoint */ - double pm[2]; /* Proper motion long/lat in rad/year, - PM in longitude has cos(lat) applied */ - double parallax; /* in rad */ - double rv; /* radial velocity in km/s */ - int parallax_valid; /* 1 if the parallax really is a NULL */ +typedef struct s_phasevec +{ + SPoint pos; /* Position as an SPoint */ + double pm[2]; /* Proper motion long/lat in rad/year, PM in + * longitude has cos(lat) applied */ + double parallax; /* in rad */ + double rv; /* radial velocity in km/s */ + int parallax_valid; /* 1 if the parallax really is a NULL */ } phasevec; - - - diff --git a/src/euler.c b/src/euler.c index a45f7b3..f9d4190 100644 --- a/src/euler.c +++ b/src/euler.c @@ -109,8 +109,8 @@ spheretrans_from_float8_and_type(PG_FUNCTION_ARGS) d[1] = PG_GETARG_DATUM(1); d[2] = PG_GETARG_DATUM(2); se = (SEuler *) DatumGetPointer( - DirectFunctionCall3(spheretrans_from_float8, - d[0], d[1], d[2])); + DirectFunctionCall3(spheretrans_from_float8, + d[0], d[1], d[2])); for (i = 0; i < 3; i++) { @@ -165,7 +165,8 @@ seuler_set_zxz(SEuler *se) bool strans_eq(const SEuler *e1, const SEuler *e2) { - SPoint in[2], p[4]; + SPoint in[2], + p[4]; in[0].lng = 0.0; in[0].lat = 0.0; @@ -210,6 +211,7 @@ Datum spheretrans_theta(PG_FUNCTION_ARGS) { SEuler *se = (SEuler *) PG_GETARG_POINTER(0); + PG_RETURN_FLOAT8(se->theta); } @@ -267,8 +269,8 @@ spheretrans_type(PG_FUNCTION_ARGS) void spheretrans_inv(SEuler *se) { - float8 lng[3]; - const unsigned char c = se->phi_a; + float8 lng[3]; + const unsigned char c = se->phi_a; lng[2] = -se->phi; lng[1] = -se->theta; @@ -298,7 +300,7 @@ strans_zxz(SEuler *ret, const SEuler *se) } else { - SEuler tmp; + SEuler tmp; tmp.psi = 0.0; tmp.theta = 0.0; @@ -339,7 +341,7 @@ spheretrans_invert(PG_FUNCTION_ARGS) void seuler_trans_zxz(SEuler *out, const SEuler *in, const SEuler *se) { - SPoint sp[4]; + SPoint sp[4]; sp[0].lng = 0.0; sp[0].lat = 0.0; @@ -380,7 +382,8 @@ spheretrans_trans_inv(PG_FUNCTION_ARGS) void euler_spoint_trans(SPoint *out, const SPoint *in, const SEuler *se) { - Vector3D v, o; + Vector3D v, + o; spoint_vector3d(&v, in); euler_vector_trans(&o, &v, se); @@ -425,7 +428,9 @@ spherevector_to_euler_inv(SEuler *se, const SPoint *spb, const SPoint *spe) } else { - Vector3D vbeg, vend, vtmp; + Vector3D vbeg, + vend, + vtmp; SPoint spt[2]; SEuler set; @@ -448,7 +453,7 @@ spherevector_to_euler_inv(SEuler *se, const SPoint *spb, const SPoint *spe) bool spherevector_to_euler(SEuler *se, const SPoint *spb, const SPoint *spe) { - bool ret; + bool ret; ret = spherevector_to_euler_inv(se, spb, spe); if (ret) @@ -461,10 +466,13 @@ spherevector_to_euler(SEuler *se, const SPoint *spb, const SPoint *spe) void euler_vector_trans(Vector3D *out, const Vector3D *in, const SEuler *se) { - int i; - unsigned char t; - const double *a; - double u[3], vr[3], sa, ca; + int i; + unsigned char t; + const double *a; + double u[3], + vr[3], + sa, + ca; t = 0; a = NULL; diff --git a/src/euler.h b/src/euler.h index 35e3a2c..6baca28 100644 --- a/src/euler.h +++ b/src/euler.h @@ -12,12 +12,12 @@ */ typedef struct { - unsigned char phi_a:2, /* first axis */ - theta_a:2, /* second axis */ - psi_a:2; /* third axis */ - float8 phi, /* first rotation angle */ - theta, /* second rotation angle */ - psi; /* third rotation angle */ + unsigned char phi_a:2, /* first axis */ + theta_a:2, /* second axis */ + psi_a:2; /* third axis */ + float8 phi, /* first rotation angle */ + theta, /* second rotation angle */ + psi; /* third rotation angle */ } SEuler; @@ -25,137 +25,137 @@ typedef struct * Transforms a spherical point and returns the pointer to a transformed spherical * point. */ -void euler_spoint_trans(SPoint *out, const SPoint *in, const SEuler *se); +extern void euler_spoint_trans(SPoint *out, const SPoint *in, const SEuler *se); /* * Transforms a spherical vector from 'spb' to 'spe' into an Euler transformation. * Returns true if the transformation was successful. */ -bool spherevector_to_euler(SEuler *se, const SPoint *spb, const SPoint *spe); +extern bool spherevector_to_euler(SEuler *se, const SPoint *spb, const SPoint *spe); /* * Sets the axes of transformation to ZXZ. */ -void seuler_set_zxz(SEuler *se); +extern void seuler_set_zxz(SEuler *se); /* * Checks equality of two transformations. */ -bool strans_eq(const SEuler *e1, const SEuler *e2); +extern bool strans_eq(const SEuler *e1, const SEuler *e2); /* * Transforms a vector using an Euler transformation. Returns the pointer to * the result vector. */ -void euler_vector_trans(Vector3D *out, const Vector3D *in, const SEuler *se); +extern void euler_vector_trans(Vector3D *out, const Vector3D *in, const SEuler *se); /* * Inverts an Euler transformation. Returns the pointer to the * inverted transformation. */ -void spheretrans_inverse(SEuler *se_out, const SEuler *se_in); +extern void spheretrans_inverse(SEuler *se_out, const SEuler *se_in); /* * Inverts an Euler transformation replacing the original Euler transformation. * Returns the pointer to the inverted transformation. */ -void spheretrans_inv(SEuler *se); +extern void spheretrans_inv(SEuler *se); /* * Converts an Euler transformation to a ZXZ-axis transformation. Returns * the pointer to the converted transformation. */ -void strans_zxz(SEuler *ret, const SEuler *se); +extern void strans_zxz(SEuler *ret, const SEuler *se); /* * Transforms an Euler transformation 'in' into 'out' using 'se'. The result * is always a ZXZ-axis transformation. Returns the pointer to the transformed * transformation. */ -void seuler_trans_zxz(SEuler *out, const SEuler *in, const SEuler *se); +extern void seuler_trans_zxz(SEuler *out, const SEuler *in, const SEuler *se); /* * Input of an Euler transformation. */ -Datum spheretrans_in(PG_FUNCTION_ARGS); +extern Datum spheretrans_in(PG_FUNCTION_ARGS); /* * Input of an Euler transformation with axis Z,X,Z from three angles * (phi, theta, psi) in radians. */ -Datum spheretrans_from_float8(PG_FUNCTION_ARGS); +extern Datum spheretrans_from_float8(PG_FUNCTION_ARGS); /* * Returns the first angle of an Euler transformation in radians. */ -Datum spheretrans_phi(PG_FUNCTION_ARGS); +extern Datum spheretrans_phi(PG_FUNCTION_ARGS); /* * Returns the second angle of an Euler transformation in radians. */ -Datum spheretrans_theta(PG_FUNCTION_ARGS); +extern Datum spheretrans_theta(PG_FUNCTION_ARGS); /* * Returns the third angle of an Euler transformation in radians. */ -Datum spheretrans_psi(PG_FUNCTION_ARGS); +extern Datum spheretrans_psi(PG_FUNCTION_ARGS); /* * Returns the axis of an Euler transformation as three letter code. */ -Datum spheretrans_type(PG_FUNCTION_ARGS); +extern Datum spheretrans_type(PG_FUNCTION_ARGS); /* * Returns the Euler transformation (does nothing). This function is needed * for +strans operator. */ -Datum spheretrans(PG_FUNCTION_ARGS); +extern Datum spheretrans(PG_FUNCTION_ARGS); /* * Returns the inverse Euler transformation. */ -Datum spheretrans_invert(PG_FUNCTION_ARGS); +extern Datum spheretrans_invert(PG_FUNCTION_ARGS); /* * Convert an Euler transformation to a ZXZ-axis transformation. */ -Datum spheretrans_zxz(PG_FUNCTION_ARGS); +extern Datum spheretrans_zxz(PG_FUNCTION_ARGS); /* * This function creates an Euler transformation from 3 angle values in * radians and three letter code used for axes. A letter can be X, Y or Z * (case-insensitive). */ -Datum spheretrans_from_float8_and_type(PG_FUNCTION_ARGS); +extern Datum spheretrans_from_float8_and_type(PG_FUNCTION_ARGS); /* * Checks equality of two Euler transformations. */ -Datum spheretrans_equal(PG_FUNCTION_ARGS); +extern Datum spheretrans_equal(PG_FUNCTION_ARGS); /* * Checks inequality of two Euler transformations. */ -Datum spheretrans_not_equal(PG_FUNCTION_ARGS); +extern Datum spheretrans_not_equal(PG_FUNCTION_ARGS); /* * Transforms an Euler transformation. */ -Datum spheretrans_trans(PG_FUNCTION_ARGS); +extern Datum spheretrans_trans(PG_FUNCTION_ARGS); /* * Transforms inverse an Euler transformations. */ -Datum spheretrans_trans_inv(PG_FUNCTION_ARGS); +extern Datum spheretrans_trans_inv(PG_FUNCTION_ARGS); /* * Transforms a spherical point. */ -Datum spheretrans_point(PG_FUNCTION_ARGS); +extern Datum spheretrans_point(PG_FUNCTION_ARGS); /* * Perform inverse transformation of a spherical point. */ -Datum spheretrans_point_inverse(PG_FUNCTION_ARGS); +extern Datum spheretrans_point_inverse(PG_FUNCTION_ARGS); #endif diff --git a/src/gist.h b/src/gist.h index 6dac2a4..58e32f1 100644 --- a/src/gist.h +++ b/src/gist.h @@ -11,150 +11,150 @@ typedef unsigned char uchar; /* PGS_KEY_REL Key relationships */ -#define SCKEY_DISJ 0 /* two keys are disjunct */ -#define SCKEY_OVERLAP 1 /* two keys are overlapping */ -#define SCKEY_IN 2 /* first key contains second key */ -#define SCKEY_SAME 3 /* keys are equal */ +#define SCKEY_DISJ 0 /* two keys are disjunct */ +#define SCKEY_OVERLAP 1 /* two keys are overlapping */ +#define SCKEY_IN 2 /* first key contains second key */ +#define SCKEY_SAME 3 /* keys are equal */ -uchar spherekey_interleave(const int32 *k1, const int32 *k2); +extern uchar spherekey_interleave(const int32 *k1, const int32 *k2); /* * For given "query" of "pgstype" of PGS_DATA_TYPES type, puts key of cached * query into "key" pointer. Returns true when given query is equal to * current query. */ -bool gq_cache_get_value(unsigned pgstype, const void *query, int32 **key); +extern bool gq_cache_get_value(unsigned pgstype, const void *query, int32 **key); /* * Copy current query, type and its key value to cache. */ -void gq_cache_set_value(unsigned pgstype, const void *query, const int32 *key); +extern void gq_cache_set_value(unsigned pgstype, const void *query, const int32 *key); /* * Input function of key value. Just a dummy. But PostgreSQL need this * function to create a data type. */ -Datum spherekey_in(PG_FUNCTION_ARGS); +extern Datum spherekey_in(PG_FUNCTION_ARGS); /* * Output function of key value. Just a dummy. But PostgreSQL need this * function to create a data type. */ -Datum spherekey_out(PG_FUNCTION_ARGS); +extern Datum spherekey_out(PG_FUNCTION_ARGS); /* * GIST's decompress method. This function does nothing. */ -Datum g_spherekey_decompress(PG_FUNCTION_ARGS); +extern Datum g_spherekey_decompress(PG_FUNCTION_ARGS); /* * GIST's compress method for circle. Creates the key value from a spherical * circle. */ -Datum g_scircle_compress(PG_FUNCTION_ARGS); +extern Datum g_scircle_compress(PG_FUNCTION_ARGS); /* * GIST's compress method for point. Creates the key value from a spherical point. */ -Datum g_spoint_compress(PG_FUNCTION_ARGS); +extern Datum g_spoint_compress(PG_FUNCTION_ARGS); /* * GIST's compress method for line. Creates the key value from a spherical line. */ -Datum g_sline_compress(PG_FUNCTION_ARGS); +extern Datum g_sline_compress(PG_FUNCTION_ARGS); /* * GIST's compress method for path. Creates the key value from a spherical path. */ -Datum g_spath_compress(PG_FUNCTION_ARGS); +extern Datum g_spath_compress(PG_FUNCTION_ARGS); /* * GIST's compress method for polygon. Creates the key value from a spherical * polygon. */ -Datum g_spoly_compress(PG_FUNCTION_ARGS); +extern Datum g_spoly_compress(PG_FUNCTION_ARGS); /* * GIST's compress method for ellipse. Creates the key value from a spherical * ellipse. */ -Datum g_sellipse_compress(PG_FUNCTION_ARGS); +extern Datum g_sellipse_compress(PG_FUNCTION_ARGS); /* * GIST's compress method for box. Creates the key value from a spherical box. */ -Datum g_sbox_compress(PG_FUNCTION_ARGS); +extern Datum g_sbox_compress(PG_FUNCTION_ARGS); /* * The GiST Union method for boxes. Returns the minimal bounding box that * encloses all the entries in entryvec. */ -Datum g_spherekey_union(PG_FUNCTION_ARGS); +extern Datum g_spherekey_union(PG_FUNCTION_ARGS); /* * GIST's equality method. */ -Datum g_spherekey_same(PG_FUNCTION_ARGS); +extern Datum g_spherekey_same(PG_FUNCTION_ARGS); /* * GIST's consistent method for a point. */ -Datum g_spoint_consistent(PG_FUNCTION_ARGS); +extern Datum g_spoint_consistent(PG_FUNCTION_ARGS); /* * GIST's consistent method for a circle. */ -Datum g_scircle_consistent(PG_FUNCTION_ARGS); +extern Datum g_scircle_consistent(PG_FUNCTION_ARGS); /* * GIST's consistent method for a line. */ -Datum g_sline_consistent(PG_FUNCTION_ARGS); +extern Datum g_sline_consistent(PG_FUNCTION_ARGS); /* * GIST's consistent method for a path. */ -Datum g_spath_consistent(PG_FUNCTION_ARGS); +extern Datum g_spath_consistent(PG_FUNCTION_ARGS); /* * GIST's consistent method for a polygon. */ -Datum g_spoly_consistent(PG_FUNCTION_ARGS); +extern Datum g_spoly_consistent(PG_FUNCTION_ARGS); /* * GIST's consistent method for an ellipse. */ -Datum g_sellipse_consistent(PG_FUNCTION_ARGS); +extern Datum g_sellipse_consistent(PG_FUNCTION_ARGS); /* * GIST's consistent method for a box. */ -Datum g_sbox_consistent(PG_FUNCTION_ARGS); +extern Datum g_sbox_consistent(PG_FUNCTION_ARGS); /* * GIST's penalty method. */ -Datum g_spherekey_penalty(PG_FUNCTION_ARGS); +extern Datum g_spherekey_penalty(PG_FUNCTION_ARGS); /* * GIST's picksplit method. This method is using the double sorting node * splitting algorithm for R-Trees. See "A new double sorting-based node * splitting algorithm for R-tree", A. Korotkov. */ -Datum g_spherekey_picksplit(PG_FUNCTION_ARGS); - -Datum pointkey_in(PG_FUNCTION_ARGS); -Datum pointkey_out(PG_FUNCTION_ARGS); -Datum pointkey_volume(PG_FUNCTION_ARGS); -Datum pointkey_area(PG_FUNCTION_ARGS); -Datum pointkey_perimeter(PG_FUNCTION_ARGS); -Datum g_spoint3_compress(PG_FUNCTION_ARGS); -Datum g_spoint3_union(PG_FUNCTION_ARGS); -Datum g_spoint3_same(PG_FUNCTION_ARGS); -Datum g_spoint3_consistent(PG_FUNCTION_ARGS); -Datum g_spoint3_penalty(PG_FUNCTION_ARGS); -Datum g_spoint3_picksplit(PG_FUNCTION_ARGS); -Datum g_spoint3_distance(PG_FUNCTION_ARGS); -Datum g_spoint3_fetch(PG_FUNCTION_ARGS); +extern Datum g_spherekey_picksplit(PG_FUNCTION_ARGS); + +extern Datum pointkey_in(PG_FUNCTION_ARGS); +extern Datum pointkey_out(PG_FUNCTION_ARGS); +extern Datum pointkey_volume(PG_FUNCTION_ARGS); +extern Datum pointkey_area(PG_FUNCTION_ARGS); +extern Datum pointkey_perimeter(PG_FUNCTION_ARGS); +extern Datum g_spoint3_compress(PG_FUNCTION_ARGS); +extern Datum g_spoint3_union(PG_FUNCTION_ARGS); +extern Datum g_spoint3_same(PG_FUNCTION_ARGS); +extern Datum g_spoint3_consistent(PG_FUNCTION_ARGS); +extern Datum g_spoint3_penalty(PG_FUNCTION_ARGS); +extern Datum g_spoint3_picksplit(PG_FUNCTION_ARGS); +extern Datum g_spoint3_distance(PG_FUNCTION_ARGS); +extern Datum g_spoint3_fetch(PG_FUNCTION_ARGS); #endif diff --git a/src/gnomo.h b/src/gnomo.h index bae1d11..c7a2777 100644 --- a/src/gnomo.h +++ b/src/gnomo.h @@ -3,7 +3,7 @@ /* function prototypes for the direct and inverse gnomonic projections */ -Datum gnomonic_proj(PG_FUNCTION_ARGS); -Datum gnomonic_inv(PG_FUNCTION_ARGS); +extern Datum gnomonic_proj(PG_FUNCTION_ARGS); +extern Datum gnomonic_inv(PG_FUNCTION_ARGS); #endif diff --git a/src/key.h b/src/key.h index aa77ca9..e4c39dc 100644 --- a/src/key.h +++ b/src/key.h @@ -20,30 +20,32 @@ typedef struct { - char vl_len_[4]; + char vl_len_[4]; union { - struct /* the compiler will probably insert 4 bytes of padding here */ + struct /* the compiler will probably insert 4 bytes + * of padding here */ { - float8 lat, - lng; + float8 lat, + lng; }; }; -} GiSTSPointKey_Leaf; +} GiSTSPointKey_Leaf; typedef struct { - char vl_len_[4]; + char vl_len_[4]; union { - struct /* the compiler will probably insert 4 bytes of padding here */ + struct /* the compiler will probably insert 4 bytes + * of padding here */ { - float8 lat, - lng; + float8 lat, + lng; }; struct { - int32 k[6]; + int32 k[6]; }; }; } GiSTSPointKey; @@ -51,10 +53,12 @@ typedef struct #define INTERNAL_KEY_SIZE sizeof(GiSTSPointKey) #define LEAF_KEY_SIZE sizeof(GiSTSPointKey_Leaf) #define IS_LEAF(key) (VARSIZE(key) == LEAF_KEY_SIZE) + #define ALLOC_LEAF_KEY(key) do { \ key = (GiSTSPointKey *)palloc0(LEAF_KEY_SIZE); \ SET_VARSIZE(key, LEAF_KEY_SIZE); \ } while (0) ; + #define ALLOC_INTERNAL_KEY(key) do { \ key = (GiSTSPointKey *)palloc0(INTERNAL_KEY_SIZE); \ SET_VARSIZE(key, INTERNAL_KEY_SIZE); \ @@ -63,128 +67,128 @@ typedef struct /* * Returns the union of two keys. Result is placed into 'kunion'. */ -void spherekey_union_two(int32 *kunion, const int32 *key); +extern void spherekey_union_two(int32 *kunion, const int32 *key); /* * Returns the intersection of two keys. Returns NULL if there is * no intersection. Result is placed into 'kinter'. */ -bool spherekey_inter_two(int32 *kinter, const int32 *key); +extern bool spherekey_inter_two(int32 *kinter, const int32 *key); /* * Generates the key of a spherical point and returns it. Result is placed * into 'k'. */ -void spherepoint_gen_key(int32 *k, const SPoint *sp); +extern void spherepoint_gen_key(int32 *k, const SPoint *sp); /* * Generates the circle's key and returns it. Result is placed into 'k'. */ -void spherecircle_gen_key(int32 *k, const SCIRCLE *c); +extern void spherecircle_gen_key(int32 *k, const SCIRCLE *c); /* * Generates the key of a spherical ellipse and returns it. Result is placed * into 'k'. */ -void sphereellipse_gen_key(int32 *k, const SELLIPSE *e); +extern void sphereellipse_gen_key(int32 *k, const SELLIPSE *e); /* * Generates the key of a spherical line and returns it. Result is placed * into 'k'. */ -void sphereline_gen_key(int32 *k, const SLine *sl); +extern void sphereline_gen_key(int32 *k, const SLine *sl); /* * Generates the key of a polygon and returns it. Result is placed into 'k'. */ -void spherepoly_gen_key(int32 *k, const SPOLY *sp); +extern void spherepoly_gen_key(int32 *k, const SPOLY *sp); /* * Generates the key of a path and returns it. Result is placed into 'k'. */ -void spherepath_gen_key(int32 *k, const SPATH *sp); +extern void spherepath_gen_key(int32 *k, const SPATH *sp); /* * Generates the key of a box and returns it. Result is placed into 'k'. */ -void spherebox_gen_key(int32 *key, const SBOX *box); +extern void spherebox_gen_key(int32 *key, const SBOX *box); /* * Returns true if the first key is less than the second key. */ -Datum spherekey_lt(PG_FUNCTION_ARGS); +extern Datum spherekey_lt(PG_FUNCTION_ARGS); /* * Returns true if the first key is less or equal than the second key. */ -Datum spherekey_le(PG_FUNCTION_ARGS); +extern Datum spherekey_le(PG_FUNCTION_ARGS); /* * Returns true if two keys are equal. */ -Datum spherekey_eq(PG_FUNCTION_ARGS); +extern Datum spherekey_eq(PG_FUNCTION_ARGS); /* * Returns true if two keys are not equal. */ -Datum spherekey_eq_neg(PG_FUNCTION_ARGS); +extern Datum spherekey_eq_neg(PG_FUNCTION_ARGS); /* * Returns true if the first key is greater or equal than the second key. */ -Datum spherekey_ge(PG_FUNCTION_ARGS); +extern Datum spherekey_ge(PG_FUNCTION_ARGS); /* * Returns true if the first key is greater than the second key. */ -Datum spherekey_gt(PG_FUNCTION_ARGS); +extern Datum spherekey_gt(PG_FUNCTION_ARGS); /* * Returns relationship between the two keys. * Calls skey_cmp(const int32 *, const int32 *) for two keys. */ -Datum spherekey_cmp(PG_FUNCTION_ARGS); +extern Datum spherekey_cmp(PG_FUNCTION_ARGS); /* * Returns relationship between the keys of two spherical points. * Calls skey_cmp(const int32 *, const int32 *) for two points. */ -Datum spherepoint_cmp(PG_FUNCTION_ARGS); +extern Datum spherepoint_cmp(PG_FUNCTION_ARGS); /* * Returns relationship between the keys of two spherical circles. * Calls skey_cmp(const int32 *, const int32 *) for two circles. */ -Datum spherecircle_cmp(PG_FUNCTION_ARGS); +extern Datum spherecircle_cmp(PG_FUNCTION_ARGS); /* * Returns relationship between the keys of two spherical ellipses. * Calls skey_cmp(const int32 *, const int32 *) for two ellipses. */ -Datum sphereellipse_cmp(PG_FUNCTION_ARGS); +extern Datum sphereellipse_cmp(PG_FUNCTION_ARGS); /* * Returns relationship between the keys of two spherical lines. * Calls skey_cmp(const int32 *, const int32 *) for two lines. */ -Datum sphereline_cmp(PG_FUNCTION_ARGS); +extern Datum sphereline_cmp(PG_FUNCTION_ARGS); /* * Returns relationship between the keys of two spherical paths. * Calls skey_cmp(const int32 *, const int32 *) for two paths. */ -Datum spherepath_cmp(PG_FUNCTION_ARGS); +extern Datum spherepath_cmp(PG_FUNCTION_ARGS); /* * Returns relationship between the keys of two spherical polygons. * Calls skey_cmp(const int32 *, const int32 *) for two polygons. */ -Datum spherepoly_cmp(PG_FUNCTION_ARGS); +extern Datum spherepoly_cmp(PG_FUNCTION_ARGS); /* * Returns relationship between the keys of two spherical boxes. * Calls skey_cmp(const int32 *, const int32 *) for two boxes. */ -Datum spherebox_cmp(PG_FUNCTION_ARGS); +extern Datum spherebox_cmp(PG_FUNCTION_ARGS); #endif diff --git a/src/line.h b/src/line.h index 002f371..deaa028 100644 --- a/src/line.h +++ b/src/line.h @@ -10,10 +10,10 @@ */ typedef struct { - float8 phi, /* the first rotation angle around z axis */ - theta, /* the second rotation angle around x axis */ - psi; /* the last rotation angle around z axis */ - float8 length; /* the length of the line */ + float8 phi, /* the first rotation angle around z axis */ + theta, /* the second rotation angle around x axis */ + psi; /* the last rotation angle around z axis */ + float8 length; /* the length of the line */ } SLine; /* PGS_RELATIONSHIPS Object relationships */ @@ -37,47 +37,47 @@ typedef struct * * Returns false if the distance between the 'pbeg' and the 'pend' is 180deg. */ -bool sline_from_points(SLine *sl, const SPoint *pbeg, const SPoint *pend); +extern bool sline_from_points(SLine *sl, const SPoint *pbeg, const SPoint *pend); /* * Returns a meridian line of a given longitude in radians. The result is placed * into 'sl'. */ -void sline_meridian(SLine *sl, float8 lng); +extern void sline_meridian(SLine *sl, float8 lng); /* * Returns the starting point of a line 'l'. Result is placed into 'p'. */ -void sline_begin(SPoint *p, const SLine *l); +extern void sline_begin(SPoint *p, const SLine *l); /* * Returns the ending point of a line 'l'. Result is placed into 'p'. */ -void sline_end(SPoint *p, const SLine *l); +extern void sline_end(SPoint *p, const SLine *l); /* * Puts the minimum and the maximum latitudes of a spherical line 's1' into 'minlat' * and 'maxlat'. */ -void sline_min_max_lat(const SLine *sl, float8 *minlat, float8 *maxlat); +extern void sline_min_max_lat(const SLine *sl, float8 *minlat, float8 *maxlat); /* * Calculates spherical points with a latitude 'lat' on a spherical line. * * Returns the number of found points or <0 if undefined. */ -int32 sphereline_latitude_points(const SLine *sl, float8 lat, SPoint *p1, SPoint *p2); +extern int32 sphereline_latitude_points(const SLine *sl, float8 lat, SPoint *p1, SPoint *p2); /* * Returns true if two lines are equal. */ -bool sline_eq(const SLine *l1, const SLine *l2); +extern bool sline_eq(const SLine *l1, const SLine *l2); /* * Returns the relationship between a line and a circle as PGS_CIRCLE_LINE_REL * int8 value. */ -int8 sphereline_circle_pos(const SLine *sl, const SCIRCLE *sc); +extern int8 sphereline_circle_pos(const SLine *sl, const SCIRCLE *sc); /* * Assuming that a line and a circle overlap, this function returns true @@ -87,31 +87,31 @@ int8 sphereline_circle_pos(const SLine *sl, const SCIRCLE *sc); * * See sphereline_circle_pos (const SLine *, const SCIRCLE *) */ -bool sline_circle_touch(const SLine *sl, const SCIRCLE *sc); +extern bool sline_circle_touch(const SLine *sl, const SCIRCLE *sc); /* * Returns the relationship between two lines as PGS_LINE_LINE_REL int8 value. */ -int8 sline_sline_pos(const SLine *l1, const SLine *l2); +extern int8 sline_sline_pos(const SLine *l1, const SLine *l2); /* * Checks whether a point is on a line. */ -bool spoint_at_sline(const SPoint *p, const SLine *sl); +extern bool spoint_at_sline(const SPoint *p, const SLine *sl); /* * Returns the Euler transformation of a line. * * See spheretrans_from_line(PG_FUNCTION_ARGS) */ -void sphereline_to_euler(SEuler *se, const SLine *sl); +extern void sphereline_to_euler(SEuler *se, const SLine *sl); /* * Returns the inverse Euler transformation of a line. * * See spheretrans_from_line(PG_FUNCTION_ARGS) */ -void sphereline_to_euler_inv(SEuler *se, const SLine *sl); +extern void sphereline_to_euler_inv(SEuler *se, const SLine *sl); /* * Transforms a line using an Euler transformation. @@ -122,187 +122,187 @@ void sphereline_to_euler_inv(SEuler *se, const SLine *sl); * * See spheretrans_line (PG_FUNCTION_ARGS) */ -void euler_sline_trans(SLine *out, const SLine *in, const SEuler *se); +extern void euler_sline_trans(SLine *out, const SLine *in, const SEuler *se); /* * Puts the center of a line 'sl' into point 'c'. */ -void sline_center(SPoint *c, const SLine *sl); +extern void sline_center(SPoint *c, const SLine *sl); /* * Calculates the distance between a line 'sl' and a point 'p' */ -float8 sline_point_dist(const SLine *sl, const SPoint *p); +float8 sline_point_dist(const SLine *sl, const SPoint *p); /* * The input function for spherical line. */ -Datum sphereline_in(PG_FUNCTION_ARGS); +extern Datum sphereline_in(PG_FUNCTION_ARGS); /* * Create a line from a spherical point. */ -Datum sphereline_from_point(PG_FUNCTION_ARGS); +extern Datum sphereline_from_point(PG_FUNCTION_ARGS); /* * This function creates a spherical line using a starting point * and an ending point. The distance between the points must not be * equal to 180deg. */ -Datum sphereline_from_points(PG_FUNCTION_ARGS); +extern Datum sphereline_from_points(PG_FUNCTION_ARGS); /* * This function creates a spherical line using a given Euler transformation * and the length of a line. If the length is less than zero, an error occurs. * If the length is larger than 360deg, it is set to 360deg. */ -Datum sphereline_from_trans(PG_FUNCTION_ARGS); +extern Datum sphereline_from_trans(PG_FUNCTION_ARGS); /* * This function creates a meridian running from south to north. * The float8 param provides the longitude in radians. */ -Datum sphereline_meridian(PG_FUNCTION_ARGS); +extern Datum sphereline_meridian(PG_FUNCTION_ARGS); /* * Swaps the starting point and the ending point of a line. */ -Datum sphereline_swap_beg_end(PG_FUNCTION_ARGS); +extern Datum sphereline_swap_beg_end(PG_FUNCTION_ARGS); /* * Turns the line while preserving the starting & ending points. */ -Datum sphereline_turn(PG_FUNCTION_ARGS); +extern Datum sphereline_turn(PG_FUNCTION_ARGS); /* * Returns the beginning of a line. */ -Datum sphereline_begin(PG_FUNCTION_ARGS); +extern Datum sphereline_begin(PG_FUNCTION_ARGS); /* * Returns the ending of a line. */ -Datum sphereline_end(PG_FUNCTION_ARGS); +extern Datum sphereline_end(PG_FUNCTION_ARGS); /* * Returns the length of a line in radians. */ -Datum sphereline_length(PG_FUNCTION_ARGS); +extern Datum sphereline_length(PG_FUNCTION_ARGS); /* * Checks whether a line contains a point. */ -Datum sphereline_cont_point(PG_FUNCTION_ARGS); +extern Datum sphereline_cont_point(PG_FUNCTION_ARGS); /* * Checks whether a line doesn't contain a point. */ -Datum sphereline_cont_point_neg(PG_FUNCTION_ARGS); +extern Datum sphereline_cont_point_neg(PG_FUNCTION_ARGS); /* * Checks whether a line contains a point. */ -Datum sphereline_cont_point_com(PG_FUNCTION_ARGS); +extern Datum sphereline_cont_point_com(PG_FUNCTION_ARGS); /* * Checks whether a line doesn't contain a point. */ -Datum sphereline_cont_point_com_neg(PG_FUNCTION_ARGS); +extern Datum sphereline_cont_point_com_neg(PG_FUNCTION_ARGS); /* * Checks whether a circle contains a line. */ -Datum spherecircle_cont_line(PG_FUNCTION_ARGS); +extern Datum spherecircle_cont_line(PG_FUNCTION_ARGS); /* * Checks whether a circle doesn't contain a line. */ -Datum spherecircle_cont_line_neg(PG_FUNCTION_ARGS); +extern Datum spherecircle_cont_line_neg(PG_FUNCTION_ARGS); /* * Checks whether a circle contains a line. */ -Datum spherecircle_cont_line_com(PG_FUNCTION_ARGS); +extern Datum spherecircle_cont_line_com(PG_FUNCTION_ARGS); /* * Checks whether a circle doesn't contain a line. */ -Datum spherecircle_cont_line_com_neg(PG_FUNCTION_ARGS); +extern Datum spherecircle_cont_line_com_neg(PG_FUNCTION_ARGS); /* * Checks whether a circle and a line overlap. */ -Datum sphereline_overlap_circle(PG_FUNCTION_ARGS); +extern Datum sphereline_overlap_circle(PG_FUNCTION_ARGS); /* * Checks whether circle and a line don't overlap. */ -Datum sphereline_overlap_circle_neg(PG_FUNCTION_ARGS); +extern Datum sphereline_overlap_circle_neg(PG_FUNCTION_ARGS); /* * Checks whether a circle and a line overlap. */ -Datum sphereline_overlap_circle_com(PG_FUNCTION_ARGS); +extern Datum sphereline_overlap_circle_com(PG_FUNCTION_ARGS); /* * Checks whether circle and a line don't overlap. */ -Datum sphereline_overlap_circle_com_neg(PG_FUNCTION_ARGS); +extern Datum sphereline_overlap_circle_com_neg(PG_FUNCTION_ARGS); /* * Checks whether two lines are equal. */ -Datum sphereline_equal(PG_FUNCTION_ARGS); +extern Datum sphereline_equal(PG_FUNCTION_ARGS); /* * Checks whether two lines are not equal. */ -Datum sphereline_equal_neg(PG_FUNCTION_ARGS); +extern Datum sphereline_equal_neg(PG_FUNCTION_ARGS); /* * Checks whether two lines cross each other. */ -Datum sphereline_crosses(PG_FUNCTION_ARGS); +extern Datum sphereline_crosses(PG_FUNCTION_ARGS); /* * Checks whether two lines don't cross each other. */ -Datum sphereline_crosses_neg(PG_FUNCTION_ARGS); +extern Datum sphereline_crosses_neg(PG_FUNCTION_ARGS); /* * Checks whether two lines overlap. */ -Datum sphereline_overlap(PG_FUNCTION_ARGS); +extern Datum sphereline_overlap(PG_FUNCTION_ARGS); /* * Checks whether two lines are overlap. */ -Datum sphereline_overlap_neg(PG_FUNCTION_ARGS); +extern Datum sphereline_overlap_neg(PG_FUNCTION_ARGS); /* * Returns an Euler transformation. An inverse transformation with it puts * the line into equator beginning at (0,0) and ending at (0,length). */ -Datum spheretrans_from_line(PG_FUNCTION_ARGS); +extern Datum spheretrans_from_line(PG_FUNCTION_ARGS); /* * Transforms a line with an Euler transformation. */ -Datum spheretrans_line(PG_FUNCTION_ARGS); +extern Datum spheretrans_line(PG_FUNCTION_ARGS); /* * Transforms a line with an inverse Euler transformation. */ -Datum spheretrans_line_inverse(PG_FUNCTION_ARGS); +extern Datum spheretrans_line_inverse(PG_FUNCTION_ARGS); /* * Returns the distance between a line and a point. */ -Datum sphereline_point_distance(PG_FUNCTION_ARGS); +extern Datum sphereline_point_distance(PG_FUNCTION_ARGS); /* * Returns the distance between a point and a line. */ -Datum sphereline_point_distance_com(PG_FUNCTION_ARGS); +extern Datum sphereline_point_distance_com(PG_FUNCTION_ARGS); #endif diff --git a/src/path.h b/src/path.h index 91e1662..8f98cee 100644 --- a/src/path.h +++ b/src/path.h @@ -12,22 +12,22 @@ */ typedef struct { - char vl_len_[4]; /* total size in bytes */ - int32 npts; /* count of points */ - SPoint p[1]; /* variable length array of SPoints */ + char vl_len_[4]; /* total size in bytes */ + int32 npts; /* count of points */ + SPoint p[1]; /* variable length array of SPoints */ } SPATH; /* Path and circle */ -#define PGS_CIRCLE_PATH_AVOID 0 /* circle avoids path */ -#define PGS_CIRCLE_CONT_PATH 1 /* circle contains path */ -#define PGS_CIRCLE_PATH_OVER 2 /* circle overlaps path */ +#define PGS_CIRCLE_PATH_AVOID 0 /* circle avoids path */ +#define PGS_CIRCLE_CONT_PATH 1 /* circle contains path */ +#define PGS_CIRCLE_PATH_OVER 2 /* circle overlaps path */ /* Path and polygon */ -#define PGS_POLY_PATH_AVOID 0 /* polygon avoids path */ -#define PGS_POLY_CONT_PATH 1 /* polygon contains path */ -#define PGS_POLY_PATH_OVER 2 /* polygon and path overlap */ +#define PGS_POLY_PATH_AVOID 0 /* polygon avoids path */ +#define PGS_POLY_CONT_PATH 1 /* polygon contains path */ +#define PGS_POLY_PATH_OVER 2 /* polygon and path overlap */ /* Path and ellipse */ #define PGS_ELLIPSE_PATH_AVOID 0 /* ellipse avoids path */ @@ -41,12 +41,12 @@ typedef struct /* * Checks whether two paths are equal. */ -bool spath_eq(const SPATH *p1, const SPATH *p2); +extern bool spath_eq(const SPATH *p1, const SPATH *p2); /* * Checks whether a path contains a point. */ -bool spath_cont_point(const SPATH *path, const SPoint *sp); +extern bool spath_cont_point(const SPATH *path, const SPoint *sp); /* * Returns the i-th line segment of a path. @@ -57,24 +57,24 @@ bool spath_cont_point(const SPATH *path, const SPoint *sp); * * Returns the pointer to the line segment or NULL if fails. */ -bool spath_segment(SLine *sl, const SPATH *path, int32 i); +extern bool spath_segment(SLine *sl, const SPATH *path, int32 i); /* * Input function of path. */ -Datum spherepath_in(PG_FUNCTION_ARGS); +extern Datum spherepath_in(PG_FUNCTION_ARGS); /* * Returns the n-th point of a path. * * See spherepath_get_point(PG_FUNCTION_ARGS) */ -Datum spherepath_get_point(PG_FUNCTION_ARGS); +extern Datum spherepath_get_point(PG_FUNCTION_ARGS); /* * Returns spath as array of points */ -Datum spherepath_get_array(PG_FUNCTION_ARGS); +extern Datum spherepath_get_array(PG_FUNCTION_ARGS); /* * This function interpolates between points of path. Returns the @@ -82,212 +82,212 @@ Datum spherepath_get_array(PG_FUNCTION_ARGS); * * See spherepath_point(PG_FUNCTION_ARGS) */ -Datum spherepath_point(PG_FUNCTION_ARGS); +extern Datum spherepath_point(PG_FUNCTION_ARGS); /* * Checks whether two paths are equal. */ -Datum spherepath_equal(PG_FUNCTION_ARGS); +extern Datum spherepath_equal(PG_FUNCTION_ARGS); /* * Checks whether two paths aren't equal. */ -Datum spherepath_equal_neg(PG_FUNCTION_ARGS); +extern Datum spherepath_equal_neg(PG_FUNCTION_ARGS); /* * Returns the length of a path. */ -Datum spherepath_length(PG_FUNCTION_ARGS); +extern Datum spherepath_length(PG_FUNCTION_ARGS); /* * Returns the number of points in a path. */ -Datum spherepath_npts(PG_FUNCTION_ARGS); +extern Datum spherepath_npts(PG_FUNCTION_ARGS); /* * Changes the direction of a path. */ -Datum spherepath_swap(PG_FUNCTION_ARGS); +extern Datum spherepath_swap(PG_FUNCTION_ARGS); /* * Checks whether a path contains a point. */ -Datum spherepath_cont_point(PG_FUNCTION_ARGS); +extern Datum spherepath_cont_point(PG_FUNCTION_ARGS); /* * Checks whether a path doesn't contain a point. */ -Datum spherepath_cont_point_neg(PG_FUNCTION_ARGS); +extern Datum spherepath_cont_point_neg(PG_FUNCTION_ARGS); /* * Checks whether a path contains a point. */ -Datum spherepath_cont_point_com(PG_FUNCTION_ARGS); +extern Datum spherepath_cont_point_com(PG_FUNCTION_ARGS); /* * Checks whether a path doesn't contain a point. */ -Datum spherepath_cont_point_com_neg(PG_FUNCTION_ARGS); +extern Datum spherepath_cont_point_com_neg(PG_FUNCTION_ARGS); /* * Checks whether a path and a line overlap. */ -Datum spherepath_overlap_line(PG_FUNCTION_ARGS); +extern Datum spherepath_overlap_line(PG_FUNCTION_ARGS); /* * Checks whether a path and a line don't overlap. */ -Datum spherepath_overlap_line_neg(PG_FUNCTION_ARGS); +extern Datum spherepath_overlap_line_neg(PG_FUNCTION_ARGS); /* * Checks whether path and line overlap. */ -Datum spherepath_overlap_line_com(PG_FUNCTION_ARGS); +extern Datum spherepath_overlap_line_com(PG_FUNCTION_ARGS); /* * Checks whether a path and a line don't overlap. */ -Datum spherepath_overlap_line_com_neg(PG_FUNCTION_ARGS); +extern Datum spherepath_overlap_line_com_neg(PG_FUNCTION_ARGS); /* * Checks whether a circle contains a path. */ -Datum spherecircle_cont_path(PG_FUNCTION_ARGS); +extern Datum spherecircle_cont_path(PG_FUNCTION_ARGS); /* * Checks whether a circle doesn't contain a path. */ -Datum spherecircle_cont_path_neg(PG_FUNCTION_ARGS); +extern Datum spherecircle_cont_path_neg(PG_FUNCTION_ARGS); /* * Checks whether a circle contains a path. */ -Datum spherecircle_cont_path_com(PG_FUNCTION_ARGS); +extern Datum spherecircle_cont_path_com(PG_FUNCTION_ARGS); /* * Checks whether a circle doesn't contain a path. */ -Datum spherecircle_cont_path_com_neg(PG_FUNCTION_ARGS); +extern Datum spherecircle_cont_path_com_neg(PG_FUNCTION_ARGS); /* * Checks whether a circle and a path overlap. */ -Datum spherecircle_overlap_path(PG_FUNCTION_ARGS); +extern Datum spherecircle_overlap_path(PG_FUNCTION_ARGS); /* * Checks whether a circle and a path don't overlap. */ -Datum spherecircle_overlap_path_neg(PG_FUNCTION_ARGS); +extern Datum spherecircle_overlap_path_neg(PG_FUNCTION_ARGS); /* * Checks whether a circle and a path overlap. */ -Datum spherecircle_overlap_path_com(PG_FUNCTION_ARGS); +extern Datum spherecircle_overlap_path_com(PG_FUNCTION_ARGS); /* * Checks whether a circle and a path don't overlap. */ -Datum spherecircle_overlap_path_com_neg(PG_FUNCTION_ARGS); +extern Datum spherecircle_overlap_path_com_neg(PG_FUNCTION_ARGS); /* * Checks whether a polygon contains a path. */ -Datum spherepoly_cont_path(PG_FUNCTION_ARGS); +extern Datum spherepoly_cont_path(PG_FUNCTION_ARGS); /* * Checks whether a polygon doesn't contain a path. */ -Datum spherepoly_cont_path_neg(PG_FUNCTION_ARGS); +extern Datum spherepoly_cont_path_neg(PG_FUNCTION_ARGS); /* * Checks whether a polygon contains path. */ -Datum spherepoly_cont_path_com(PG_FUNCTION_ARGS); +extern Datum spherepoly_cont_path_com(PG_FUNCTION_ARGS); /* * Checks whether a polygon doesn't contain a path. */ -Datum spherepoly_cont_path_com_neg(PG_FUNCTION_ARGS); +extern Datum spherepoly_cont_path_com_neg(PG_FUNCTION_ARGS); /* * Checks whether a polygon and a path overlap. */ -Datum spherepoly_overlap_path(PG_FUNCTION_ARGS); +extern Datum spherepoly_overlap_path(PG_FUNCTION_ARGS); /* * Checks whether a polygon and a path don't overlap. */ -Datum spherepoly_overlap_path_neg(PG_FUNCTION_ARGS); +extern Datum spherepoly_overlap_path_neg(PG_FUNCTION_ARGS); /* * Checks whether a polygon and a path overlap. */ -Datum spherepoly_overlap_path_com(PG_FUNCTION_ARGS); +extern Datum spherepoly_overlap_path_com(PG_FUNCTION_ARGS); /* * Checks whether a polygon and a path don't overlap. */ -Datum spherepoly_overlap_path_com_neg(PG_FUNCTION_ARGS); +extern Datum spherepoly_overlap_path_com_neg(PG_FUNCTION_ARGS); /* * Checks whether two paths overlap. */ -Datum spherepath_overlap_path(PG_FUNCTION_ARGS); +extern Datum spherepath_overlap_path(PG_FUNCTION_ARGS); /* * Checks whether two paths don't overlap. */ -Datum spherepath_overlap_path_neg(PG_FUNCTION_ARGS); +extern Datum spherepath_overlap_path_neg(PG_FUNCTION_ARGS); /* * Checks whether an ellipse contains path. */ -Datum sphereellipse_cont_path(PG_FUNCTION_ARGS); +extern Datum sphereellipse_cont_path(PG_FUNCTION_ARGS); /* * Checks whether an ellipse doesn't contain a path. */ -Datum sphereellipse_cont_path_neg(PG_FUNCTION_ARGS); +extern Datum sphereellipse_cont_path_neg(PG_FUNCTION_ARGS); /* * Checks whether an ellipse contains a path. */ -Datum sphereellipse_cont_path_com(PG_FUNCTION_ARGS); +extern Datum sphereellipse_cont_path_com(PG_FUNCTION_ARGS); /* * Checks whether an ellipse doesn't contain a path. */ -Datum sphereellipse_cont_path_com_neg(PG_FUNCTION_ARGS); +extern Datum sphereellipse_cont_path_com_neg(PG_FUNCTION_ARGS); /* * Checks whether an ellipse and a path overlap. */ -Datum sphereellipse_overlap_path(PG_FUNCTION_ARGS); +extern Datum sphereellipse_overlap_path(PG_FUNCTION_ARGS); /* * Checks whether an ellipse and a path don't overlap. */ -Datum sphereellipse_overlap_path_neg(PG_FUNCTION_ARGS); +extern Datum sphereellipse_overlap_path_neg(PG_FUNCTION_ARGS); /* * Checks whether an ellipse and a path overlap. */ -Datum sphereellipse_overlap_path_com(PG_FUNCTION_ARGS); +extern Datum sphereellipse_overlap_path_com(PG_FUNCTION_ARGS); /* * Checks whether an ellipse and a path don't overlap. */ -Datum sphereellipse_overlap_path_com_neg(PG_FUNCTION_ARGS); +extern Datum sphereellipse_overlap_path_com_neg(PG_FUNCTION_ARGS); /* * Performs an Euler transformation on a path. */ -Datum spheretrans_path(PG_FUNCTION_ARGS); +extern Datum spheretrans_path(PG_FUNCTION_ARGS); /* * Performs an inverse Euler transformation on a path. */ -Datum spheretrans_path_inverse(PG_FUNCTION_ARGS); +extern Datum spheretrans_path_inverse(PG_FUNCTION_ARGS); /* * State transition function for aggregate function spath(spoint). Never @@ -295,11 +295,11 @@ Datum spheretrans_path_inverse(PG_FUNCTION_ARGS); * * Adds a point to a path. */ -Datum spherepath_add_point(PG_FUNCTION_ARGS); +extern Datum spherepath_add_point(PG_FUNCTION_ARGS); /* * Finalize function for adding spoints to a path. */ -Datum spherepath_add_points_finalize(PG_FUNCTION_ARGS); +extern Datum spherepath_add_points_finalize(PG_FUNCTION_ARGS); #endif diff --git a/src/pg_sphere.h b/src/pg_sphere.h index 24d950a..9cfc5f2 100644 --- a/src/pg_sphere.h +++ b/src/pg_sphere.h @@ -72,7 +72,7 @@ #else #define PGSPHERE_FLOAT_STORE 0 #endif -#endif // PGSPHERE_FLOAT_STORE +#endif /* PGSPHERE_FLOAT_STORE */ #define EPSILON 1.0E-09 @@ -84,6 +84,7 @@ static inline bool FPeq(double A, double B) { const volatile double AB = A - B; + return A == B || fabs(AB) <= EPSILON; } @@ -91,6 +92,7 @@ static inline bool FPne(double A, double B) { const volatile double AB = A - B; + return A != B && fabs(AB) > EPSILON; } @@ -98,6 +100,7 @@ static inline bool FPlt(double A, double B) { const volatile double AE = A + EPSILON; + return AE < B; } @@ -105,6 +108,7 @@ static inline bool FPle(double A, double B) { const volatile double BE = B + EPSILON; + return A <= BE; } @@ -112,6 +116,7 @@ static inline bool FPgt(double A, double B) { const volatile double BE = B + EPSILON; + return A > BE; } @@ -119,6 +124,7 @@ static inline bool FPge(double A, double B) { const volatile double AE = A + EPSILON; + return AE >= B; } @@ -160,7 +166,7 @@ FPge(double A, double B) return A + EPSILON >= B; } -#endif // PGSPHERE_FLOAT_STORE +#endif /* PGSPHERE_FLOAT_STORE */ /*--------------------------------------------------------------------- * Point - (x,y) @@ -171,7 +177,6 @@ typedef struct y; } Point; -void sphere_yyparse(void); +extern void sphere_yyparse(void); #endif - diff --git a/src/pgs_chealpix.h b/src/pgs_chealpix.h index c3233d1..f15b4fe 100644 --- a/src/pgs_chealpix.h +++ b/src/pgs_chealpix.h @@ -2,7 +2,7 @@ #define __PGS_CHEALPIX_H__ #include -#include /* PostgreSQL type definitions */ +#include /* PostgreSQL type definitions */ /* * Actually, chealpix changed its API: thus, this file must be included first, * directly or indirectly. diff --git a/src/pgs_util.h b/src/pgs_util.h index 1b3ad76..f04d5be 100644 --- a/src/pgs_util.h +++ b/src/pgs_util.h @@ -1,18 +1,18 @@ #ifndef __PGS_UTIL_H__ #define __PGS_UTIL_H__ -#define PI 3.14159265358979323846 /* pi */ -#define PIH 1.57079632679489661923 /* pi/2 */ -#define PID 6.2831853071795864769 /* 2*pi */ -#define RADIANS 57.295779513082320877 /* 180/pi */ +#define PI 3.14159265358979323846 /* pi */ +#define PIH 1.57079632679489661923 /* pi/2 */ +#define PID 6.2831853071795864769 /* 2*pi */ +#define RADIANS 57.295779513082320877 /* 180/pi */ #define PI_EPS 4.4408920985006261617e-16 /* 2 ** -51 */ -#define Sqr(a) ( (a) * (a) ) /* square function as macro */ +#define Sqr(a) ( (a) * (a) ) /* square function as macro */ #ifdef EPSILON #undef EPSILON #endif -#define EPSILON 1.0E-09 /* precision of floating point values */ +#define EPSILON 1.0E-09 /* precision of floating point values */ /* spherical circle constants */ #define SPHERE_SURFACE (4 * PI) @@ -22,7 +22,8 @@ static inline double conv_theta(double x) { - double y = PIH - x; + double y = PIH - x; + if (fabs(x) < PI_EPS / 2) return PIH; if (fabs(y) < PI_EPS / 2) @@ -30,7 +31,8 @@ conv_theta(double x) return y; } -static inline double deg_to_rad(double in) +static inline double +deg_to_rad(double in) { return in * PI / 180; } diff --git a/src/point.h b/src/point.h index d7af228..b9d85d1 100644 --- a/src/point.h +++ b/src/point.h @@ -11,100 +11,109 @@ */ typedef struct { - float8 lng; /* longitude value in radians */ - float8 lat; /* latitude value in radians */ + float8 lng; /* longitude value in radians */ + float8 lat; /* latitude value in radians */ } SPoint; -Oid get_spoint_type_oid(void); +extern Oid get_spoint_type_oid(void); /* * Calculate the distance between two spherical points in radians. */ -float8 spoint_dist(const SPoint *p1, const SPoint *p2); + +extern float8 spoint_dist(const SPoint *p1, const SPoint *p2); /* * Check whether two points are equal. */ -bool spoint_eq(const SPoint *p1, const SPoint *p2); + +extern bool spoint_eq(const SPoint *p1, const SPoint *p2); /* * Check the longitude and latitude values of a spherical point. */ -void spoint_check(SPoint *spoint); + +extern void spoint_check(SPoint *spoint); /* * Transforms a 3d vector into a spherical point. */ -void vector3d_spoint(SPoint *p, const Vector3D *v); + +extern void vector3d_spoint(SPoint *p, const Vector3D *v); /* * Transforms a spherical point into a 3d vector. */ -void spoint_vector3d(Vector3D *v, const SPoint *p); + +extern void spoint_vector3d(Vector3D *v, const SPoint *p); /* * Take the input and store it as a spherical point. */ -Datum spherepoint_in(PG_FUNCTION_ARGS); + +extern Datum spherepoint_in(PG_FUNCTION_ARGS); /* * Create spherical point from lat, lng and store to first argument(pointer) */ -void create_spherepoint_from_long_lat(SPoint *p, float8 lng, float8 lat); + +extern void create_spherepoint_from_long_lat(SPoint *p, float8 lng, float8 lat); /* * Create a spherical point from longitude and latitude both in radians. */ -Datum spherepoint_from_long_lat(PG_FUNCTION_ARGS); + +extern Datum spherepoint_from_long_lat(PG_FUNCTION_ARGS); /* * Create a spherical point from longitude and latitude both in degrees. */ -Datum spherepoint_from_long_lat_deg(PG_FUNCTION_ARGS); + +extern Datum spherepoint_from_long_lat_deg(PG_FUNCTION_ARGS); /* * Calculate the distance between two spherical points. */ -Datum spherepoint_distance(PG_FUNCTION_ARGS); +extern Datum spherepoint_distance(PG_FUNCTION_ARGS); /* * Longitude of a spherical point. */ -Datum spherepoint_long(PG_FUNCTION_ARGS); +extern Datum spherepoint_long(PG_FUNCTION_ARGS); /* * Latitude of a spherical point. */ -Datum spherepoint_lat(PG_FUNCTION_ARGS); +extern Datum spherepoint_lat(PG_FUNCTION_ARGS); /* * Cartesian x-value of a spherical point. */ -Datum spherepoint_x(PG_FUNCTION_ARGS); +extern Datum spherepoint_x(PG_FUNCTION_ARGS); /* * Cartesian y-value of a spherical point. */ -Datum spherepoint_y(PG_FUNCTION_ARGS); +extern Datum spherepoint_y(PG_FUNCTION_ARGS); /* * Cartesian z-value of a spherical point. */ -Datum spherepoint_z(PG_FUNCTION_ARGS); +extern Datum spherepoint_z(PG_FUNCTION_ARGS); /* * Cartesian values of a spherical point as an array. */ -Datum spherepoint_xyz(PG_FUNCTION_ARGS); +extern Datum spherepoint_xyz(PG_FUNCTION_ARGS); /* * Check whether two points are equal. */ -Datum spherepoint_equal(PG_FUNCTION_ARGS); +extern Datum spherepoint_equal(PG_FUNCTION_ARGS); /* * Compute a 32-bit hash value of a point. */ -Datum spherepoint_hash32(PG_FUNCTION_ARGS); +extern Datum spherepoint_hash32(PG_FUNCTION_ARGS); #endif diff --git a/src/polygon.h b/src/polygon.h index b8c754d..0233c41 100644 --- a/src/polygon.h +++ b/src/polygon.h @@ -12,9 +12,9 @@ */ typedef struct { - char vl_len_[4]; /* total size in bytes */ - int32 npts; /* count of points */ - SPoint p[1]; /* variable length array of SPoints */ + char vl_len_[4]; /* total size in bytes */ + int32 npts; /* count of points */ + SPoint p[1]; /* variable length array of SPoints */ } SPOLY; #define MAX_POINTS 1024 @@ -26,20 +26,20 @@ typedef struct #define PGS_ELLIPSE_POLY_OVER 3 /* ellipse overlaps polygon */ /* Polygon and circle */ -#define PGS_CIRCLE_POLY_AVOID 0 /* circle avoids polygon */ -#define PGS_POLY_CONT_CIRCLE 1 /* polygon contains circle */ -#define PGS_CIRCLE_CONT_POLY 2 /* circle contains polygon */ -#define PGS_CIRCLE_POLY_OVER 3 /* circle overlap polygon */ +#define PGS_CIRCLE_POLY_AVOID 0 /* circle avoids polygon */ +#define PGS_POLY_CONT_CIRCLE 1 /* polygon contains circle */ +#define PGS_CIRCLE_CONT_POLY 2 /* circle contains polygon */ +#define PGS_CIRCLE_POLY_OVER 3 /* circle overlap polygon */ /* Polygon and line */ -#define PGS_LINE_POLY_AVOID 0 /* line avoids polygon */ -#define PGS_POLY_CONT_LINE 1 /* polygon contains line */ -#define PGS_LINE_POLY_OVER 2 /* line overlap polygon */ +#define PGS_LINE_POLY_AVOID 0 /* line avoids polygon */ +#define PGS_POLY_CONT_LINE 1 /* polygon contains line */ +#define PGS_LINE_POLY_OVER 2 /* line overlap polygon */ /* Polygon and polygon */ -#define PGS_POLY_AVOID 0 /* polygon avoids other polygon */ -#define PGS_POLY_CONT 1 /* polygon contains other polygon */ -#define PGS_POLY_OVER 2 /* polygons overlap */ +#define PGS_POLY_AVOID 0 /* polygon avoids other polygon */ +#define PGS_POLY_CONT 1 /* polygon contains other polygon */ +#define PGS_POLY_OVER 2 /* polygons overlap */ #define PG_GETARG_SPOLY( arg ) \ @@ -53,7 +53,7 @@ typedef struct * * If 'dir' is true, check with reverse polygon of 'p2'. */ -bool spoly_eq(const SPOLY *p1, const SPOLY *p2, bool dir); +extern bool spoly_eq(const SPOLY *p1, const SPOLY *p2, bool dir); /* * Returns the i-th line segment of a polygon. @@ -62,7 +62,7 @@ bool spoly_eq(const SPOLY *p1, const SPOLY *p2, bool dir); * poly - pointer to the polygon * i - number of the segment */ -bool spoly_segment(SLine *sl, const SPOLY *poly, int32 i); +extern bool spoly_segment(SLine *sl, const SPOLY *poly, int32 i); /* * Checks whether a polygon contains a point. @@ -70,12 +70,12 @@ bool spoly_segment(SLine *sl, const SPOLY *poly, int32 i); * pg - pointer to the polygon * sp - pointer to the point */ -bool spoly_contains_point(const SPOLY *pg, const SPoint *sp); +extern bool spoly_contains_point(const SPOLY *pg, const SPoint *sp); /* * Returns the n-th point of a spoly. */ -Datum spherepoly_get_point(PG_FUNCTION_ARGS); +extern Datum spherepoly_get_point(PG_FUNCTION_ARGS); /* * Returns the relationship between a polygon and a line as @@ -84,295 +84,295 @@ Datum spherepoly_get_point(PG_FUNCTION_ARGS); * poly - pointer to the polygon * line - pointer to the line */ -int8 poly_line_pos(const SPOLY *poly, const SLine *line); +extern int8 poly_line_pos(const SPOLY *poly, const SLine *line); /* * Creates a spherical polygon (spoly) from an array of pair-consecutive * numbers (lng, lat), in radians. */ -Datum spherepoly_rad(PG_FUNCTION_ARGS); +extern Datum spherepoly_rad(PG_FUNCTION_ARGS); /* * Creates a spherical polygon (spoly) from an array of pair-consecutive * numbers (lng, lat), in degrees. */ -Datum spherepoly_deg(PG_FUNCTION_ARGS); +extern Datum spherepoly_deg(PG_FUNCTION_ARGS); /* * Creates a spherical polygon (spoly) from an array of spoint elements. */ -Datum spherepoly_from_point_array(PG_FUNCTION_ARGS); +extern Datum spherepoly_from_point_array(PG_FUNCTION_ARGS); /* * Input of a spherical polygon. */ -Datum spherepoly_in(PG_FUNCTION_ARGS); +extern Datum spherepoly_in(PG_FUNCTION_ARGS); /* * Checks whether two polygons are equal. */ -Datum spherepoly_equal(PG_FUNCTION_ARGS); +extern Datum spherepoly_equal(PG_FUNCTION_ARGS); /* * Checks whether two polygons are not equal. */ -Datum spherepoly_equal_neg(PG_FUNCTION_ARGS); +extern Datum spherepoly_equal_neg(PG_FUNCTION_ARGS); /* * Circumstance of a polygon. Returns circumference in radians * (float8 datum). */ -Datum spherepoly_circ(PG_FUNCTION_ARGS); +extern Datum spherepoly_circ(PG_FUNCTION_ARGS); /* * Count points (edges) of a polygon. */ -Datum spherepoly_npts(PG_FUNCTION_ARGS); +extern Datum spherepoly_npts(PG_FUNCTION_ARGS); /* * Returns area of a polygon. */ -Datum spherepoly_area(PG_FUNCTION_ARGS); +extern Datum spherepoly_area(PG_FUNCTION_ARGS); /* * Checks whether a polygon contains a point. */ -Datum spherepoly_cont_point(PG_FUNCTION_ARGS); +extern Datum spherepoly_cont_point(PG_FUNCTION_ARGS); /* * Checks whether a polygon doesn't contain a point. */ -Datum spherepoly_cont_point_neg(PG_FUNCTION_ARGS); +extern Datum spherepoly_cont_point_neg(PG_FUNCTION_ARGS); /* * Checks whether a polygon contains a point. */ -Datum spherepoly_cont_point_com(PG_FUNCTION_ARGS); +extern Datum spherepoly_cont_point_com(PG_FUNCTION_ARGS); /* * Checks whether a polygon doesn't contain a point. */ -Datum spherepoly_cont_point_com_neg(PG_FUNCTION_ARGS); +extern Datum spherepoly_cont_point_com_neg(PG_FUNCTION_ARGS); /* * Checks whether a polygon contains a circle. */ -Datum spherepoly_cont_circle(PG_FUNCTION_ARGS); +extern Datum spherepoly_cont_circle(PG_FUNCTION_ARGS); /* * Checks whether a polygon doesn't contain a circle. */ -Datum spherepoly_cont_circle_neg(PG_FUNCTION_ARGS); +extern Datum spherepoly_cont_circle_neg(PG_FUNCTION_ARGS); /* * Checks whether a polygon contains a circle. */ -Datum spherepoly_cont_circle_com(PG_FUNCTION_ARGS); +extern Datum spherepoly_cont_circle_com(PG_FUNCTION_ARGS); /* * Checks whether a polygon doesn't contain a circle. */ -Datum spherepoly_cont_circle_com_neg(PG_FUNCTION_ARGS); +extern Datum spherepoly_cont_circle_com_neg(PG_FUNCTION_ARGS); /* * Checks whether a circle contains a polygon. */ -Datum spherecircle_cont_poly(PG_FUNCTION_ARGS); +extern Datum spherecircle_cont_poly(PG_FUNCTION_ARGS); /* * Checks whether a circle doesn't contain a polygon. */ -Datum spherecircle_cont_poly_neg(PG_FUNCTION_ARGS); +extern Datum spherecircle_cont_poly_neg(PG_FUNCTION_ARGS); /* * Checks whether a circle contains a polygon. */ -Datum spherecircle_cont_poly_com(PG_FUNCTION_ARGS); +extern Datum spherecircle_cont_poly_com(PG_FUNCTION_ARGS); /* * Checks whether a circle doesn't contain a polygon. */ -Datum spherecircle_cont_poly_com_neg(PG_FUNCTION_ARGS); +extern Datum spherecircle_cont_poly_com_neg(PG_FUNCTION_ARGS); /* * Checks whether a polygon and a circle overlap. */ -Datum spherepoly_overlap_circle(PG_FUNCTION_ARGS); +extern Datum spherepoly_overlap_circle(PG_FUNCTION_ARGS); /* * Checks whether a polygon and a circle don't overlap. */ -Datum spherepoly_overlap_circle_neg(PG_FUNCTION_ARGS); +extern Datum spherepoly_overlap_circle_neg(PG_FUNCTION_ARGS); /* * Checks whether a polygon and a circle overlap. */ -Datum spherepoly_overlap_circle_com(PG_FUNCTION_ARGS); +extern Datum spherepoly_overlap_circle_com(PG_FUNCTION_ARGS); /* * Checks whether a polygon and a circle don't overlap. */ -Datum spherepoly_overlap_circle_com_neg(PG_FUNCTION_ARGS); +extern Datum spherepoly_overlap_circle_com_neg(PG_FUNCTION_ARGS); /* * Checks whether a polygon contains a line. */ -Datum spherepoly_cont_line(PG_FUNCTION_ARGS); +extern Datum spherepoly_cont_line(PG_FUNCTION_ARGS); /* * Checks whether a polygon doesn't contain a line. */ -Datum spherepoly_cont_line_neg(PG_FUNCTION_ARGS); +extern Datum spherepoly_cont_line_neg(PG_FUNCTION_ARGS); /* * Checks whether a polygon contains a line. */ -Datum spherepoly_cont_line_com(PG_FUNCTION_ARGS); +extern Datum spherepoly_cont_line_com(PG_FUNCTION_ARGS); /* * Checks whether a polygon doesn't contain a line. */ -Datum spherepoly_cont_line_com_neg(PG_FUNCTION_ARGS); +extern Datum spherepoly_cont_line_com_neg(PG_FUNCTION_ARGS); /* * Checks whether a polygon and a line overlap. */ -Datum spherepoly_overlap_line(PG_FUNCTION_ARGS); +extern Datum spherepoly_overlap_line(PG_FUNCTION_ARGS); /* * Checks whether a polygon and a line don't overlap. */ -Datum spherepoly_overlap_line_neg(PG_FUNCTION_ARGS); +extern Datum spherepoly_overlap_line_neg(PG_FUNCTION_ARGS); /* * Checks whether a polygon and a line overlap. */ -Datum spherepoly_overlap_line_com(PG_FUNCTION_ARGS); +extern Datum spherepoly_overlap_line_com(PG_FUNCTION_ARGS); /* * Checks whether a polygon and a line don't overlap. */ -Datum spherepoly_overlap_line_com_neg(PG_FUNCTION_ARGS); +extern Datum spherepoly_overlap_line_com_neg(PG_FUNCTION_ARGS); /* * Checks whether a polygon contains other polygon. */ -Datum spherepoly_cont_poly(PG_FUNCTION_ARGS); +extern Datum spherepoly_cont_poly(PG_FUNCTION_ARGS); /* * Checks whether a polygon doesn't contain other polygon. */ -Datum spherepoly_cont_poly_neg(PG_FUNCTION_ARGS); +extern Datum spherepoly_cont_poly_neg(PG_FUNCTION_ARGS); /* * Checks whether a polygon contains other polygon. */ -Datum spherepoly_cont_poly_com(PG_FUNCTION_ARGS); +extern Datum spherepoly_cont_poly_com(PG_FUNCTION_ARGS); /* * Checks whether a polygon doesn't contain other polygon. */ -Datum spherepoly_cont_poly_com_neg(PG_FUNCTION_ARGS); +extern Datum spherepoly_cont_poly_com_neg(PG_FUNCTION_ARGS); /* * Checks whether two polygons overlap. */ -Datum spherepoly_overlap_poly(PG_FUNCTION_ARGS); +extern Datum spherepoly_overlap_poly(PG_FUNCTION_ARGS); /* * Checks whether two polygons don't overlap. */ -Datum spherepoly_overlap_poly_neg(PG_FUNCTION_ARGS); +extern Datum spherepoly_overlap_poly_neg(PG_FUNCTION_ARGS); /* * Checks whether a polygon contains an ellipse. */ -Datum spherepoly_cont_ellipse(PG_FUNCTION_ARGS); +extern Datum spherepoly_cont_ellipse(PG_FUNCTION_ARGS); /* * Checks whether a polygon doesn't contain an ellipse. */ -Datum spherepoly_cont_ellipse_neg(PG_FUNCTION_ARGS); +extern Datum spherepoly_cont_ellipse_neg(PG_FUNCTION_ARGS); /* * Checks whether a polygon contains an ellipse. */ -Datum spherepoly_cont_ellipse_com(PG_FUNCTION_ARGS); +extern Datum spherepoly_cont_ellipse_com(PG_FUNCTION_ARGS); /* * Checks whether a polygon doesn't contain an ellipse. */ -Datum spherepoly_cont_ellipse_com_neg(PG_FUNCTION_ARGS); +extern Datum spherepoly_cont_ellipse_com_neg(PG_FUNCTION_ARGS); /* * Checks whether an ellipse contains a polygon. */ -Datum sphereellipse_cont_poly(PG_FUNCTION_ARGS); +extern Datum sphereellipse_cont_poly(PG_FUNCTION_ARGS); /* * Checks whether an ellipse doesn't contain a polygon. */ -Datum sphereellipse_cont_poly_neg(PG_FUNCTION_ARGS); +extern Datum sphereellipse_cont_poly_neg(PG_FUNCTION_ARGS); /* * Checks whether an ellipse contains a polygon. */ -Datum sphereellipse_cont_poly_com(PG_FUNCTION_ARGS); +extern Datum sphereellipse_cont_poly_com(PG_FUNCTION_ARGS); /* * Checks whether an ellipse doesn't contain a polygon. */ -Datum sphereellipse_cont_poly_com_neg(PG_FUNCTION_ARGS); +extern Datum sphereellipse_cont_poly_com_neg(PG_FUNCTION_ARGS); /* * Checks whether a polygon and an ellipse overlap. */ -Datum spherepoly_overlap_ellipse(PG_FUNCTION_ARGS); +extern Datum spherepoly_overlap_ellipse(PG_FUNCTION_ARGS); /* * Checks whether a polygon and an ellipse don't overlap. */ -Datum spherepoly_overlap_ellipse_neg(PG_FUNCTION_ARGS); +extern Datum spherepoly_overlap_ellipse_neg(PG_FUNCTION_ARGS); /* * Checks whether a polygon and an ellipse overlap. */ -Datum spherepoly_overlap_ellipse_com(PG_FUNCTION_ARGS); +extern Datum spherepoly_overlap_ellipse_com(PG_FUNCTION_ARGS); /* * Checks whether a polygon and an ellipse don't overlap. */ -Datum spherepoly_overlap_ellipse_com_neg(PG_FUNCTION_ARGS); +extern Datum spherepoly_overlap_ellipse_com_neg(PG_FUNCTION_ARGS); /* * Performs inverse transform on a polygon using an Euler transformation. */ -Datum spheretrans_poly(PG_FUNCTION_ARGS); +extern Datum spheretrans_poly(PG_FUNCTION_ARGS); /* * Performs inverse transform on a polygon using an Euler transformation. */ -Datum spheretrans_poly_inverse(PG_FUNCTION_ARGS); +extern Datum spheretrans_poly_inverse(PG_FUNCTION_ARGS); /* * State transition function for the aggregate function spoly(spoint). Never * call this function outside an aggregate function! Adds a point to a polygon. */ -Datum spherepoly_add_point(PG_FUNCTION_ARGS); +extern Datum spherepoly_add_point(PG_FUNCTION_ARGS); /* * Finalize function for adding spoints to a polygon. */ -Datum spherepoly_add_points_finalize(PG_FUNCTION_ARGS); +extern Datum spherepoly_add_points_finalize(PG_FUNCTION_ARGS); /* * Returns spoly as array of points */ -Datum spherepoly_get_array(PG_FUNCTION_ARGS); +extern Datum spherepoly_get_array(PG_FUNCTION_ARGS); /* * Checks whether a polygon is convex */ -Datum spherepoly_is_convex(PG_FUNCTION_ARGS); +extern Datum spherepoly_is_convex(PG_FUNCTION_ARGS); #endif diff --git a/src/sbuffer.h b/src/sbuffer.h index 57599ee..b16f152 100644 --- a/src/sbuffer.h +++ b/src/sbuffer.h @@ -3,89 +3,89 @@ /* Parser buffer declarations */ -#define STYPE_UNKNOWN 0 /* unknown type */ -#define STYPE_POINT 1 /* input is spherical type */ -#define STYPE_CIRCLE 2 /* input is spherical circle */ -#define STYPE_LINE 3 /* input is spherical line */ -#define STYPE_EULER 4 /* input is Euler transformation */ -#define STYPE_PATH 5 /* input is spherical path or polygon */ -#define STYPE_ELLIPSE 6 /* input is spherical ellipse */ -#define STYPE_BOX 7 /* input is spherical box */ +#define STYPE_UNKNOWN 0 /* unknown type */ +#define STYPE_POINT 1 /* input is spherical type */ +#define STYPE_CIRCLE 2 /* input is spherical circle */ +#define STYPE_LINE 3 /* input is spherical line */ +#define STYPE_EULER 4 /* input is Euler transformation */ +#define STYPE_PATH 5 /* input is spherical path or polygon */ +#define STYPE_ELLIPSE 6 /* input is spherical ellipse */ +#define STYPE_BOX 7 /* input is spherical box */ /* PGS_EULER_AXIS Euler axis */ -#define EULER_AXIS_X 1 /* x - axis for Euler transformation */ -#define EULER_AXIS_Y 2 /* y - axis for Euler transformation */ -#define EULER_AXIS_Z 3 /* z - axis for Euler transformation */ +#define EULER_AXIS_X 1 /* x - axis for Euler transformation */ +#define EULER_AXIS_Y 2 /* y - axis for Euler transformation */ +#define EULER_AXIS_Z 3 /* z - axis for Euler transformation */ -int sphere_yylex(); -void sphere_yyerror(const char *str); -void sphere_flush_scanner_buffer(void); +extern int sphere_yylex(); +extern void sphere_yyerror(const char *str); +extern void sphere_flush_scanner_buffer(void); /* Sets the data type */ -void set_spheretype(unsigned char st); +extern void set_spheretype(unsigned char st); /* Initialize the input buffer */ -void init_buffer(char *buffer); +extern void init_buffer(char *buffer); /* Resets the input buffer */ -void reset_buffer(void); +extern void reset_buffer(void); /* * Read the "offset" number of bytes from "buf" buffer. * Returns the number of read bytes. */ -int get_buffer(char *buf, int offset); +extern int get_buffer(char *buf, int offset); /* * Input of an angle. When is_deg > 0 then "a" is in degrees, * otherwise it's in radians. Returns the unique ID (position) of the angle. */ -int set_angle(unsigned char is_deg, double a); +extern int set_angle(unsigned char is_deg, double a); /* * Set the sign of an angle. "apos" is the angle. "s" is a sign of the angle * ( < 0 .. - , > 0 .. + ). Returns the unique ID (position) of the angle. */ -int set_angle_sign(int apos, int s); +extern int set_angle_sign(int apos, int s); /* * Creates a spherical point. "lngpos" is the ID of a longitude angle, "latpos" * is the ID of a latitude angle. Returns the unique ID (position) of the spherical * point. */ -int set_point(int lngpos, int latpos); +extern int set_point(int lngpos, int latpos); /* * Creates a spherical circle. "spos" is the ID of a spherical point, "rpos" * is the ID of a radius angle. */ -void set_circle(int spos, int rpos); +extern void set_circle(int spos, int rpos); /* * Sets the length of a spherical line. "length" is the ID of a length angle. */ -void set_line(int length); +extern void set_line(int length); /* * Creates an Euler transformation. "phi" is the ID of a first angle, * "theta" is the ID of a second angle, "psi" is the ID of a third angle, * "etype" is the three letter code of Euler transformation axes. */ -void set_euler(int phi, int theta, int psi, char *etype); +extern void set_euler(int phi, int theta, int psi, char *etype); /* * Creates a spherical ellipse. "r1" is the ID of a first radius angle, * "r2" is the ID of a second radius angle, "sp" is the ID of a spherical * point ( center ), "inc" is the ID of an inclination angle. */ -void set_ellipse(int r1, int r2, int sp, int inc); +extern void set_ellipse(int r1, int r2, int sp, int inc); /* * Returns the point parameters. "lng" is the pointer to a longitude * value, "lat" is the pointer to a latitude value. Returns 0 if user * input is a spherical point. */ -int get_point(double *lng, double *lat); +extern int get_point(double *lng, double *lat); /* * Returns the circle parameters. "lng" is pointer to a longitude @@ -93,7 +93,7 @@ int get_point(double *lng, double *lat); * "radius" is the pointer to the radius value. Returns 0 if user input * is a spherical circle. */ -int get_circle(double *lng, double *lat, double *radius); +extern int get_circle(double *lng, double *lat, double *radius); /* * Returns the ellipse parameters. "lng" is the pointer to a longitude value @@ -102,8 +102,8 @@ int get_circle(double *lng, double *lat, double *radius); * radius value, "inc" is the pointer to an inclination angle. Returns 0 if user * input is a spherical ellipse. */ -int get_ellipse(double *lng, double *lat, double *r1, - double *r2, double *inc); +extern int get_ellipse(double *lng, double *lat, double *r1, + double *r2, double *inc); /* * Returns the line parameters. "phi" is the pointer to the first angle @@ -112,8 +112,8 @@ int get_ellipse(double *lng, double *lat, double *r1, * "etype" is the pointer to the axes value of Euler transformation, "length" is * the pointer to the length value. Returns 0 if user input is a spherical line. */ -int get_line(double *phi, double *theta, double *psi, - unsigned char *etype, double *length); +extern int get_line(double *phi, double *theta, double *psi, + unsigned char *etype, double *length); /* * Returns the Euler transformation parameters. "phi" is the pointer to the @@ -122,20 +122,20 @@ int get_line(double *phi, double *theta, double *psi, * transformation, "etype" is the pointer to the axes value of Euler transformation. * Returns 0 if user input is an Euler transformation. */ -int get_euler(double *phi, double *theta, - double *psi, unsigned char *etype); +extern int get_euler(double *phi, double *theta, + double *psi, unsigned char *etype); /* * Returns the number of path elements. */ -int get_path_count(void); +extern int get_path_count(void); /* * Returns the elements of a path. "spos" is the number of element, "lng" is * the ID of longitude angle, "lat" is the ID of a latitude angle. Returns 0 * if user input is a path or a polygon and "spos" is valid. */ -int get_path_elem(int spos, double *lng, double *lat); +extern int get_path_elem(int spos, double *lng, double *lat); /* * Returns the elements of a box. "lng1" is the ID of the first longitude @@ -143,6 +143,6 @@ int get_path_elem(int spos, double *lng, double *lat); * the second longitude angle, "lat2" is the ID of the second latitude angle. * Returns 0 if user input is a box. */ -int get_box(double *lng1, double *lat1, double *lng2, double *lat2); +extern int get_box(double *lng1, double *lat1, double *lng2, double *lat2); #endif diff --git a/src/vector3d.h b/src/vector3d.h index 23ba9b9..47a5a82 100644 --- a/src/vector3d.h +++ b/src/vector3d.h @@ -10,9 +10,9 @@ */ typedef struct { - float8 x; /* x (-1.0 .. 1.0) */ - float8 y; /* y (-1.0 .. 1.0) */ - float8 z; /* z (-1.0 .. 1.0) */ + float8 x; /* x (-1.0 .. 1.0) */ + float8 y; /* y (-1.0 .. 1.0) */ + float8 z; /* z (-1.0 .. 1.0) */ } Vector3D; @@ -20,27 +20,28 @@ typedef struct * Calculate the cross product of two vectors. Puts * cross product of v1 and v2 into out and returns it. */ -void vector3d_cross(Vector3D *out, const Vector3D *v1, const Vector3D *v2); +extern void vector3d_cross(Vector3D *out, const Vector3D *v1, + const Vector3D *v2); /* * Checks equality of two vectors. */ -bool vector3d_eq(const Vector3D *a, const Vector3D *b); +extern bool vector3d_eq(const Vector3D *a, const Vector3D *b); /* * Calculate the scalar product of two vectors. */ -float8 vector3d_scalar(Vector3D *v1, Vector3D *v2); +extern float8 vector3d_scalar(Vector3D *v1, Vector3D *v2); /* * Calculate the length of a vector. */ -float8 vector3d_length(const Vector3D *v); +extern float8 vector3d_length(const Vector3D *v); -/* - * Calculate result + scalar*delta +/* + * Calculate result + scalar*delta */ -void vector3d_addwithscalar( - Vector3D *result, double scalar, const Vector3D *delta); +extern void vector3d_addwithscalar(Vector3D *result, double scalar, + const Vector3D *delta); #endif From 462fa03ea0d9024d0dfe9de0b52dea5945c9ec01 Mon Sep 17 00:00:00 2001 From: Vitaly Davydov Date: Tue, 19 Dec 2023 17:12:48 +0300 Subject: [PATCH 73/87] Implement pgindent-headers Makefile rule This rule executes pgindent with header files only. --- Makefile | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/Makefile b/Makefile index 14350ec..fe74e06 100644 --- a/Makefile +++ b/Makefile @@ -258,3 +258,10 @@ pgindent: --excludes=pgindent-excludes.list \ --indent=${PGBSDINDENT} \ src + +pgindent-headers: + $(PGINDENT) \ + --typedefs=pgindent-typedefs.list \ + --excludes=pgindent-excludes.list \ + --indent=${PGBSDINDENT} \ + src/*.h From 8394ae72fd4a01d415c8b9dc4d08d89872aa1164 Mon Sep 17 00:00:00 2001 From: Vitaly Date: Tue, 26 Mar 2024 16:22:14 +0300 Subject: [PATCH 74/87] Fix output precision limit for double values (issue #118) (#119) Fix output precision limit for double values (issue #118) pgSphere used its own setting (set_sphere_output_precision function) to limit the output precision of double values, that could not be greater than 15 significant digits (DBL_DIG). It introduced some problems with dump/restore. PostgreSQL uses its own precision setting: extra_float_digits. The PostgreSQL setting allows to use more significant digits. This patch changes the default pgSphere output behaviour to utilize PostgreSQL extra_float_digits. Now, extra_float_digits is used by default, until set_sphere_output_precision is called. The old behaviour is kept for compatibility purposes. Once, set_sphere_output_precision is called, pgSphere starts to use the old behaviour (read, please, issue #118 discussion). The patch introduces a new function - reset_sphere_output_precision. It is used to reset to the PostgreSQL behaviour after using set_sphere_output_precision. * Update upgrade script (reset_sphere_output_precision function) * Add test for pgSphere output precision with different settings expected/output_precision.out - PG 10-11 expected/output_precision_1.out - PG 12+ * Add extra_float_digits = 2 for epochprop and bounding_box_gist tests --- Makefile | 3 +- expected/bounding_box_gist.out | 37 +- expected/bounding_box_gist_1.out | 37 +- expected/epochprop.out | 13 +- expected/epochprop_1.out | 108 +++ expected/output_precision.out | 212 ++++++ expected/output_precision_1.out | 212 ++++++ pgs_point.sql.in | 6 +- sql/bounding_box_gist.sql | 1 + sql/epochprop.sql | 2 + sql/output_precision.sql | 82 +++ src/output.c | 620 +++++++++++++++++- .../pg_sphere--1.4.2--1.5.0.sql.in | 5 + 13 files changed, 1283 insertions(+), 55 deletions(-) create mode 100644 expected/epochprop_1.out create mode 100644 expected/output_precision.out create mode 100644 expected/output_precision_1.out create mode 100644 sql/output_precision.sql diff --git a/Makefile b/Makefile index fe74e06..81dc57c 100644 --- a/Makefile +++ b/Makefile @@ -40,7 +40,8 @@ DATA_built = $(RELEASE_SQL) \ DOCS = README.pg_sphere COPYRIGHT.pg_sphere TESTS = version tables points euler circle line ellipse poly path box \ index contains_ops contains_ops_compat bounding_box_gist gnomo \ - epochprop contains overlaps spoint_brin sbox_brin selectivity knn + epochprop contains overlaps spoint_brin sbox_brin selectivity \ + knn output_precision REGRESS = init $(TESTS) PG_CFLAGS += -DPGSPHERE_VERSION=$(PGSPHERE_VERSION) diff --git a/expected/bounding_box_gist.out b/expected/bounding_box_gist.out index 6307ac1..ef42474 100644 --- a/expected/bounding_box_gist.out +++ b/expected/bounding_box_gist.out @@ -1,3 +1,4 @@ +SET extra_float_digits = 2; SET enable_seqscan=true; CREATE TABLE bbox_ellipse (e sellipse not null); INSERT INTO bbox_ellipse VALUES ('<{10d, 0.1d}, (0d,0d), 0d>'); @@ -20,19 +21,19 @@ SELECT COUNT(*) FROM bbox_ellipse WHERE spoint '(5d, 0d)' <@ e; (1 row) EXPLAIN (COSTS OFF) SELECT COUNT(*) FROM bbox_ellipse WHERE spoint '(5d, 0d)' @ e; - QUERY PLAN ----------------------------------------------------------- + QUERY PLAN +------------------------------------------------------------ Aggregate -> Seq Scan on bbox_ellipse - Filter: ('(0.0872664625997165 , 0)'::spoint @ e) + Filter: ('(0.087266462599716474 , 0)'::spoint @ e) (3 rows) EXPLAIN (COSTS OFF) SELECT COUNT(*) FROM bbox_ellipse WHERE spoint '(5d, 0d)' <@ e; - QUERY PLAN ------------------------------------------------------------ + QUERY PLAN +------------------------------------------------------------- Aggregate -> Seq Scan on bbox_ellipse - Filter: ('(0.0872664625997165 , 0)'::spoint <@ e) + Filter: ('(0.087266462599716474 , 0)'::spoint <@ e) (3 rows) -- The ellipse has semi-major axis length of 10 degrees along the equator, @@ -53,19 +54,19 @@ SELECT COUNT(*) FROM bbox_ellipse WHERE spoint '(5d, 0d)' <@ e; (1 row) EXPLAIN (COSTS OFF) SELECT COUNT(*) FROM bbox_ellipse WHERE spoint '(5d, 0d)' @ e; - QUERY PLAN --------------------------------------------------------------- + QUERY PLAN +---------------------------------------------------------------- Aggregate -> Index Scan using idx_bbox_ellipse on bbox_ellipse - Index Cond: ('(0.0872664625997165 , 0)'::spoint @ e) + Index Cond: ('(0.087266462599716474 , 0)'::spoint @ e) (3 rows) EXPLAIN (COSTS OFF) SELECT COUNT(*) FROM bbox_ellipse WHERE spoint '(5d, 0d)' <@ e; - QUERY PLAN ---------------------------------------------------------------- + QUERY PLAN +----------------------------------------------------------------- Aggregate -> Index Scan using idx_bbox_ellipse on bbox_ellipse - Index Cond: ('(0.0872664625997165 , 0)'::spoint <@ e) + Index Cond: ('(0.087266462599716474 , 0)'::spoint <@ e) (3 rows) SET enable_seqscan=true; @@ -170,11 +171,11 @@ SELECT COUNT(*) FROM bbox_path WHERE spoint '(0d, 0d)' <@ p; (1 row) EXPLAIN (COSTS OFF) SELECT COUNT(*) FROM bbox_path WHERE sline(spoint '(0d, -10d)', spoint '(0d, 10d)') && p; - QUERY PLAN --------------------------------------------------------------------------------------------------- + QUERY PLAN +--------------------------------------------------------------------------------------------------------- Aggregate -> Seq Scan on bbox_path - Filter: ('( 6.10865238198015, 1.5707963267949, 0, ZXZ ), 0.349065850398866'::sline && p) + Filter: ('( 6.1086523819801535, 1.5707963267948966, 0, ZXZ ), 0.34906585039886584'::sline && p) (3 rows) EXPLAIN (COSTS OFF) SELECT COUNT(*) FROM bbox_path WHERE spoint '(0d, 0d)' @ p; @@ -215,11 +216,11 @@ SELECT COUNT(*) FROM bbox_path WHERE spoint '(0d, 0d)' <@ p; (1 row) EXPLAIN (COSTS OFF) SELECT COUNT(*) FROM bbox_path WHERE sline(spoint '(0d, -10d)', spoint '(0d, 10d)') && p; - QUERY PLAN ------------------------------------------------------------------------------------------------------- + QUERY PLAN +------------------------------------------------------------------------------------------------------------- Aggregate -> Index Scan using idx_bbox_path on bbox_path - Index Cond: ('( 6.10865238198015, 1.5707963267949, 0, ZXZ ), 0.349065850398866'::sline && p) + Index Cond: ('( 6.1086523819801535, 1.5707963267948966, 0, ZXZ ), 0.34906585039886584'::sline && p) (3 rows) EXPLAIN (COSTS OFF) SELECT COUNT(*) FROM bbox_path WHERE spoint '(0d, 0d)' @ p; diff --git a/expected/bounding_box_gist_1.out b/expected/bounding_box_gist_1.out index 8c08936..48d4ff3 100644 --- a/expected/bounding_box_gist_1.out +++ b/expected/bounding_box_gist_1.out @@ -1,3 +1,4 @@ +SET extra_float_digits = 2; SET enable_seqscan=true; CREATE TABLE bbox_ellipse (e sellipse not null); INSERT INTO bbox_ellipse VALUES ('<{10d, 0.1d}, (0d,0d), 0d>'); @@ -20,19 +21,19 @@ SELECT COUNT(*) FROM bbox_ellipse WHERE spoint '(5d, 0d)' <@ e; (1 row) EXPLAIN (COSTS OFF) SELECT COUNT(*) FROM bbox_ellipse WHERE spoint '(5d, 0d)' @ e; - QUERY PLAN ----------------------------------------------------------- + QUERY PLAN +----------------------------------------------------------- Aggregate -> Seq Scan on bbox_ellipse - Filter: ('(0.0872664625997165 , 0)'::spoint @ e) + Filter: ('(0.08726646259971647 , 0)'::spoint @ e) (3 rows) EXPLAIN (COSTS OFF) SELECT COUNT(*) FROM bbox_ellipse WHERE spoint '(5d, 0d)' <@ e; - QUERY PLAN ------------------------------------------------------------ + QUERY PLAN +------------------------------------------------------------ Aggregate -> Seq Scan on bbox_ellipse - Filter: ('(0.0872664625997165 , 0)'::spoint <@ e) + Filter: ('(0.08726646259971647 , 0)'::spoint <@ e) (3 rows) -- The ellipse has semi-major axis length of 10 degrees along the equator, @@ -53,19 +54,19 @@ SELECT COUNT(*) FROM bbox_ellipse WHERE spoint '(5d, 0d)' <@ e; (1 row) EXPLAIN (COSTS OFF) SELECT COUNT(*) FROM bbox_ellipse WHERE spoint '(5d, 0d)' @ e; - QUERY PLAN --------------------------------------------------------------- + QUERY PLAN +--------------------------------------------------------------- Aggregate -> Index Scan using idx_bbox_ellipse on bbox_ellipse - Index Cond: (e ~ '(0.0872664625997165 , 0)'::spoint) + Index Cond: (e ~ '(0.08726646259971647 , 0)'::spoint) (3 rows) EXPLAIN (COSTS OFF) SELECT COUNT(*) FROM bbox_ellipse WHERE spoint '(5d, 0d)' <@ e; - QUERY PLAN ---------------------------------------------------------------- + QUERY PLAN +---------------------------------------------------------------- Aggregate -> Index Scan using idx_bbox_ellipse on bbox_ellipse - Index Cond: (e @> '(0.0872664625997165 , 0)'::spoint) + Index Cond: (e @> '(0.08726646259971647 , 0)'::spoint) (3 rows) SET enable_seqscan=true; @@ -170,11 +171,11 @@ SELECT COUNT(*) FROM bbox_path WHERE spoint '(0d, 0d)' <@ p; (1 row) EXPLAIN (COSTS OFF) SELECT COUNT(*) FROM bbox_path WHERE sline(spoint '(0d, -10d)', spoint '(0d, 10d)') && p; - QUERY PLAN --------------------------------------------------------------------------------------------------- + QUERY PLAN +--------------------------------------------------------------------------------------------------------- Aggregate -> Seq Scan on bbox_path - Filter: ('( 6.10865238198015, 1.5707963267949, 0, ZXZ ), 0.349065850398866'::sline && p) + Filter: ('( 6.1086523819801535, 1.5707963267948966, 0, ZXZ ), 0.34906585039886584'::sline && p) (3 rows) EXPLAIN (COSTS OFF) SELECT COUNT(*) FROM bbox_path WHERE spoint '(0d, 0d)' @ p; @@ -215,11 +216,11 @@ SELECT COUNT(*) FROM bbox_path WHERE spoint '(0d, 0d)' <@ p; (1 row) EXPLAIN (COSTS OFF) SELECT COUNT(*) FROM bbox_path WHERE sline(spoint '(0d, -10d)', spoint '(0d, 10d)') && p; - QUERY PLAN ------------------------------------------------------------------------------------------------------- + QUERY PLAN +------------------------------------------------------------------------------------------------------------- Aggregate -> Index Scan using idx_bbox_path on bbox_path - Index Cond: (p && '( 6.10865238198015, 1.5707963267949, 0, ZXZ ), 0.349065850398866'::sline) + Index Cond: (p && '( 6.1086523819801535, 1.5707963267948966, 0, ZXZ ), 0.34906585039886584'::sline) (3 rows) EXPLAIN (COSTS OFF) SELECT COUNT(*) FROM bbox_path WHERE spoint '(0d, 0d)' @ p; diff --git a/expected/epochprop.out b/expected/epochprop.out index 8541601..3a52832 100644 --- a/expected/epochprop.out +++ b/expected/epochprop.out @@ -1,3 +1,4 @@ +SET extra_float_digits = 2; SELECT to_char(DEGREES(tp[1]), '999D9999999999'), to_char(DEGREES(tp[2]), '999D9999999999'), @@ -92,16 +93,16 @@ SELECT epoch_prop_pos(spoint(radians(269.45207695), radians(4.693364966)), 23, RADIANS(-801.551/3.6e6), RADIANS(10362/3.6e6), -110, 20) AS tp; - tp ------------------------------------------ - (4.70274792658313 , 0.0829194509345993) + tp +--------------------------------------------- + (4.7027479265831289 , 0.082919450934599334) (1 row) SELECT epoch_prop_pos(spoint(radians(269.45207695), radians(4.693364966)), RADIANS(-801.551/3.6e6), RADIANS(10362/3.6e6), 20) AS tp; - tp ------------------------------------------ - (4.70274793061952 , 0.0829193989380876) + tp +--------------------------------------------- + (4.7027479306195161 , 0.082919398938087627) (1 row) diff --git a/expected/epochprop_1.out b/expected/epochprop_1.out new file mode 100644 index 0000000..08317fc --- /dev/null +++ b/expected/epochprop_1.out @@ -0,0 +1,108 @@ +SET extra_float_digits = 2; +SELECT + to_char(DEGREES(tp[1]), '999D9999999999'), + to_char(DEGREES(tp[2]), '999D9999999999'), + to_char(tp[3], '999D999'), + to_char(DEGREES(tp[4])*3.6e6, '999D999'), + to_char(DEGREES(tp[5])*3.6e6, '99999D999'), + to_char(tp[6], '999D999') +FROM ( + SELECT epoch_prop(spoint(radians(269.45207695), radians(4.693364966)), + 546.9759, + RADIANS(-801.551/3.6e6), RADIANS(10362/3.6e6), -110, + -100) AS tp) AS q; + to_char | to_char | to_char | to_char | to_char | to_char +-----------------+-----------------+----------+----------+------------+---------- + 269.4742714391 | 4.4072939987 | 543.624 | -791.442 | 10235.412 | -110.450 +(1 row) + +SELECT + to_char(DEGREES(tp[1]), '999D9999999999'), + to_char(DEGREES(tp[2]), '999D9999999999'), + to_char(tp[3], '999D999'), + to_char(DEGREES(tp[4])*3.6e6, '999D999'), + to_char(DEGREES(tp[5])*3.6e6, '99999D999'), + to_char(tp[6], '999D999') +FROM ( + SELECT epoch_prop(spoint(radians(269.45207695), radians(4.693364966)), + 0, + RADIANS(-801.551/3.6e6), RADIANS(10362/3.6e6), -110, + -100) AS tp) AS q; + to_char | to_char | to_char | to_char | to_char | to_char +-----------------+-----------------+---------+----------+------------+--------- + 269.4744079540 | 4.4055337210 | | -801.210 | 10361.762 | +(1 row) + +SELECT + to_char(DEGREES(tp[1]), '999D9999999999'), + to_char(DEGREES(tp[2]), '999D9999999999'), + to_char(tp[3], '999D999'), + to_char(DEGREES(tp[4])*3.6e6, '999D999'), + to_char(DEGREES(tp[5])*3.6e6, '99999D999'), + to_char(tp[6], '999D999') +FROM ( + SELECT epoch_prop(spoint(radians(269.45207695), radians(4.693364966)), + NULL, + RADIANS(-801.551/3.6e6), RADIANS(10362/3.6e6), -110, + -100) AS tp) AS q; + to_char | to_char | to_char | to_char | to_char | to_char +-----------------+-----------------+---------+----------+------------+--------- + 269.4744079540 | 4.4055337210 | | -801.210 | 10361.762 | +(1 row) + +SELECT + to_char(DEGREES(tp[1]), '999D9999999999'), + to_char(DEGREES(tp[2]), '999D9999999999'), + to_char(tp[3], '999D999'), + to_char(DEGREES(tp[4])*3.6e6, '999D999'), + to_char(DEGREES(tp[5])*3.6e6, '99999D999'), + to_char(tp[6], '999D999') +FROM ( + SELECT epoch_prop(spoint(radians(269.45207695), radians(4.693364966)), + 23, + RADIANS(-801.551/3.6e6), RADIANS(10362/3.6e6), NULL, + 20) AS tp) AS q; + to_char | to_char | to_char | to_char | to_char | to_char +-----------------+-----------------+----------+----------+------------+---------- + 269.4476085384 | 4.7509315989 | 23.000 | -801.617 | 10361.984 | 2.159 +(1 row) + +SELECT + to_char(DEGREES(tp[1]), '999D9999999999'), + to_char(DEGREES(tp[2]), '999D9999999999'), + to_char(tp[3], '999D999'), + to_char(DEGREES(tp[4])*3.6e6, '999D999'), + to_char(DEGREES(tp[5])*3.6e6, '99999D999'), + to_char(tp[6], '999D999') +FROM ( + SELECT epoch_prop(spoint(radians(269.45207695), radians(4.693364966)), + 23, + NULL, RADIANS(10362/3.6e6), -110, + 120) AS tp) AS q; + to_char | to_char | to_char | to_char | to_char | to_char +-----------------+-----------------+----------+----------+------------+---------- + 269.4520769500 | 5.0388680565 | 23.007 | -.000 | 10368.061 | -97.120 +(1 row) + +SELECT epoch_prop(NULL, + 23, + 0.01 , RADIANS(10362/3.6e6), -110, + 120); +ERROR: NULL position not supported in epoch propagation +SELECT epoch_prop_pos(spoint(radians(269.45207695), radians(4.693364966)), + 23, + RADIANS(-801.551/3.6e6), RADIANS(10362/3.6e6), -110, + 20) AS tp; + tp +------------------------------------------- + (4.702747926583129 , 0.08291945093459933) +(1 row) + +SELECT epoch_prop_pos(spoint(radians(269.45207695), radians(4.693364966)), + RADIANS(-801.551/3.6e6), RADIANS(10362/3.6e6), + 20) AS tp; + tp +------------------------------------------- + (4.702747930619516 , 0.08291939893808763) +(1 row) + diff --git a/expected/output_precision.out b/expected/output_precision.out new file mode 100644 index 0000000..9109c4b --- /dev/null +++ b/expected/output_precision.out @@ -0,0 +1,212 @@ +-- +-- Test default and custom output precisions for double values. +-- +SELECT set_sphere_output( 'RAD' ); + set_sphere_output +------------------- + SET RAD +(1 row) + +-- +-- Check default precision +-- +SELECT '( 1h 2m 30s , +1d 2m 30s)'::spoint; + spoint +------------------------------------------ + (0.272707695624114 , 0.0181805130416076) +(1 row) + +-- +-- Check option extra_float_digits +-- +SET extra_float_digits TO -6; +SELECT '( 1h 2m 30s , +1d 2m 30s)'::spoint; + spoint +----------------------------- + (0.272707696 , 0.018180513) +(1 row) + +SET extra_float_digits TO -2; +SELECT '( 1h 2m 30s , +1d 2m 30s)'::spoint; + spoint +-------------------------------------- + (0.2727076956241 , 0.01818051304161) +(1 row) + +SET extra_float_digits TO 0; +SELECT '( 1h 2m 30s , +1d 2m 30s)'::spoint; + spoint +------------------------------------------ + (0.272707695624114 , 0.0181805130416076) +(1 row) + +SET extra_float_digits TO 1; +SELECT '( 1h 2m 30s , +1d 2m 30s)'::spoint; + spoint +------------------------------------------ + (0.272707695624114 , 0.0181805130416076) +(1 row) + +SET extra_float_digits TO 2; +SELECT '( 1h 2m 30s , +1d 2m 30s)'::spoint; + spoint +---------------------------------------------- + (0.27270769562411401 , 0.018180513041607602) +(1 row) + +SET extra_float_digits TO 3; +SELECT '( 1h 2m 30s , +1d 2m 30s)'::spoint; + spoint +----------------------------------------------- + (0.27270769562411401 , 0.0181805130416076016) +(1 row) + +SET extra_float_digits TO 6; +ERROR: 6 is outside the valid range for parameter "extra_float_digits" (-15 .. 3) +SELECT '( 1h 2m 30s , +1d 2m 30s)'::spoint; + spoint +----------------------------------------------- + (0.27270769562411401 , 0.0181805130416076016) +(1 row) + +-- +-- Check compatibility behaviour +-- +SELECT set_sphere_output_precision(10); + set_sphere_output_precision +----------------------------- + SET 10 +(1 row) + +SELECT '( 1h 2m 30s , +1d 2m 30s)'::spoint; + spoint +-------------------------------- + (0.2727076956 , 0.01818051304) +(1 row) + +SELECT set_sphere_output_precision(12); + set_sphere_output_precision +----------------------------- + SET 12 +(1 row) + +SELECT '( 1h 2m 30s , +1d 2m 30s)'::spoint; + spoint +------------------------------------ + (0.272707695624 , 0.0181805130416) +(1 row) + +SELECT set_sphere_output_precision(15); + set_sphere_output_precision +----------------------------- + SET 15 +(1 row) + +SELECT '( 1h 2m 30s , +1d 2m 30s)'::spoint; + spoint +------------------------------------------ + (0.272707695624114 , 0.0181805130416076) +(1 row) + +SELECT set_sphere_output_precision(17); + set_sphere_output_precision +----------------------------- + SET 15 +(1 row) + +SELECT '( 1h 2m 30s , +1d 2m 30s)'::spoint; + spoint +------------------------------------------ + (0.272707695624114 , 0.0181805130416076) +(1 row) + +SELECT set_sphere_output_precision(20); + set_sphere_output_precision +----------------------------- + SET 15 +(1 row) + +SELECT '( 1h 2m 30s , +1d 2m 30s)'::spoint; + spoint +------------------------------------------ + (0.272707695624114 , 0.0181805130416076) +(1 row) + +SELECT set_sphere_output_precision(0); + set_sphere_output_precision +----------------------------- + SET 15 +(1 row) + +SELECT '( 1h 2m 30s , +1d 2m 30s)'::spoint; + spoint +------------------------------------------ + (0.272707695624114 , 0.0181805130416076) +(1 row) + +SELECT set_sphere_output_precision(-3); + set_sphere_output_precision +----------------------------- + SET 15 +(1 row) + +SELECT '( 1h 2m 30s , +1d 2m 30s)'::spoint; + spoint +------------------------------------------ + (0.272707695624114 , 0.0181805130416076) +(1 row) + +-- +-- Check extra_float_digits after set_sphere_output_precision. +-- The change of extra_float_digits should not affect the precision of pgsphere +-- output because set_sphere_output_precision enables compatibility mode. +-- +SELECT set_sphere_output_precision(10); + set_sphere_output_precision +----------------------------- + SET 10 +(1 row) + +SELECT '( 1h 2m 30s , +1d 2m 30s)'::spoint; + spoint +-------------------------------- + (0.2727076956 , 0.01818051304) +(1 row) + +SET extra_float_digits TO -6; +SELECT '( 1h 2m 30s , +1d 2m 30s)'::spoint; + spoint +-------------------------------- + (0.2727076956 , 0.01818051304) +(1 row) + +SET extra_float_digits TO -10; +SELECT '( 1h 2m 30s , +1d 2m 30s)'::spoint; + spoint +-------------------------------- + (0.2727076956 , 0.01818051304) +(1 row) + +-- +-- Check reset_sphere_output_precision. +-- It should disable compatibility mode - extra_float_digits should work. +-- +SELECT reset_sphere_output_precision(); + reset_sphere_output_precision +------------------------------- + RESET +(1 row) + +SELECT '( 1h 2m 30s , +1d 2m 30s)'::spoint; + spoint +---------------------- + (0.27271 , 0.018181) +(1 row) + +SET extra_float_digits TO -6; +SELECT '( 1h 2m 30s , +1d 2m 30s)'::spoint; + spoint +----------------------------- + (0.272707696 , 0.018180513) +(1 row) + diff --git a/expected/output_precision_1.out b/expected/output_precision_1.out new file mode 100644 index 0000000..02ca521 --- /dev/null +++ b/expected/output_precision_1.out @@ -0,0 +1,212 @@ +-- +-- Test default and custom output precisions for double values. +-- +SELECT set_sphere_output( 'RAD' ); + set_sphere_output +------------------- + SET RAD +(1 row) + +-- +-- Check default precision +-- +SELECT '( 1h 2m 30s , +1d 2m 30s)'::spoint; + spoint +------------------------------------------ + (0.272707695624114 , 0.0181805130416076) +(1 row) + +-- +-- Check option extra_float_digits +-- +SET extra_float_digits TO -6; +SELECT '( 1h 2m 30s , +1d 2m 30s)'::spoint; + spoint +----------------------------- + (0.272707696 , 0.018180513) +(1 row) + +SET extra_float_digits TO -2; +SELECT '( 1h 2m 30s , +1d 2m 30s)'::spoint; + spoint +-------------------------------------- + (0.2727076956241 , 0.01818051304161) +(1 row) + +SET extra_float_digits TO 0; +SELECT '( 1h 2m 30s , +1d 2m 30s)'::spoint; + spoint +------------------------------------------ + (0.272707695624114 , 0.0181805130416076) +(1 row) + +SET extra_float_digits TO 1; +SELECT '( 1h 2m 30s , +1d 2m 30s)'::spoint; + spoint +------------------------------------------ + (0.272707695624114 , 0.0181805130416076) +(1 row) + +SET extra_float_digits TO 2; +SELECT '( 1h 2m 30s , +1d 2m 30s)'::spoint; + spoint +------------------------------------------ + (0.272707695624114 , 0.0181805130416076) +(1 row) + +SET extra_float_digits TO 3; +SELECT '( 1h 2m 30s , +1d 2m 30s)'::spoint; + spoint +------------------------------------------ + (0.272707695624114 , 0.0181805130416076) +(1 row) + +SET extra_float_digits TO 6; +ERROR: 6 is outside the valid range for parameter "extra_float_digits" (-15 .. 3) +SELECT '( 1h 2m 30s , +1d 2m 30s)'::spoint; + spoint +------------------------------------------ + (0.272707695624114 , 0.0181805130416076) +(1 row) + +-- +-- Check compatibility behaviour +-- +SELECT set_sphere_output_precision(10); + set_sphere_output_precision +----------------------------- + SET 10 +(1 row) + +SELECT '( 1h 2m 30s , +1d 2m 30s)'::spoint; + spoint +-------------------------------- + (0.2727076956 , 0.01818051304) +(1 row) + +SELECT set_sphere_output_precision(12); + set_sphere_output_precision +----------------------------- + SET 12 +(1 row) + +SELECT '( 1h 2m 30s , +1d 2m 30s)'::spoint; + spoint +------------------------------------ + (0.272707695624 , 0.0181805130416) +(1 row) + +SELECT set_sphere_output_precision(15); + set_sphere_output_precision +----------------------------- + SET 15 +(1 row) + +SELECT '( 1h 2m 30s , +1d 2m 30s)'::spoint; + spoint +------------------------------------------ + (0.272707695624114 , 0.0181805130416076) +(1 row) + +SELECT set_sphere_output_precision(17); + set_sphere_output_precision +----------------------------- + SET 15 +(1 row) + +SELECT '( 1h 2m 30s , +1d 2m 30s)'::spoint; + spoint +------------------------------------------ + (0.272707695624114 , 0.0181805130416076) +(1 row) + +SELECT set_sphere_output_precision(20); + set_sphere_output_precision +----------------------------- + SET 15 +(1 row) + +SELECT '( 1h 2m 30s , +1d 2m 30s)'::spoint; + spoint +------------------------------------------ + (0.272707695624114 , 0.0181805130416076) +(1 row) + +SELECT set_sphere_output_precision(0); + set_sphere_output_precision +----------------------------- + SET 15 +(1 row) + +SELECT '( 1h 2m 30s , +1d 2m 30s)'::spoint; + spoint +------------------------------------------ + (0.272707695624114 , 0.0181805130416076) +(1 row) + +SELECT set_sphere_output_precision(-3); + set_sphere_output_precision +----------------------------- + SET 15 +(1 row) + +SELECT '( 1h 2m 30s , +1d 2m 30s)'::spoint; + spoint +------------------------------------------ + (0.272707695624114 , 0.0181805130416076) +(1 row) + +-- +-- Check extra_float_digits after set_sphere_output_precision. +-- The change of extra_float_digits should not affect the precision of pgsphere +-- output because set_sphere_output_precision enables compatibility mode. +-- +SELECT set_sphere_output_precision(10); + set_sphere_output_precision +----------------------------- + SET 10 +(1 row) + +SELECT '( 1h 2m 30s , +1d 2m 30s)'::spoint; + spoint +-------------------------------- + (0.2727076956 , 0.01818051304) +(1 row) + +SET extra_float_digits TO -6; +SELECT '( 1h 2m 30s , +1d 2m 30s)'::spoint; + spoint +-------------------------------- + (0.2727076956 , 0.01818051304) +(1 row) + +SET extra_float_digits TO -10; +SELECT '( 1h 2m 30s , +1d 2m 30s)'::spoint; + spoint +-------------------------------- + (0.2727076956 , 0.01818051304) +(1 row) + +-- +-- Check reset_sphere_output_precision. +-- It should disable compatibility mode - extra_float_digits should work. +-- +SELECT reset_sphere_output_precision(); + reset_sphere_output_precision +------------------------------- + RESET +(1 row) + +SELECT '( 1h 2m 30s , +1d 2m 30s)'::spoint; + spoint +---------------------- + (0.27271 , 0.018181) +(1 row) + +SET extra_float_digits TO -6; +SELECT '( 1h 2m 30s , +1d 2m 30s)'::spoint; + spoint +----------------------------- + (0.272707696 , 0.018180513) +(1 row) + diff --git a/pgs_point.sql.in b/pgs_point.sql.in index 908707e..724a119 100644 --- a/pgs_point.sql.in +++ b/pgs_point.sql.in @@ -26,6 +26,11 @@ CREATE FUNCTION set_sphere_output_precision(INT4) AS 'MODULE_PATHNAME', 'set_sphere_output_precision' LANGUAGE 'c'; +CREATE FUNCTION reset_sphere_output_precision() + RETURNS CSTRING + AS 'MODULE_PATHNAME', 'reset_sphere_output_precision' + LANGUAGE 'c'; + CREATE FUNCTION set_sphere_output(CSTRING) RETURNS CSTRING AS 'MODULE_PATHNAME', 'set_sphere_output' @@ -175,4 +180,3 @@ CREATE OPERATOR <-> ( COMMENT ON OPERATOR <-> (spoint, spoint) IS 'distance between spherical points'; - diff --git a/sql/bounding_box_gist.sql b/sql/bounding_box_gist.sql index fb862d6..20176c4 100644 --- a/sql/bounding_box_gist.sql +++ b/sql/bounding_box_gist.sql @@ -1,3 +1,4 @@ +SET extra_float_digits = 2; SET enable_seqscan=true; CREATE TABLE bbox_ellipse (e sellipse not null); INSERT INTO bbox_ellipse VALUES ('<{10d, 0.1d}, (0d,0d), 0d>'); diff --git a/sql/epochprop.sql b/sql/epochprop.sql index fea9737..d8ae2b7 100644 --- a/sql/epochprop.sql +++ b/sql/epochprop.sql @@ -1,3 +1,5 @@ +SET extra_float_digits = 2; + SELECT to_char(DEGREES(tp[1]), '999D9999999999'), to_char(DEGREES(tp[2]), '999D9999999999'), diff --git a/sql/output_precision.sql b/sql/output_precision.sql new file mode 100644 index 0000000..514af1e --- /dev/null +++ b/sql/output_precision.sql @@ -0,0 +1,82 @@ +-- +-- Test default and custom output precisions for double values. +-- + +SELECT set_sphere_output( 'RAD' ); + +-- +-- Check default precision +-- +SELECT '( 1h 2m 30s , +1d 2m 30s)'::spoint; + +-- +-- Check option extra_float_digits +-- +SET extra_float_digits TO -6; +SELECT '( 1h 2m 30s , +1d 2m 30s)'::spoint; + +SET extra_float_digits TO -2; +SELECT '( 1h 2m 30s , +1d 2m 30s)'::spoint; + +SET extra_float_digits TO 0; +SELECT '( 1h 2m 30s , +1d 2m 30s)'::spoint; + +SET extra_float_digits TO 1; +SELECT '( 1h 2m 30s , +1d 2m 30s)'::spoint; + +SET extra_float_digits TO 2; +SELECT '( 1h 2m 30s , +1d 2m 30s)'::spoint; + +SET extra_float_digits TO 3; +SELECT '( 1h 2m 30s , +1d 2m 30s)'::spoint; + +SET extra_float_digits TO 6; +SELECT '( 1h 2m 30s , +1d 2m 30s)'::spoint; + +-- +-- Check compatibility behaviour +-- +SELECT set_sphere_output_precision(10); +SELECT '( 1h 2m 30s , +1d 2m 30s)'::spoint; + +SELECT set_sphere_output_precision(12); +SELECT '( 1h 2m 30s , +1d 2m 30s)'::spoint; + +SELECT set_sphere_output_precision(15); +SELECT '( 1h 2m 30s , +1d 2m 30s)'::spoint; + +SELECT set_sphere_output_precision(17); +SELECT '( 1h 2m 30s , +1d 2m 30s)'::spoint; + +SELECT set_sphere_output_precision(20); +SELECT '( 1h 2m 30s , +1d 2m 30s)'::spoint; + +SELECT set_sphere_output_precision(0); +SELECT '( 1h 2m 30s , +1d 2m 30s)'::spoint; + +SELECT set_sphere_output_precision(-3); +SELECT '( 1h 2m 30s , +1d 2m 30s)'::spoint; + +-- +-- Check extra_float_digits after set_sphere_output_precision. +-- The change of extra_float_digits should not affect the precision of pgsphere +-- output because set_sphere_output_precision enables compatibility mode. +-- +SELECT set_sphere_output_precision(10); +SELECT '( 1h 2m 30s , +1d 2m 30s)'::spoint; + +SET extra_float_digits TO -6; +SELECT '( 1h 2m 30s , +1d 2m 30s)'::spoint; + +SET extra_float_digits TO -10; +SELECT '( 1h 2m 30s , +1d 2m 30s)'::spoint; + +-- +-- Check reset_sphere_output_precision. +-- It should disable compatibility mode - extra_float_digits should work. +-- +SELECT reset_sphere_output_precision(); +SELECT '( 1h 2m 30s , +1d 2m 30s)'::spoint; + +SET extra_float_digits TO -6; +SELECT '( 1h 2m 30s , +1d 2m 30s)'::spoint; diff --git a/src/output.c b/src/output.c index 7598d46..7df5889 100644 --- a/src/output.c +++ b/src/output.c @@ -1,5 +1,12 @@ #include "types.h" +#if PG_VERSION_NUM >= 120000 +#include "utils/float.h" +#include "common/shortest_dec.h" +#endif + +#include + #if !defined(PGSPHERE_VERSION) #error "PGSPHERE_VERSION macro is not set" #endif @@ -9,7 +16,6 @@ /* Output functions */ - /* Output modes */ #define OUTPUT_RAD 1 /* output in radians */ #define OUTPUT_DEG 2 /* output in degrees */ @@ -25,7 +31,7 @@ static unsigned char sphere_output = OUTPUT_RAD; /* * Defines the precision of floating point values in output. */ -static int sphere_output_precision = DBL_DIG; +static int sphere_output_precision = INT_MAX; PG_FUNCTION_INFO_V1(set_sphere_output); PG_FUNCTION_INFO_V1(spherepoint_out); @@ -37,6 +43,7 @@ PG_FUNCTION_INFO_V1(spherepath_out); PG_FUNCTION_INFO_V1(sphereellipse_out); PG_FUNCTION_INFO_V1(spherebox_out); PG_FUNCTION_INFO_V1(set_sphere_output_precision); +PG_FUNCTION_INFO_V1(reset_sphere_output_precision); PG_FUNCTION_INFO_V1(pg_sphere_version); /* @@ -94,6 +101,8 @@ Datum spherebox_out(PG_FUNCTION_ARGS); */ Datum pg_sphere_version(PG_FUNCTION_ARGS); +static void +spheretrans_out_buffer(StringInfo si, const SEuler *se); /* * Converts radians to DEG ( degrees, minutes, seconds ) @@ -128,6 +137,116 @@ rad_to_dms(double rad, unsigned int *deg, unsigned int *min, double *sec) } } +static void +pgs_strinfo_put_chr(StringInfo si, char c) +{ + appendStringInfoChar(si, c); +} + +static void +pgs_strinfo_put_str(StringInfo si, char *s) +{ + appendStringInfoString(si, s); +} + +static void +pgs_strinfo_put_d64(StringInfo si, double value) +{ + int cw, + ndig; + char buf[128]; + +#if PG_VERSION_NUM >= 120000 + + if (extra_float_digits > 0) + { + cw = double_to_shortest_decimal_buf(value, buf); + } + else + { + ndig = DBL_DIG + extra_float_digits; + if (ndig < 1) + ndig = 1; + + cw = pg_strfromd(buf, 128, ndig, value); + } + +#else + + ndig = DBL_DIG + extra_float_digits; + if (ndig < 1) + ndig = 1; + + cw = snprintf(buf, 128, "%.*g", ndig, value); + +#endif + + if (cw < 0) + { + fflush(stderr); + abort(); + } + + pgs_strinfo_put_str(si, buf); +} + +static void +pgs_strinfo_put_lng_dms(StringInfo si, double lng) +{ + unsigned int lngdeg, + lngmin; + double lngsec; + + rad_to_dms(lng, &lngdeg, &lngmin, &lngsec); + + appendStringInfo(si, "%3ud %2um ", lngdeg, lngmin); + pgs_strinfo_put_d64(si, lngsec); + pgs_strinfo_put_chr(si, 's'); +} + +static void +pgs_strinfo_put_lng_hms(StringInfo si, double lng) +{ + unsigned int lnghour, + lngmin; + double lngsec; + + rad_to_dms(lng / 15.0, &lnghour, &lngmin, &lngsec); + + appendStringInfo(si, "%3uh %2um ", lnghour, lngmin); + pgs_strinfo_put_d64(si, lngsec); + pgs_strinfo_put_chr(si, 's'); +} + +static void +pgs_strinfo_put_lat_dms(StringInfo si, double lat) +{ + unsigned int latdeg, + latmin; + double latsec; + const char latsign = lat >= 0 ? '+' : '-'; + + rad_to_dms(lat, &latdeg, &latmin, &latsec); + + appendStringInfo(si, "%c%2ud %2um ", latsign, latdeg, latmin); + pgs_strinfo_put_d64(si, latsec); + pgs_strinfo_put_chr(si, 's'); +} + +static void +pgs_strinfo_put_radius_dms(StringInfo si, double radius) +{ + unsigned int rdeg, + rmin; + double rsec; + + rad_to_dms(radius, &rdeg, &rmin, &rsec); + + appendStringInfo(si, "%2ud %2um ", rdeg, rmin); + pgs_strinfo_put_d64(si, rsec); + pgs_strinfo_put_chr(si, 's'); +} + Datum set_sphere_output_precision(PG_FUNCTION_ARGS) { @@ -144,6 +263,18 @@ set_sphere_output_precision(PG_FUNCTION_ARGS) PG_RETURN_CSTRING(buf); } +Datum +reset_sphere_output_precision(PG_FUNCTION_ARGS) +{ + char *buf = (char *) palloc(20); + + sphere_output_precision = INT_MAX; + + sprintf(buf, "RESET"); + + PG_RETURN_CSTRING(buf); +} + Datum set_sphere_output(PG_FUNCTION_ARGS) { @@ -176,8 +307,8 @@ set_sphere_output(PG_FUNCTION_ARGS) PG_RETURN_CSTRING(buf); } -Datum -spherepoint_out(PG_FUNCTION_ARGS) +static Datum +spherepoint_out_compat(PG_FUNCTION_ARGS) { SPoint *sp = (SPoint *) PG_GETARG_POINTER(0); char *buffer = (char *) palloc(255); @@ -227,11 +358,89 @@ spherepoint_out(PG_FUNCTION_ARGS) } PG_RETURN_CSTRING(buffer); +} + +static void +spherepoint_out_deg(StringInfo si, const SPoint *sp) +{ + pgs_strinfo_put_chr(si, '('); + pgs_strinfo_put_d64(si, RADIANS * sp->lng); + pgs_strinfo_put_str(si, "d, "); + pgs_strinfo_put_d64(si, RADIANS * sp->lat); + pgs_strinfo_put_str(si, "d)"); +} +static void +spherepoint_out_rad(StringInfo si, const SPoint *sp) +{ + pgs_strinfo_put_chr(si, '('); + pgs_strinfo_put_d64(si, sp->lng); + pgs_strinfo_put_str(si, " , "); + pgs_strinfo_put_d64(si, sp->lat); + pgs_strinfo_put_str(si, ")"); +} + +static void +spherepoint_out_dms(StringInfo si, const SPoint *sp) +{ + pgs_strinfo_put_chr(si, '('); + pgs_strinfo_put_lng_dms(si, sp->lng); + pgs_strinfo_put_str(si, " , "); + pgs_strinfo_put_lat_dms(si, sp->lat); + pgs_strinfo_put_chr(si, ')'); +} + +static void +spherepoint_out_hms(StringInfo si, const SPoint *sp) +{ + pgs_strinfo_put_chr(si, '('); + pgs_strinfo_put_lng_hms(si, sp->lng); + pgs_strinfo_put_str(si, " , "); + pgs_strinfo_put_lat_dms(si, sp->lat); + pgs_strinfo_put_chr(si, ')'); +} + +static inline void +spherepoint_out_buffer(StringInfo si, const SPoint *sp) +{ + switch (sphere_output) + { + case OUTPUT_DEG: + spherepoint_out_deg(si, sp); + break; + case OUTPUT_DMS: + spherepoint_out_dms(si, sp); + break; + case OUTPUT_HMS: + spherepoint_out_hms(si, sp); + break; + default: + spherepoint_out_rad(si, sp); + break; + } } Datum -spherecircle_out(PG_FUNCTION_ARGS) +spherepoint_out(PG_FUNCTION_ARGS) +{ + StringInfoData si; + SPoint *sp; + + if (sphere_output_precision != INT_MAX) + return spherepoint_out_compat(fcinfo); + + sp = (SPoint *) PG_GETARG_POINTER(0); + if (!sp) + PG_RETURN_NULL(); + + initStringInfo(&si); + spherepoint_out_buffer(&si, sp); + + PG_RETURN_CSTRING(si.data); +} + +static Datum +spherecircle_out_compat(PG_FUNCTION_ARGS) { SCIRCLE *c = (SCIRCLE *) PG_GETARG_POINTER(0); char *buffer = (char *) palloc(255); @@ -272,12 +481,86 @@ spherecircle_out(PG_FUNCTION_ARGS) } pfree(pointstr); + PG_RETURN_CSTRING(buffer); +} + +static void +spherecircle_out_deg(StringInfo si, const SCIRCLE *sc) +{ + pgs_strinfo_put_chr(si, '<'); + spherepoint_out_deg(si, &sc->center); + pgs_strinfo_put_str(si, " , "); + pgs_strinfo_put_d64(si, RADIANS * sc->radius); + pgs_strinfo_put_chr(si, '>'); +} +static void +spherecircle_out_rad(StringInfo si, const SCIRCLE *sc) +{ + pgs_strinfo_put_chr(si, '<'); + spherepoint_out_rad(si, &sc->center); + pgs_strinfo_put_str(si, " , "); + pgs_strinfo_put_d64(si, sc->radius); + pgs_strinfo_put_chr(si, '>'); +} + +static void +spherecircle_out_dms(StringInfo si, const SCIRCLE *sc) +{ + pgs_strinfo_put_chr(si, '<'); + spherepoint_out_dms(si, &sc->center); + pgs_strinfo_put_str(si, " , "); + pgs_strinfo_put_radius_dms(si, sc->radius); + pgs_strinfo_put_chr(si, '>'); +} + +static void +spherecircle_out_hms(StringInfo si, const SCIRCLE *sc) +{ + pgs_strinfo_put_chr(si, '<'); + spherepoint_out_hms(si, &sc->center); + pgs_strinfo_put_str(si, " , "); + pgs_strinfo_put_radius_dms(si, sc->radius); + pgs_strinfo_put_chr(si, '>'); } Datum -sphereellipse_out(PG_FUNCTION_ARGS) +spherecircle_out(PG_FUNCTION_ARGS) +{ + StringInfoData si; + SCIRCLE *sc; + + if (sphere_output_precision != INT_MAX) + return spherecircle_out_compat(fcinfo); + + sc = (SCIRCLE *) PG_GETARG_POINTER(0); + if (!sc) + PG_RETURN_NULL(); + + initStringInfo(&si); + + switch (sphere_output) + { + case OUTPUT_DEG: + spherecircle_out_deg(&si, sc); + break; + case OUTPUT_DMS: + spherecircle_out_dms(&si, sc); + break; + case OUTPUT_HMS: + spherecircle_out_hms(&si, sc); + break; + default: + spherecircle_out_rad(&si, sc); + break; + } + + PG_RETURN_CSTRING(si.data); +} + +static Datum +sphereellipse_out_compat(PG_FUNCTION_ARGS) { SELLIPSE *e = (SELLIPSE *) PG_GETARG_POINTER(0); char *buffer = (char *) palloc(255); @@ -333,8 +616,88 @@ sphereellipse_out(PG_FUNCTION_ARGS) PG_RETURN_CSTRING(buffer); } +static void +sphereellipse_out_deg(StringInfo si, SELLIPSE *e) +{ + const SPoint sp = { e->psi, e->theta }; + + pgs_strinfo_put_str(si, "<{ "); + pgs_strinfo_put_d64(si, RADIANS * e->rad[0]); + pgs_strinfo_put_str(si, "d , "); + pgs_strinfo_put_d64(si, RADIANS * e->rad[1]); + pgs_strinfo_put_str(si, "d },"); + spherepoint_out_buffer(si, &sp); + pgs_strinfo_put_str(si, " , "); + pgs_strinfo_put_d64(si, RADIANS * e->phi); + pgs_strinfo_put_str(si, "d>"); +} + +static void +sphereellipse_out_rad(StringInfo si, SELLIPSE *e) +{ + const SPoint sp = { e->psi, e->theta }; + + pgs_strinfo_put_str(si, "<{ "); + pgs_strinfo_put_d64(si, e->rad[0]); + pgs_strinfo_put_str(si, " , "); + pgs_strinfo_put_d64(si, e->rad[1]); + pgs_strinfo_put_str(si, " },"); + spherepoint_out_buffer(si, &sp); + pgs_strinfo_put_str(si, " , "); + pgs_strinfo_put_d64(si, e->phi); + pgs_strinfo_put_str(si, ">"); +} + +static void +sphereellipse_out_dms(StringInfo si, SELLIPSE *e) +{ + const SPoint sp = { e->psi, e->theta }; + + pgs_strinfo_put_str(si, "<{ "); + pgs_strinfo_put_lng_dms(si, e->rad[0]); + pgs_strinfo_put_str(si, " , "); + pgs_strinfo_put_lng_dms(si, e->rad[1]); + pgs_strinfo_put_str(si, " },"); + spherepoint_out_buffer(si, &sp); + pgs_strinfo_put_str(si, " , "); + pgs_strinfo_put_lng_dms(si, e->phi); + pgs_strinfo_put_str(si, ">"); +} + Datum -sphereline_out(PG_FUNCTION_ARGS) +sphereellipse_out(PG_FUNCTION_ARGS) +{ + StringInfoData si; + SELLIPSE *e; + + if (sphere_output_precision != INT_MAX) + return sphereellipse_out_compat(fcinfo); + + e = (SELLIPSE *) PG_GETARG_POINTER(0); + if (!e) + PG_RETURN_NULL(); + + initStringInfo(&si); + + switch (sphere_output) + { + case OUTPUT_DEG: + sphereellipse_out_deg(&si, e); + break; + case OUTPUT_HMS: + case OUTPUT_DMS: + sphereellipse_out_dms(&si, e); + break; + default: + sphereellipse_out_rad(&si, e); + break; + } + + PG_RETURN_CSTRING(si.data); +} + +static Datum +sphereline_out_compat(PG_FUNCTION_ARGS) { SLine *sl = (SLine *) PG_GETARG_POINTER(0); char *out = (char *) palloc(255); @@ -384,7 +747,49 @@ sphereline_out(PG_FUNCTION_ARGS) } Datum -spheretrans_out(PG_FUNCTION_ARGS) +sphereline_out(PG_FUNCTION_ARGS) +{ + StringInfoData si; + SLine *sl; + SEuler se; + + if (sphere_output_precision != INT_MAX) + return sphereline_out_compat(fcinfo); + + sl = (SLine *) PG_GETARG_POINTER(0); + if (!sl) + PG_RETURN_NULL(); + + seuler_set_zxz(&se); + se.phi = sl->phi; + se.theta = sl->theta; + se.psi = sl->psi; + + initStringInfo(&si); + + pgs_strinfo_put_str(&si, "( "); + spheretrans_out_buffer(&si, &se); + pgs_strinfo_put_str(&si, " ), "); + + switch (sphere_output) + { + case OUTPUT_DEG: + pgs_strinfo_put_d64(&si, RADIANS * sl->length); + break; + case OUTPUT_HMS: + case OUTPUT_DMS: + pgs_strinfo_put_lng_dms(&si, sl->length); + break; + default: + pgs_strinfo_put_d64(&si, sl->length); + break; + } + + PG_RETURN_CSTRING(si.data); +} + +static Datum +spheretrans_out_compat(PG_FUNCTION_ARGS) { SEuler *se = (SEuler *) PG_GETARG_POINTER(0); char *buffer = (char *) palloc(255); @@ -469,8 +874,117 @@ spheretrans_out(PG_FUNCTION_ARGS) PG_RETURN_CSTRING(buffer); } +static void +spheretrans_out_deg(StringInfo si, SPoint sp[3]) +{ + int i; + + for (i = 0; i < 3; ++i) + { + pgs_strinfo_put_d64(si, RADIANS * sp[i].lng); + pgs_strinfo_put_str(si, ", "); + } +} + +static void +spheretrans_out_rad(StringInfo si, SPoint sp[3]) +{ + int i; + + for (i = 0; i < 3; ++i) + { + pgs_strinfo_put_d64(si, sp[i].lng); + pgs_strinfo_put_str(si, ", "); + } +} + +static void +spheretrans_out_dms(StringInfo si, SPoint sp[3]) +{ + int i; + + for (i = 0; i < 3; ++i) + { + pgs_strinfo_put_lng_dms(si, sp[i].lng); + pgs_strinfo_put_str(si, ", "); + } +} + +static void +spheretrans_out_buffer(StringInfo si, const SEuler *se) +{ + SPoint val[3]; + unsigned char t[3]; + int i; + + val[0].lat = val[1].lat = val[2].lat = 0.0; + val[0].lng = se->phi; + val[1].lng = se->theta; + val[2].lng = se->psi; + + t[0] = se->phi_a; + t[1] = se->theta_a; + t[2] = se->psi_a; + + spoint_check(&val[0]); + spoint_check(&val[1]); + spoint_check(&val[2]); + + switch (sphere_output) + { + case OUTPUT_DEG: + spheretrans_out_deg(si, val); + break; + case OUTPUT_HMS: + case OUTPUT_DMS: + spheretrans_out_dms(si, val); + break; + default: + spheretrans_out_rad(si, val); + break; + } + + for (i = 0; i < 3; i++) + { + switch (t[i]) + { + case EULER_AXIS_X: + pgs_strinfo_put_chr(si, 'X'); + break; + case EULER_AXIS_Y: + pgs_strinfo_put_chr(si, 'Y'); + break; + case EULER_AXIS_Z: + pgs_strinfo_put_chr(si, 'Z'); + break; + default: + Assert(false); + } + } +} + Datum -spherepath_out(PG_FUNCTION_ARGS) +spheretrans_out(PG_FUNCTION_ARGS) +{ + StringInfoData si; + SEuler *se; + + if (sphere_output_precision != INT_MAX) + return spheretrans_out_compat(fcinfo); + + se = (SEuler *) PG_GETARG_POINTER(0); + if (!se) + PG_RETURN_NULL(); + + initStringInfo(&si); + + spheretrans_out_buffer(&si, se); + + PG_RETURN_CSTRING(si.data); +} + +static Datum +spherepath_out_compat(PG_FUNCTION_ARGS) { SPATH *path = PG_GETARG_SPATH(0); int32 i; @@ -494,7 +1008,37 @@ spherepath_out(PG_FUNCTION_ARGS) } Datum -spherepoly_out(PG_FUNCTION_ARGS) +spherepath_out(PG_FUNCTION_ARGS) +{ + StringInfoData si; + SPATH *path; + int32 i; + + if (sphere_output_precision != INT_MAX) + return spherepath_out_compat(fcinfo); + + path = PG_GETARG_SPATH(0); + if (!path) + PG_RETURN_NULL(); + + initStringInfo(&si); + + pgs_strinfo_put_chr(&si, '{'); + + for (i = 0; i < path->npts; ++i) + { + if (i > 0) + pgs_strinfo_put_chr(&si, ','); + spherepoint_out_buffer(&si, &path->p[i]); + } + + pgs_strinfo_put_chr(&si, '}'); + + PG_RETURN_CSTRING(si.data); +} + +static Datum +spherepoly_out_compat(PG_FUNCTION_ARGS) { SPOLY *poly = PG_GETARG_SPOLY(0); int32 i; @@ -518,7 +1062,37 @@ spherepoly_out(PG_FUNCTION_ARGS) } Datum -spherebox_out(PG_FUNCTION_ARGS) +spherepoly_out(PG_FUNCTION_ARGS) +{ + StringInfoData si; + SPOLY *poly; + int32 i; + + if (sphere_output_precision != INT_MAX) + return spherepoly_out_compat(fcinfo); + + poly = PG_GETARG_SPOLY(0); + if (!poly) + PG_RETURN_NULL(); + + initStringInfo(&si); + + pgs_strinfo_put_chr(&si, '{'); + + for (i = 0; i < poly->npts; ++i) + { + if (i > 0) + pgs_strinfo_put_chr(&si, ','); + spherepoint_out_buffer(&si, &poly->p[i]); + } + + pgs_strinfo_put_chr(&si, '}'); + + PG_RETURN_CSTRING(si.data); +} + +static Datum +spherebox_out_compat(PG_FUNCTION_ARGS) { SBOX *box = (SBOX *) PG_GETARG_POINTER(0); char *buffer = (char *) palloc(255); @@ -535,6 +1109,30 @@ spherebox_out(PG_FUNCTION_ARGS) PG_RETURN_CSTRING(buffer); } +Datum +spherebox_out(PG_FUNCTION_ARGS) +{ + StringInfoData si; + SBOX *box; + + if (sphere_output_precision != INT_MAX) + return spherebox_out_compat(fcinfo); + + box = (SBOX *) PG_GETARG_POINTER(0); + if (!box) + PG_RETURN_NULL(); + + initStringInfo(&si); + + pgs_strinfo_put_chr(&si, '('); + spherepoint_out_buffer(&si, &box->sw); + pgs_strinfo_put_str(&si, ", "); + spherepoint_out_buffer(&si, &box->ne); + pgs_strinfo_put_chr(&si, ')'); + + PG_RETURN_CSTRING(si.data); +} + Datum pg_sphere_version(PG_FUNCTION_ARGS) { diff --git a/upgrade_scripts/pg_sphere--1.4.2--1.5.0.sql.in b/upgrade_scripts/pg_sphere--1.4.2--1.5.0.sql.in index 35c964e..8b2ce2b 100644 --- a/upgrade_scripts/pg_sphere--1.4.2--1.5.0.sql.in +++ b/upgrade_scripts/pg_sphere--1.4.2--1.5.0.sql.in @@ -14,3 +14,8 @@ EXCEPTION WHEN OTHERS THEN RAISE; END; $$; + +CREATE FUNCTION reset_sphere_output_precision() + RETURNS CSTRING + AS 'MODULE_PATHNAME', 'reset_sphere_output_precision' + LANGUAGE 'c'; From daa9478bcd1988d5934541b7e09b37a909d23b92 Mon Sep 17 00:00:00 2001 From: Vitaly Date: Mon, 22 Apr 2024 09:22:05 +0300 Subject: [PATCH 75/87] Alter spoint op family to add missed operator 17 (<->) (#121) The upgrade script misses the altering of spoint operator family to add operator 17. It is required for k-NN search. Change the version to 1.5.1. --- Makefile | 6 +++++- Makefile.common.mk | 2 +- expected/version.out | 2 +- pg_sphere.control | 2 +- upgrade_scripts/pg_sphere--1.5.0--1.5.1.sql.in | 11 +++++++++++ 5 files changed, 19 insertions(+), 4 deletions(-) create mode 100644 upgrade_scripts/pg_sphere--1.5.0--1.5.1.sql.in diff --git a/Makefile b/Makefile index 81dc57c..78f2dc5 100644 --- a/Makefile +++ b/Makefile @@ -35,7 +35,8 @@ DATA_built = $(RELEASE_SQL) \ pg_sphere--1.3.1--1.4.0.sql \ pg_sphere--1.4.0--1.4.1.sql \ pg_sphere--1.4.1--1.4.2.sql \ - pg_sphere--1.4.2--1.5.0.sql + pg_sphere--1.4.2--1.5.0.sql \ + pg_sphere--1.5.0--1.5.1.sql DOCS = README.pg_sphere COPYRIGHT.pg_sphere TESTS = version tables points euler circle line ellipse poly path box \ @@ -214,6 +215,9 @@ pg_sphere--1.4.0--1.4.1.sql pg_sphere--1.4.1--1.4.2.sql: pg_sphere--1.4.2--1.5.0.sql: cat upgrade_scripts/$@.in $^ > $@ +pg_sphere--1.5.0--1.5.1.sql: + cat upgrade_scripts/$@.in $^ > $@ + # end of local stuff src/sscan.o : src/sparse.c diff --git a/Makefile.common.mk b/Makefile.common.mk index 7764d84..be82047 100644 --- a/Makefile.common.mk +++ b/Makefile.common.mk @@ -5,4 +5,4 @@ #---------------------------------------------------------------------------- EXTENSION := pg_sphere -PGSPHERE_VERSION := 1.5.0 +PGSPHERE_VERSION := 1.5.1 diff --git a/expected/version.out b/expected/version.out index 1d82d75..ffad8f5 100644 --- a/expected/version.out +++ b/expected/version.out @@ -2,6 +2,6 @@ SELECT pg_sphere_version(); pg_sphere_version ------------------- - 1.5.0 + 1.5.1 (1 row) diff --git a/pg_sphere.control b/pg_sphere.control index 4ecf4cd..1e73251 100644 --- a/pg_sphere.control +++ b/pg_sphere.control @@ -1,5 +1,5 @@ # pg_sphere extension comment = 'spherical objects with useful functions, operators and index support' -default_version = '1.5.0' +default_version = '1.5.1' module_pathname = '$libdir/pg_sphere' relocatable = true diff --git a/upgrade_scripts/pg_sphere--1.5.0--1.5.1.sql.in b/upgrade_scripts/pg_sphere--1.5.0--1.5.1.sql.in new file mode 100644 index 0000000..20c7cf6 --- /dev/null +++ b/upgrade_scripts/pg_sphere--1.5.0--1.5.1.sql.in @@ -0,0 +1,11 @@ +-- Upgrade: 1.5.0 -> 1.5.1 + +DO $$ +BEGIN + ALTER OPERATOR FAMILY spoint USING gist ADD + OPERATOR 17 <-> (spoint, spoint) FOR ORDER BY float_ops; +EXCEPTION + WHEN duplicate_object THEN NULL; + WHEN OTHERS THEN RAISE; +END; +$$; From 59ae17964ac812515b47606eef8f69edf0f15684 Mon Sep 17 00:00:00 2001 From: Vitaly Davydov Date: Mon, 20 May 2024 16:41:21 +0300 Subject: [PATCH 76/87] Re-generate parser source files --- src/sparse.c | 180 +++++++++++++++++++++++++-------------------------- src/sparse.h | 10 +-- src/sscan.c | 60 ++++++++--------- 3 files changed, 125 insertions(+), 125 deletions(-) diff --git a/src/sparse.c b/src/sparse.c index f220086..9eb7d57 100644 --- a/src/sparse.c +++ b/src/sparse.c @@ -74,7 +74,7 @@ #define yychar sphere_yychar /* First part of user prologue. */ -#line 1 "sparse.y" +#line 1 "src/sparse.y" #include #include @@ -110,7 +110,7 @@ static double human2dec(double d, double m, double s) } -#line 114 "sparse.c" +#line 114 "src/sparse.c" # ifndef YY_NULLPTR # if defined __cplusplus @@ -134,8 +134,8 @@ static double human2dec(double d, double m, double s) /* Use api.header.include to #include this header instead of duplicating it here. */ -#ifndef YY_SPHERE_YY_SPARSE_H_INCLUDED -# define YY_SPHERE_YY_SPARSE_H_INCLUDED +#ifndef YY_SPHERE_YY_SRC_SPARSE_H_INCLUDED +# define YY_SPHERE_YY_SRC_SPARSE_H_INCLUDED /* Debug traces. */ #ifndef YYDEBUG # define YYDEBUG 0 @@ -187,13 +187,13 @@ extern int sphere_yydebug; #if ! defined YYSTYPE && ! defined YYSTYPE_IS_DECLARED union YYSTYPE { -#line 41 "sparse.y" +#line 41 "src/sparse.y" int i; double d; char c[3]; -#line 197 "sparse.c" +#line 197 "src/sparse.c" }; typedef union YYSTYPE YYSTYPE; @@ -206,7 +206,7 @@ extern YYSTYPE sphere_yylval; int sphere_yyparse (void); -#endif /* !YY_SPHERE_YY_SPARSE_H_INCLUDED */ +#endif /* !YY_SPHERE_YY_SRC_SPARSE_H_INCLUDED */ @@ -1349,265 +1349,265 @@ yyparse (void) switch (yyn) { case 4: -#line 70 "sparse.y" +#line 70 "src/sparse.y" { set_spheretype( STYPE_POINT ); } -#line 1355 "sparse.c" +#line 1355 "src/sparse.c" break; case 5: -#line 71 "sparse.y" +#line 71 "src/sparse.y" { set_spheretype( STYPE_CIRCLE ); } -#line 1361 "sparse.c" +#line 1361 "src/sparse.c" break; case 6: -#line 72 "sparse.y" +#line 72 "src/sparse.y" { set_spheretype( STYPE_LINE ); } -#line 1367 "sparse.c" +#line 1367 "src/sparse.c" break; case 7: -#line 73 "sparse.y" +#line 73 "src/sparse.y" { set_spheretype( STYPE_EULER ); } -#line 1373 "sparse.c" +#line 1373 "src/sparse.c" break; case 8: -#line 74 "sparse.y" +#line 74 "src/sparse.y" { set_spheretype( STYPE_PATH ); } -#line 1379 "sparse.c" +#line 1379 "src/sparse.c" break; case 9: -#line 75 "sparse.y" +#line 75 "src/sparse.y" { set_spheretype( STYPE_ELLIPSE ); } -#line 1385 "sparse.c" +#line 1385 "src/sparse.c" break; case 10: -#line 76 "sparse.y" +#line 76 "src/sparse.y" { set_spheretype( STYPE_BOX ); } -#line 1391 "sparse.c" +#line 1391 "src/sparse.c" break; case 11: -#line 81 "sparse.y" +#line 81 "src/sparse.y" { (yyval.d) = (yyvsp[0].d); } -#line 1397 "sparse.c" +#line 1397 "src/sparse.c" break; case 12: -#line 82 "sparse.y" +#line 82 "src/sparse.y" { (yyval.d) = (yyvsp[0].i); } -#line 1403 "sparse.c" +#line 1403 "src/sparse.c" break; case 13: -#line 87 "sparse.y" +#line 87 "src/sparse.y" { (yyval.i) = set_angle(0, (yyvsp[0].d) ); } -#line 1409 "sparse.c" +#line 1409 "src/sparse.c" break; case 14: -#line 88 "sparse.y" +#line 88 "src/sparse.y" { (yyval.i) = set_angle(1, human2dec((yyvsp[-1].d), 0, 0) ); } -#line 1415 "sparse.c" +#line 1415 "src/sparse.c" break; case 15: -#line 89 "sparse.y" +#line 89 "src/sparse.y" { (yyval.i) = set_angle(1, human2dec((yyvsp[-1].i), 0, 0) ); } -#line 1421 "sparse.c" +#line 1421 "src/sparse.c" break; case 16: -#line 90 "sparse.y" +#line 90 "src/sparse.y" { (yyval.i) = set_angle(1, human2dec((yyvsp[-2].i), (yyvsp[0].d), 0) ); } -#line 1427 "sparse.c" +#line 1427 "src/sparse.c" break; case 17: -#line 91 "sparse.y" +#line 91 "src/sparse.y" { (yyval.i) = set_angle(1, human2dec((yyvsp[-3].i), (yyvsp[-1].d), 0) ); } -#line 1433 "sparse.c" +#line 1433 "src/sparse.c" break; case 18: -#line 92 "sparse.y" +#line 92 "src/sparse.y" { (yyval.i) = set_angle(1, human2dec((yyvsp[-3].i), (yyvsp[-1].i), 0) ); } -#line 1439 "sparse.c" +#line 1439 "src/sparse.c" break; case 19: -#line 93 "sparse.y" +#line 93 "src/sparse.y" { (yyval.i) = set_angle(1, human2dec((yyvsp[-4].i), (yyvsp[-2].i), (yyvsp[0].d)) ); } -#line 1445 "sparse.c" +#line 1445 "src/sparse.c" break; case 20: -#line 94 "sparse.y" +#line 94 "src/sparse.y" { (yyval.i) = set_angle(1, human2dec((yyvsp[-5].i), (yyvsp[-3].i), (yyvsp[-1].d)) ); } -#line 1451 "sparse.c" +#line 1451 "src/sparse.c" break; case 21: -#line 99 "sparse.y" +#line 99 "src/sparse.y" { (yyval.i) = set_angle(0, (yyvsp[0].d)); } -#line 1457 "sparse.c" +#line 1457 "src/sparse.c" break; case 22: -#line 100 "sparse.y" +#line 100 "src/sparse.y" { (yyval.i) = set_angle(1, human2dec((yyvsp[-1].d), 0, 0)); } -#line 1463 "sparse.c" +#line 1463 "src/sparse.c" break; case 23: -#line 101 "sparse.y" +#line 101 "src/sparse.y" { (yyval.i) = set_angle(1, human2dec((yyvsp[-1].i), 0, 0)); } -#line 1469 "sparse.c" +#line 1469 "src/sparse.c" break; case 24: -#line 102 "sparse.y" +#line 102 "src/sparse.y" { (yyval.i) = set_angle(1, human2dec((yyvsp[-2].i), (yyvsp[0].d), 0)); } -#line 1475 "sparse.c" +#line 1475 "src/sparse.c" break; case 25: -#line 103 "sparse.y" +#line 103 "src/sparse.y" { (yyval.i) = set_angle(1, human2dec((yyvsp[-3].i), (yyvsp[-1].d), 0)); } -#line 1481 "sparse.c" +#line 1481 "src/sparse.c" break; case 26: -#line 104 "sparse.y" +#line 104 "src/sparse.y" { (yyval.i) = set_angle(1, human2dec((yyvsp[-3].i), (yyvsp[-1].i), 0)); } -#line 1487 "sparse.c" +#line 1487 "src/sparse.c" break; case 27: -#line 105 "sparse.y" +#line 105 "src/sparse.y" { (yyval.i) = set_angle(1, human2dec((yyvsp[-4].i), (yyvsp[-2].i), (yyvsp[0].d))); } -#line 1493 "sparse.c" +#line 1493 "src/sparse.c" break; case 28: -#line 106 "sparse.y" +#line 106 "src/sparse.y" { (yyval.i) = set_angle(1, human2dec((yyvsp[-5].i), (yyvsp[-3].i), (yyvsp[-1].d))); } -#line 1499 "sparse.c" +#line 1499 "src/sparse.c" break; case 29: -#line 107 "sparse.y" +#line 107 "src/sparse.y" { (yyval.i) = set_angle(1, 15 * human2dec((yyvsp[-2].i), (yyvsp[0].d), 0)); } -#line 1505 "sparse.c" +#line 1505 "src/sparse.c" break; case 30: -#line 108 "sparse.y" +#line 108 "src/sparse.y" { (yyval.i) = set_angle(1, 15 * human2dec((yyvsp[-4].i), (yyvsp[-2].i), (yyvsp[0].d))); } -#line 1511 "sparse.c" +#line 1511 "src/sparse.c" break; case 31: -#line 109 "sparse.y" +#line 109 "src/sparse.y" { (yyval.i) = set_angle(1, 15 * human2dec((yyvsp[-5].i), (yyvsp[-3].i), (yyvsp[-1].d))); } -#line 1517 "sparse.c" +#line 1517 "src/sparse.c" break; case 32: -#line 114 "sparse.y" +#line 114 "src/sparse.y" { (yyval.i) = set_angle_sign((yyvsp[0].i), 1); } -#line 1523 "sparse.c" +#line 1523 "src/sparse.c" break; case 33: -#line 115 "sparse.y" +#line 115 "src/sparse.y" { (yyval.i) = set_angle_sign((yyvsp[0].i), (yyvsp[-1].i)); } -#line 1529 "sparse.c" +#line 1529 "src/sparse.c" break; case 34: -#line 120 "sparse.y" +#line 120 "src/sparse.y" { (yyval.i) = set_angle_sign((yyvsp[0].i), 1); } -#line 1535 "sparse.c" +#line 1535 "src/sparse.c" break; case 35: -#line 121 "sparse.y" +#line 121 "src/sparse.y" { (yyval.i) = set_angle_sign((yyvsp[0].i), (yyvsp[-1].i)); } -#line 1541 "sparse.c" +#line 1541 "src/sparse.c" break; case 36: -#line 128 "sparse.y" +#line 128 "src/sparse.y" { (yyval.i) = set_point((yyvsp[-3].i), (yyvsp[-1].i)); } -#line 1549 "sparse.c" +#line 1549 "src/sparse.c" break; case 37: -#line 136 "sparse.y" +#line 136 "src/sparse.y" { set_circle((yyvsp[-3].i), (yyvsp[-1].i)); } -#line 1557 "sparse.c" +#line 1557 "src/sparse.c" break; case 38: -#line 144 "sparse.y" +#line 144 "src/sparse.y" { set_euler((yyvsp[-4].i), (yyvsp[-2].i), (yyvsp[0].i), "ZXZ"); } -#line 1565 "sparse.c" +#line 1565 "src/sparse.c" break; case 39: -#line 148 "sparse.y" +#line 148 "src/sparse.y" { set_euler((yyvsp[-6].i), (yyvsp[-4].i), (yyvsp[-2].i), (yyvsp[0].c)); } -#line 1573 "sparse.c" +#line 1573 "src/sparse.c" break; case 40: -#line 156 "sparse.y" +#line 156 "src/sparse.y" { set_line ((yyvsp[0].i)); } -#line 1581 "sparse.c" +#line 1581 "src/sparse.c" break; case 43: -#line 168 "sparse.y" +#line 168 "src/sparse.y" { } -#line 1587 "sparse.c" +#line 1587 "src/sparse.c" break; case 44: -#line 174 "sparse.y" +#line 174 "src/sparse.y" { set_ellipse((yyvsp[-8].i), (yyvsp[-6].i), (yyvsp[-3].i), (yyvsp[-1].i)); } -#line 1595 "sparse.c" +#line 1595 "src/sparse.c" break; case 45: -#line 181 "sparse.y" +#line 181 "src/sparse.y" { } -#line 1601 "sparse.c" +#line 1601 "src/sparse.c" break; case 46: -#line 182 "sparse.y" +#line 182 "src/sparse.y" { } -#line 1607 "sparse.c" +#line 1607 "src/sparse.c" break; -#line 1611 "sparse.c" +#line 1611 "src/sparse.c" default: break; } diff --git a/src/sparse.h b/src/sparse.h index 032b5fd..e6a1000 100644 --- a/src/sparse.h +++ b/src/sparse.h @@ -34,8 +34,8 @@ /* Undocumented macros, especially those whose name start with YY_, are private implementation details. Do not rely on them. */ -#ifndef YY_SPHERE_YY_SPARSE_H_INCLUDED -# define YY_SPHERE_YY_SPARSE_H_INCLUDED +#ifndef YY_SPHERE_YY_SRC_SPARSE_H_INCLUDED +# define YY_SPHERE_YY_SRC_SPARSE_H_INCLUDED /* Debug traces. */ #ifndef YYDEBUG # define YYDEBUG 0 @@ -87,13 +87,13 @@ extern int sphere_yydebug; #if ! defined YYSTYPE && ! defined YYSTYPE_IS_DECLARED union YYSTYPE { -#line 41 "sparse.y" +#line 41 "src/sparse.y" int i; double d; char c[3]; -#line 97 "sparse.h" +#line 97 "src/sparse.h" }; typedef union YYSTYPE YYSTYPE; @@ -106,4 +106,4 @@ extern YYSTYPE sphere_yylval; int sphere_yyparse (void); -#endif /* !YY_SPHERE_YY_SPARSE_H_INCLUDED */ +#endif /* !YY_SPHERE_YY_SRC_SPARSE_H_INCLUDED */ diff --git a/src/sscan.c b/src/sscan.c index 3d904c6..0df711e 100644 --- a/src/sscan.c +++ b/src/sscan.c @@ -1,6 +1,6 @@ -#line 2 "sscan.c" +#line 2 "src/sscan.c" -#line 4 "sscan.c" +#line 4 "src/sscan.c" #define YY_INT_ALIGNED short int @@ -722,8 +722,8 @@ int yy_flex_debug = 0; #define YY_MORE_ADJ 0 #define YY_RESTORE_YY_MORE_OFFSET char *yytext; -#line 1 "sscan.l" -#line 2 "sscan.l" +#line 1 "src/sscan.l" +#line 2 "src/sscan.l" #include #include "string.h" #include "sparse.h" @@ -745,8 +745,8 @@ void sphere_flush_scanner_buffer(void) { YY_FLUSH_BUFFER; } -#line 749 "sscan.c" -#line 750 "sscan.c" +#line 749 "src/sscan.c" +#line 750 "src/sscan.c" #define INITIAL 0 @@ -961,9 +961,9 @@ YY_DECL } { -#line 35 "sscan.l" +#line 35 "src/sscan.l" -#line 967 "sscan.c" +#line 967 "src/sscan.c" while ( /*CONSTCOND*/1 ) /* loops until end-of-file is reached */ { @@ -1018,106 +1018,106 @@ YY_DECL case 1: YY_RULE_SETUP -#line 36 "sscan.l" +#line 36 "src/sscan.l" sphere_yylval.i = (strcmp("-", yytext)) ? (1) : (-1); return SIGN; YY_BREAK case 2: YY_RULE_SETUP -#line 37 "sscan.l" +#line 37 "src/sscan.l" sphere_yylval.i = atoi(yytext); return INT; YY_BREAK case 3: YY_RULE_SETUP -#line 38 "sscan.l" +#line 38 "src/sscan.l" sphere_yylval.d = atof(yytext); return FLOAT; YY_BREAK case 4: YY_RULE_SETUP -#line 39 "sscan.l" +#line 39 "src/sscan.l" memcpy(&sphere_yylval.c[0], yytext, 3); return EULERAXIS; YY_BREAK case 5: YY_RULE_SETUP -#line 40 "sscan.l" +#line 40 "src/sscan.l" return HOUR; YY_BREAK case 6: YY_RULE_SETUP -#line 41 "sscan.l" +#line 41 "src/sscan.l" return DEG; YY_BREAK case 7: YY_RULE_SETUP -#line 42 "sscan.l" +#line 42 "src/sscan.l" return MIN; YY_BREAK case 8: YY_RULE_SETUP -#line 43 "sscan.l" +#line 43 "src/sscan.l" return MIN; YY_BREAK case 9: YY_RULE_SETUP -#line 44 "sscan.l" +#line 44 "src/sscan.l" return SEC; YY_BREAK case 10: YY_RULE_SETUP -#line 45 "sscan.l" +#line 45 "src/sscan.l" return SEC; YY_BREAK case 11: YY_RULE_SETUP -#line 46 "sscan.l" +#line 46 "src/sscan.l" return COMMA; YY_BREAK case 12: YY_RULE_SETUP -#line 47 "sscan.l" +#line 47 "src/sscan.l" return OPENCIRC; YY_BREAK case 13: YY_RULE_SETUP -#line 48 "sscan.l" +#line 48 "src/sscan.l" return CLOSECIRC; YY_BREAK case 14: YY_RULE_SETUP -#line 49 "sscan.l" +#line 49 "src/sscan.l" return OPENPOINT; YY_BREAK case 15: YY_RULE_SETUP -#line 50 "sscan.l" +#line 50 "src/sscan.l" return CLOSEPOINT; YY_BREAK case 16: YY_RULE_SETUP -#line 51 "sscan.l" +#line 51 "src/sscan.l" return OPENARR; YY_BREAK case 17: YY_RULE_SETUP -#line 52 "sscan.l" +#line 52 "src/sscan.l" return CLOSEARR; YY_BREAK case 18: /* rule 18 can match eol */ YY_RULE_SETUP -#line 53 "sscan.l" +#line 53 "src/sscan.l" /* discard spaces */ YY_BREAK case 19: YY_RULE_SETUP -#line 54 "sscan.l" +#line 54 "src/sscan.l" /* alert parser of the garbage */ YY_BREAK case 20: YY_RULE_SETUP -#line 55 "sscan.l" +#line 55 "src/sscan.l" ECHO; YY_BREAK -#line 1121 "sscan.c" +#line 1121 "src/sscan.c" case YY_STATE_EOF(INITIAL): yyterminate(); @@ -2086,6 +2086,6 @@ void yyfree (void * ptr ) #define YYTABLES_NAME "yytables" -#line 55 "sscan.l" +#line 55 "src/sscan.l" From ac1d4ffa6339a79b46dba873f7d1c9d90e101b17 Mon Sep 17 00:00:00 2001 From: Vitaly Davydov Date: Mon, 20 May 2024 16:50:32 +0300 Subject: [PATCH 77/87] Fix build under mingw64 Add TOK_ prefix to INT, FLOAT, SIGN token names to distinguist these names from macro directives under mingw64. --- src/sparse.c | 105 ++++++++++++++++++++++++++------------------------- src/sparse.h | 12 +++--- src/sparse.y | 48 +++++++++++------------ src/sscan.c | 6 +-- src/sscan.l | 6 +-- 5 files changed, 89 insertions(+), 88 deletions(-) diff --git a/src/sparse.c b/src/sparse.c index 9eb7d57..16a65d1 100644 --- a/src/sparse.c +++ b/src/sparse.c @@ -160,9 +160,9 @@ extern int sphere_yydebug; CLOSEPOINT = 266, OPENARR = 267, CLOSEARR = 268, - SIGN = 269, - INT = 270, - FLOAT = 271, + TOK_SIGN = 269, + TOK_INT = 270, + TOK_FLOAT = 271, EULERAXIS = 272 }; #endif @@ -178,9 +178,9 @@ extern int sphere_yydebug; #define CLOSEPOINT 266 #define OPENARR 267 #define CLOSEARR 268 -#define SIGN 269 -#define INT 270 -#define FLOAT 271 +#define TOK_SIGN 269 +#define TOK_INT 270 +#define TOK_FLOAT 271 #define EULERAXIS 272 /* Value type. */ @@ -515,10 +515,11 @@ static const char *const yytname[] = { "$end", "error", "$undefined", "HOUR", "DEG", "MIN", "SEC", "COMMA", "OPENCIRC", "CLOSECIRC", "OPENPOINT", "CLOSEPOINT", "OPENARR", - "CLOSEARR", "SIGN", "INT", "FLOAT", "EULERAXIS", "$accept", "commands", - "command", "number", "angle_lat_us", "angle_long_us", "angle_long", - "angle_lat", "spherepoint", "spherecircle", "eulertrans", "sphereline", - "spherepointlist", "spherepath", "sphereellipse", "spherebox", YY_NULLPTR + "CLOSEARR", "TOK_SIGN", "TOK_INT", "TOK_FLOAT", "EULERAXIS", "$accept", + "commands", "command", "number", "angle_lat_us", "angle_long_us", + "angle_long", "angle_lat", "spherepoint", "spherecircle", "eulertrans", + "sphereline", "spherepointlist", "spherepath", "sphereellipse", + "spherebox", YY_NULLPTR }; #endif @@ -1351,193 +1352,193 @@ yyparse (void) case 4: #line 70 "src/sparse.y" { set_spheretype( STYPE_POINT ); } -#line 1355 "src/sparse.c" +#line 1356 "src/sparse.c" break; case 5: #line 71 "src/sparse.y" { set_spheretype( STYPE_CIRCLE ); } -#line 1361 "src/sparse.c" +#line 1362 "src/sparse.c" break; case 6: #line 72 "src/sparse.y" { set_spheretype( STYPE_LINE ); } -#line 1367 "src/sparse.c" +#line 1368 "src/sparse.c" break; case 7: #line 73 "src/sparse.y" { set_spheretype( STYPE_EULER ); } -#line 1373 "src/sparse.c" +#line 1374 "src/sparse.c" break; case 8: #line 74 "src/sparse.y" { set_spheretype( STYPE_PATH ); } -#line 1379 "src/sparse.c" +#line 1380 "src/sparse.c" break; case 9: #line 75 "src/sparse.y" { set_spheretype( STYPE_ELLIPSE ); } -#line 1385 "src/sparse.c" +#line 1386 "src/sparse.c" break; case 10: #line 76 "src/sparse.y" { set_spheretype( STYPE_BOX ); } -#line 1391 "src/sparse.c" +#line 1392 "src/sparse.c" break; case 11: #line 81 "src/sparse.y" { (yyval.d) = (yyvsp[0].d); } -#line 1397 "src/sparse.c" +#line 1398 "src/sparse.c" break; case 12: #line 82 "src/sparse.y" { (yyval.d) = (yyvsp[0].i); } -#line 1403 "src/sparse.c" +#line 1404 "src/sparse.c" break; case 13: #line 87 "src/sparse.y" { (yyval.i) = set_angle(0, (yyvsp[0].d) ); } -#line 1409 "src/sparse.c" +#line 1410 "src/sparse.c" break; case 14: #line 88 "src/sparse.y" { (yyval.i) = set_angle(1, human2dec((yyvsp[-1].d), 0, 0) ); } -#line 1415 "src/sparse.c" +#line 1416 "src/sparse.c" break; case 15: #line 89 "src/sparse.y" { (yyval.i) = set_angle(1, human2dec((yyvsp[-1].i), 0, 0) ); } -#line 1421 "src/sparse.c" +#line 1422 "src/sparse.c" break; case 16: #line 90 "src/sparse.y" { (yyval.i) = set_angle(1, human2dec((yyvsp[-2].i), (yyvsp[0].d), 0) ); } -#line 1427 "src/sparse.c" +#line 1428 "src/sparse.c" break; case 17: #line 91 "src/sparse.y" { (yyval.i) = set_angle(1, human2dec((yyvsp[-3].i), (yyvsp[-1].d), 0) ); } -#line 1433 "src/sparse.c" +#line 1434 "src/sparse.c" break; case 18: #line 92 "src/sparse.y" { (yyval.i) = set_angle(1, human2dec((yyvsp[-3].i), (yyvsp[-1].i), 0) ); } -#line 1439 "src/sparse.c" +#line 1440 "src/sparse.c" break; case 19: #line 93 "src/sparse.y" { (yyval.i) = set_angle(1, human2dec((yyvsp[-4].i), (yyvsp[-2].i), (yyvsp[0].d)) ); } -#line 1445 "src/sparse.c" +#line 1446 "src/sparse.c" break; case 20: #line 94 "src/sparse.y" { (yyval.i) = set_angle(1, human2dec((yyvsp[-5].i), (yyvsp[-3].i), (yyvsp[-1].d)) ); } -#line 1451 "src/sparse.c" +#line 1452 "src/sparse.c" break; case 21: #line 99 "src/sparse.y" { (yyval.i) = set_angle(0, (yyvsp[0].d)); } -#line 1457 "src/sparse.c" +#line 1458 "src/sparse.c" break; case 22: #line 100 "src/sparse.y" { (yyval.i) = set_angle(1, human2dec((yyvsp[-1].d), 0, 0)); } -#line 1463 "src/sparse.c" +#line 1464 "src/sparse.c" break; case 23: #line 101 "src/sparse.y" { (yyval.i) = set_angle(1, human2dec((yyvsp[-1].i), 0, 0)); } -#line 1469 "src/sparse.c" +#line 1470 "src/sparse.c" break; case 24: #line 102 "src/sparse.y" { (yyval.i) = set_angle(1, human2dec((yyvsp[-2].i), (yyvsp[0].d), 0)); } -#line 1475 "src/sparse.c" +#line 1476 "src/sparse.c" break; case 25: #line 103 "src/sparse.y" { (yyval.i) = set_angle(1, human2dec((yyvsp[-3].i), (yyvsp[-1].d), 0)); } -#line 1481 "src/sparse.c" +#line 1482 "src/sparse.c" break; case 26: #line 104 "src/sparse.y" { (yyval.i) = set_angle(1, human2dec((yyvsp[-3].i), (yyvsp[-1].i), 0)); } -#line 1487 "src/sparse.c" +#line 1488 "src/sparse.c" break; case 27: #line 105 "src/sparse.y" { (yyval.i) = set_angle(1, human2dec((yyvsp[-4].i), (yyvsp[-2].i), (yyvsp[0].d))); } -#line 1493 "src/sparse.c" +#line 1494 "src/sparse.c" break; case 28: #line 106 "src/sparse.y" { (yyval.i) = set_angle(1, human2dec((yyvsp[-5].i), (yyvsp[-3].i), (yyvsp[-1].d))); } -#line 1499 "src/sparse.c" +#line 1500 "src/sparse.c" break; case 29: #line 107 "src/sparse.y" { (yyval.i) = set_angle(1, 15 * human2dec((yyvsp[-2].i), (yyvsp[0].d), 0)); } -#line 1505 "src/sparse.c" +#line 1506 "src/sparse.c" break; case 30: #line 108 "src/sparse.y" { (yyval.i) = set_angle(1, 15 * human2dec((yyvsp[-4].i), (yyvsp[-2].i), (yyvsp[0].d))); } -#line 1511 "src/sparse.c" +#line 1512 "src/sparse.c" break; case 31: #line 109 "src/sparse.y" { (yyval.i) = set_angle(1, 15 * human2dec((yyvsp[-5].i), (yyvsp[-3].i), (yyvsp[-1].d))); } -#line 1517 "src/sparse.c" +#line 1518 "src/sparse.c" break; case 32: #line 114 "src/sparse.y" { (yyval.i) = set_angle_sign((yyvsp[0].i), 1); } -#line 1523 "src/sparse.c" +#line 1524 "src/sparse.c" break; case 33: #line 115 "src/sparse.y" { (yyval.i) = set_angle_sign((yyvsp[0].i), (yyvsp[-1].i)); } -#line 1529 "src/sparse.c" +#line 1530 "src/sparse.c" break; case 34: #line 120 "src/sparse.y" { (yyval.i) = set_angle_sign((yyvsp[0].i), 1); } -#line 1535 "src/sparse.c" +#line 1536 "src/sparse.c" break; case 35: #line 121 "src/sparse.y" { (yyval.i) = set_angle_sign((yyvsp[0].i), (yyvsp[-1].i)); } -#line 1541 "src/sparse.c" +#line 1542 "src/sparse.c" break; case 36: @@ -1545,7 +1546,7 @@ yyparse (void) { (yyval.i) = set_point((yyvsp[-3].i), (yyvsp[-1].i)); } -#line 1549 "src/sparse.c" +#line 1550 "src/sparse.c" break; case 37: @@ -1553,7 +1554,7 @@ yyparse (void) { set_circle((yyvsp[-3].i), (yyvsp[-1].i)); } -#line 1557 "src/sparse.c" +#line 1558 "src/sparse.c" break; case 38: @@ -1561,7 +1562,7 @@ yyparse (void) { set_euler((yyvsp[-4].i), (yyvsp[-2].i), (yyvsp[0].i), "ZXZ"); } -#line 1565 "src/sparse.c" +#line 1566 "src/sparse.c" break; case 39: @@ -1569,7 +1570,7 @@ yyparse (void) { set_euler((yyvsp[-6].i), (yyvsp[-4].i), (yyvsp[-2].i), (yyvsp[0].c)); } -#line 1573 "src/sparse.c" +#line 1574 "src/sparse.c" break; case 40: @@ -1577,13 +1578,13 @@ yyparse (void) { set_line ((yyvsp[0].i)); } -#line 1581 "src/sparse.c" +#line 1582 "src/sparse.c" break; case 43: #line 168 "src/sparse.y" { } -#line 1587 "src/sparse.c" +#line 1588 "src/sparse.c" break; case 44: @@ -1591,23 +1592,23 @@ yyparse (void) { set_ellipse((yyvsp[-8].i), (yyvsp[-6].i), (yyvsp[-3].i), (yyvsp[-1].i)); } -#line 1595 "src/sparse.c" +#line 1596 "src/sparse.c" break; case 45: #line 181 "src/sparse.y" { } -#line 1601 "src/sparse.c" +#line 1602 "src/sparse.c" break; case 46: #line 182 "src/sparse.y" { } -#line 1607 "src/sparse.c" +#line 1608 "src/sparse.c" break; -#line 1611 "src/sparse.c" +#line 1612 "src/sparse.c" default: break; } diff --git a/src/sparse.h b/src/sparse.h index e6a1000..c6607ba 100644 --- a/src/sparse.h +++ b/src/sparse.h @@ -60,9 +60,9 @@ extern int sphere_yydebug; CLOSEPOINT = 266, OPENARR = 267, CLOSEARR = 268, - SIGN = 269, - INT = 270, - FLOAT = 271, + TOK_SIGN = 269, + TOK_INT = 270, + TOK_FLOAT = 271, EULERAXIS = 272 }; #endif @@ -78,9 +78,9 @@ extern int sphere_yydebug; #define CLOSEPOINT 266 #define OPENARR 267 #define CLOSEARR 268 -#define SIGN 269 -#define INT 270 -#define FLOAT 271 +#define TOK_SIGN 269 +#define TOK_INT 270 +#define TOK_FLOAT 271 #define EULERAXIS 272 /* Value type. */ diff --git a/src/sparse.y b/src/sparse.y index 22e8778..0b65d9f 100644 --- a/src/sparse.y +++ b/src/sparse.y @@ -44,9 +44,9 @@ static double human2dec(double d, double m, double s) char c[3]; } -%token SIGN -%token INT -%token FLOAT +%token TOK_SIGN +%token TOK_INT +%token TOK_FLOAT %token EULERAXIS %left COMMA @@ -78,47 +78,47 @@ command: /* unsigned number */ number : - FLOAT { $$ = $1; } - | INT { $$ = $1; } + TOK_FLOAT { $$ = $1; } + | TOK_INT { $$ = $1; } ; /* unsigned longitude */ angle_lat_us : number { $$ = set_angle(0, $1 ); } - | FLOAT DEG { $$ = set_angle(1, human2dec($1, 0, 0) ); } - | INT DEG { $$ = set_angle(1, human2dec($1, 0, 0) ); } - | INT DEG number { $$ = set_angle(1, human2dec($1, $3, 0) ); } - | INT DEG FLOAT MIN { $$ = set_angle(1, human2dec($1, $3, 0) ); } - | INT DEG INT MIN { $$ = set_angle(1, human2dec($1, $3, 0) ); } - | INT DEG INT MIN number { $$ = set_angle(1, human2dec($1, $3, $5) ); } - | INT DEG INT MIN number SEC { $$ = set_angle(1, human2dec($1, $3, $5) ); } + | TOK_FLOAT DEG { $$ = set_angle(1, human2dec($1, 0, 0) ); } + | TOK_INT DEG { $$ = set_angle(1, human2dec($1, 0, 0) ); } + | TOK_INT DEG number { $$ = set_angle(1, human2dec($1, $3, 0) ); } + | TOK_INT DEG TOK_FLOAT MIN { $$ = set_angle(1, human2dec($1, $3, 0) ); } + | TOK_INT DEG TOK_INT MIN { $$ = set_angle(1, human2dec($1, $3, 0) ); } + | TOK_INT DEG TOK_INT MIN number { $$ = set_angle(1, human2dec($1, $3, $5) ); } + | TOK_INT DEG TOK_INT MIN number SEC { $$ = set_angle(1, human2dec($1, $3, $5) ); } ; /* unsigned latitude */ angle_long_us : number { $$ = set_angle(0, $1); } - | FLOAT DEG { $$ = set_angle(1, human2dec($1, 0, 0)); } - | INT DEG { $$ = set_angle(1, human2dec($1, 0, 0)); } - | INT DEG number { $$ = set_angle(1, human2dec($1, $3, 0)); } - | INT DEG FLOAT MIN { $$ = set_angle(1, human2dec($1, $3, 0)); } - | INT DEG INT MIN { $$ = set_angle(1, human2dec($1, $3, 0)); } - | INT DEG INT MIN number { $$ = set_angle(1, human2dec($1, $3, $5)); } - | INT DEG INT MIN number SEC { $$ = set_angle(1, human2dec($1, $3, $5)); } - | INT HOUR number { $$ = set_angle(1, 15 * human2dec($1, $3, 0)); } - | INT HOUR INT MIN number { $$ = set_angle(1, 15 * human2dec($1, $3, $5)); } - | INT HOUR INT MIN number SEC { $$ = set_angle(1, 15 * human2dec($1, $3, $5)); } + | TOK_FLOAT DEG { $$ = set_angle(1, human2dec($1, 0, 0)); } + | TOK_INT DEG { $$ = set_angle(1, human2dec($1, 0, 0)); } + | TOK_INT DEG number { $$ = set_angle(1, human2dec($1, $3, 0)); } + | TOK_INT DEG TOK_FLOAT MIN { $$ = set_angle(1, human2dec($1, $3, 0)); } + | TOK_INT DEG TOK_INT MIN { $$ = set_angle(1, human2dec($1, $3, 0)); } + | TOK_INT DEG TOK_INT MIN number { $$ = set_angle(1, human2dec($1, $3, $5)); } + | TOK_INT DEG TOK_INT MIN number SEC { $$ = set_angle(1, human2dec($1, $3, $5)); } + | TOK_INT HOUR number { $$ = set_angle(1, 15 * human2dec($1, $3, 0)); } + | TOK_INT HOUR TOK_INT MIN number { $$ = set_angle(1, 15 * human2dec($1, $3, $5)); } + | TOK_INT HOUR TOK_INT MIN number SEC { $$ = set_angle(1, 15 * human2dec($1, $3, $5)); } ; /* longitude */ angle_long : angle_long_us { $$ = set_angle_sign($1, 1); } - | SIGN angle_long_us { $$ = set_angle_sign($2, $1); } + | TOK_SIGN angle_long_us { $$ = set_angle_sign($2, $1); } ; /* latitude */ angle_lat : angle_lat_us { $$ = set_angle_sign($1, 1); } - | SIGN angle_lat_us { $$ = set_angle_sign($2, $1); } + | TOK_SIGN angle_lat_us { $$ = set_angle_sign($2, $1); } ; diff --git a/src/sscan.c b/src/sscan.c index 0df711e..50e0e70 100644 --- a/src/sscan.c +++ b/src/sscan.c @@ -1019,17 +1019,17 @@ YY_DECL case 1: YY_RULE_SETUP #line 36 "src/sscan.l" -sphere_yylval.i = (strcmp("-", yytext)) ? (1) : (-1); return SIGN; +sphere_yylval.i = (strcmp("-", yytext)) ? (1) : (-1); return TOK_SIGN; YY_BREAK case 2: YY_RULE_SETUP #line 37 "src/sscan.l" -sphere_yylval.i = atoi(yytext); return INT; +sphere_yylval.i = atoi(yytext); return TOK_INT; YY_BREAK case 3: YY_RULE_SETUP #line 38 "src/sscan.l" -sphere_yylval.d = atof(yytext); return FLOAT; +sphere_yylval.d = atof(yytext); return TOK_FLOAT; YY_BREAK case 4: YY_RULE_SETUP diff --git a/src/sscan.l b/src/sscan.l index 99bd8ac..d3103b6 100644 --- a/src/sscan.l +++ b/src/sscan.l @@ -33,9 +33,9 @@ real ({int})?\.({int}) float ({int}|{real})([eE]{sign}{int})? %% -{sign} sphere_yylval.i = (strcmp("-", yytext)) ? (1) : (-1); return SIGN; -{int} sphere_yylval.i = atoi(yytext); return INT; -{float} sphere_yylval.d = atof(yytext); return FLOAT; +{sign} sphere_yylval.i = (strcmp("-", yytext)) ? (1) : (-1); return TOK_SIGN; +{int} sphere_yylval.i = atoi(yytext); return TOK_INT; +{float} sphere_yylval.d = atof(yytext); return TOK_FLOAT; [x-zX-Z]{3} memcpy(&sphere_yylval.c[0], yytext, 3); return EULERAXIS; h return HOUR; d return DEG; From 06074880bfff8024e269abf297794ccb04f82a84 Mon Sep 17 00:00:00 2001 From: Vitaly Davydov Date: Sat, 25 May 2024 17:29:15 +0300 Subject: [PATCH 78/87] Bump version up to 1.5.2 --- Makefile | 3 +++ Makefile.common.mk | 2 +- expected/version.out | 2 +- pg_sphere.control | 2 +- upgrade_scripts/pg_sphere--1.5.1--1.5.2.sql.in | 2 ++ 5 files changed, 8 insertions(+), 3 deletions(-) create mode 100644 upgrade_scripts/pg_sphere--1.5.1--1.5.2.sql.in diff --git a/Makefile b/Makefile index 78f2dc5..782961c 100644 --- a/Makefile +++ b/Makefile @@ -218,6 +218,9 @@ pg_sphere--1.4.2--1.5.0.sql: pg_sphere--1.5.0--1.5.1.sql: cat upgrade_scripts/$@.in $^ > $@ +pg_sphere--1.5.1--1.5.2.sql: + cat upgrade_scripts/$@.in $^ > $@ + # end of local stuff src/sscan.o : src/sparse.c diff --git a/Makefile.common.mk b/Makefile.common.mk index be82047..8963227 100644 --- a/Makefile.common.mk +++ b/Makefile.common.mk @@ -5,4 +5,4 @@ #---------------------------------------------------------------------------- EXTENSION := pg_sphere -PGSPHERE_VERSION := 1.5.1 +PGSPHERE_VERSION := 1.5.2 diff --git a/expected/version.out b/expected/version.out index ffad8f5..c1f0efe 100644 --- a/expected/version.out +++ b/expected/version.out @@ -2,6 +2,6 @@ SELECT pg_sphere_version(); pg_sphere_version ------------------- - 1.5.1 + 1.5.2 (1 row) diff --git a/pg_sphere.control b/pg_sphere.control index 1e73251..85f7589 100644 --- a/pg_sphere.control +++ b/pg_sphere.control @@ -1,5 +1,5 @@ # pg_sphere extension comment = 'spherical objects with useful functions, operators and index support' -default_version = '1.5.1' +default_version = '1.5.2' module_pathname = '$libdir/pg_sphere' relocatable = true diff --git a/upgrade_scripts/pg_sphere--1.5.1--1.5.2.sql.in b/upgrade_scripts/pg_sphere--1.5.1--1.5.2.sql.in new file mode 100644 index 0000000..3ff6a66 --- /dev/null +++ b/upgrade_scripts/pg_sphere--1.5.1--1.5.2.sql.in @@ -0,0 +1,2 @@ +-- Upgrade: 1.5.1 -> 1.5.2 +-- Nothing to do yet From e1dee2488847482d9cee29b6ff07a5e127c1cedb Mon Sep 17 00:00:00 2001 From: Markus Demleitner Date: Wed, 15 May 2024 15:35:20 +0200 Subject: [PATCH 79/87] Now more carefully nulling out null inputs in epoch_prop. This is so we do not invent values for pm, parallax, or rv. We are actually a bit over-cautious and invalidate both PMs even if only one is missing. This is because PMs mix, and hence there are traces of the invented 0 in the other component of the PM. Similarly, when the parallax is missing or bad, the RV would be heavily contaminated; in these cases, we copy through the original RV, as it may still be useful and certainly will not be grossly wrong. (sorry about a few whitespace diffs introduced by killing trailing whitespace in sql/epochprop.sql and src/epochprop.c) --- doc/functions.sgm | 9 ++++-- expected/epochprop.out | 62 +++++++++++++++++++++--------------------- sql/epochprop.sql | 26 +++++++++--------- src/epochprop.c | 37 +++++++++++++++---------- src/epochprop.h | 11 +------- 5 files changed, 73 insertions(+), 72 deletions(-) diff --git a/doc/functions.sgm b/doc/functions.sgm index 232b755..047b7f1 100644 --- a/doc/functions.sgm +++ b/doc/functions.sgm @@ -867,9 +867,12 @@ It is an error to have either pos or delta_t NULL. For all other arguments, NULLs are turned into 0s, except for parallax, - where some very small default is put in. In that case, - both parallax and radial_velocity will be NULL in the output - array. + where some very small default is put in. Whatever is NULL + on the input is NULL on the output. In addition, we null + out a non-NULL input on one component of the proper motion + if the other component is NULL, and we null out the radial + velocity if the parallax is missing, as it would be horribly + off with the propagation algorithm we use here. diff --git a/expected/epochprop.out b/expected/epochprop.out index 3a52832..1111f1a 100644 --- a/expected/epochprop.out +++ b/expected/epochprop.out @@ -1,5 +1,5 @@ -SET extra_float_digits = 2; -SELECT +SET extra_float_digits = 1; +SELECT to_char(DEGREES(tp[1]), '999D9999999999'), to_char(DEGREES(tp[2]), '999D9999999999'), to_char(tp[3], '999D999'), @@ -7,7 +7,7 @@ SELECT to_char(DEGREES(tp[5])*3.6e6, '99999D999'), to_char(tp[6], '999D999') FROM ( - SELECT epoch_prop(spoint(radians(269.45207695), radians(4.693364966)), + SELECT epoch_prop(spoint(radians(269.45207695), radians(4.693364966)), 546.9759, RADIANS(-801.551/3.6e6), RADIANS(10362/3.6e6), -110, -100) AS tp) AS q; @@ -16,7 +16,7 @@ FROM ( 269.4742714391 | 4.4072939987 | 543.624 | -791.442 | 10235.412 | -110.450 (1 row) -SELECT +SELECT to_char(DEGREES(tp[1]), '999D9999999999'), to_char(DEGREES(tp[2]), '999D9999999999'), to_char(tp[3], '999D999'), @@ -24,16 +24,16 @@ SELECT to_char(DEGREES(tp[5])*3.6e6, '99999D999'), to_char(tp[6], '999D999') FROM ( - SELECT epoch_prop(spoint(radians(269.45207695), radians(4.693364966)), + SELECT epoch_prop(spoint(radians(269.45207695), radians(4.693364966)), 0, RADIANS(-801.551/3.6e6), RADIANS(10362/3.6e6), -110, -100) AS tp) AS q; - to_char | to_char | to_char | to_char | to_char | to_char ------------------+-----------------+---------+----------+------------+--------- - 269.4744079540 | 4.4055337210 | | -801.210 | 10361.762 | + to_char | to_char | to_char | to_char | to_char | to_char +-----------------+-----------------+----------+----------+------------+---------- + 269.4744079540 | 4.4055337210 | .000 | -801.210 | 10361.762 | -110.000 (1 row) -SELECT +SELECT to_char(DEGREES(tp[1]), '999D9999999999'), to_char(DEGREES(tp[2]), '999D9999999999'), to_char(tp[3], '999D999'), @@ -41,16 +41,16 @@ SELECT to_char(DEGREES(tp[5])*3.6e6, '99999D999'), to_char(tp[6], '999D999') FROM ( - SELECT epoch_prop(spoint(radians(269.45207695), radians(4.693364966)), + SELECT epoch_prop(spoint(radians(269.45207695), radians(4.693364966)), NULL, RADIANS(-801.551/3.6e6), RADIANS(10362/3.6e6), -110, -100) AS tp) AS q; - to_char | to_char | to_char | to_char | to_char | to_char ------------------+-----------------+---------+----------+------------+--------- - 269.4744079540 | 4.4055337210 | | -801.210 | 10361.762 | + to_char | to_char | to_char | to_char | to_char | to_char +-----------------+-----------------+---------+----------+------------+---------- + 269.4744079540 | 4.4055337210 | | -801.210 | 10361.762 | -110.000 (1 row) -SELECT +SELECT to_char(DEGREES(tp[1]), '999D9999999999'), to_char(DEGREES(tp[2]), '999D9999999999'), to_char(tp[3], '999D999'), @@ -58,16 +58,16 @@ SELECT to_char(DEGREES(tp[5])*3.6e6, '99999D999'), to_char(tp[6], '999D999') FROM ( - SELECT epoch_prop(spoint(radians(269.45207695), radians(4.693364966)), + SELECT epoch_prop(spoint(radians(269.45207695), radians(4.693364966)), 23, RADIANS(-801.551/3.6e6), RADIANS(10362/3.6e6), NULL, 20) AS tp) AS q; - to_char | to_char | to_char | to_char | to_char | to_char ------------------+-----------------+----------+----------+------------+---------- - 269.4476085384 | 4.7509315989 | 23.000 | -801.617 | 10361.984 | 2.159 + to_char | to_char | to_char | to_char | to_char | to_char +-----------------+-----------------+----------+----------+------------+--------- + 269.4476085384 | 4.7509315989 | 23.000 | -801.617 | 10361.984 | (1 row) -SELECT +SELECT to_char(DEGREES(tp[1]), '999D9999999999'), to_char(DEGREES(tp[2]), '999D9999999999'), to_char(tp[3], '999D999'), @@ -75,13 +75,13 @@ SELECT to_char(DEGREES(tp[5])*3.6e6, '99999D999'), to_char(tp[6], '999D999') FROM ( - SELECT epoch_prop(spoint(radians(269.45207695), radians(4.693364966)), + SELECT epoch_prop(spoint(radians(269.45207695), radians(4.693364966)), 23, NULL, RADIANS(10362/3.6e6), -110, 120) AS tp) AS q; - to_char | to_char | to_char | to_char | to_char | to_char ------------------+-----------------+----------+----------+------------+---------- - 269.4520769500 | 5.0388680565 | 23.007 | -.000 | 10368.061 | -97.120 + to_char | to_char | to_char | to_char | to_char | to_char +-----------------+-----------------+----------+---------+---------+---------- + 269.4520769500 | 4.6933649660 | 23.007 | | | -110.000 (1 row) SELECT epoch_prop(NULL, @@ -89,20 +89,20 @@ SELECT epoch_prop(NULL, 0.01 , RADIANS(10362/3.6e6), -110, 120); ERROR: NULL position not supported in epoch propagation -SELECT epoch_prop_pos(spoint(radians(269.45207695), radians(4.693364966)), +SELECT epoch_prop_pos(spoint(radians(269.45207695), radians(4.693364966)), 23, RADIANS(-801.551/3.6e6), RADIANS(10362/3.6e6), -110, 20) AS tp; - tp ---------------------------------------------- - (4.7027479265831289 , 0.082919450934599334) + tp +------------------------------------------- + (4.702747926583129 , 0.08291945093459933) (1 row) -SELECT epoch_prop_pos(spoint(radians(269.45207695), radians(4.693364966)), +SELECT epoch_prop_pos(spoint(radians(269.45207695), radians(4.693364966)), RADIANS(-801.551/3.6e6), RADIANS(10362/3.6e6), 20) AS tp; - tp ---------------------------------------------- - (4.7027479306195161 , 0.082919398938087627) + tp +------------------------------------------- + (4.702747930619516 , 0.08291939893808763) (1 row) diff --git a/sql/epochprop.sql b/sql/epochprop.sql index d8ae2b7..a6c69dd 100644 --- a/sql/epochprop.sql +++ b/sql/epochprop.sql @@ -1,6 +1,6 @@ -SET extra_float_digits = 2; +SET extra_float_digits = 1; -SELECT +SELECT to_char(DEGREES(tp[1]), '999D9999999999'), to_char(DEGREES(tp[2]), '999D9999999999'), to_char(tp[3], '999D999'), @@ -8,12 +8,12 @@ SELECT to_char(DEGREES(tp[5])*3.6e6, '99999D999'), to_char(tp[6], '999D999') FROM ( - SELECT epoch_prop(spoint(radians(269.45207695), radians(4.693364966)), + SELECT epoch_prop(spoint(radians(269.45207695), radians(4.693364966)), 546.9759, RADIANS(-801.551/3.6e6), RADIANS(10362/3.6e6), -110, -100) AS tp) AS q; -SELECT +SELECT to_char(DEGREES(tp[1]), '999D9999999999'), to_char(DEGREES(tp[2]), '999D9999999999'), to_char(tp[3], '999D999'), @@ -21,12 +21,12 @@ SELECT to_char(DEGREES(tp[5])*3.6e6, '99999D999'), to_char(tp[6], '999D999') FROM ( - SELECT epoch_prop(spoint(radians(269.45207695), radians(4.693364966)), + SELECT epoch_prop(spoint(radians(269.45207695), radians(4.693364966)), 0, RADIANS(-801.551/3.6e6), RADIANS(10362/3.6e6), -110, -100) AS tp) AS q; -SELECT +SELECT to_char(DEGREES(tp[1]), '999D9999999999'), to_char(DEGREES(tp[2]), '999D9999999999'), to_char(tp[3], '999D999'), @@ -34,12 +34,12 @@ SELECT to_char(DEGREES(tp[5])*3.6e6, '99999D999'), to_char(tp[6], '999D999') FROM ( - SELECT epoch_prop(spoint(radians(269.45207695), radians(4.693364966)), + SELECT epoch_prop(spoint(radians(269.45207695), radians(4.693364966)), NULL, RADIANS(-801.551/3.6e6), RADIANS(10362/3.6e6), -110, -100) AS tp) AS q; -SELECT +SELECT to_char(DEGREES(tp[1]), '999D9999999999'), to_char(DEGREES(tp[2]), '999D9999999999'), to_char(tp[3], '999D999'), @@ -47,12 +47,12 @@ SELECT to_char(DEGREES(tp[5])*3.6e6, '99999D999'), to_char(tp[6], '999D999') FROM ( - SELECT epoch_prop(spoint(radians(269.45207695), radians(4.693364966)), + SELECT epoch_prop(spoint(radians(269.45207695), radians(4.693364966)), 23, RADIANS(-801.551/3.6e6), RADIANS(10362/3.6e6), NULL, 20) AS tp) AS q; -SELECT +SELECT to_char(DEGREES(tp[1]), '999D9999999999'), to_char(DEGREES(tp[2]), '999D9999999999'), to_char(tp[3], '999D999'), @@ -60,7 +60,7 @@ SELECT to_char(DEGREES(tp[5])*3.6e6, '99999D999'), to_char(tp[6], '999D999') FROM ( - SELECT epoch_prop(spoint(radians(269.45207695), radians(4.693364966)), + SELECT epoch_prop(spoint(radians(269.45207695), radians(4.693364966)), 23, NULL, RADIANS(10362/3.6e6), -110, 120) AS tp) AS q; @@ -70,11 +70,11 @@ SELECT epoch_prop(NULL, 0.01 , RADIANS(10362/3.6e6), -110, 120); -SELECT epoch_prop_pos(spoint(radians(269.45207695), radians(4.693364966)), +SELECT epoch_prop_pos(spoint(radians(269.45207695), radians(4.693364966)), 23, RADIANS(-801.551/3.6e6), RADIANS(10362/3.6e6), -110, 20) AS tp; -SELECT epoch_prop_pos(spoint(radians(269.45207695), radians(4.693364966)), +SELECT epoch_prop_pos(spoint(radians(269.45207695), radians(4.693364966)), RADIANS(-801.551/3.6e6), RADIANS(10362/3.6e6), 20) AS tp; diff --git a/src/epochprop.c b/src/epochprop.c index ab9abc8..12ad621 100644 --- a/src/epochprop.c +++ b/src/epochprop.c @@ -133,6 +133,7 @@ epoch_prop(PG_FUNCTION_ARGS) { phasevec input, output; ArrayType *result; Datum retvals[6]; + bool output_null[6] = {0, 0, 0, 0, 0, 0}; if (PG_ARGISNULL(0)) { ereport(ERROR, @@ -141,25 +142,29 @@ epoch_prop(PG_FUNCTION_ARGS) { memcpy(&(input.pos), (void*)PG_GETARG_POINTER(0), sizeof(SPoint)); if (PG_ARGISNULL(1)) { input.parallax = 0; + output_null[2] = 1; + /* The way we do our computation, with a bad parallax the RV + will be horribly off, too, so null this out, too; if avaialble, + we will fiddle in the original RV below again. */ + output_null[5] = 1; } else { input.parallax = PG_GETARG_FLOAT8(1); } input.parallax_valid = fabs(input.parallax) > PX_MIN; - - if (PG_ARGISNULL(2)) { - input.pm[0] = 0; - } else { - input.pm[0] = PG_GETARG_FLOAT8(2); - } - if (PG_ARGISNULL(3)) { + if (PG_ARGISNULL(2) || PG_ARGISNULL(3)) { + input.pm[0] = 0; input.pm[1] = 0; + output_null[3] = 1; + output_null[4] = 1; } else { + input.pm[0] = PG_GETARG_FLOAT8(2); input.pm[1] = PG_GETARG_FLOAT8(3); } if (PG_ARGISNULL(4)) { input.rv = 0; + output_null[5] = 1; } else { input.rv = PG_GETARG_FLOAT8(4); } @@ -172,6 +177,15 @@ epoch_prop(PG_FUNCTION_ARGS) { propagate_phasevec(&input, delta_t, &output); + /* If we have an invalid parallax but a good RV, preserve the original, + untransformed RV on output. See + https://github.com/ivoa-std/udf-catalogue/pull/20#issuecomment-2115053757 + for the rationale. */ + if (!PG_ARGISNULL(4) && !input.parallax_valid) { + output_null[5] = 0; + output.rv = input.rv; + } + /* change to internal units: rad, rad/yr, mas, and km/s */ retvals[0] = Float8GetDatum(output.pos.lng); retvals[1] = Float8GetDatum(output.pos.lat); @@ -181,7 +195,6 @@ epoch_prop(PG_FUNCTION_ARGS) { retvals[5] = Float8GetDatum(output.rv); { - bool isnull[6] = {0, 0, 0, 0, 0, 0}; int lower_bounds[1] = {1}; int dims[1] = {6}; #ifdef USE_FLOAT8_BYVAL @@ -190,13 +203,7 @@ epoch_prop(PG_FUNCTION_ARGS) { bool embyval = false; #endif - if (! output.parallax_valid) { - /* invalidate parallax and rv */ - isnull[2] = 1; - isnull[5] = 1; - } - - result = construct_md_array(retvals, isnull, 1, dims, lower_bounds, + result = construct_md_array(retvals, output_null, 1, dims, lower_bounds, FLOAT8OID, sizeof(float8), embyval, 'd'); } PG_RETURN_ARRAYTYPE_P(result); diff --git a/src/epochprop.h b/src/epochprop.h index a93e4c3..3b61a02 100644 --- a/src/epochprop.h +++ b/src/epochprop.h @@ -6,15 +6,6 @@ extern Datum epoch_prop(PG_FUNCTION_ARGS); -/* a cartesian point; this is like geo_decl's point, but you can't -have both geo_decls and pg_sphere right now (both define a type Point, -not to mention they have different ideas on EPSILON */ -typedef struct s_cpoint -{ - double x, - y; -} CPoint; - typedef struct s_phasevec { SPoint pos; /* Position as an SPoint */ @@ -22,5 +13,5 @@ typedef struct s_phasevec * longitude has cos(lat) applied */ double parallax; /* in rad */ double rv; /* radial velocity in km/s */ - int parallax_valid; /* 1 if the parallax really is a NULL */ + int parallax_valid; /* 1 if we accept the parallax as physical */ } phasevec; From adda8984d20fa13d7b017c59e76a3e5ac905264c Mon Sep 17 00:00:00 2001 From: Ed Sabol Date: Sun, 2 Jun 2024 15:52:30 -0400 Subject: [PATCH 80/87] Issue #125: Add PostgreSQL 17 builds to CI workflow This merge request addresses issue #125 by updating the GitHub Actions CI workflow to build and test on PostrgeSQL 17. --- .github/workflows/build-and-check.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/build-and-check.yml b/.github/workflows/build-and-check.yml index a4247b8..f7633b5 100644 --- a/.github/workflows/build-and-check.yml +++ b/.github/workflows/build-and-check.yml @@ -12,7 +12,7 @@ jobs: strategy: fail-fast: false matrix: - pg_version: [10, 11, 12, 13, 14, 15, 16] + pg_version: [10, 11, 12, 13, 14, 15, 16, 17] use_healpix: [0, 1] name: PostgreSQL ${{ matrix.pg_version }} - USE_HEALPIX=${{ matrix.use_healpix }} @@ -29,7 +29,7 @@ jobs: xsltproc \ fop - - name: Install Postgres + - name: Install PostgreSQL run: sudo /usr/share/postgresql-common/pgdg/apt.postgresql.org.sh -p -v ${{ matrix.pg_version }} -i - name: Clone pgSphere From bd5915ad7a06f2494dedc6f6fc44999a5002e100 Mon Sep 17 00:00:00 2001 From: Vitaly Davydov Date: Mon, 14 Oct 2024 16:00:57 +0300 Subject: [PATCH 81/87] Enable manual run of the build workflow --- .github/workflows/build-and-check.yml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/.github/workflows/build-and-check.yml b/.github/workflows/build-and-check.yml index f7633b5..6038637 100644 --- a/.github/workflows/build-and-check.yml +++ b/.github/workflows/build-and-check.yml @@ -3,6 +3,9 @@ name: Build and Check on: push: pull_request: + workflow_dispatch: + schedule: + - cron: '0 0 * * 5' jobs: build_and_test: From dcdc52ff2866c2abe13951b9f257c118d2d4bcb8 Mon Sep 17 00:00:00 2001 From: Ed Sabol Date: Tue, 15 Oct 2024 15:51:30 -0400 Subject: [PATCH 82/87] Update actions/upload-artifact version in CI workflow This PR updates the version number on `actions/upload-artifact` in `.github/workflows/build-and-check.yml` in order to silence the following warning: > The following actions use a deprecated Node.js version and will be forced to run on node20: actions/upload-artifact@v3. For more info: https://github.blog/changelog/2024-03-07-github-actions-all-actions-will-run-on-node20-instead-of-node16-by-default/ https://github.com/actions/upload-artifact says: > actions/upload-artifact@v3 is scheduled for deprecation on November 30, 2024. [Learn more.](https://github.blog/changelog/2024-04-16-deprecation-notice-v3-of-the-artifact-actions/) Similarly, v1/v2 are scheduled for deprecation on June 30, 2024. Please update your workflow to use v4 of the artifact actions. This deprecation will not impact any existing versions of GitHub Enterprise Server being used by customers. --- .github/workflows/build-and-check.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/build-and-check.yml b/.github/workflows/build-and-check.yml index 6038637..b89bdba 100644 --- a/.github/workflows/build-and-check.yml +++ b/.github/workflows/build-and-check.yml @@ -75,7 +75,7 @@ jobs: uses: rlespinasse/github-slug-action@v4 - name: Upload artifacts - uses: actions/upload-artifact@v3 + uses: actions/upload-artifact@v4 if: success() || failure() with: name: ${{ env.GITHUB_REF_SLUG_URL }}-pg${{ matrix.pg_version }}-use-healpix-${{ matrix.use_healpix }}-${{ github.run_id }} From e059e5e462eb902614e8aaa91ae88a9c1100600c Mon Sep 17 00:00:00 2001 From: Vitaly Davydov Date: Mon, 28 Oct 2024 09:30:30 +0300 Subject: [PATCH 83/87] Build and check workflow for MS Windows --- .../build-and-check-windows-latest.yml | 81 +++++++++++++++++++ 1 file changed, 81 insertions(+) create mode 100644 .github/workflows/build-and-check-windows-latest.yml diff --git a/.github/workflows/build-and-check-windows-latest.yml b/.github/workflows/build-and-check-windows-latest.yml new file mode 100644 index 0000000..4189fc2 --- /dev/null +++ b/.github/workflows/build-and-check-windows-latest.yml @@ -0,0 +1,81 @@ +name: Build and Check (windows-latest) + +on: + push: + pull_request: + workflow_dispatch: + schedule: + - cron: '0 0 * * 5' + +jobs: + build_and_test: + + runs-on: windows-latest + + strategy: + fail-fast: false + matrix: + pg_version: [10, 11, 12, 13, 14, 15, 16, 17] + use_healpix: [0] + + name: PostgreSQL ${{ matrix.pg_version }} - USE_HEALPIX=${{ matrix.use_healpix }} (windows-latest) + + defaults: + run: + shell: msys2 {0} + + steps: + + - name: Install MSYS2 + uses: msys2/setup-msys2@v2 + with: + update: true + msystem: mingw64 + install: >- + base-devel + curl + git + make + perl + flex + bison + diffutils + mingw-w64-x86_64-zlib + mingw-w64-x86_64-icu + mingw-w64-x86_64-gcc + + - name: Install PostgreSQL + run: | + echo "Workspace: ${GITHUB_WORKSPACE}" + git clone --single-branch -b "REL_${{ matrix.pg_version }}_STABLE" git://git.postgresql.org/git/postgresql.git + cd ${GITHUB_WORKSPACE}/postgresql + ./configure --enable-cassert --without-icu + make -j$(nproc) + make install + + - name: Clone pgSphere + uses: actions/checkout@v4 + with: + ref: 'master' + fetch-depth: 1 + + - name: Build pgSphere + run: | + make --keep-going -j$(nproc) PROFILE='-Werror -Wall' USE_HEALPIX=0 + make USE_HEALPIX=0 install + + - name: Test pgSphere + run: | + initdb -D pgdata -U postgres + pg_ctl -D pgdata -l postgres.log start + make USE_HEALPIX=0 installcheck + + - name: Upload artifacts + uses: actions/upload-artifact@v4 + if: success() || failure() + with: + name: ${{ env.GITHUB_REF_SLUG_URL }}-pg${{ matrix.pg_version }}-use-healpix-${{ matrix.use_healpix }}-${{ github.run_id }} + if-no-files-found: ignore + path: | + ./**/*.log + ./**/*.diffs From 50268d5ac33893c41dcf5e95bfffc7eefc470d0d Mon Sep 17 00:00:00 2001 From: Vitaly Davydov Date: Tue, 5 Nov 2024 13:48:10 +0300 Subject: [PATCH 84/87] Fix found issues after review --- .github/workflows/build-and-check-windows-latest.yml | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/.github/workflows/build-and-check-windows-latest.yml b/.github/workflows/build-and-check-windows-latest.yml index 4189fc2..b4c8158 100644 --- a/.github/workflows/build-and-check-windows-latest.yml +++ b/.github/workflows/build-and-check-windows-latest.yml @@ -70,6 +70,10 @@ jobs: pg_ctl -D pgdata -l postgres.log start make USE_HEALPIX=0 installcheck + - name: Show installcheck regression.diffs + if: ${{ failure() }} + run: cat regression.diffs + - name: Upload artifacts uses: actions/upload-artifact@v4 if: success() || failure() From 37897e98169c0e1fdcb8101764f095c94aa081a6 Mon Sep 17 00:00:00 2001 From: Vitaly Davydov Date: Thu, 7 Nov 2024 12:47:14 +0300 Subject: [PATCH 85/87] Add crushtest in build-and-check-windows-latest workflow --- .../workflows/build-and-check-windows-latest.yml | 14 +++++++++++++- expected/init_extended.out | 6 +++--- sql/init_extended.sql | 6 +++--- 3 files changed, 19 insertions(+), 7 deletions(-) diff --git a/.github/workflows/build-and-check-windows-latest.yml b/.github/workflows/build-and-check-windows-latest.yml index b4c8158..1bbb43e 100644 --- a/.github/workflows/build-and-check-windows-latest.yml +++ b/.github/workflows/build-and-check-windows-latest.yml @@ -64,16 +64,28 @@ jobs: make --keep-going -j$(nproc) PROFILE='-Werror -Wall' USE_HEALPIX=0 make USE_HEALPIX=0 install - - name: Test pgSphere + - name: Test pgSphere (installcheck) run: | initdb -D pgdata -U postgres pg_ctl -D pgdata -l postgres.log start make USE_HEALPIX=0 installcheck + pg_ctl -D pgdata -l postgres_installcheck.log stop + rm -rf pgdata - name: Show installcheck regression.diffs if: ${{ failure() }} run: cat regression.diffs + - name: Test pgSphere (crushtest) + run: | + initdb -D pgdata -U postgres + pg_ctl -D pgdata -l postgres_crushtest.log start + make USE_HEALPIX=0 crushtest + + - name: Show crushtest regression.diffs + if: ${{ failure() }} + run: cat regression.diffs + - name: Upload artifacts uses: actions/upload-artifact@v4 if: success() || failure() diff --git a/expected/init_extended.out b/expected/init_extended.out index 382a0dc..adeaa8d 100644 --- a/expected/init_extended.out +++ b/expected/init_extended.out @@ -1,18 +1,18 @@ -- indexed operations..... -- spoint_data and scircle_data tables have to be created and indexed using -\! testsuite/gen_point.pl 1 > results/gen_point_1.sql +\! perl testsuite/gen_point.pl 1 > results/gen_point_1.sql \i results/gen_point_1.sql CREATE TABLE spoint_data (sp spoint); COPY spoint_data (sp) FROM stdin; CREATE INDEX sp_idx ON spoint_data USING gist (sp); -- and -\! testsuite/gen_circle.pl 1 0.1 > results/gen_circle_1_0.1.sql +\! perl testsuite/gen_circle.pl 1 0.1 > results/gen_circle_1_0.1.sql \i results/gen_circle_1_0.1.sql CREATE TABLE scircle_data (sc scircle); COPY scircle_data (sc) FROM stdin; CREATE INDEX sc_idx ON scircle_data USING gist (sc); -- -\! testsuite/gen_poly.pl 1 0.1 4 > results/gen_poly_1_0.1_4.sql +\! perl testsuite/gen_poly.pl 1 0.1 4 > results/gen_poly_1_0.1_4.sql \i results/gen_poly_1_0.1_4.sql CREATE TABLE spoly_data (sp spoly); COPY spoly_data (sp) FROM stdin; diff --git a/sql/init_extended.sql b/sql/init_extended.sql index 800d7e4..b28f0ef 100644 --- a/sql/init_extended.sql +++ b/sql/init_extended.sql @@ -2,15 +2,15 @@ -- spoint_data and scircle_data tables have to be created and indexed using -\! testsuite/gen_point.pl 1 > results/gen_point_1.sql +\! perl testsuite/gen_point.pl 1 > results/gen_point_1.sql \i results/gen_point_1.sql -- and -\! testsuite/gen_circle.pl 1 0.1 > results/gen_circle_1_0.1.sql +\! perl testsuite/gen_circle.pl 1 0.1 > results/gen_circle_1_0.1.sql \i results/gen_circle_1_0.1.sql -- -\! testsuite/gen_poly.pl 1 0.1 4 > results/gen_poly_1_0.1_4.sql +\! perl testsuite/gen_poly.pl 1 0.1 4 > results/gen_poly_1_0.1_4.sql \i results/gen_poly_1_0.1_4.sql From 6c244248c9daa5cb1cf0bfb7e2de37ad70c90f46 Mon Sep 17 00:00:00 2001 From: Vitaly Davydov Date: Thu, 7 Nov 2024 13:13:18 +0300 Subject: [PATCH 86/87] Fix pgsphere cloned branch --- .github/workflows/build-and-check-windows-latest.yml | 3 --- 1 file changed, 3 deletions(-) diff --git a/.github/workflows/build-and-check-windows-latest.yml b/.github/workflows/build-and-check-windows-latest.yml index 1bbb43e..658da28 100644 --- a/.github/workflows/build-and-check-windows-latest.yml +++ b/.github/workflows/build-and-check-windows-latest.yml @@ -55,9 +55,6 @@ jobs: - name: Clone pgSphere uses: actions/checkout@v4 - with: - ref: 'master' - fetch-depth: 1 - name: Build pgSphere run: | From 461e873748d68498db50893acd6397c5f0ec9239 Mon Sep 17 00:00:00 2001 From: Vitaly Davydov Date: Thu, 7 Nov 2024 14:57:11 +0300 Subject: [PATCH 87/87] Change log file name --- .github/workflows/build-and-check-windows-latest.yml | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/.github/workflows/build-and-check-windows-latest.yml b/.github/workflows/build-and-check-windows-latest.yml index 658da28..e2d7b27 100644 --- a/.github/workflows/build-and-check-windows-latest.yml +++ b/.github/workflows/build-and-check-windows-latest.yml @@ -64,9 +64,9 @@ jobs: - name: Test pgSphere (installcheck) run: | initdb -D pgdata -U postgres - pg_ctl -D pgdata -l postgres.log start + pg_ctl -D pgdata -l postgres_installcheck.log start make USE_HEALPIX=0 installcheck - pg_ctl -D pgdata -l postgres_installcheck.log stop + pg_ctl -D pgdata stop rm -rf pgdata - name: Show installcheck regression.diffs @@ -78,6 +78,7 @@ jobs: initdb -D pgdata -U postgres pg_ctl -D pgdata -l postgres_crushtest.log start make USE_HEALPIX=0 crushtest + pg_ctl -D pgdata stop - name: Show crushtest regression.diffs if: ${{ failure() }}