diff --git a/src/dsql/ExprNodes.cpp b/src/dsql/ExprNodes.cpp index 12db93d945..519858bd0d 100644 --- a/src/dsql/ExprNodes.cpp +++ b/src/dsql/ExprNodes.cpp @@ -3560,10 +3560,7 @@ dsc* CastNode::execute(thread_db* tdbb, jrd_req* request) const if (!value) return NULL; - if (DTYPE_IS_BLOB(value->dsc_dtype) || DTYPE_IS_BLOB(impure->vlu_desc.dsc_dtype)) - blb::move(tdbb, value, &impure->vlu_desc); - else - MOV_move(tdbb, value, &impure->vlu_desc); + MOV_move(tdbb, value, &impure->vlu_desc); if (impure->vlu_desc.dsc_dtype == dtype_text) INTL_adjust_text_descriptor(tdbb, &impure->vlu_desc); diff --git a/src/jrd/exe.cpp b/src/jrd/exe.cpp index 66d5aa44a9..8f899e24b5 100644 --- a/src/jrd/exe.cpp +++ b/src/jrd/exe.cpp @@ -395,7 +395,7 @@ void EXE_assignment(thread_db* tdbb, const ValueExprNode* to, dsc* from_desc, bo if (DTYPE_IS_BLOB_OR_QUAD(from_desc->dsc_dtype) || DTYPE_IS_BLOB_OR_QUAD(to_desc->dsc_dtype)) { // ASF: Don't let MOV_move call blb::move because MOV - // will not pass the destination field to blb::_move. + // will not pass the destination field to blb::move. record_param* rpb = NULL; USHORT fieldId = 0; diff --git a/src/jrd/vio.cpp b/src/jrd/vio.cpp index 63d6a5ad55..a43e6eb7ef 100644 --- a/src/jrd/vio.cpp +++ b/src/jrd/vio.cpp @@ -1257,6 +1257,15 @@ void VIO_copy_record(thread_db* tdbb, record_param* org_rpb, record_param* new_r Record* const new_record = new_rpb->rpb_record; fb_assert(org_record && new_record); + // dimitr: Clear the req_null flag that may stay active after the last + // boolean evaluation. Here we use only EVL_field() calls that + // do not touch this flag and data copying is done only for + // non-NULL fields, so req_null should never be seen inside blb::move(). + // See CORE-6090 for details. + + jrd_req* const request = tdbb->getRequest(); + request->req_flags &= ~req_null; + // Copy the original record to the new record. If the format hasn't changed, // this is a simple move. If the format has changed, each field must be // fetched and moved separately, remembering to set the missing flag. @@ -1275,8 +1284,18 @@ void VIO_copy_record(thread_db* tdbb, record_param* org_rpb, record_param* new_r { if (EVL_field(org_rpb->rpb_relation, org_record, i, &org_desc)) { - if (DTYPE_IS_BLOB_OR_QUAD(org_desc.dsc_dtype) || DTYPE_IS_BLOB_OR_QUAD(new_desc.dsc_dtype)) - Jrd::blb::move(tdbb, &org_desc, &new_desc, new_rpb, i); + // If the source is not a blob or it's a temporary blob, + // then we'll need to materialize the resulting blob. + // Thus blb::move() is called with rpb and field ID. + // See also CORE-5600. + + const bool materialize = + (DTYPE_IS_BLOB_OR_QUAD(new_desc.dsc_dtype) && + !(DTYPE_IS_BLOB_OR_QUAD(org_desc.dsc_dtype) && + ((bid*) org_desc.dsc_address)->bid_internal.bid_relation_id)); + + if (materialize) + blb::move(tdbb, &org_desc, &new_desc, new_rpb, i); else MOV_move(tdbb, &org_desc, &new_desc); }