Location via proxy:   [ UP ]  
[Report a bug]   [Manage cookies]                
Skip to content

Commit 3d1588c

Browse files
committed
Make earthdistance use version-0 calling convention if not USE_FLOAT8_BYVAL,
and version-1 if USE_FLOAT8_BYVAL. This might seem a bit pointless, but the idea is to have at least one regression test that will fail if we ever accidentally break version-0 functions that return float8. However, they're already broken, or at least hopelessly unportable, in the USE_FLOAT8_BYVAL case. Per a recent suggestion from Greg Stark.
1 parent 8472bf7 commit 3d1588c

File tree

1 file changed

+56
-14
lines changed

1 file changed

+56
-14
lines changed

contrib/earthdistance/earthdistance.c

+56-14
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
/* $PostgreSQL: pgsql/contrib/earthdistance/earthdistance.c,v 1.14 2008/04/20 01:05:52 tgl Exp $ */
1+
/* $PostgreSQL: pgsql/contrib/earthdistance/earthdistance.c,v 1.15 2008/04/21 01:11:43 tgl Exp $ */
22

33
#include "postgres.h"
44

@@ -17,10 +17,6 @@ PG_MODULE_MAGIC;
1717
static const double EARTH_RADIUS = 3958.747716;
1818
static const double TWO_PI = 2.0 * M_PI;
1919

20-
PG_FUNCTION_INFO_V1(geo_distance);
21-
22-
Datum geo_distance(PG_FUNCTION_ARGS);
23-
2420

2521
/******************************************************
2622
*
@@ -37,26 +33,22 @@ degtorad(double degrees)
3733
return (degrees / 360.0) * TWO_PI;
3834
}
3935

40-
4136
/******************************************************
4237
*
43-
* geo_distance - distance between points
38+
* geo_distance_internal - distance between points
4439
*
4540
* args:
4641
* a pair of points - for each point,
4742
* x-coordinate is longitude in degrees west of Greenwich
4843
* y-coordinate is latitude in degrees above equator
4944
*
50-
* returns: float8
45+
* returns: double
5146
* distance between the points in miles on earth's surface
5247
******************************************************/
5348

54-
Datum
55-
geo_distance(PG_FUNCTION_ARGS)
49+
static double
50+
geo_distance_internal(Point *pt1, Point *pt2)
5651
{
57-
Point *pt1 = PG_GETARG_POINT_P(0);
58-
Point *pt2 = PG_GETARG_POINT_P(1);
59-
float8 result;
6052
double long1,
6153
lat1,
6254
long2,
@@ -81,7 +73,57 @@ geo_distance(PG_FUNCTION_ARGS)
8173
cos(lat1) * cos(lat2) * sin(longdiff / 2.) * sin(longdiff / 2.));
8274
if (sino > 1.)
8375
sino = 1.;
84-
result = 2. * EARTH_RADIUS * asin(sino);
8576

77+
return 2. * EARTH_RADIUS * asin(sino);
78+
}
79+
80+
81+
/******************************************************
82+
*
83+
* geo_distance - distance between points
84+
*
85+
* args:
86+
* a pair of points - for each point,
87+
* x-coordinate is longitude in degrees west of Greenwich
88+
* y-coordinate is latitude in degrees above equator
89+
*
90+
* returns: float8
91+
* distance between the points in miles on earth's surface
92+
*
93+
* If float8 is passed-by-value, the oldstyle version-0 calling convention
94+
* is unportable, so we use version-1. However, if it's passed-by-reference,
95+
* continue to use oldstyle. This is just because we'd like earthdistance
96+
* to serve as a canary for any unintentional breakage of version-0 functions
97+
* with float8 results.
98+
******************************************************/
99+
100+
#ifdef USE_FLOAT8_BYVAL
101+
102+
Datum geo_distance(PG_FUNCTION_ARGS);
103+
PG_FUNCTION_INFO_V1(geo_distance);
104+
105+
Datum
106+
geo_distance(PG_FUNCTION_ARGS)
107+
{
108+
Point *pt1 = PG_GETARG_POINT_P(0);
109+
Point *pt2 = PG_GETARG_POINT_P(1);
110+
float8 result;
111+
112+
result = geo_distance_internal(pt1, pt2);
86113
PG_RETURN_FLOAT8(result);
87114
}
115+
116+
#else /* !USE_FLOAT8_BYVAL */
117+
118+
double *geo_distance(Point *pt1, Point *pt2);
119+
120+
double *
121+
geo_distance(Point *pt1, Point *pt2)
122+
{
123+
double *resultp = palloc(sizeof(double));
124+
125+
*resultp = geo_distance_internal(pt1, pt2);
126+
return resultp;
127+
}
128+
129+
#endif /* USE_FLOAT8_BYVAL */

0 commit comments

Comments
 (0)