• Tom Lane's avatar
    Fix GiST index build for NaN values in geometric types. · 1acf7572
    Tom Lane authored
    GiST index build could go into an infinite loop when presented with boxes
    (or points, circles or polygons) containing NaN component values.  This
    happened essentially because the code assumed that x == x is true for any
    "double" value x; but it's not true for NaNs.  The looping behavior was not
    the only problem though: we also attempted to sort the items using simple
    double comparisons.  Since NaNs violate the trichotomy law, qsort could
    (in principle at least) get arbitrarily confused and mess up the sorting of
    ordinary values as well as NaNs.  And we based splitting choices on box size
    calculations that could produce NaNs, again resulting in undesirable
    behavior.
    
    To fix, replace all comparisons of doubles in this logic with
    float8_cmp_internal, which is NaN-aware and is careful to sort NaNs
    consistently, higher than any non-NaN.  Also rearrange the box size
    calculation to not produce NaNs; instead it should produce an infinity
    for a box with NaN on one side and not-NaN on the other.
    
    I don't by any means claim that this solves all problems with NaNs in
    geometric values, but it should at least make GiST index insertion work
    reliably with such data.  It's likely that the index search side of things
    still needs some work, and probably regular geometric operations too.
    But with this patch we're laying down a convention for how such cases
    ought to behave.
    
    Per bug #14238 from Guang-Dih Lei.  Back-patch to 9.2; the code used before
    commit 7f3bd868 is quite different and doesn't lock up on my simple
    test case, nor on the submitter's dataset.
    
    Report: <20160708151747.1426.60150@wrigleys.postgresql.org>
    Discussion: <28685.1468246504@sss.pgh.pa.us>
    1acf7572
gistproc.c 41.7 KB