mirror of
https://github.com/FirebirdSQL/firebird.git
synced 2025-01-24 01:23:03 +01:00
Fixed CORE-3138: Internal error or crash occurs when accessing any MON$ table after altering its structure.
This commit is contained in:
parent
3bb7d22126
commit
f2c890e1fc
@ -614,31 +614,48 @@ DatabaseSnapshot::~DatabaseSnapshot()
|
||||
}
|
||||
|
||||
|
||||
RecordBuffer* DatabaseSnapshot::getData(const jrd_rel* relation) const
|
||||
const DatabaseSnapshot::RelationData* DatabaseSnapshot::getRelationData(int id) const
|
||||
{
|
||||
fb_assert(relation);
|
||||
|
||||
for (size_t i = 0; i < snapshot.getCount(); i++)
|
||||
{
|
||||
if (snapshot[i].rel_id == relation->rel_id)
|
||||
return snapshot[i].data;
|
||||
if (snapshot[i].rel_id == id)
|
||||
return &snapshot[i];
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
const Format* DatabaseSnapshot::getFormat(const jrd_rel* relation) const
|
||||
{
|
||||
fb_assert(relation);
|
||||
|
||||
const RelationData* const relData = getRelationData(relation->rel_id);
|
||||
return relData ? relData->format : NULL;
|
||||
}
|
||||
|
||||
|
||||
RecordBuffer* DatabaseSnapshot::getData(const jrd_rel* relation) const
|
||||
{
|
||||
fb_assert(relation);
|
||||
|
||||
const RelationData* const relData = getRelationData(relation->rel_id);
|
||||
return relData ? relData->data : NULL;
|
||||
}
|
||||
|
||||
|
||||
RecordBuffer* DatabaseSnapshot::allocBuffer(thread_db* tdbb, MemoryPool& pool, int rel_id)
|
||||
{
|
||||
jrd_rel* relation = MET_lookup_relation_id(tdbb, rel_id, false);
|
||||
jrd_rel* const relation = MET_lookup_relation_id(tdbb, rel_id, false);
|
||||
fb_assert(relation);
|
||||
MET_scan_relation(tdbb, relation);
|
||||
fb_assert(relation->isVirtual());
|
||||
Format* format = MET_current(tdbb, relation);
|
||||
|
||||
const Format* const format = MET_current(tdbb, relation);
|
||||
fb_assert(format);
|
||||
|
||||
RecordBuffer* buffer = FB_NEW(pool) RecordBuffer(pool, format);
|
||||
RelationData data = {relation->rel_id, buffer};
|
||||
RecordBuffer* const buffer = FB_NEW(pool) RecordBuffer(pool, format);
|
||||
RelationData data = {relation->rel_id, format, buffer};
|
||||
snapshot.add(data);
|
||||
|
||||
return buffer;
|
||||
@ -662,9 +679,18 @@ void DatabaseSnapshot::putField(thread_db* tdbb, Record* record, const DumpField
|
||||
fb_assert(record);
|
||||
|
||||
const Format* const format = record->rec_format;
|
||||
fb_assert(format && field.id < format->fmt_count);
|
||||
fb_assert(format);
|
||||
|
||||
dsc to_desc;
|
||||
|
||||
if (field.id < format->fmt_count)
|
||||
{
|
||||
to_desc = format->fmt_desc[field.id];
|
||||
}
|
||||
|
||||
if (to_desc.isUnknown())
|
||||
return;
|
||||
|
||||
dsc to_desc = format->fmt_desc[field.id];
|
||||
to_desc.dsc_address += (IPTR) record->rec_data;
|
||||
|
||||
if (field.type == VALUE_GLOBAL_ID)
|
||||
|
@ -180,6 +180,7 @@ class DatabaseSnapshot
|
||||
struct RelationData
|
||||
{
|
||||
int rel_id;
|
||||
const Format* format;
|
||||
RecordBuffer* data;
|
||||
};
|
||||
|
||||
@ -318,6 +319,7 @@ private:
|
||||
public:
|
||||
~DatabaseSnapshot();
|
||||
|
||||
const Format* getFormat(const jrd_rel*) const;
|
||||
RecordBuffer* getData(const jrd_rel*) const;
|
||||
|
||||
static DatabaseSnapshot* create(thread_db*);
|
||||
@ -330,6 +332,7 @@ private:
|
||||
RecordBuffer* allocBuffer(thread_db*, MemoryPool&, int);
|
||||
void clearRecord(Record*);
|
||||
void putField(thread_db*, Record*, const DumpField&, int&, bool = false);
|
||||
const RelationData* getRelationData(int id) const;
|
||||
|
||||
static void dumpData(thread_db*);
|
||||
|
||||
|
@ -141,21 +141,13 @@ void VirtualTable::open(thread_db* tdbb, RecordSource* rsb)
|
||||
record_param* const rpb = &request->req_rpb[rsb->rsb_stream];
|
||||
irsb_virtual* const impure = (irsb_virtual*) ((UCHAR *) request + rsb->rsb_impure);
|
||||
|
||||
const Record* const record = rpb->rpb_record;
|
||||
const Format* format = NULL;
|
||||
if (!record || !record->rec_format)
|
||||
{
|
||||
format = MET_current(tdbb, relation);
|
||||
VIO_record(tdbb, rpb, format, request->req_pool);
|
||||
}
|
||||
else {
|
||||
format = record->rec_format;
|
||||
}
|
||||
DatabaseSnapshot* const snapshot = DatabaseSnapshot::create(tdbb);
|
||||
impure->irsb_record_buffer = snapshot->getData(relation);
|
||||
|
||||
const Format* const format = snapshot->getFormat(relation);
|
||||
VIO_record(tdbb, rpb, format, request->req_pool);
|
||||
|
||||
rpb->rpb_number.setValue(BOF_NUMBER);
|
||||
|
||||
DatabaseSnapshot* snapshot = DatabaseSnapshot::create(tdbb);
|
||||
impure->irsb_record_buffer = snapshot->getData(relation);
|
||||
}
|
||||
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user