diff options
author | Tomas Vondra <tomas.vondra@postgresql.org> | 2018-08-16 19:56:11 +0200 |
---|---|---|
committer | Tomas Vondra <tomas.vondra@postgresql.org> | 2018-08-16 19:56:11 +0200 |
commit | c4c34008854654279ec30067d72fc5d174d2f42f (patch) | |
tree | e598b56e55eb225263be08af6a0a7aad9e48f651 /src/backend/utils/adt/geo_spgist.c | |
parent | a082aed0723c737ec65222730ccede5db5251b4d (diff) | |
download | postgresql-c4c34008854654279ec30067d72fc5d174d2f42f.tar.gz postgresql-c4c34008854654279ec30067d72fc5d174d2f42f.zip |
Use the built-in float datatypes to implement geometric types
This patch makes the geometric operators and functions use the exported
function of the float4/float8 datatypes. The main reason of doing so is
to check for underflow and overflow, and to handle NaNs consciously.
The float datatypes consider NaNs values to be equal and greater than
all non-NaN values. This change considers NaNs equal only for equality
operators. The placement operators, contains, overlaps, left/right of
etc. continue to return false when NaNs are involved. We don't need
to worry about them being considered greater than any-NaN because there
aren't any basic comparison operators like less/greater than for the
geometric datatypes.
The changes may be summarised as:
* Check for underflow, overflow and division by zero
* Consider NaN values to be equal
* Return NULL when the distance is NaN for all closest point operators
* Favour not-NaN over NaN where it makes sense
The patch also replaces all occurrences of "double" as "float8". They
are the same, but were used inconsistently in the same file.
Author: Emre Hasegeli
Reviewed-by: Kyotaro Horiguchi, Tomas Vondra
Discussion: https://www.postgresql.org/message-id/CAE2gYzxF7-5djV6-cEvqQu-fNsnt%3DEqbOURx7ZDg%2BVv6ZMTWbg%40mail.gmail.com
Diffstat (limited to 'src/backend/utils/adt/geo_spgist.c')
-rw-r--r-- | src/backend/utils/adt/geo_spgist.c | 28 |
1 files changed, 14 insertions, 14 deletions
diff --git a/src/backend/utils/adt/geo_spgist.c b/src/backend/utils/adt/geo_spgist.c index fea36f361ae..4aff973ef37 100644 --- a/src/backend/utils/adt/geo_spgist.c +++ b/src/backend/utils/adt/geo_spgist.c @@ -84,14 +84,14 @@ * Comparator for qsort * * We don't need to use the floating point macros in here, because this - * is going only going to be used in a place to effect the performance + * is only going to be used in a place to effect the performance * of the index, not the correctness. */ static int compareDoubles(const void *a, const void *b) { - double x = *(double *) a; - double y = *(double *) b; + float8 x = *(float8 *) a; + float8 y = *(float8 *) b; if (x == y) return 0; @@ -100,8 +100,8 @@ compareDoubles(const void *a, const void *b) typedef struct { - double low; - double high; + float8 low; + float8 high; } Range; typedef struct @@ -175,7 +175,7 @@ static RectBox * initRectBox(void) { RectBox *rect_box = (RectBox *) palloc(sizeof(RectBox)); - double infinity = get_float8_infinity(); + float8 infinity = get_float8_infinity(); rect_box->range_box_x.left.low = -infinity; rect_box->range_box_x.left.high = infinity; @@ -418,10 +418,10 @@ spg_box_quad_picksplit(PG_FUNCTION_ARGS) BOX *centroid; int median, i; - double *lowXs = palloc(sizeof(double) * in->nTuples); - double *highXs = palloc(sizeof(double) * in->nTuples); - double *lowYs = palloc(sizeof(double) * in->nTuples); - double *highYs = palloc(sizeof(double) * in->nTuples); + float8 *lowXs = palloc(sizeof(float8) * in->nTuples); + float8 *highXs = palloc(sizeof(float8) * in->nTuples); + float8 *lowYs = palloc(sizeof(float8) * in->nTuples); + float8 *highYs = palloc(sizeof(float8) * in->nTuples); /* Calculate median of all 4D coordinates */ for (i = 0; i < in->nTuples; i++) @@ -434,10 +434,10 @@ spg_box_quad_picksplit(PG_FUNCTION_ARGS) highYs[i] = box->high.y; } - qsort(lowXs, in->nTuples, sizeof(double), compareDoubles); - qsort(highXs, in->nTuples, sizeof(double), compareDoubles); - qsort(lowYs, in->nTuples, sizeof(double), compareDoubles); - qsort(highYs, in->nTuples, sizeof(double), compareDoubles); + qsort(lowXs, in->nTuples, sizeof(float8), compareDoubles); + qsort(highXs, in->nTuples, sizeof(float8), compareDoubles); + qsort(lowYs, in->nTuples, sizeof(float8), compareDoubles); + qsort(highYs, in->nTuples, sizeof(float8), compareDoubles); median = in->nTuples / 2; |