| 6594 | |
| 6595 | |
| 6596 | static contents remove_leaf_node(thread_db* tdbb, index_insertion* insertion, WIN* window) |
| 6597 | { |
| 6598 | /************************************** |
| 6599 | * |
| 6600 | * r e m o v e _ l e a f _ n o d e |
| 6601 | * |
| 6602 | ************************************** |
| 6603 | * |
| 6604 | * Functional description |
| 6605 | * Remove an index node from the leaf level. |
| 6606 | * |
| 6607 | **************************************/ |
| 6608 | SET_TDBB(tdbb); |
| 6609 | btree_page* page = (btree_page*) window->win_buffer; |
| 6610 | temporary_key* key = insertion->iib_key; |
| 6611 | |
| 6612 | const index_desc* const idx = insertion->iib_descriptor; |
| 6613 | const bool primary = (idx->idx_flags & idx_primary); |
| 6614 | const bool unique = (idx->idx_flags & idx_unique); |
| 6615 | const bool key_all_nulls = (key->key_nulls == (1 << idx->idx_count) - 1); |
| 6616 | const bool validateDuplicates = (unique && !key_all_nulls) || primary; |
| 6617 | |
| 6618 | // Look for the first node with the value to be removed. |
| 6619 | UCHAR* pointer; |
| 6620 | USHORT prefix; |
| 6621 | while (!(pointer = find_node_start_point(page, key, 0, &prefix, |
| 6622 | (idx->idx_flags & idx_descending), |
| 6623 | false, false, |
| 6624 | (validateDuplicates ? NO_VALUE : insertion->iib_number)))) |
| 6625 | { |
| 6626 | page = (btree_page*) CCH_HANDOFF(tdbb, window, page->btr_sibling, LCK_write, pag_index); |
| 6627 | } |
| 6628 | |
| 6629 | // Make sure first node looks ok |
| 6630 | IndexNode node; |
| 6631 | pointer = node.readNode(pointer, true); |
| 6632 | if (prefix > node.prefix || key->key_length != node.length + node.prefix) |
| 6633 | { |
| 6634 | #ifdef DEBUG_BTR |
| 6635 | CCH_RELEASE(tdbb, window); |
| 6636 | CORRUPT(204); // msg 204 index inconsistent |
| 6637 | #endif |
| 6638 | return contents_above_threshold; |
| 6639 | } |
| 6640 | |
| 6641 | if (node.length && memcmp(node.data, key->key_data + node.prefix, node.length)) |
| 6642 | { |
| 6643 | #ifdef DEBUG_BTR |
| 6644 | CCH_RELEASE(tdbb, window); |
| 6645 | CORRUPT(204); // msg 204 index inconsistent |
| 6646 | #endif |
| 6647 | return contents_above_threshold; |
| 6648 | } |
| 6649 | |
| 6650 | |
| 6651 | // ***************************************************** |
| 6652 | // AB: This becomes a very expensive task if there are |
| 6653 | // many duplicates inside the index (non-unique index)! |
no test coverage detected