| 1587 | } |
| 1588 | |
| 1589 | static bool cmpRecordKeys(thread_db* tdbb, |
| 1590 | Record* rec1, jrd_rel* rel1, index_desc* idx1, |
| 1591 | Record* rec2, jrd_rel* rel2, index_desc* idx2) |
| 1592 | { |
| 1593 | /************************************** |
| 1594 | * |
| 1595 | * c m p R e c o r d K e y s |
| 1596 | * |
| 1597 | ************************************** |
| 1598 | * |
| 1599 | * Functional description |
| 1600 | * Compare indexed fields in two records. Records could belong to different |
| 1601 | * relations but set of indexed fields to compare should be equal. |
| 1602 | * |
| 1603 | **************************************/ |
| 1604 | if (idx2->idx_flags & idx_expression) |
| 1605 | { |
| 1606 | // Remove assertion below if\when expression index will participate in FK, |
| 1607 | // currently it is impossible. |
| 1608 | fb_assert(idx1->idx_flags & idx_expression); |
| 1609 | |
| 1610 | if (auto idxDesc = BTR_eval_expression(tdbb, idx2, rec2)) |
| 1611 | { |
| 1612 | HalfStaticArray<UCHAR, 256> tmp; |
| 1613 | dsc tempDesc; |
| 1614 | |
| 1615 | if (idx1 == idx2) |
| 1616 | { |
| 1617 | // hvlad: BTR_eval_expression call EVL_expr which returns impure->vlu_desc. |
| 1618 | // If idx2 and idx1 are the same indexes then the second call to |
| 1619 | // BTR_eval_expression will overwrite value from the first call. |
| 1620 | // So we must save the first result into another dsc. |
| 1621 | |
| 1622 | tempDesc = *idxDesc; |
| 1623 | const auto idxDscLength = idx2->idx_expression_desc.dsc_length; |
| 1624 | tempDesc.dsc_address = tmp.getBuffer(idxDscLength + FB_DOUBLE_ALIGN); |
| 1625 | tempDesc.dsc_address = FB_ALIGN(tempDesc.dsc_address, FB_DOUBLE_ALIGN); |
| 1626 | fb_assert(idxDesc->dsc_length <= idxDscLength); |
| 1627 | memmove(tempDesc.dsc_address, idxDesc->dsc_address, idxDesc->dsc_length); |
| 1628 | idxDesc = &tempDesc; |
| 1629 | } |
| 1630 | |
| 1631 | if (const auto recDesc = BTR_eval_expression(tdbb, idx1, rec1)) |
| 1632 | { |
| 1633 | if (!MOV_compare(tdbb, recDesc, idxDesc)) |
| 1634 | return true; |
| 1635 | } |
| 1636 | } |
| 1637 | } |
| 1638 | else |
| 1639 | { |
| 1640 | fb_assert(idx1->idx_count == idx2->idx_count); |
| 1641 | |
| 1642 | dsc desc1, desc2; |
| 1643 | bool all_nulls = true; |
| 1644 | USHORT i; |
| 1645 | |
| 1646 | for (i = 0; i < idx1->idx_count; i++) |
no test coverage detected