@@ -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