Fix overly-strict assertions in spgtextproc.c.

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.
This commit is contained in:
Tom Lane 2016-01-02 16:24:50 -05:00
parent df35af2ca7
commit 7157fe80f4

View File

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