From f2b6879704fc737aa020a26e7c1ad113bff83dd8 Mon Sep 17 00:00:00 2001 From: Ivan Panchenko Date: Sat, 9 Dec 2023 13:19:06 +0300 Subject: [PATCH 01/18] 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 c9c225ff..eb862f42 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 998b5461..c27ef5e4 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 00000000..49c89031 --- /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 e8ac1191..3ac99711 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 00000000..0207c981 --- /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 b3223a50..f373448f 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 02/18] 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 eb862f42..14350ec9 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 9a73710f..7764d849 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 c27ef5e4..6b874b02 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 5e361bff..1d82d755 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 69ca7729..4ecf4cdb 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 3ac99711..fcd4f116 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 f373448f..0fef2ac6 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 00000000..35c964e1 --- /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 03/18] 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 c3add5cc..629df906 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 7314ac03..6444a52a 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 b8aa5200..614b0e81 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 b27bc3b7..f600936b 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 9e1b87e8..a93e4c34 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 a45f7b3c..f9d41906 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 35e3a2ca..6baca284 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 6dac2a47..58e32f10 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 bae1d11f..c7a27777 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 aa77ca98..e4c39dc8 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 002f3714..deaa028d 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 91e1662e..8f98cee5 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 24d950a4..9cfc5f21 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 c3233d10..f15b4fe1 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 1b3ad76f..f04d5be9 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 d7af2281..b9d85d14 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 b8c754d4..0233c413 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 57599eee..b16f152c 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 23ba9b9e..47a5a82b 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 04/18] 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 14350ec9..fe74e062 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 05/18] 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 fe74e062..81dc57cb 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 6307ac1a..ef424748 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 8c089360..48d4ff30 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 8541601e..3a528326 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 00000000..08317fcd --- /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 00000000..9109c4bf --- /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 00000000..02ca5218 --- /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 908707ee..724a1190 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 fb862d65..20176c41 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 fea97378..d8ae2b7d 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 00000000..514af1ec --- /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 7598d466..7df58899 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 35c964e1..8b2ce2b9 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 06/18] 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 81dc57cb..78f2dc5c 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 7764d849..be82047c 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 1d82d755..ffad8f51 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 4ecf4cdb..1e73251e 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 00000000..20c7cf63 --- /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 07/18] 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 f2200860..9eb7d578 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 032b5fdb..e6a10008 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 3d904c67..0df711e4 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 08/18] 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 9eb7d578..16a65d11 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 e6a10008..c6607ba4 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 22e87781..0b65d9ff 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 0df711e4..50e0e70d 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 99bd8ac6..d3103b6d 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 09/18] 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 78f2dc5c..782961cd 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 be82047c..89632277 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 ffad8f51..c1f0efe9 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 1e73251e..85f75896 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 00000000..3ff6a66e --- /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 10/18] 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 232b7552..047b7f11 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 3a528326..1111f1a7 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 d8ae2b7d..a6c69dd5 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 ab9abc88..12ad6219 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 a93e4c34..3b61a02c 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 11/18] 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 a4247b8a..f7633b55 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 12/18] 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 f7633b55..6038637e 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 13/18] 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 6038637e..b89bdba0 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 14/18] 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 00000000..4189fc22 --- /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 15/18] 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 4189fc22..b4c81583 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 16/18] 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 b4c81583..1bbb43e9 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 382a0dcb..adeaa8d8 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 800d7e46..b28f0efd 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 17/18] 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 1bbb43e9..658da283 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 18/18] 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 658da283..e2d7b274 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() }}