| 1668 | } |
| 1669 | |
| 1670 | static idx_e check_duplicates(thread_db* tdbb, |
| 1671 | Record* record, |
| 1672 | index_desc* record_idx, |
| 1673 | index_insertion* insertion, jrd_rel* relation_2) |
| 1674 | { |
| 1675 | /************************************** |
| 1676 | * |
| 1677 | * c h e c k _ d u p l i c a t e s |
| 1678 | * |
| 1679 | ************************************** |
| 1680 | * |
| 1681 | * Functional description |
| 1682 | * Make sure there aren't any active duplicates for |
| 1683 | * a unique index or a foreign key. |
| 1684 | * |
| 1685 | **************************************/ |
| 1686 | DSC desc1, desc2; |
| 1687 | |
| 1688 | SET_TDBB(tdbb); |
| 1689 | |
| 1690 | idx_e result = idx_e_ok; |
| 1691 | jrd_tra* const transaction = insertion->iib_transaction; |
| 1692 | index_desc* insertion_idx = insertion->iib_descriptor; |
| 1693 | record_param rpb; |
| 1694 | rpb.rpb_relation = insertion->iib_relation; |
| 1695 | |
| 1696 | AutoTempRecord gc_record(VIO_gc_record(tdbb, rpb.rpb_relation)); |
| 1697 | rpb.rpb_record = gc_record; |
| 1698 | |
| 1699 | jrd_rel* const relation_1 = insertion->iib_relation; |
| 1700 | RecordBitmap::Accessor accessor(insertion->iib_duplicates); |
| 1701 | |
| 1702 | fb_assert(!(tdbb->tdbb_status_vector->getState() & IStatus::STATE_ERRORS)); |
| 1703 | |
| 1704 | if (accessor.getFirst()) |
| 1705 | do { |
| 1706 | bool rec_tx_active; |
| 1707 | const bool is_fk = (record_idx->idx_flags & idx_foreign) != 0; |
| 1708 | |
| 1709 | rpb.rpb_number.setValue(accessor.current()); |
| 1710 | |
| 1711 | if (rpb.rpb_number != insertion->iib_number && |
| 1712 | VIO_get_current(tdbb, &rpb, transaction, tdbb->getDefaultPool(), |
| 1713 | is_fk, rec_tx_active) ) |
| 1714 | { |
| 1715 | // hvlad: if record's transaction is still active, we should consider |
| 1716 | // it as present and prevent duplicates |
| 1717 | |
| 1718 | if ((rpb.rpb_flags & rpb_deleted) || rec_tx_active) |
| 1719 | { |
| 1720 | result = idx_e_duplicate; |
| 1721 | break; |
| 1722 | } |
| 1723 | |
| 1724 | // check the values of the fields in the record being inserted with the |
| 1725 | // record retrieved -- for unique indexes the insertion index and the |
| 1726 | // record index are the same, but for foreign keys they are different |
| 1727 |
no test coverage detected