Skip to content

Commit

Permalink
Fixed CORE-3138: Internal error or crash occurs when accessing any MO…
Browse files Browse the repository at this point in the history
…N$ table after altering its structure.
  • Loading branch information
dyemanov committed Feb 14, 2011
1 parent e4a3f1b commit e65cc13
Show file tree
Hide file tree
Showing 3 changed files with 45 additions and 23 deletions.
48 changes: 37 additions & 11 deletions src/jrd/DatabaseSnapshot.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -618,33 +618,50 @@ 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;
Expand All @@ -666,9 +683,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)
Expand Down
3 changes: 3 additions & 0 deletions src/jrd/DatabaseSnapshot.h
Original file line number Diff line number Diff line change
Expand Up @@ -175,6 +175,7 @@ class DatabaseSnapshot
struct RelationData
{
int rel_id;
const Format* format;
RecordBuffer* data;
};

Expand Down Expand Up @@ -307,6 +308,7 @@ class DatabaseSnapshot
public:
~DatabaseSnapshot();

const Format* getFormat(const jrd_rel*) const;
RecordBuffer* getData(const jrd_rel*) const;

static DatabaseSnapshot* create(thread_db*);
Expand All @@ -325,6 +327,7 @@ class DatabaseSnapshot
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*, bool);

Expand Down
17 changes: 5 additions & 12 deletions src/jrd/VirtualTable.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -129,20 +129,13 @@ void VirtualTable::open(thread_db* tdbb, RecordSource* rsb)
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);

rpb->rpb_number.setValue(BOF_NUMBER);
const Format* const format = snapshot->getFormat(relation);
VIO_record(tdbb, rpb, format, request->req_pool);

DatabaseSnapshot* snapshot = DatabaseSnapshot::create(tdbb);
impure->irsb_record_buffer = snapshot->getData(relation);
rpb->rpb_number.setValue(BOF_NUMBER);
}


Expand Down

0 comments on commit e65cc13

Please sign in to comment.