This function can't take from_desc as const because it may call store_array, which in turn calls blb::create2 that writes in the blob id. Although the compiler allows to modify from_desc->dsc_address' contents when from_desc is constant, this is misleading so I didn't make the source descriptor constant.
| 1001 | // compiler allows to modify from_desc->dsc_address' contents when from_desc is |
| 1002 | // constant, this is misleading so I didn't make the source descriptor constant. |
| 1003 | void blb::move(thread_db* tdbb, dsc* from_desc, dsc* to_desc, |
| 1004 | jrd_rel* relation, Record* record, USHORT fieldId, bool bulk) |
| 1005 | { |
| 1006 | /************************************** |
| 1007 | * |
| 1008 | * b l b : : m o v e |
| 1009 | * |
| 1010 | ************************************** |
| 1011 | * |
| 1012 | * Functional description |
| 1013 | * Perform an assignment to a blob field or a blob descriptor. |
| 1014 | * When assigning to a field, unless the blob is null, |
| 1015 | * this requires that either a temporary blob be materialized or that |
| 1016 | * a permanent blob be copied. Note: it is illegal to have a blob |
| 1017 | * field in a message. |
| 1018 | * |
| 1019 | **************************************/ |
| 1020 | SET_TDBB(tdbb); |
| 1021 | |
| 1022 | if (to_desc->dsc_dtype == dtype_array) |
| 1023 | { |
| 1024 | // only array->array conversions are allowed |
| 1025 | if (from_desc->dsc_dtype != dtype_array && from_desc->dsc_dtype != dtype_quad) |
| 1026 | { |
| 1027 | ERR_post(Arg::Gds(isc_array_convert_error)); |
| 1028 | } |
| 1029 | } |
| 1030 | else if (DTYPE_IS_BLOB_OR_QUAD(to_desc->dsc_dtype)) |
| 1031 | { |
| 1032 | if (!DTYPE_IS_BLOB_OR_QUAD(from_desc->dsc_dtype)) |
| 1033 | { |
| 1034 | // anything that can be copied into a string can be copied into a blob |
| 1035 | move_from_string(tdbb, from_desc, to_desc, relation, record, fieldId); |
| 1036 | return; |
| 1037 | } |
| 1038 | } |
| 1039 | else if (DTYPE_IS_BLOB_OR_QUAD(from_desc->dsc_dtype)) |
| 1040 | { |
| 1041 | move_to_string(tdbb, from_desc, to_desc); |
| 1042 | return; |
| 1043 | } |
| 1044 | else |
| 1045 | fb_assert(false); |
| 1046 | |
| 1047 | // If the target node is a field, we need more work to do. |
| 1048 | |
| 1049 | // We should not materialize the blob if the destination field |
| 1050 | // stream (nod_union, for example) doesn't have a relation. |
| 1051 | const bool simpleMove = (relation == NULL); |
| 1052 | |
| 1053 | // Use local copy of source blob id to not change contents of from_desc in |
| 1054 | // a case when it points to materialized temporary blob (see below for |
| 1055 | // assignment to *source). |
| 1056 | bid srcBlobID = *(bid*)from_desc->dsc_address; |
| 1057 | bid* source = &srcBlobID; |
| 1058 | bid* destination = (bid*) to_desc->dsc_address; |
| 1059 | |
| 1060 | // If nothing changed, do nothing. If it isn't broken, don't fix it. |
nothing calls this directly
no test coverage detected