Skip to content

Commit

Permalink
Fixed CORE-1040: Wrong single-segment ascending index on character fi…
Browse files Browse the repository at this point in the history
…eld with NULL and empty string values
  • Loading branch information
hvlad committed Dec 6, 2006
1 parent 2fefa99 commit a211ffc
Show file tree
Hide file tree
Showing 2 changed files with 20 additions and 2 deletions.
5 changes: 5 additions & 0 deletions src/jrd/btr.cpp
Expand Up @@ -3161,6 +3161,10 @@ static SLONG fast_load(thread_db* tdbb,
duplicatesList.grow(segments);
memset(duplicatesList.begin(), 0, segments * sizeof(ULONG));

// hvlad: look at IDX_create_index for explanations about NULL indicator below
const bool isODS11 = (dbb->dbb_ods_version >= ODS_VERSION11);
const int nullIndLen = isODS11 && !descending && (idx->idx_count == 1) ? 1 : 0;

try {

// If there's an error during index construction, fall
Expand Down Expand Up @@ -3202,6 +3206,7 @@ static SLONG fast_load(thread_db* tdbb,
}
index_sort_record* isr = (index_sort_record*) (record + key_length);
count++;
record += nullIndLen;

// restore previous values
bucket = buckets[0];
Expand Down
17 changes: 15 additions & 2 deletions src/jrd/idx.cpp
Expand Up @@ -256,7 +256,17 @@ void IDX_create_index(
const bool isDescending = (idx->idx_flags & idx_descending);
const bool isPrimary = (idx->idx_flags & idx_primary);

const USHORT key_length = ROUNDUP(BTR_key_length(tdbb, relation, idx), sizeof(SLONG));
// hvlad: in ODS11 empty string and NULL values can have the same binary
// representation in index keys. BTR can distinguish it by the key_length
// but SORT module currently don't take it into account. Therefore add to
// the index key one byte prefix with 0 for NULL value and 1 for not-NULL
// value to produce right sorting.
// BTR\fast_load will remove this one byte prefix from the index key.
// Note that this is necessary only for single-segment ascending indexes
// and only for ODS11 and higer.

const int nullIndLen = isODS11 && !isDescending && (idx->idx_count == 1) ? 1 : 0;
const USHORT key_length = ROUNDUP(BTR_key_length(tdbb, relation, idx) + nullIndLen, sizeof(SLONG));

const USHORT max_key_size =
isODS11 ? MAX_KEY_LIMIT : MAX_KEY_PRE_ODS11;
Expand Down Expand Up @@ -459,11 +469,14 @@ void IDX_create_index(

USHORT l = key.key_length;

if (nullIndLen) {
*p++ = (key.key_length == 0) ? 0 : 1;
}
if (l > 0) {
memcpy(p, key.key_data, l);
p += l;
}
if ( (l = key_length - key.key_length) ) {
if ( (l = key_length - nullIndLen - key.key_length) ) {
memset(p, pad, l);
p += l;
}
Expand Down

0 comments on commit a211ffc

Please sign in to comment.