Skip to content

Commit 71e4f9a

Browse files
committed
Fixed the first part of CORE-2832: Optimizer fails applying stream-local predicates before merging.
This part is related to the merge/hash join algorithms.
1 parent c42b8b1 commit 71e4f9a

1 file changed

Lines changed: 43 additions & 20 deletions

File tree

src/jrd/opt.cpp

Lines changed: 43 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -3631,6 +3631,19 @@ static bool gen_equi_join(thread_db* tdbb, OptimizerBlk* opt, RiverList& org_riv
36313631
return false;
36323632
}
36333633

3634+
// AB: Inactivate currently all streams from every river, because we
3635+
// need to know which nodes are computable between the rivers used
3636+
// for the merge.
3637+
3638+
USHORT flag_vector[MAX_STREAMS + 1], *fv;
3639+
UCHAR stream_nr;
3640+
3641+
for (stream_nr = 0, fv = flag_vector; stream_nr < csb->csb_n_stream; stream_nr++)
3642+
{
3643+
*fv++ = csb->csb_rpt[stream_nr].csb_flags & csb_active;
3644+
csb->csb_rpt[stream_nr].csb_flags &= ~csb_active;
3645+
}
3646+
36343647
HalfStaticArray<RecordSource*, OPT_STATIC_ITEMS> rsbs;
36353648
HalfStaticArray<jrd_nod*, OPT_STATIC_ITEMS> keys;
36363649

@@ -3661,10 +3674,37 @@ static bool gen_equi_join(thread_db* tdbb, OptimizerBlk* opt, RiverList& org_riv
36613674
rivers_to_merge.add(river);
36623675
org_rivers.remove(iter);
36633676

3677+
RecordSource* rsb = river->getRecordSource();
3678+
3679+
// Apply local river booleans, if any
3680+
3681+
river->activate(csb);
3682+
3683+
jrd_nod* river_boolean = NULL;
3684+
for (tail = opt->opt_conjuncts.begin(); tail < end; tail++)
3685+
{
3686+
jrd_nod* const node = tail->opt_conjunct_node;
3687+
3688+
if (!(tail->opt_conjunct_flags & opt_conjunct_used) &&
3689+
OPT_computable(csb, node, -1, false, false))
3690+
{
3691+
compose(&river_boolean, node, nod_and);
3692+
tail->opt_conjunct_flags |= opt_conjunct_used;
3693+
}
3694+
}
3695+
3696+
river->deactivate(csb);
3697+
3698+
if (river_boolean)
3699+
{
3700+
rsb = FB_NEW(*tdbb->getDefaultPool()) FilteredStream(csb, rsb, river_boolean);
3701+
}
3702+
3703+
// Collect RSBs and keys to join
3704+
36643705
const size_t selected_count = selected_classes.getCount();
36653706

36663707
jrd_nod* key = NULL;
3667-
RecordSource* rsb = NULL;
36683708

36693709
if (prefer_merge_over_hash)
36703710
{
@@ -3685,7 +3725,7 @@ static bool gen_equi_join(thread_db* tdbb, OptimizerBlk* opt, RiverList& org_riv
36853725
stream_array_t streams;
36863726
streams[0] = (UCHAR) stream_count;
36873727
memcpy(streams + 1, river->getStreams(), stream_count);
3688-
rsb = OPT_gen_sort(tdbb, opt->opt_csb, streams, NULL, river->getRecordSource(), key, false);
3728+
rsb = OPT_gen_sort(tdbb, opt->opt_csb, streams, NULL, rsb, key, false);
36893729
}
36903730
else
36913731
{
@@ -3698,8 +3738,6 @@ static bool gen_equi_join(thread_db* tdbb, OptimizerBlk* opt, RiverList& org_riv
36983738
{
36993739
*ptr++ = (*selected_class)[number];
37003740
}
3701-
3702-
rsb = river->getRecordSource();
37033741
}
37043742

37053743
// It seems that rivers are already sorted by their cardinality.
@@ -3735,29 +3773,14 @@ static bool gen_equi_join(thread_db* tdbb, OptimizerBlk* opt, RiverList& org_riv
37353773
HashJoin(csb, rsbs.getCount(), rsbs.begin(), keys.begin());
37363774
}
37373775

3738-
// Pick up any boolean that may apply
3739-
3740-
USHORT flag_vector[MAX_STREAMS + 1], *fv;
3741-
UCHAR stream_nr;
3742-
3743-
// AB: Inactivate currently all streams from every river, because we
3744-
// need to know which nodes are computable between the rivers used
3745-
// for the merge.
3746-
3747-
for (stream_nr = 0, fv = flag_vector; stream_nr < csb->csb_n_stream; stream_nr++)
3748-
{
3749-
*fv++ = csb->csb_rpt[stream_nr].csb_flags & csb_active;
3750-
csb->csb_rpt[stream_nr].csb_flags &= ~csb_active;
3751-
}
3752-
37533776
// Activate streams of all the rivers being merged
37543777

37553778
for (River** iter = rivers_to_merge.begin(); iter < rivers_to_merge.end(); iter++)
37563779
{
37573780
(*iter)->activate(csb);
37583781
}
37593782

3760-
// Get computable booleans, if any
3783+
// Pick up any boolean that may apply
37613784

37623785
jrd_nod* boolean = NULL;
37633786
for (tail = opt->opt_conjuncts.begin(); tail < end; tail++)

0 commit comments

Comments
 (0)