Skip to content

Commit 350241c

Browse files
Fix assertion failure in getNdvBySegHeapTuple for empty partitions.
When merging leaf partition statistics for a partitioned table, getNdvBySegHeapTuple could hit Assert(valuetype == FLOAT8OID) if a partition had relTuples == 0 and its pg_statistic entry lacked a valid STATISTIC_KIND_NDV_BY_SEGMENTS slot (or the slot had an unexpected element type). The original guard condition only handled two cases: 1. Non-empty partition with NDV value == 0 2. Non-empty partition without NDV_BY_SEGMENTS It missed the case where an empty partition (relTuples == 0) has a pg_statistic entry but no valid FLOAT8OID NDV_BY_SEGMENTS slot, causing the code to fall through to the assertion. Fix by checking valuetype != FLOAT8OID upfront: skip empty partitions gracefully, and mark non-empty partitions as invalid.
1 parent cce58a8 commit 350241c

1 file changed

Lines changed: 22 additions & 8 deletions

File tree

src/backend/commands/analyzeutils.c

Lines changed: 22 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -759,17 +759,31 @@ getNdvBySegHeapTuple(AttStatsSlot * *ndvbsSlots, HeapTuple *heaptupleStats, floa
759759
(void) get_attstatsslot(ndvbsSlots[i], heaptupleStats[i],
760760
STATISTIC_KIND_NDV_BY_SEGMENTS, InvalidOid, ATTSTATSSLOT_VALUES);
761761

762-
if ((InvalidOid != ndvbsSlots[i]->valuetype && // result is not empty
763-
// not empty partition with invalid ndvbs
764-
(relTuples[i] > 0 && DatumGetFloat8(ndvbsSlots[i]->values[0]) == 0)) ||
765-
// not empty partition without ndvbs
766-
(InvalidOid == ndvbsSlots[i]->valuetype && relTuples[i] > 0)) {
767-
valid = false;
768-
break;
762+
if (ndvbsSlots[i]->valuetype != FLOAT8OID)
763+
{
764+
/*
765+
* NDV_BY_SEGMENTS slot not found or has unexpected type.
766+
* Non-empty partitions must have valid NDV_BY_SEGMENTS;
767+
* empty partitions (relTuples == 0) can be skipped.
768+
*/
769+
if (relTuples[i] > 0)
770+
{
771+
valid = false;
772+
break;
773+
}
774+
pfree(ndvbsSlots[i]);
775+
ndvbsSlots[i] = NULL;
776+
continue;
769777
}
770778

771-
Assert(ndvbsSlots[i]->valuetype == FLOAT8OID);
772779
Assert(ndvbsSlots[i]->nvalues == 1);
780+
781+
/* Non-empty partition with zero NDV is suspicious */
782+
if (relTuples[i] > 0 && DatumGetFloat8(ndvbsSlots[i]->values[0]) == 0)
783+
{
784+
valid = false;
785+
break;
786+
}
773787
}
774788
return valid;
775789
}

0 commit comments

Comments
 (0)