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

Avoid using rpb in places where only record is needed, this also fixes a regression after #6995

This commit is contained in:
Dmitry Yemanov 2021-11-25 10:33:29 +03:00
parent 3022cf7f95
commit 5ca78a00f9
7 changed files with 67 additions and 61 deletions

View File

@ -7103,10 +7103,11 @@ const StmtNode* ModifyNode::modify(thread_db* tdbb, jrd_req* request, WhichTrigg
newRpb->rpb_length = newFormat->fmt_length;
newRpb->rpb_format_number = newFormat->fmt_version;
if (!orgRpb->rpb_record)
Record* orgRecord = orgRpb->rpb_record;
if (!orgRecord)
{
const Format* const orgFormat = newFormat;
Record* const orgRecord = VIO_record(tdbb, orgRpb, orgFormat, tdbb->getDefaultPool());
orgRecord = VIO_record(tdbb, orgRpb, orgFormat, tdbb->getDefaultPool());
orgRpb->rpb_address = orgRecord->getData();
orgRpb->rpb_length = orgFormat->fmt_length;
orgRpb->rpb_format_number = orgFormat->fmt_version;
@ -7114,7 +7115,7 @@ const StmtNode* ModifyNode::modify(thread_db* tdbb, jrd_req* request, WhichTrigg
// Copy the original record to the new record
VIO_copy_record(tdbb, orgRpb, newRpb);
VIO_copy_record(tdbb, relation, orgRecord, newRecord);
newRpb->rpb_number = orgRpb->rpb_number;
newRpb->rpb_number.setValid(true);

View File

@ -87,7 +87,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 record_param* rpb, USHORT fieldId);
static void move_from_string(Jrd::thread_db*, const dsc*, dsc*, jrd_rel*, Record*, USHORT);
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*);
@ -949,7 +949,8 @@ 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 record_param* rpb, USHORT fieldId)
void blb::move(thread_db* tdbb, dsc* from_desc, dsc* to_desc,
jrd_rel* relation, Record* record, USHORT fieldId)
{
/**************************************
*
@ -980,7 +981,7 @@ void blb::move(thread_db* tdbb, dsc* from_desc, dsc* to_desc, const record_param
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, rpb, fieldId);
move_from_string(tdbb, from_desc, to_desc, relation, record, fieldId);
return;
}
}
@ -996,7 +997,7 @@ void blb::move(thread_db* tdbb, dsc* from_desc, dsc* to_desc, const record_param
// 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);
const bool simpleMove = (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
@ -1052,14 +1053,12 @@ void blb::move(thread_db* tdbb, dsc* from_desc, dsc* to_desc, const record_param
}
jrd_req* request = tdbb->getRequest();
jrd_rel* relation = rpb->rpb_relation;
if (relation->isVirtual()) {
ERR_post(Arg::Gds(isc_read_only));
}
RelationPages* relPages = relation->getPages(tdbb);
Record* record = rpb->rpb_record;
// If either the source value is null or the blob id itself is null
// (all zeros), then the blob is null.
@ -2502,7 +2501,7 @@ void blb::insert_page(thread_db* tdbb)
static void move_from_string(thread_db* tdbb, const dsc* from_desc, dsc* to_desc,
const record_param* rpb, USHORT fieldId)
jrd_rel* relation, Record* record, USHORT fieldId)
{
/**************************************
*
@ -2558,7 +2557,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, rpb, fieldId);
blb::move(tdbb, &blob_desc, to_desc, relation, record, fieldId);
// 14-June-2004. Nickolay Samofatov
// The code below saves a lot of memory when bunches of records are

View File

@ -56,7 +56,7 @@ class jrd_tra;
class vcl;
class thread_db;
struct win;
struct record_param;
class Record;
class ArrayField;
struct impure_value;
@ -109,7 +109,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 record_param* rpb = NULL, USHORT fieldId = 0);
static void move(thread_db* tdbb, dsc* from_desc, dsc* to_desc, jrd_rel* relation = nullptr, Record* record = nullptr, 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

@ -399,21 +399,25 @@ 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.
record_param* rpb = NULL;
jrd_rel* relation = nullptr;
Record* record = nullptr;
USHORT fieldId = 0;
if (to)
{
const FieldNode* toField = nodeAs<FieldNode>(to);
if (toField)
{
const auto rpb = &request->req_rpb[toField->fieldStream];
relation = rpb->rpb_relation;
record = rpb->rpb_record;
fieldId = toField->fieldId;
rpb = &request->req_rpb[toField->fieldStream];
}
else if (!(nodeAs<ParameterNode>(to) || nodeAs<VariableNode>(to)))
BUGCHECK(199); // msg 199 expected field node
}
blb::move(tdbb, from_desc, to_desc, rpb, fieldId);
blb::move(tdbb, from_desc, to_desc, relation, record, fieldId);
}
else if (!DSC_EQUIV(from_desc, to_desc, false))
{

View File

@ -432,7 +432,8 @@ void SortedStream::mapData(thread_db* tdbb, jrd_req* request, UCHAR* data) const
const auto relation = rpb->rpb_relation;
// Ensure the record is still in the most recent format
VIO_record(tdbb, rpb, MET_current(tdbb, relation), tdbb->getDefaultPool());
const auto record =
VIO_record(tdbb, rpb, MET_current(tdbb, relation), tdbb->getDefaultPool());
// Set all fields to NULL if the stream was originally marked as invalid
if (!rpb->rpb_number.isValid())
@ -456,7 +457,7 @@ void SortedStream::mapData(thread_db* tdbb, jrd_req* request, UCHAR* data) const
auto temp = *rpb;
temp.rpb_record = nullptr;
AutoPtr<Record> cleanupRecord;
AutoPtr<Record> tempRecord;
// If the primary record version disappeared, we cannot proceed
@ -470,9 +471,9 @@ void SortedStream::mapData(thread_db* tdbb, jrd_req* request, UCHAR* data) const
if (!(temp.rpb_runtime_flags & RPB_undo_data))
VIO_data(tdbb, &temp, tdbb->getDefaultPool());
cleanupRecord = temp.rpb_record;
tempRecord = temp.rpb_record;
VIO_copy_record(tdbb, &temp, rpb);
VIO_copy_record(tdbb, relation, tempRecord, record);
if (temp.rpb_transaction_nr == orgTraNum && orgTraNum != selfTraNum)
continue; // we surely see the original record version
@ -588,11 +589,11 @@ void SortedStream::mapData(thread_db* tdbb, jrd_req* request, UCHAR* data) const
VIO_data(tdbb, &temp, tdbb->getDefaultPool());
cleanupRecord.reset(temp.rpb_record);
tempRecord.reset(temp.rpb_record);
++backversions;
}
VIO_copy_record(tdbb, &temp, rpb);
VIO_copy_record(tdbb, relation, tempRecord, record);
}
}

View File

@ -1252,7 +1252,7 @@ bool VIO_chase_record_version(thread_db* tdbb, record_param* rpb,
}
void VIO_copy_record(thread_db* tdbb, record_param* org_rpb, record_param* new_rpb)
void VIO_copy_record(thread_db* tdbb, jrd_rel* relation, Record* orgRecord, Record* newRecord)
{
/**************************************
*
@ -1264,60 +1264,60 @@ void VIO_copy_record(thread_db* tdbb, record_param* org_rpb, record_param* new_r
* Copy the given record to a new destination,
* taking care about possible format differences.
**************************************/
fb_assert(org_rpb && new_rpb);
Record* const org_record = org_rpb->rpb_record;
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();
const auto request = tdbb->getRequest();
request->req_flags &= ~req_null;
const auto orgFormat = orgRecord->getFormat();
const auto newFormat = newRecord->getFormat();
fb_assert(orgFormat && newFormat);
// 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.
if (new_rpb->rpb_format_number == org_rpb->rpb_format_number)
new_record->copyDataFrom(org_record, true);
else
if (newFormat->fmt_version == orgFormat->fmt_version)
{
DSC org_desc, new_desc;
newRecord->copyDataFrom(orgRecord, true);
return;
}
for (USHORT i = 0; i < new_record->getFormat()->fmt_count; i++)
dsc orgDesc, newDesc;
for (USHORT i = 0; i < newFormat->fmt_count; i++)
{
newRecord->clearNull(i);
if (EVL_field(relation, newRecord, i, &newDesc))
{
new_record->clearNull(i);
if (EVL_field(new_rpb->rpb_relation, new_record, i, &new_desc))
if (EVL_field(relation, orgRecord, i, &orgDesc))
{
if (EVL_field(org_rpb->rpb_relation, org_record, i, &org_desc))
{
// 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.
// 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));
const bool materialize =
(DTYPE_IS_BLOB_OR_QUAD(newDesc.dsc_dtype) &&
!(DTYPE_IS_BLOB_OR_QUAD(orgDesc.dsc_dtype) &&
((bid*) orgDesc.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);
}
if (materialize)
blb::move(tdbb, &orgDesc, &newDesc, relation, newRecord, i);
else
{
new_record->setNull(i);
MOV_move(tdbb, &orgDesc, &newDesc);
}
else
{
newRecord->setNull(i);
if (new_desc.dsc_dtype)
memset(new_desc.dsc_address, 0, new_desc.dsc_length);
}
if (!newDesc.isUnknown())
memset(newDesc.dsc_address, 0, newDesc.dsc_length);
}
}
}
@ -4038,9 +4038,10 @@ bool VIO_writelock(thread_db* tdbb, record_param* org_rpb, jrd_tra* transaction)
transaction->tra_flags |= TRA_write;
if (!org_rpb->rpb_record)
Record* org_record = org_rpb->rpb_record;
if (!org_record)
{
Record* const org_record = VIO_record(tdbb, org_rpb, NULL, tdbb->getDefaultPool());
org_record = VIO_record(tdbb, org_rpb, NULL, tdbb->getDefaultPool());
org_rpb->rpb_address = org_record->getData();
const Format* const org_format = org_record->getFormat();
org_rpb->rpb_length = org_format->fmt_length;
@ -4066,7 +4067,7 @@ bool VIO_writelock(thread_db* tdbb, record_param* org_rpb, jrd_tra* transaction)
new_rpb.rpb_length = new_format->fmt_length;
new_rpb.rpb_format_number = new_format->fmt_version;
VIO_copy_record(tdbb, org_rpb, &new_rpb);
VIO_copy_record(tdbb, relation, org_record, new_record);
}
// We're about to lock the record. Post a refetch request

View File

@ -40,7 +40,7 @@ namespace Jrd {
void VIO_backout(Jrd::thread_db*, Jrd::record_param*, const Jrd::jrd_tra*);
bool VIO_chase_record_version(Jrd::thread_db*, Jrd::record_param*,
Jrd::jrd_tra*, MemoryPool*, bool, bool);
void VIO_copy_record(Jrd::thread_db*, Jrd::record_param*, Jrd::record_param*);
void VIO_copy_record(Jrd::thread_db*, Jrd::jrd_rel*, Jrd::Record*, Jrd::Record*);
void VIO_data(Jrd::thread_db*, Jrd::record_param*, MemoryPool*);
bool VIO_erase(Jrd::thread_db*, Jrd::record_param*, Jrd::jrd_tra*);
void VIO_fini(Jrd::thread_db*);