Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
19 changes: 7 additions & 12 deletions src/jrd/btr.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1241,8 +1241,8 @@ void BTR_evaluate(thread_db* tdbb, const IndexRetrieval* retrieval, RecordBitmap
{
// If we're walking in a descending index and we need to ignore NULLs
// then stop at the first NULL we see (only for single segment!)
if (descending && ignoreNulls && node.prefix == 0 &&
node.length >= 1 && node.data[0] == 255)
if (descending && ignoreNulls &&
node.prefix == 0 && node.length >= 1 && node.data[0] == 255)
{
break;
}
Expand Down Expand Up @@ -6906,18 +6906,13 @@ static bool scan(thread_db* tdbb, UCHAR* pointer, RecordBitmap** bitmap, RecordB
return true;
}

// Ignore NULL-values, this is currently only available for single segment indexes.
// Ignore NULL-values, this is currently only available for single segment indexes
if (ignoreNulls)
{
ignore = false;
if (descending)
{
if ((node.prefix == 0) && (node.length >= 1) && (node.data[0] == 255))
return false;
}
else {
ignore = (node.prefix + node.length == 0); // Ascending (prefix + length == 0)
}
if (descending && node.prefix == 0 && node.length >= 1 && node.data[0] == 255)
return false;

ignore = descending ? false : (node.prefix + node.length == 0);
}

if (skipLowerKey)
Expand Down
23 changes: 19 additions & 4 deletions src/jrd/recsrc/IndexTableScan.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -198,13 +198,16 @@ bool IndexTableScan::internalGetRecord(thread_db* tdbb) const
}

index_desc* const idx = (index_desc*) ((SCHAR*) impure + m_offset);
const bool descending = (idx->idx_flags & idx_descending);

// find the last fetched position from the index
const USHORT pageSpaceID = m_relation->getPages(tdbb)->rel_pg_space_id;
win window(pageSpaceID, impure->irsb_nav_page);

const IndexRetrieval* const retrieval = m_index->retrieval;
const USHORT flags = retrieval->irb_generic & (irb_descending | irb_partial | irb_starting);
const bool ignoreNulls =
(retrieval->irb_generic & irb_ignore_null_value_key) && (idx->idx_count == 1);

do
{
Expand Down Expand Up @@ -252,6 +255,14 @@ bool IndexTableScan::internalGetRecord(thread_db* tdbb) const
continue;
}

// If we're walking in a descending index and we need to ignore NULLs
// then stop at the first NULL we see (only for single segment!)
if (descending && ignoreNulls &&
node.prefix == 0 && node.length >= 1 && node.data[0] == 255)
{
break;
}

// Build the current key value from the prefix and current node data.
memcpy(key.key_data + node.prefix, node.data, node.length);
key.key_length = node.length + node.prefix;
Expand Down Expand Up @@ -297,12 +308,16 @@ bool IndexTableScan::internalGetRecord(thread_db* tdbb) const
break;
}

// skip this record if:
// 1) there is an inversion tree for this index and this record
const bool skipNullKey = (ignoreNulls && !descending && !key.key_length);

// Skip this record if:
// 1) NULL key is found and we were asked to ignore them, or
// 2) there is an inversion tree for this index and this record
// is not in the bitmap for the inversion, or
// 2) the record has already been visited
// 3) the record has already been visited

if ((!(impure->irsb_flags & irsb_mustread) &&
if (skipNullKey ||
(!(impure->irsb_flags & irsb_mustread) &&
(!impure->irsb_nav_bitmap ||
!RecordBitmap::test(*impure->irsb_nav_bitmap, number.getValue()))) ||
RecordBitmap::test(impure->irsb_nav_records_visited, number.getValue()))
Expand Down
Loading