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

Fix "no current record .." bug when an undependent stream A is dependent on stream B and B is dependent on stream C.

Stream A was merged with the stream C and only B was correctly joined.
This commit is contained in:
arnobrinkman 2006-04-22 23:25:17 +00:00
parent c749838d31
commit b9456e4747

View File

@ -755,65 +755,73 @@ RecordSource* OPT_compile(thread_db* tdbb,
fb_assert(streams[0] != 1 || csb->csb_rpt[streams[1]].csb_relation != 0); fb_assert(streams[0] != 1 || csb->csb_rpt[streams[1]].csb_relation != 0);
// AB: Determine which streams have an index relationship // Walk until no dependent streams are left
// with the currently active rivers. This is needed so that while (true)
// no merge is made between a new cross river and the {
// currently active rivers. Where in the new cross river // AB: Determine which streams have an index relationship
// a stream depends (index) on the active rivers. // with the currently active rivers. This is needed so that
stream_array_t dependent_streams, free_streams; // no merge is made between a new cross river and the
dependent_streams[0] = free_streams[0] = 0; // currently active rivers. Where in the new cross river
find_index_relationship_streams(tdbb, opt, streams, // a stream depends (index) on the active rivers.
dependent_streams, free_streams); stream_array_t dependent_streams, free_streams;
dependent_streams[0] = free_streams[0] = 0;
find_index_relationship_streams(tdbb, opt, streams,
dependent_streams, free_streams);
// If we have dependent and free streams then we can't rely on // If we have dependent and free streams then we can't rely on
// the sort node to be used for index navigation. // the sort node to be used for index navigation.
if (dependent_streams[0] && free_streams[0]) { if (dependent_streams[0] && free_streams[0]) {
sort = NULL; sort = NULL;
sort_can_be_used = false; sort_can_be_used = false;
}
if (dependent_streams[0]) {
// copy free streams
for (i = 0; i <= free_streams[0]; i++) {
streams[i] = free_streams[i];
} }
// Make rivers from the dependent streams if (dependent_streams[0]) {
gen_join(tdbb, opt, dependent_streams, rivers_stack, &sort, // copy free streams
&project, rse->rse_plan); for (i = 0; i <= free_streams[0]; i++) {
streams[i] = free_streams[i];
}
// Generate 1 river which holds a cross join rsb between // Make rivers from the dependent streams
// all currently available rivers. gen_join(tdbb, opt, dependent_streams, rivers_stack, &sort,
&project, rse->rse_plan);
// First get total count of streams. // Generate 1 river which holds a cross join rsb between
int count = 0; // all currently available rivers.
RiverStack::iterator stack1(rivers_stack);
for (; stack1.hasData(); ++stack1) { // First get total count of streams.
count += stack1.object()->riv_count; int count = 0;
RiverStack::iterator stack1(rivers_stack);
for (; stack1.hasData(); ++stack1) {
count += stack1.object()->riv_count;
}
// Create river and copy the streams.
River* river = FB_NEW_RPT(*tdbb->getDefaultPool(), count) River();
river->riv_count = (UCHAR) count;
UCHAR* stream_itr = river->riv_streams;
RiverStack::iterator stack2(rivers_stack);
for (; stack2.hasData(); ++stack2) {
River* subRiver = stack2.object();
MOVE_FAST(subRiver->riv_streams, stream_itr, subRiver->riv_count);
stream_itr += subRiver->riv_count;
}
river->riv_rsb = make_cross(tdbb, opt, rivers_stack);
rivers_stack.push(river);
// Mark the river as active.
set_made_river(opt, river);
set_active(opt, river);
} }
else
{
if (free_streams[0]) {
// Deactivate streams
for (i = 1; i <= sub_streams[0]; i++) {
csb->csb_rpt[sub_streams[i]].csb_flags &= ~csb_active;
}
}
// Create river and copy the streams. break;
River* river = FB_NEW_RPT(*tdbb->getDefaultPool(), count) River();
river->riv_count = (UCHAR) count;
UCHAR* stream_itr = river->riv_streams;
RiverStack::iterator stack2(rivers_stack);
for (; stack2.hasData(); ++stack2) {
River* subRiver = stack2.object();
MOVE_FAST(subRiver->riv_streams, stream_itr, subRiver->riv_count);
stream_itr += subRiver->riv_count;
}
river->riv_rsb = make_cross(tdbb, opt, rivers_stack);
rivers_stack.push(river);
// Mark the river as active.
set_made_river(opt, river);
set_active(opt, river);
}
if (free_streams[0]) {
// Deactivate streams
for (i = 1; i <= sub_streams[0]; i++) {
csb->csb_rpt[sub_streams[i]].csb_flags &= ~csb_active;
} }
} }