diff --git a/src/jrd/dpm.epp b/src/jrd/dpm.epp index 083e9cfddb0..e2b72b97aa4 100644 --- a/src/jrd/dpm.epp +++ b/src/jrd/dpm.epp @@ -3716,7 +3716,10 @@ static void store_big_record(thread_db* tdbb, // The last fragment should have rhd header because rhd_incomplete flag won't be set for it. // It's important for get_header() function which relies on rhd_incomplete flag to determine header size. FB_SIZE_T header_size = RHD_SIZE; - USHORT max_data = dbb->dbb_page_size - (static_cast(sizeof(data_page)) + header_size); + // We can have a big record that is not fitting into single page with RHDE header, but with RHD header + // it does fit into single page, so to handle such case use `size` as maximum possible data, write whole + // data in tail with RHD, and create head with no data at all. + USHORT max_data = MIN(dbb->dbb_page_size - (static_cast(sizeof(data_page)) + header_size), size); // Fill up data pages tail first until what's left fits on a single page. diff --git a/src/utilities/gstat/dba.epp b/src/utilities/gstat/dba.epp index a1ff5701a1c..a10a382febd 100644 --- a/src/utilities/gstat/dba.epp +++ b/src/utilities/gstat/dba.epp @@ -1434,6 +1434,10 @@ static bool analyze_data_page( dba_rel* relation, const data_page* page, bool sw relation->rel_record_space -= RHDF_SIZE; relation->rel_record_space += analyze_fragments(relation, header); } + else if (header->rhdf_flags & rhd_long_tranum) + { + relation->rel_record_space -= RHDE_SIZE; + } else { relation->rel_record_space -= RHD_SIZE; @@ -1538,10 +1542,16 @@ static ULONG analyze_fragments(dba_rel* relation, const rhdf* header) const data_page::dpg_repeat* index = &page->dpg_rpt[f_line]; if (!index->dpg_offset) break; - space += index->dpg_length; - space -= RHDF_SIZE; header = (const rhdf*) ((SCHAR *) page + index->dpg_offset); + space += index->dpg_length; + if (header->rhdf_flags & rhd_incomplete) + space -= RHDF_SIZE; + else if (header->rhdf_flags & rhd_long_tranum) + space -= RHDE_SIZE; + else + space -= RHD_SIZE; + fragments++; } @@ -1741,6 +1751,8 @@ static ULONG analyze_versions( dba_rel* relation, const rhdf* header) space -= RHDF_SIZE; space += analyze_fragments(relation, header); } + else if (header->rhdf_flags & rhd_long_tranum) + space -= RHDE_SIZE; else space -= RHD_SIZE; }