Plug holes in SP-GiST quad tree getQuadrant() getQuadrant() places a point on each axis with the fuzzy comparisons FPlt(), FPgt() and FPeq(), which do not cover every case. FPeq() compares the rounded difference against EPSILON, while FPlt() and FPgt() round the sum of one operand and EPSILON. When the centroid plus EPSILON rounds up, a point equal to that rounded sum is more than EPSILON above the centroid, so FPeq() is false. FPgt() compares it with the same rounded sum, so it is false too, and FPlt() is false because the point is above the centroid. The same gap exists below the centroid, when the centroid minus EPSILON rounds down. No quadrant matches, and index builds, inserts and searches fail with "getQuadrant: impossible case".
To fix, fall back to deciding each axis separately: Use fuzzy tests first and then tiebreak with exact comparisons. That gives every finite value a quadrant (NaN coordinates are still an error). Points that matched a fuzzy test before are routed as before, so existing indexes remain valid. Bug: #19597 Reported-by: Michael Malis <[email protected]> Author: Ayush Tiwari <[email protected]> Reviewed-by: Andrey Rachitskiy <[email protected]> Reviewed-by: Pierre Forstmann <[email protected]> Discussion: https://postgr.es/m/[email protected] Backpatch-through: 14 Branch ------ REL_15_STABLE Details ------- https://git.postgresql.org/pg/commitdiff/37ecbb4384348f6ee9c2c1e3576e41d8a7d7c68b Modified Files -------------- src/backend/access/spgist/spgquadtreeproc.c | 43 +++++++++++++++++++++++++++-- src/test/regress/expected/spgist.out | 16 +++++++++++ src/test/regress/sql/spgist.sql | 13 +++++++++ 3 files changed, 70 insertions(+), 2 deletions(-)
