Skip to content

Fix assertion failure in getNdvBySegHeapTuple for empty partitions.#1599

Open
zhangwenchao-123 wants to merge 1 commit intoapache:mainfrom
zhangwenchao-123:fix_analyze_core
Open

Fix assertion failure in getNdvBySegHeapTuple for empty partitions.#1599
zhangwenchao-123 wants to merge 1 commit intoapache:mainfrom
zhangwenchao-123:fix_analyze_core

Conversation

@zhangwenchao-123
Copy link
Contributor

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.

Fixes #ISSUE_Number

What does this PR do?

Type of Change

  • Bug fix (non-breaking change)
  • New feature (non-breaking change)
  • Breaking change (fix or feature with breaking changes)
  • Documentation update

Breaking Changes

Test Plan

  • Unit tests added/updated
  • Integration tests added/updated
  • Passed make installcheck
  • Passed make -C src/test installcheck-cbdb-parallel

Impact

Performance:

User-facing changes:

Dependencies:

Checklist

Additional Context

CI Skip Instructions


@zhangwenchao-123 zhangwenchao-123 force-pushed the fix_analyze_core branch 2 times, most recently from 6721fc5 to dd82ba3 Compare March 5, 2026 03:27
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.

Authored-by: Zhang Wenchao zwcpostgres@gmail.com
continue;
}

Assert(ndvbsSlots[i]->valuetype == FLOAT8OID);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This assert may keep here.

break;
}
}
return valid;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

All of the ndvbsSlots could be release if the valid becomes false. On the other side, the ndvbsSlots and its pointer array could be also freed in aggregate_leaf_partition_ndvbs no matter it's valid or not.


Assert(ndvbsSlots[i]->valuetype == FLOAT8OID);
Assert(ndvbsSlots[i]->nvalues == 1);

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

if (ndvbsSlots[i]->nvalues != 1)
  {
      valid = false;
      break;
  }

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants