@@ -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