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:
parent
3022cf7f95
commit
5ca78a00f9
@ -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);
|
||||
|
@ -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
|
||||
|
@ -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);
|
||||
|
@ -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))
|
||||
{
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
@ -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
|
||||
|
@ -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*);
|
||||
|
Loading…
Reference in New Issue
Block a user