Skip to content

Commit 14530b4

Browse files
committed
Ignore NULLs (if desired) while scanning keys during index navigation
1 parent 9fccb55 commit 14530b4

File tree

1 file changed

+19
-4
lines changed

1 file changed

+19
-4
lines changed

src/jrd/recsrc/IndexTableScan.cpp

Lines changed: 19 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -198,13 +198,16 @@ bool IndexTableScan::internalGetRecord(thread_db* tdbb) const
198198
}
199199

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

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

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

209212
do
210213
{
@@ -252,6 +255,14 @@ bool IndexTableScan::internalGetRecord(thread_db* tdbb) const
252255
continue;
253256
}
254257

258+
// If we're walking in a descending index and we need to ignore NULLs
259+
// then stop at the first NULL we see (only for single segment!)
260+
if (descending && ignoreNulls && node.prefix == 0 &&
261+
node.length >= 1 && node.data[0] == 255)
262+
{
263+
break;
264+
}
265+
255266
// Build the current key value from the prefix and current node data.
256267
memcpy(key.key_data + node.prefix, node.data, node.length);
257268
key.key_length = node.length + node.prefix;
@@ -297,12 +308,16 @@ bool IndexTableScan::internalGetRecord(thread_db* tdbb) const
297308
break;
298309
}
299310

300-
// skip this record if:
301-
// 1) there is an inversion tree for this index and this record
311+
const bool skipNullKey = (ignoreNulls && !descending && !key.key_length);
312+
313+
// Skip this record if:
314+
// 1) NULL key is found and we were asked to ignore them, or
315+
// 2) there is an inversion tree for this index and this record
302316
// is not in the bitmap for the inversion, or
303-
// 2) the record has already been visited
317+
// 3) the record has already been visited
304318

305-
if ((!(impure->irsb_flags & irsb_mustread) &&
319+
if (skipNullKey ||
320+
(!(impure->irsb_flags & irsb_mustread) &&
306321
(!impure->irsb_nav_bitmap ||
307322
!RecordBitmap::test(*impure->irsb_nav_bitmap, number.getValue()))) ||
308323
RecordBitmap::test(impure->irsb_nav_records_visited, number.getValue()))

0 commit comments

Comments
 (0)