~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to drizzled/join.cc

Made the best_positions member of the JOIN class private and added any
necessary accessors for it.

Show diffs side-by-side

added added

removed removed

Lines of Context:
3065
3065
      read_time+=record_count;      // We have to make a temp table
3066
3066
    if (read_time < join->best_read)
3067
3067
    {
3068
 
      memcpy(join->best_positions, join->positions, sizeof(Position)*idx);
 
3068
      join->copyPartialPlanIntoOptimalPlan(idx);
3069
3069
      join->best_read= read_time - 0.001;
3070
3070
    }
3071
3071
    return(false);
3228
3228
  KeyUse *keyuse;
3229
3229
  uint32_t table_count;
3230
3230
  Session *session=join->session;
 
3231
  Position cur_pos;
3231
3232
 
3232
3233
  table_count=join->tables;
3233
3234
  if (!(join->join_tab=join_tab=
3240
3241
  for (j=join_tab, tablenr=0 ; tablenr < table_count ; tablenr++,j++)
3241
3242
  {
3242
3243
    Table *form;
3243
 
    *j= *join->best_positions[tablenr].table;
 
3244
    cur_pos= join->getPosFromOptimalPlan(tablenr);
 
3245
    *j= *cur_pos.table;
3244
3246
    form=join->table[tablenr]=j->table;
3245
3247
    used_tables|= form->map;
3246
3248
    form->reginfo.join_tab=j;
3254
3256
 
3255
3257
    if (j->type == AT_SYSTEM)
3256
3258
      continue;
3257
 
    if (j->keys.none() || !(keyuse= join->best_positions[tablenr].key))
 
3259
    if (j->keys.none() || !(keyuse= cur_pos.key))
3258
3260
    {
3259
3261
      j->type= AT_ALL;
3260
3262
      if (tablenr != join->const_tables)
3942
3944
  if (join->sort_by_table &&
3943
3945
      join->sort_by_table != join->positions[join->const_tables].table->table)
3944
3946
    read_time+= record_count;  // We have to make a temp table
3945
 
  memcpy(join->best_positions, join->positions, sizeof(Position)*idx);
 
3947
  join->copyPartialPlanIntoOptimalPlan(idx);
3946
3948
  join->best_read= read_time;
3947
3949
}
3948
3950
 
4059
4061
    }
4060
4062
 
4061
4063
    /* select the first table in the optimal extension as most promising */
4062
 
    best_pos= join->best_positions[idx];
 
4064
    best_pos= join->getPosFromOptimalPlan(idx);
4063
4065
    best_table= best_pos.table;
4064
4066
    /*
4065
4067
      Each subsequent loop of 'best_extension_by_limited_search' uses
4308
4310
          current_read_time+= current_record_count;
4309
4311
        if ((search_depth == 1) || (current_read_time < join->best_read))
4310
4312
        {
4311
 
          memcpy(join->best_positions, join->positions,
4312
 
                 sizeof(Position) * (idx + 1));
 
4313
          join->copyPartialPlanIntoOptimalPlan(idx + 1);
4313
4314
          join->best_read= current_read_time - 0.001;
4314
4315
        }
4315
4316
      }
4527
4528
static bool make_join_select(JOIN *join,SQL_SELECT *select,COND *cond)
4528
4529
{
4529
4530
  Session *session= join->session;
 
4531
  Position cur_pos;
4530
4532
  if (select)
4531
4533
  {
4532
4534
    add_not_null_conds(join);
4536
4538
      if (join->tables > 1)
4537
4539
        cond->update_used_tables();             // Tablenr may have changed
4538
4540
      if (join->const_tables == join->tables &&
4539
 
          session->lex->current_select->master_unit() ==
4540
 
          &session->lex->unit)          // not upper level SELECT
 
4541
          session->lex->current_select->master_unit() ==
 
4542
          &session->lex->unit)          // not upper level SELECT
4541
4543
        join->const_table_map|=RAND_TABLE_BIT;
4542
4544
      {                                         // Check const tables
4543
4545
        COND *const_cond=
4544
 
          make_cond_for_table(cond,
4545
 
                              join->const_table_map,
4546
 
                              (table_map) 0, 1);
 
4546
          make_cond_for_table(cond,
 
4547
              join->const_table_map,
 
4548
              (table_map) 0, 1);
4547
4549
        for (JoinTable *tab= join->join_tab+join->const_tables;
4548
 
             tab < join->join_tab+join->tables ; tab++)
 
4550
            tab < join->join_tab+join->tables ; tab++)
4549
4551
        {
4550
4552
          if (*tab->on_expr_ref)
4551
4553
          {
4552
4554
            JoinTable *cond_tab= tab->first_inner;
4553
4555
            COND *tmp= make_cond_for_table(*tab->on_expr_ref,
4554
 
                                           join->const_table_map,
4555
 
                                           (  table_map) 0, 0);
 
4556
                join->const_table_map,
 
4557
                (  table_map) 0, 0);
4556
4558
            if (!tmp)
4557
4559
              continue;
4558
4560
            tmp= new Item_func_trig_cond(tmp, &cond_tab->not_null_compl);
4560
4562
              return(1);
4561
4563
            tmp->quick_fix_field();
4562
4564
            cond_tab->select_cond= !cond_tab->select_cond ? tmp :
4563
 
                                    new Item_cond_and(cond_tab->select_cond,
4564
 
                                                      tmp);
 
4565
              new Item_cond_and(cond_tab->select_cond,
 
4566
                  tmp);
4565
4567
            if (!cond_tab->select_cond)
4566
 
              return(1);
 
4568
              return(1);
4567
4569
            cond_tab->select_cond->quick_fix_field();
4568
4570
          }
4569
4571
        }
4570
4572
        if (const_cond && !const_cond->val_int())
4571
4573
        {
4572
 
          return(1);     // Impossible const condition
 
4574
          return(1);     // Impossible const condition
4573
4575
        }
4574
4576
      }
4575
4577
    }
4576
4578
    used_tables=((select->const_tables=join->const_table_map) |
4577
 
                 OUTER_REF_TABLE_BIT | RAND_TABLE_BIT);
 
4579
        OUTER_REF_TABLE_BIT | RAND_TABLE_BIT);
4578
4580
    for (uint32_t i=join->const_tables ; i < join->tables ; i++)
4579
4581
    {
4580
4582
      JoinTable *tab=join->join_tab+i;
4581
4583
      /*
4582
 
        first_inner is the X in queries like:
4583
 
        SELECT * FROM t1 LEFT OUTER JOIN (t2 JOIN t3) ON X
4584
 
      */
 
4584
         first_inner is the X in queries like:
 
4585
         SELECT * FROM t1 LEFT OUTER JOIN (t2 JOIN t3) ON X
 
4586
       */
4585
4587
      JoinTable *first_inner_tab= tab->first_inner;
4586
4588
      table_map current_map= tab->table->map;
4587
4589
      bool use_quick_range=0;
4588
4590
      COND *tmp;
4589
4591
 
4590
4592
      /*
4591
 
        Following force including random expression in last table condition.
4592
 
        It solve problem with select like SELECT * FROM t1 WHERE rand() > 0.5
4593
 
      */
 
4593
         Following force including random expression in last table condition.
 
4594
         It solve problem with select like SELECT * FROM t1 WHERE rand() > 0.5
 
4595
       */
4594
4596
      if (i == join->tables-1)
4595
 
        current_map|= OUTER_REF_TABLE_BIT | RAND_TABLE_BIT;
 
4597
        current_map|= OUTER_REF_TABLE_BIT | RAND_TABLE_BIT;
4596
4598
      used_tables|=current_map;
4597
4599
 
4598
4600
      if (tab->type == AT_REF && tab->quick &&
4599
 
          (uint32_t) tab->ref.key == tab->quick->index &&
4600
 
          tab->ref.key_length < tab->quick->max_used_key_length)
 
4601
          (uint32_t) tab->ref.key == tab->quick->index &&
 
4602
          tab->ref.key_length < tab->quick->max_used_key_length)
4601
4603
      {
4602
 
        /* Range uses longer key;  Use this instead of ref on key */
4603
 
        tab->type= AT_ALL;
4604
 
        use_quick_range=1;
4605
 
        tab->use_quick=1;
 
4604
        /* Range uses longer key;  Use this instead of ref on key */
 
4605
        tab->type= AT_ALL;
 
4606
        use_quick_range=1;
 
4607
        tab->use_quick=1;
4606
4608
        tab->ref.key= -1;
4607
 
        tab->ref.key_parts=0;           // Don't use ref key.
4608
 
        join->best_positions[i].records_read= rows2double(tab->quick->records);
 
4609
        tab->ref.key_parts=0;           // Don't use ref key.
 
4610
        cur_pos= join->getPosFromOptimalPlan(i);
 
4611
        cur_pos.records_read= rows2double(tab->quick->records);
4609
4612
        /*
4610
 
          We will use join cache here : prevent sorting of the first
4611
 
          table only and sort at the end.
4612
 
        */
 
4613
           We will use join cache here : prevent sorting of the first
 
4614
           table only and sort at the end.
 
4615
         */
4613
4616
        if (i != join->const_tables && join->tables > join->const_tables + 1)
4614
4617
          join->full_join= 1;
4615
4618
      }
4622
4625
        if (tab->type != AT_ALL)
4623
4626
        {
4624
4627
          /*
4625
 
            Don't use the quick method
4626
 
            We come here in the case where we have 'key=constant' and
4627
 
            the test is removed by make_cond_for_table()
4628
 
          */
 
4628
             Don't use the quick method
 
4629
             We come here in the case where we have 'key=constant' and
 
4630
             the test is removed by make_cond_for_table()
 
4631
           */
4629
4632
          delete tab->quick;
4630
4633
          tab->quick= 0;
4631
4634
        }
4632
4635
        else
4633
4636
        {
4634
4637
          /*
4635
 
            Hack to handle the case where we only refer to a table
4636
 
            in the ON part of an OUTER JOIN. In this case we want the code
4637
 
            below to check if we should use 'quick' instead.
4638
 
          */
 
4638
             Hack to handle the case where we only refer to a table
 
4639
             in the ON part of an OUTER JOIN. In this case we want the code
 
4640
             below to check if we should use 'quick' instead.
 
4641
           */
4639
4642
          tmp= new Item_int((int64_t) 1,1);     // Always true
4640
4643
        }
4641
4644
 
4643
4646
      if (tmp || !cond || tab->type == AT_REF || tab->type == AT_REF_OR_NULL ||
4644
4647
          tab->type == AT_EQ_REF)
4645
4648
      {
4646
 
        SQL_SELECT *sel= tab->select= ((SQL_SELECT*)
4647
 
                                       session->memdup((unsigned char*) select,
4648
 
                                                   sizeof(*select)));
4649
 
        if (!sel)
4650
 
          return(1);                    // End of memory
 
4649
        SQL_SELECT *sel= tab->select= ((SQL_SELECT*)
 
4650
            session->memdup((unsigned char*) select,
 
4651
              sizeof(*select)));
 
4652
        if (!sel)
 
4653
          return(1);                    // End of memory
4651
4654
        /*
4652
 
          If tab is an inner table of an outer join operation,
4653
 
          add a match guard to the pushed down predicate.
4654
 
          The guard will turn the predicate on only after
4655
 
          the first match for outer tables is encountered.
4656
 
        */
 
4655
           If tab is an inner table of an outer join operation,
 
4656
           add a match guard to the pushed down predicate.
 
4657
           The guard will turn the predicate on only after
 
4658
           the first match for outer tables is encountered.
 
4659
         */
4657
4660
        if (cond && tmp)
4658
4661
        {
4659
4662
          /*
4660
 
            Because of QUICK_GROUP_MIN_MAX_SELECT there may be a select without
4661
 
            a cond, so neutralize the hack above.
4662
 
          */
 
4663
             Because of QUICK_GROUP_MIN_MAX_SELECT there may be a select without
 
4664
             a cond, so neutralize the hack above.
 
4665
           */
4663
4666
          if (!(tmp= add_found_match_trig_cond(first_inner_tab, tmp, 0)))
4664
4667
            return(1);
4665
4668
          tab->select_cond=sel->cond=tmp;
4666
4669
          /* Push condition to storage engine if this is enabled
4667
4670
             and the condition is not guarded */
4668
4671
          tab->table->file->pushed_cond= NULL;
4669
 
          if (session->variables.engine_condition_pushdown)
 
4672
          if (session->variables.engine_condition_pushdown)
4670
4673
          {
4671
4674
            COND *push_cond=
4672
4675
              make_cond_for_table(tmp, current_map, current_map, 0);
4681
4684
        else
4682
4685
          tab->select_cond= sel->cond= NULL;
4683
4686
 
4684
 
        sel->head=tab->table;
4685
 
        if (tab->quick)
4686
 
        {
4687
 
          /* Use quick key read if it's a constant and it's not used
4688
 
             with key reading */
4689
 
          if (tab->needed_reg.none() && tab->type != AT_EQ_REF
4690
 
              && (tab->type != AT_REF || (uint32_t) tab->ref.key == tab->quick->index))
4691
 
          {
4692
 
            sel->quick=tab->quick;              // Use value from get_quick_...
4693
 
            sel->quick_keys.reset();
4694
 
            sel->needed_reg.reset();
4695
 
          }
4696
 
          else
4697
 
          {
4698
 
            delete tab->quick;
4699
 
          }
4700
 
          tab->quick=0;
4701
 
        }
4702
 
        uint32_t ref_key=(uint32_t) sel->head->reginfo.join_tab->ref.key+1;
4703
 
        if (i == join->const_tables && ref_key)
4704
 
        {
4705
 
          if (tab->const_keys.any() &&
4706
 
              tab->table->reginfo.impossible_range)
4707
 
            return(1);
4708
 
        }
4709
 
        else if (tab->type == AT_ALL && ! use_quick_range)
4710
 
        {
4711
 
          if (tab->const_keys.any() &&
4712
 
              tab->table->reginfo.impossible_range)
4713
 
            return(1);                          // Impossible range
4714
 
          /*
4715
 
            We plan to scan all rows.
4716
 
            Check again if we should use an index.
4717
 
            We could have used an column from a previous table in
4718
 
            the index if we are using limit and this is the first table
4719
 
          */
4720
 
 
4721
 
          if ((cond && (!((tab->keys & tab->const_keys) == tab->keys) && i > 0)) ||
4722
 
              (!tab->const_keys.none() && (i == join->const_tables) && (join->unit->select_limit_cnt < join->best_positions[i].records_read) && ((join->select_options & OPTION_FOUND_ROWS) == false)))
4723
 
          {
4724
 
            /* Join with outer join condition */
4725
 
            COND *orig_cond=sel->cond;
4726
 
            sel->cond= and_conds(sel->cond, *tab->on_expr_ref);
4727
 
 
4728
 
            /*
4729
 
              We can't call sel->cond->fix_fields,
4730
 
              as it will break tab->on_expr if it's AND condition
4731
 
              (fix_fields currently removes extra AND/OR levels).
4732
 
              Yet attributes of the just built condition are not needed.
4733
 
              Thus we call sel->cond->quick_fix_field for safety.
4734
 
            */
4735
 
            if (sel->cond && !sel->cond->fixed)
4736
 
              sel->cond->quick_fix_field();
4737
 
 
4738
 
            if (sel->test_quick_select(session, tab->keys,
4739
 
                                       used_tables & ~ current_map,
4740
 
                                       (join->select_options &
4741
 
                                        OPTION_FOUND_ROWS ?
4742
 
                                        HA_POS_ERROR :
4743
 
                                        join->unit->select_limit_cnt), 0,
4744
 
                                        false) < 0)
 
4687
        sel->head=tab->table;
 
4688
        if (tab->quick)
 
4689
        {
 
4690
          /* Use quick key read if it's a constant and it's not used
 
4691
             with key reading */
 
4692
          if (tab->needed_reg.none() && tab->type != AT_EQ_REF
 
4693
              && (tab->type != AT_REF || (uint32_t) tab->ref.key == tab->quick->index))
 
4694
          {
 
4695
            sel->quick=tab->quick;              // Use value from get_quick_...
 
4696
            sel->quick_keys.reset();
 
4697
            sel->needed_reg.reset();
 
4698
          }
 
4699
          else
 
4700
          {
 
4701
            delete tab->quick;
 
4702
          }
 
4703
          tab->quick=0;
 
4704
        }
 
4705
        uint32_t ref_key=(uint32_t) sel->head->reginfo.join_tab->ref.key+1;
 
4706
        if (i == join->const_tables && ref_key)
 
4707
        {
 
4708
          if (tab->const_keys.any() &&
 
4709
              tab->table->reginfo.impossible_range)
 
4710
            return(1);
 
4711
        }
 
4712
        else if (tab->type == AT_ALL && ! use_quick_range)
 
4713
        {
 
4714
          if (tab->const_keys.any() &&
 
4715
              tab->table->reginfo.impossible_range)
 
4716
            return(1);                          // Impossible range
 
4717
          /*
 
4718
             We plan to scan all rows.
 
4719
             Check again if we should use an index.
 
4720
             We could have used an column from a previous table in
 
4721
             the index if we are using limit and this is the first table
 
4722
           */
 
4723
 
 
4724
          cur_pos= join->getPosFromOptimalPlan(i);
 
4725
          if ((cond && (!((tab->keys & tab->const_keys) == tab->keys) && i > 0)) ||
 
4726
              (!tab->const_keys.none() && (i == join->const_tables) &&
 
4727
              (join->unit->select_limit_cnt < cur_pos.records_read) && ((join->select_options & OPTION_FOUND_ROWS) == false)))
 
4728
          {
 
4729
            /* Join with outer join condition */
 
4730
            COND *orig_cond=sel->cond;
 
4731
            sel->cond= and_conds(sel->cond, *tab->on_expr_ref);
 
4732
 
 
4733
            /*
 
4734
               We can't call sel->cond->fix_fields,
 
4735
               as it will break tab->on_expr if it's AND condition
 
4736
               (fix_fields currently removes extra AND/OR levels).
 
4737
               Yet attributes of the just built condition are not needed.
 
4738
               Thus we call sel->cond->quick_fix_field for safety.
 
4739
             */
 
4740
            if (sel->cond && !sel->cond->fixed)
 
4741
              sel->cond->quick_fix_field();
 
4742
 
 
4743
            if (sel->test_quick_select(session, tab->keys,
 
4744
                  used_tables & ~ current_map,
 
4745
                  (join->select_options &
 
4746
                   OPTION_FOUND_ROWS ?
 
4747
                   HA_POS_ERROR :
 
4748
                   join->unit->select_limit_cnt), 0,
 
4749
                  false) < 0)
4745
4750
            {
4746
 
              /*
4747
 
                Before reporting "Impossible WHERE" for the whole query
4748
 
                we have to check isn't it only "impossible ON" instead
4749
 
              */
 
4751
              /*
 
4752
                 Before reporting "Impossible WHERE" for the whole query
 
4753
                 we have to check isn't it only "impossible ON" instead
 
4754
               */
4750
4755
              sel->cond=orig_cond;
4751
4756
              if (!*tab->on_expr_ref ||
4752
4757
                  sel->test_quick_select(session, tab->keys,
4753
 
                                         used_tables & ~ current_map,
4754
 
                                         (join->select_options &
4755
 
                                          OPTION_FOUND_ROWS ?
4756
 
                                          HA_POS_ERROR :
4757
 
                                          join->unit->select_limit_cnt),0,
4758
 
                                          false) < 0)
4759
 
                return(1);                      // Impossible WHERE
 
4758
                    used_tables & ~ current_map,
 
4759
                    (join->select_options &
 
4760
                     OPTION_FOUND_ROWS ?
 
4761
                     HA_POS_ERROR :
 
4762
                     join->unit->select_limit_cnt),0,
 
4763
                    false) < 0)
 
4764
                return(1);                      // Impossible WHERE
4760
4765
            }
4761
4766
            else
4762
 
              sel->cond=orig_cond;
 
4767
              sel->cond=orig_cond;
4763
4768
 
4764
 
            /* Fix for EXPLAIN */
4765
 
            if (sel->quick)
4766
 
              join->best_positions[i].records_read= (double)sel->quick->records;
4767
 
          }
4768
 
          else
4769
 
          {
4770
 
            sel->needed_reg=tab->needed_reg;
4771
 
            sel->quick_keys.reset();
4772
 
          }
 
4769
            /* Fix for EXPLAIN */
 
4770
            if (sel->quick)
 
4771
            {
 
4772
              cur_pos= join->getPosFromOptimalPlan(i);
 
4773
              cur_pos.records_read= (double)sel->quick->records;
 
4774
            }
 
4775
          }
 
4776
          else
 
4777
          {
 
4778
            sel->needed_reg=tab->needed_reg;
 
4779
            sel->quick_keys.reset();
 
4780
          }
4773
4781
          if (!((tab->checked_keys & sel->quick_keys) == sel->quick_keys) ||
4774
4782
              !((tab->checked_keys & sel->needed_reg) == sel->needed_reg))
4775
 
          {
4776
 
            tab->keys= sel->quick_keys;
 
4783
          {
 
4784
            tab->keys= sel->quick_keys;
4777
4785
            tab->keys|= sel->needed_reg;
4778
 
            tab->use_quick= (!sel->needed_reg.none() &&
4779
 
                             (select->quick_keys.none() ||
4780
 
                              (select->quick &&
4781
 
                               (select->quick->records >= 100L)))) ?
4782
 
              2 : 1;
4783
 
            sel->read_tables= used_tables & ~current_map;
4784
 
          }
4785
 
          if (i != join->const_tables && tab->use_quick != 2)
4786
 
          {                                     /* Read with cache */
4787
 
            if (cond &&
 
4786
            tab->use_quick= (!sel->needed_reg.none() &&
 
4787
                (select->quick_keys.none() ||
 
4788
                 (select->quick &&
 
4789
                  (select->quick->records >= 100L)))) ?
 
4790
              2 : 1;
 
4791
            sel->read_tables= used_tables & ~current_map;
 
4792
          }
 
4793
          if (i != join->const_tables && tab->use_quick != 2)
 
4794
          {                                     /* Read with cache */
 
4795
            if (cond &&
4788
4796
                (tmp=make_cond_for_table(cond,
4789
 
                                         join->const_table_map |
4790
 
                                         current_map,
4791
 
                                         current_map, 0)))
4792
 
            {
4793
 
              tab->cache.select=(SQL_SELECT*)
4794
 
                session->memdup((unsigned char*) sel, sizeof(SQL_SELECT));
4795
 
              tab->cache.select->cond=tmp;
4796
 
              tab->cache.select->read_tables=join->const_table_map;
4797
 
            }
4798
 
          }
4799
 
        }
 
4797
                                         join->const_table_map |
 
4798
                                         current_map,
 
4799
                                         current_map, 0)))
 
4800
            {
 
4801
              tab->cache.select=(SQL_SELECT*)
 
4802
                session->memdup((unsigned char*) sel, sizeof(SQL_SELECT));
 
4803
              tab->cache.select->cond=tmp;
 
4804
              tab->cache.select->read_tables=join->const_table_map;
 
4805
            }
 
4806
          }
 
4807
        }
4800
4808
      }
4801
4809
 
4802
4810
      /*
4803
 
        Push down conditions from all on expressions.
4804
 
        Each of these conditions are guarded by a variable
4805
 
        that turns if off just before null complemented row for
4806
 
        outer joins is formed. Thus, the condition from an
4807
 
        'on expression' are guaranteed not to be checked for
4808
 
        the null complemented row.
4809
 
      */
 
4811
         Push down conditions from all on expressions.
 
4812
         Each of these conditions are guarded by a variable
 
4813
         that turns if off just before null complemented row for
 
4814
         outer joins is formed. Thus, the condition from an
 
4815
         'on expression' are guaranteed not to be checked for
 
4816
         the null complemented row.
 
4817
       */
4810
4818
 
4811
4819
      /* First push down constant conditions from on expressions */
4812
4820
      for (JoinTable *join_tab= join->join_tab+join->const_tables;
4813
 
           join_tab < join->join_tab+join->tables ; join_tab++)
 
4821
          join_tab < join->join_tab+join->tables ; join_tab++)
4814
4822
      {
4815
4823
        if (*join_tab->on_expr_ref)
4816
4824
        {
4817
4825
          JoinTable *cond_tab= join_tab->first_inner;
4818
4826
          tmp= make_cond_for_table(*join_tab->on_expr_ref,
4819
 
                                   join->const_table_map,
4820
 
                                   (table_map) 0, 0);
 
4827
              join->const_table_map,
 
4828
              (table_map) 0, 0);
4821
4829
          if (!tmp)
4822
4830
            continue;
4823
4831
          tmp= new Item_func_trig_cond(tmp, &cond_tab->not_null_compl);
4825
4833
            return(1);
4826
4834
          tmp->quick_fix_field();
4827
4835
          cond_tab->select_cond= !cond_tab->select_cond ? tmp :
4828
 
                                    new Item_cond_and(cond_tab->select_cond,tmp);
 
4836
            new Item_cond_and(cond_tab->select_cond,tmp);
4829
4837
          if (!cond_tab->select_cond)
4830
 
            return(1);
 
4838
            return(1);
4831
4839
          cond_tab->select_cond->quick_fix_field();
4832
4840
        }
4833
4841
      }
4837
4845
      while (first_inner_tab && first_inner_tab->last_inner == last_tab)
4838
4846
      {
4839
4847
        /*
4840
 
          Table tab is the last inner table of an outer join.
4841
 
          An on expression is always attached to it.
4842
 
        */
 
4848
           Table tab is the last inner table of an outer join.
 
4849
           An on expression is always attached to it.
 
4850
         */
4843
4851
        COND *on_expr= *first_inner_tab->on_expr_ref;
4844
4852
 
4845
4853
        table_map used_tables2= (join->const_table_map |
4846
 
                                 OUTER_REF_TABLE_BIT | RAND_TABLE_BIT);
4847
 
        for (tab= join->join_tab+join->const_tables; tab <= last_tab ; tab++)
 
4854
            OUTER_REF_TABLE_BIT | RAND_TABLE_BIT);
 
4855
        for (tab= join->join_tab+join->const_tables; tab <= last_tab ; tab++)
4848
4856
        {
4849
4857
          current_map= tab->table->map;
4850
4858
          used_tables2|= current_map;
4851
4859
          COND *tmp_cond= make_cond_for_table(on_expr, used_tables2,
4852
 
                                              current_map, 0);
 
4860
              current_map, 0);
4853
4861
          if (tmp_cond)
4854
4862
          {
4855
4863
            JoinTable *cond_tab= tab < first_inner_tab ? first_inner_tab : tab;
4856
4864
            /*
4857
 
              First add the guards for match variables of
4858
 
              all embedding outer join operations.
4859
 
            */
 
4865
               First add the guards for match variables of
 
4866
               all embedding outer join operations.
 
4867
             */
4860
4868
            if (!(tmp_cond= add_found_match_trig_cond(cond_tab->first_inner,
4861
 
                                                     tmp_cond,
4862
 
                                                     first_inner_tab)))
 
4869
                    tmp_cond,
 
4870
                    first_inner_tab)))
4863
4871
              return(1);
4864
4872
            /*
4865
 
              Now add the guard turning the predicate off for
4866
 
              the null complemented row.
4867
 
            */
 
4873
               Now add the guard turning the predicate off for
 
4874
               the null complemented row.
 
4875
             */
4868
4876
            tmp_cond= new Item_func_trig_cond(tmp_cond,
4869
 
                                              &first_inner_tab->
4870
 
                                              not_null_compl);
 
4877
                &first_inner_tab->
 
4878
                not_null_compl);
4871
4879
            if (tmp_cond)
4872
4880
              tmp_cond->quick_fix_field();
4873
 
            /* Add the predicate to other pushed down predicates */
 
4881
            /* Add the predicate to other pushed down predicates */
4874
4882
            cond_tab->select_cond= !cond_tab->select_cond ? tmp_cond :
4875
 
                                  new Item_cond_and(cond_tab->select_cond,
4876
 
                                                    tmp_cond);
 
4883
              new Item_cond_and(cond_tab->select_cond,
 
4884
                  tmp_cond);
4877
4885
            if (!cond_tab->select_cond)
4878
 
              return(1);
 
4886
              return(1);
4879
4887
            cond_tab->select_cond->quick_fix_field();
4880
4888
          }
4881
4889
        }
6027
6035
  }
6028
6036
  else
6029
6037
  {
6030
 
    memcpy(join->best_positions, join->positions, sizeof(Position)*join->const_tables);
 
6038
    join->copyPartialPlanIntoOptimalPlan(join->const_tables);
6031
6039
    join->best_read= 1.0;
6032
6040
  }
6033
6041
  /* Generate an execution plan from the found optimal join order. */