]> granicus.if.org Git - postgresql/commitdiff
Fix overly-strict assertions in spgtextproc.c.
authorTom Lane <tgl@sss.pgh.pa.us>
Sat, 2 Jan 2016 21:24:50 +0000 (16:24 -0500)
committerTom Lane <tgl@sss.pgh.pa.us>
Sat, 2 Jan 2016 21:24:50 +0000 (16:24 -0500)
spg_text_inner_consistent is capable of reconstructing an empty string
to pass down to the next index level; this happens if we have an empty
string coming in, no prefix, and a dummy node label.  (In practice, what
is needed to trigger that is insertion of a whole bunch of empty-string
values.)  Then, we will arrive at the next level with in->level == 0
and a non-NULL (but zero length) in->reconstructedValue, which is valid
but the Assert tests weren't expecting it.

Per report from Andreas Seltenreich.  This has no impact in non-Assert
builds, so should not be a problem in production, but back-patch to
all affected branches anyway.

In passing, remove a couple of useless variable initializations and
shorten the code by not duplicating DatumGetPointer() calls.

src/backend/access/spgist/spgtextproc.c

index 5e0629f7d0d4c8062826bb6583a1f4140a71bfdf..e0d8f30ef16c1e44f2861875ec948f6143a7559f 100644 (file)
@@ -403,8 +403,9 @@ spg_text_inner_consistent(PG_FUNCTION_ARGS)
        spgInnerConsistentIn *in = (spgInnerConsistentIn *) PG_GETARG_POINTER(0);
        spgInnerConsistentOut *out = (spgInnerConsistentOut *) PG_GETARG_POINTER(1);
        bool            collate_is_c = lc_collate_is_c(PG_GET_COLLATION());
-       text       *reconstrText = NULL;
-       int                     maxReconstrLen = 0;
+       text       *reconstructedValue;
+       text       *reconstrText;
+       int                     maxReconstrLen;
        text       *prefixText = NULL;
        int                     prefixSize = 0;
        int                     i;
@@ -420,8 +421,9 @@ spg_text_inner_consistent(PG_FUNCTION_ARGS)
         * created by a previous invocation of this routine, and we always emit
         * long-format reconstructed values.
         */
-       Assert(in->level == 0 ? DatumGetPointer(in->reconstructedValue) == NULL :
-       VARSIZE_ANY_EXHDR(DatumGetPointer(in->reconstructedValue)) == in->level);
+       reconstructedValue = (text *) DatumGetPointer(in->reconstructedValue);
+       Assert(reconstructedValue == NULL ? in->level == 0 :
+                  VARSIZE_ANY_EXHDR(reconstructedValue) == in->level);
 
        maxReconstrLen = in->level + 1;
        if (in->hasPrefix)
@@ -436,7 +438,7 @@ spg_text_inner_consistent(PG_FUNCTION_ARGS)
 
        if (in->level)
                memcpy(VARDATA(reconstrText),
-                          VARDATA(DatumGetPointer(in->reconstructedValue)),
+                          VARDATA(reconstructedValue),
                           in->level);
        if (prefixSize)
                memcpy(((char *) VARDATA(reconstrText)) + in->level,
@@ -560,7 +562,7 @@ spg_text_leaf_consistent(PG_FUNCTION_ARGS)
        if (DatumGetPointer(in->reconstructedValue))
                reconstrValue = DatumGetTextP(in->reconstructedValue);
 
-       Assert(level == 0 ? reconstrValue == NULL :
+       Assert(reconstrValue == NULL ? level == 0 :
                   VARSIZE_ANY_EXHDR(reconstrValue) == level);
 
        /* Reconstruct the full string represented by this leaf tuple */