Skip to content

Commit daac348

Browse files
authored
Merge pull request #8162 from FirebirdSQL/work/gh-8161
Improvement #8161 : Cardinality estimation should use primary record versions only
2 parents b259d5a + 406569a commit daac348

File tree

1 file changed

+33
-29
lines changed

1 file changed

+33
-29
lines changed

src/jrd/dpm.epp

Lines changed: 33 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -245,47 +245,51 @@ double DPM_cardinality(thread_db* tdbb, jrd_rel* relation, const Format* format)
245245

246246
ULONG recordCount = 0, recordLength = 0;
247247

248-
const RelationPages* const relPages = relation->getPages(tdbb);
249-
const vcl* const vector = relPages->rel_pages;
250-
if (vector)
248+
RelationPages* const relPages = relation->getPages(tdbb);
249+
if (relPages->rel_pages)
251250
{
252-
WIN window(relPages->rel_pg_space_id, (*vector)[0]);
253-
254-
Ods::pointer_page* ppage =
255-
(Ods::pointer_page*) CCH_FETCH(tdbb, &window, LCK_read, pag_pointer);
256-
if (!ppage)
251+
bool done = false;
252+
for (ULONG sequence = 0; !done; sequence++)
257253
{
258-
BUGCHECK(243);
259-
// msg 243 missing pointer page in DPM_data_pages
260-
}
254+
WIN window(relPages->rel_pg_space_id, -1);
261255

262-
const ULONG* page = ppage->ppg_page;
263-
const ULONG* const end_page = page + ppage->ppg_count;
264-
while (page < end_page)
265-
{
266-
if (*page)
256+
const pointer_page* ppage =
257+
get_pointer_page(tdbb, relation, relPages, &window, sequence, LCK_read);
258+
if (!ppage)
267259
{
268-
Ods::data_page* dpage =
269-
(Ods::data_page*) CCH_HANDOFF(tdbb, &window, *page, LCK_read, pag_data);
260+
BUGCHECK(243);
261+
// msg 243 missing pointer page in DPM_data_pages
262+
}
270263

271-
const data_page::dpg_repeat* index = dpage->dpg_rpt;
272-
const data_page::dpg_repeat* const end = index + dpage->dpg_count;
273-
for (; index < end; index++)
264+
const UCHAR* bits = (UCHAR*)(ppage->ppg_page + dbb->dbb_dp_per_pp);
265+
for (USHORT slot = 0; slot < ppage->ppg_count; slot++)
266+
{
267+
if (ppage->ppg_page[slot] &&
268+
!PPG_DP_BIT_TEST(bits, slot, ppg_dp_secondary) &&
269+
!PPG_DP_BIT_TEST(bits, slot, ppg_dp_empty))
274270
{
275-
if (index->dpg_offset)
271+
Ods::data_page* dpage =
272+
(Ods::data_page*) CCH_HANDOFF(tdbb, &window, ppage->ppg_page[slot], LCK_read, pag_data);
273+
274+
const data_page::dpg_repeat* index = dpage->dpg_rpt;
275+
const data_page::dpg_repeat* const end = index + dpage->dpg_count;
276+
for (; index < end; index++)
276277
{
277-
recordCount++;
278-
recordLength += index->dpg_length - RHD_SIZE;
278+
if (index->dpg_offset)
279+
{
280+
recordCount++;
281+
recordLength += index->dpg_length - RHD_SIZE;
282+
}
279283
}
280-
}
281284

282-
break;
285+
if (recordCount)
286+
break;
287+
}
283288
}
284289

285-
page++;
290+
done = (recordCount != 0) || (ppage->ppg_header.pag_flags & ppg_eof);
291+
CCH_RELEASE(tdbb, &window);
286292
}
287-
288-
CCH_RELEASE(tdbb, &window);
289293
}
290294

291295
// AB: If we have only 1 data-page then the cardinality calculation

0 commit comments

Comments
 (0)