| 1685 | |
| 1686 | |
| 1687 | void VIO_copy_record(thread_db* tdbb, jrd_rel* relation, Record* orgRecord, Record* newRecord) |
| 1688 | { |
| 1689 | /************************************** |
| 1690 | * |
| 1691 | * V I O _ c o p y _ r e c o r d |
| 1692 | * |
| 1693 | ************************************** |
| 1694 | * |
| 1695 | * Functional description |
| 1696 | * Copy the given record to a new destination, |
| 1697 | * taking care about possible format differences. |
| 1698 | **************************************/ |
| 1699 | // dimitr: Clear the req_null flag that may stay active after the last |
| 1700 | // boolean evaluation. Here we use only EVL_field() calls that |
| 1701 | // do not touch this flag and data copying is done only for |
| 1702 | // non-NULL fields, so req_null should never be seen inside blb::move(). |
| 1703 | // See CORE-6090 for details. |
| 1704 | |
| 1705 | const auto request = tdbb->getRequest(); |
| 1706 | request->req_flags &= ~req_null; |
| 1707 | |
| 1708 | const auto orgFormat = orgRecord->getFormat(); |
| 1709 | const auto newFormat = newRecord->getFormat(); |
| 1710 | fb_assert(orgFormat && newFormat); |
| 1711 | |
| 1712 | // Copy the original record to the new record. If the format hasn't changed, |
| 1713 | // this is a simple move. If the format has changed, each field must be |
| 1714 | // fetched and moved separately, remembering to set the missing flag. |
| 1715 | |
| 1716 | if (newFormat->fmt_version == orgFormat->fmt_version) |
| 1717 | { |
| 1718 | newRecord->copyDataFrom(orgRecord, true); |
| 1719 | return; |
| 1720 | } |
| 1721 | |
| 1722 | dsc orgDesc, newDesc; |
| 1723 | |
| 1724 | for (USHORT i = 0; i < newFormat->fmt_count; i++) |
| 1725 | { |
| 1726 | newRecord->clearNull(i); |
| 1727 | |
| 1728 | if (EVL_field(relation, newRecord, i, &newDesc)) |
| 1729 | { |
| 1730 | if (EVL_field(relation, orgRecord, i, &orgDesc)) |
| 1731 | { |
| 1732 | // If the source is not a blob or it's a temporary blob, |
| 1733 | // then we'll need to materialize the resulting blob. |
| 1734 | // Thus blb::move() is called with rpb and field ID. |
| 1735 | // See also CORE-5600. |
| 1736 | |
| 1737 | const bool materialize = |
| 1738 | (DTYPE_IS_BLOB_OR_QUAD(newDesc.dsc_dtype) && |
| 1739 | !(DTYPE_IS_BLOB_OR_QUAD(orgDesc.dsc_dtype) && |
| 1740 | ((bid*) orgDesc.dsc_address)->bid_internal.bid_relation_id)); |
| 1741 | |
| 1742 | if (materialize) |
| 1743 | blb::move(tdbb, &orgDesc, &newDesc, relation, newRecord, i); |
| 1744 | else |
no test coverage detected