8
0
mirror of https://github.com/FirebirdSQL/firebird.git synced 2025-01-23 06:03:02 +01:00

frontported fixes from 2.0

This commit is contained in:
alexpeshkoff 2006-12-15 17:30:41 +00:00
parent c063adce3e
commit 8896a21641

View File

@ -211,8 +211,10 @@ static CONTENTS remove_node(thread_db*, index_insertion*, WIN*);
static CONTENTS remove_leaf_node(thread_db*, index_insertion*, WIN*);
static bool scan(thread_db*, UCHAR*, RecordBitmap**, index_desc*,
IndexRetrieval*, USHORT, temporary_key*, const SCHAR,
bool&, const USHORT);
bool&, const temporary_key&);
static void update_selectivity(index_root_page*, USHORT, const SelectivityList&);
static void checkForLowerKeySkip(bool&, const bool, const IndexNode&, const temporary_key&,
const index_desc&, const IndexRetrieval*);
USHORT BTR_all(thread_db* tdbb,
jrd_rel* relation,
@ -487,7 +489,7 @@ DSC* BTR_eval_expression(thread_db* tdbb, index_desc* idx, Record* record, bool
}
inline void checkForLowerKeySkip(
static void checkForLowerKeySkip(
bool& skipLowerKey,
const bool partLower,
const IndexNode& node,
@ -495,19 +497,56 @@ inline void checkForLowerKeySkip(
const index_desc& idx,
const IndexRetrieval* retrieval)
{
if (skipLowerKey)
if (node.prefix == 0)
{
// are we skip all duplicates of lower key ?
// If the prefix is 0 we have a full key.
// (first node on every new page for example has prefix zero)
if (partLower)
{
// With multi-segment compare first part of data with lowerKey
skipLowerKey =
((lower.key_length <= node.length) &&
(memcmp(node.data, lower.key_data, lower.key_length) == 0));
if (skipLowerKey && (node.length > lower.key_length))
{
// We've bigger data in the node as the lowerKey,
// now check the segment-number
const UCHAR *segp = node.data + lower.key_length;
const USHORT segnum =
idx.idx_count - (UCHAR)((idx.idx_flags & idx_descending) ?
((*segp) ^ -1) : *segp);
if (segnum < retrieval->irb_lower_count)
{
skipLowerKey = false;
}
}
}
else
{
// Compare full data with lowerKey
skipLowerKey =
((lower.key_length == node.length) &&
(memcmp(node.data, lower.key_data, lower.key_length) == 0));
}
}
else
{
// Check if we have a duplicate node (for the same page)
if (node.prefix < lower.key_length) {
skipLowerKey = false;
}
else if ((node.prefix == lower.key_length) && node.length)
{
// In case of multi-segment check segment-number else
// it's a different key
if (partLower)
{
const USHORT segnum =
idx.idx_count - (UCHAR)(idx.idx_flags & idx_descending ?
(*node.data) ^ -1 : *node.data);
idx.idx_count - (UCHAR)((idx.idx_flags & idx_descending) ?
(*node.data) ^ -1 : *node.data);
if (segnum < retrieval->irb_lower_count) {
skipLowerKey = false;
@ -623,7 +662,7 @@ void BTR_evaluate(thread_db* tdbb, IndexRetrieval* retrieval, RecordBitmap** bit
// if there is an upper bound, scan the index pages looking for it
if (retrieval->irb_upper_count) {
while (scan(tdbb, pointer, bitmap, &idx, retrieval, prefix, &upper, flags,
skipLowerKey, lower.key_length))
skipLowerKey, lower))
{
page = (btree_page*) CCH_HANDOFF(tdbb, &window, page->btr_sibling,
LCK_read, pag_index);
@ -659,6 +698,12 @@ void BTR_evaluate(thread_db* tdbb, IndexRetrieval* retrieval, RecordBitmap** bit
break;
}
if (skipLowerKey)
{
checkForLowerKeySkip(skipLowerKey, partLower, node,
lower, idx, retrieval);
}
if (!skipLowerKey) {
RBM_SET(tdbb->getDefaultPool(), bitmap, node.recordNumber.getValue());
}
@ -667,9 +712,6 @@ void BTR_evaluate(thread_db* tdbb, IndexRetrieval* retrieval, RecordBitmap** bit
if (pointer > endPointer) {
BUGCHECK(204); // msg 204 index inconsistent
}
checkForLowerKeySkip(skipLowerKey, partLower, node,
lower, idx, retrieval);
continue;
}
@ -6352,7 +6394,7 @@ static CONTENTS remove_leaf_node(thread_db* tdbb, index_insertion* insertion, WI
static bool scan(thread_db* tdbb, UCHAR* pointer, RecordBitmap** bitmap,
index_desc* idx, IndexRetrieval* retrieval, USHORT prefix,
temporary_key* key, const SCHAR page_flags,
bool& skipLowerKey, const USHORT lowerKeyLen)
bool& skipLowerKey, const temporary_key& lowerKey)
{
/**************************************
*
@ -6516,6 +6558,12 @@ static bool scan(thread_db* tdbb, UCHAR* pointer, RecordBitmap** bitmap,
}
}
if (skipLowerKey)
{
checkForLowerKeySkip(skipLowerKey, partLower, node,
lowerKey, *idx, retrieval);
}
if (!ignore && !skipLowerKey) {
if ((flag & irb_starting) || !count) {
RBM_SET(tdbb->getDefaultPool(), bitmap, node.recordNumber.getValue());
@ -6526,28 +6574,6 @@ static bool scan(thread_db* tdbb, UCHAR* pointer, RecordBitmap** bitmap,
}
pointer = BTreeNode::readNode(&node, pointer, page_flags, true);
if (skipLowerKey)
{
if (node.prefix < lowerKeyLen) {
skipLowerKey = false;
}
else if ((node.prefix == lowerKeyLen) && node.length)
{
if (partLower)
{
const USHORT segnum = idx->idx_count -
(UCHAR)(descending ? (*node.data) ^ -1 : *node.data);
if (segnum < retrieval->irb_lower_count) {
skipLowerKey = false;
}
}
else {
skipLowerKey = false;
}
}
}
}
}
else {
@ -6677,10 +6703,10 @@ static bool scan(thread_db* tdbb, UCHAR* pointer, RecordBitmap** bitmap,
node = NEXT_NODE(node);
if (skipLowerKey) {
if (node->btn_prefix < lowerKeyLen) {
if (node->btn_prefix < lowerKey.key_length) {
skipLowerKey = false;
}
else if ((node->btn_prefix == lowerKeyLen) && node->btn_length)
else if ((node->btn_prefix == lowerKey.key_length) && node->btn_length)
{
if (partLower)
{