• Tom Lane's avatar
    Prevent infinite insertion loops in spgdoinsert(). · c3c35a73
    Tom Lane authored
    Formerly we just relied on operator classes that assert longValuesOK
    to eventually shorten the leaf value enough to fit on an index page.
    That fails since the introduction of INCLUDE-column support (commit
    09c1c6ab), because the INCLUDE columns might alone take up more
    than a page, meaning no amount of leaf-datum compaction will get
    the job done.  At least with spgtextproc.c, that leads to an infinite
    loop, since spgtextproc.c won't throw an error for not being able
    to shorten the leaf datum anymore.
    
    To fix without breaking cases that would otherwise work, add logic
    to spgdoinsert() to verify that the leaf tuple size is decreasing
    after each "choose" step.  Some opclasses might not decrease the
    size on every single cycle, and in any case, alignment roundoff
    of the tuple size could obscure small gains.  Therefore, allow
    up to 10 cycles without additional savings before throwing an
    error.  (Perhaps this number will need adjustment, but it seems
    quite generous right now.)
    
    As long as we've developed this logic, let's back-patch it.
    The back branches don't have INCLUDE columns to worry about, but
    this seems like a good defense against possible bugs in operator
    classes.  We already know that an infinite loop here is pretty
    unpleasant, so having a defense seems to outweigh the risk of
    breaking things.  (Note that spgtextproc.c is actually the only
    known opclass with longValuesOK support, so that this is all moot
    for known non-core opclasses anyway.)
    
    Per report from Dilip Kumar.
    
    Discussion: https://postgr.es/m/CAFiTN-uxP_soPhVG840tRMQTBmtA_f_Y8N51G7DKYYqDh7XN-A@mail.gmail.com
    c3c35a73
spgist.sgml 52.2 KB