8
0
mirror of https://github.com/FirebirdSQL/firebird.git synced 2025-01-24 06:03:02 +01:00

Backport fix for bug CORE-5600 : Invalid blob id when add a new blob column of type text and update another field

This commit is contained in:
hvlad 2017-10-31 19:41:53 +02:00
parent a760da1a14
commit 8f893fda73
6 changed files with 36 additions and 31 deletions

View File

@ -2885,7 +2885,7 @@ dsc* CastNode::execute(thread_db* tdbb, jrd_req* request) const
return NULL;
if (DTYPE_IS_BLOB(value->dsc_dtype) || DTYPE_IS_BLOB(impure->vlu_desc.dsc_dtype))
blb::move(tdbb, value, &impure->vlu_desc, NULL);
blb::move(tdbb, value, &impure->vlu_desc);
else
MOV_move(tdbb, value, &impure->vlu_desc);

View File

@ -52,7 +52,6 @@
#include "../common/sdl.h"
#include "../jrd/intl.h"
#include "../jrd/cch.h"
#include "../dsql/ExprNodes.h"
#include "../common/gdsassert.h"
#include "../jrd/blb_proto.h"
#include "../jrd/blf_proto.h"
@ -87,7 +86,7 @@ static ArrayField* find_array(jrd_tra*, const bid*);
static BlobFilter* find_filter(thread_db*, SSHORT, SSHORT);
//static blob_page* get_next_page(thread_db*, blb*, WIN *);
//static void insert_page(thread_db*, blb*);
static void move_from_string(Jrd::thread_db*, const dsc*, dsc*, const ValueExprNode*);
static void move_from_string(Jrd::thread_db*, const dsc*, dsc*, const record_param* rpb, USHORT fieldId);
static void move_to_string(Jrd::thread_db*, dsc*, dsc*);
static void slice_callback(array_slice*, ULONG, dsc*);
static blb* store_array(thread_db*, jrd_tra*, bid*);
@ -947,7 +946,7 @@ SLONG blb::BLB_lseek(USHORT mode, SLONG offset)
// 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.
void blb::move(thread_db* tdbb, dsc* from_desc, dsc* to_desc, const ValueExprNode* field)
void blb::move(thread_db* tdbb, dsc* from_desc, dsc* to_desc, const record_param* rpb, USHORT fieldId)
{
/**************************************
*
@ -978,7 +977,7 @@ void blb::move(thread_db* tdbb, dsc* from_desc, dsc* to_desc, const ValueExprNod
if (!DTYPE_IS_BLOB_OR_QUAD(from_desc->dsc_dtype))
{
// anything that can be copied into a string can be copied into a blob
move_from_string(tdbb, from_desc, to_desc, field);
move_from_string(tdbb, from_desc, to_desc, rpb, fieldId);
return;
}
}
@ -990,23 +989,11 @@ void blb::move(thread_db* tdbb, dsc* from_desc, dsc* to_desc, const ValueExprNod
else
fb_assert(false);
bool simpleMove = true;
// If the target node is a field, we need more work to do.
const FieldNode* fieldNode = NULL;
if (field)
{
if ((fieldNode = ExprNode::as<FieldNode>(field)))
{
// We should not materialize the blob if the destination field
// stream (nod_union, for example) doesn't have a relation.
simpleMove = tdbb->getRequest()->req_rpb[fieldNode->fieldStream].rpb_relation == NULL;
}
else if (!(ExprNode::is<ParameterNode>(field) || ExprNode::is<VariableNode>(field)))
BUGCHECK(199); // msg 199 expected field node
}
// We should not materialize the blob if the destination field
// stream (nod_union, for example) doesn't have a relation.
const bool simpleMove = !rpb || (rpb->rpb_relation == NULL);
// Use local copy of source blob id to not change contents of from_desc in
// a case when it points to materialized temporary blob (see below for
@ -1062,8 +1049,6 @@ void blb::move(thread_db* tdbb, dsc* from_desc, dsc* to_desc, const ValueExprNod
}
jrd_req* request = tdbb->getRequest();
const USHORT id = fieldNode->fieldId;
record_param* rpb = &request->req_rpb[fieldNode->fieldStream];
jrd_rel* relation = rpb->rpb_relation;
if (relation->isVirtual()) {
@ -1078,12 +1063,12 @@ void blb::move(thread_db* tdbb, dsc* from_desc, dsc* to_desc, const ValueExprNod
if ((request->req_flags & req_null) || source->isEmpty())
{
record->setNull(id);
record->setNull(fieldId);
destination->clear();
return;
}
record->clearNull(id);
record->clearNull(fieldId);
jrd_tra* transaction = request->req_transaction;
transaction = transaction->getOuter();
@ -2503,7 +2488,7 @@ void blb::insert_page(thread_db* tdbb)
static void move_from_string(thread_db* tdbb, const dsc* from_desc, dsc* to_desc,
const ValueExprNode* field)
const record_param* rpb, USHORT fieldId)
{
/**************************************
*
@ -2557,7 +2542,7 @@ static void move_from_string(thread_db* tdbb, const dsc* from_desc, dsc* to_desc
blob->BLB_put_segment(tdbb, fromstr, length);
blob->BLB_close(tdbb);
ULONG blob_temp_id = blob->getTempId();
blb::move(tdbb, &blob_desc, to_desc, field);
blb::move(tdbb, &blob_desc, to_desc, rpb, fieldId);
// 14-June-2004. Nickolay Samofatov
// The code below saves a lot of memory when bunches of records are

View File

@ -55,7 +55,7 @@ class jrd_tra;
class vcl;
class thread_db;
struct win;
class ValueExprNode;
struct record_param;
class ArrayField;
struct impure_value;
@ -107,7 +107,7 @@ public:
static SLONG get_slice(Jrd::thread_db*, Jrd::jrd_tra*, const Jrd::bid*, const UCHAR*, USHORT,
const UCHAR*, SLONG, UCHAR*);
SLONG BLB_lseek(USHORT, SLONG);
static void move(thread_db* tdbb, dsc* from_desc, dsc* to_desc, const ValueExprNode* field);
static void move(thread_db* tdbb, dsc* from_desc, dsc* to_desc, const record_param* rpb = NULL, USHORT fieldId = 0);
static blb* open(thread_db*, jrd_tra*, const bid*);
static blb* open2(thread_db*, jrd_tra*, const bid*, USHORT, const UCHAR*, bool = false);
void BLB_put_data(thread_db*, const UCHAR*, SLONG);

View File

@ -371,7 +371,22 @@ void EXE_assignment(thread_db* tdbb, const ValueExprNode* to, dsc* from_desc, bo
{
// ASF: Don't let MOV_move call blb::move because MOV
// will not pass the destination field to blb::_move.
blb::move(tdbb, from_desc, to_desc, to);
record_param* rpb = NULL;
USHORT fieldId = 0;
if (to)
{
const FieldNode* toField = ExprNode::as<FieldNode>(to);
if (toField)
{
fieldId = toField->fieldId;
rpb = &request->req_rpb[toField->fieldStream];
}
else if (!(ExprNode::is<ParameterNode>(to) || ExprNode::is<VariableNode>(to)))
BUGCHECK(199); // msg 199 expected field node
}
blb::move(tdbb, from_desc, to_desc, rpb, fieldId);
}
else if (!DSC_EQUIV(from_desc, to_desc, false))
{

View File

@ -446,7 +446,7 @@ void MOV_move(Jrd::thread_db* tdbb, /*const*/ dsc* from, dsc* to)
**************************************/
if (DTYPE_IS_BLOB_OR_QUAD(from->dsc_dtype) || DTYPE_IS_BLOB_OR_QUAD(to->dsc_dtype))
Jrd::blb::move(tdbb, from, to, NULL);
Jrd::blb::move(tdbb, from, to);
else
CVT_move(from, to);
}

View File

@ -1284,7 +1284,12 @@ void VIO_copy_record(thread_db* tdbb, record_param* org_rpb, record_param* new_r
if (EVL_field(new_rpb->rpb_relation, new_record, i, &new_desc))
{
if (EVL_field(org_rpb->rpb_relation, org_record, i, &org_desc))
MOV_move(tdbb, &org_desc, &new_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);
else
MOV_move(tdbb, &org_desc, &new_desc);
}
else
{
new_record->setNull(i);