~mathiaz/ubuntu/lucid/mysql-dfsg-5.1/zap-bug-552053

« back to all changes in this revision

Viewing changes to sql/sql_select.cc

  • Committer: Bazaar Package Importer
  • Author(s): Mathias Gug
  • Date: 2009-06-25 12:55:45 UTC
  • mfrom: (1.1.2 upstream) (0.1.3 experimental)
  • Revision ID: james.westby@ubuntu.com-20090625125545-m8ogs96zzsri74xe
Tags: 5.1.34-1ubuntu1
* Merge from debian experimental (and 5.0 from main), remaining changes:
  - debian/mysql-server-5.1.config:
    + ask for MySQL root password at priority high instead of medium so
      that the password prompt is seen on a default install. (LP: #319843)
    + don't ask for root password when upgrading from a 5.0 install.
  - debian/control:
    + Make libmysqlclient16-dev a transitional package depending on
      libmysqlclient-dev.
    + Make libmysqlclient-dev conflict with libmysqlclient15-dev.
    + Don't build mysql-server, mysql-client, mysql-common and
      libmysqlclient15-dev binary packages since they're still provided
      by mysql-dfsg-5.0.
    + Make mysql-{client,server}-5.1 packages conflict and
      replace mysql-{client,server}-5.0, but not provide
      mysql-{client,server}.
    + Depend on a specific version of mysql-common rather than the src
      version of mysql-dfsg-5.1 since mysql-common is currently part of
      mysql-dfsg-5.0.
    + Lower mailx from a Recommends to a Suggests to avoid pulling in
      a full MTA on all installs of mysql-server. (LP: #259477)
  - debian/rules:
    + added -fno-strict-aliasing to CFLAGS to get around mysql testsuite
      build failures.
    + install mysql-test and sql-bench to /usr/share/mysql/ rather than
      /usr/.
  - debian/additions/debian-start.inc.sh: support ANSI mode (LP: #310211)
  - Add AppArmor profile:
    - debian/apparmor-profile: apparmor profile.
    - debian/rules, debian/mysql-server-5.0.files: install apparmor profile.
    - debian/mysql-server-5.0.dirs: add etc/apparmor.d/force-complain
    - debian/mysql-server-5.0.postrm: remove symlink in force-complain/ on
      purge.
    - debian/mysql-server-5.1.README.Debian: add apparmor documentation.
    - debian/additions/my.cnf: Add warning about apparmor. (LP: #201799)
    - debian/mysql-server-5.1.postinst: reload apparmor profiles.
  - debian/additions/my.cnf: remove language option. Error message files are
    located in a different directory in MySQL 5.0. Setting the language
    option to use /usr/share/mysql/english breaks 5.0. Both 5.0 and 5.1
    use a default value that works. (LP: #316974)
  - debian/mysql-server-5.1.mysql.init:
    + Clearly indicate that we do not support running multiple instances
      of mysqld by duplicating the init script.
      (closes: #314785, #324834, #435165, #444216)
    + Properly parameterize all existing references to the mysql config
      file (/etc/mysql/my.cnf).
  - debian/mysql-server-5.0.postinst: Clear out the second password
    when setting up mysql. (LP: #344816)
  - mysql-server-core-5.1 package for files needed by Akonadi:
    + debian/control: create mysql-server-core-5.1 package.
    + debian/mysql-server-core-5.1.files, debian/mysql-server-5.1.files:
      move core mysqld files to mysql-server-core-5.1 package.
  - Don't package sql-bench and mysql-test file.
* Dropped changes:
  - debian/patches/92_ssl_test_cert.dpatch: certificate expiration in
    test suite (LP: #323755). Included upstream.
* Dropped from 5.0:
  - apparmor profile:
    - debian/control: Recommends apparmor >= 2.1+1075-0ubuntu6. All version
      of apparmor-profile (>hardy) are higher than this version.
    - debian/mysql-server-5.0.preinst: create symlink for force-complain/
      on pre-feisty upgrades, upgrades where apparmor-profiles profile is
      unchanged (ie non-enforcing) and upgrades where the profile
      doesn't exist. Support for pre-hardy upgrades is no longer needed.
* debian/mysql-server-5.1.postinst: fix debian-sys-maint user creation.

Show diffs side-by-side

added added

removed removed

Lines of Context:
87
87
                                KEYUSE *keyuse, table_map used_tables,
88
88
                                KEY_PART_INFO *key_part, uchar *key_buff,
89
89
                                uint maybe_null);
90
 
static bool make_simple_join(JOIN *join,TABLE *tmp_table);
91
90
static void make_outerjoin_info(JOIN *join);
92
91
static bool make_join_select(JOIN *join,SQL_SELECT *select,COND *item);
93
92
static void make_join_readinfo(JOIN *join, ulonglong options);
109
108
                                             void *table_join_idx);
110
109
static COND *simplify_joins(JOIN *join, List<TABLE_LIST> *join_list,
111
110
                            COND *conds, bool top);
112
 
static bool check_interleaving_with_nj(JOIN_TAB *last, JOIN_TAB *next);
 
111
static bool check_interleaving_with_nj(JOIN_TAB *next);
113
112
static void restore_prev_nj_state(JOIN_TAB *last);
114
113
static void reset_nj_counters(List<TABLE_LIST> *join_list);
115
114
static uint build_bitmap_for_nested_joins(List<TABLE_LIST> *join_list,
1676
1675
        We have to test for 'conds' here as the WHERE may not be constant
1677
1676
        even if we don't have any tables for prepared statements or if
1678
1677
        conds uses something like 'rand()'.
 
1678
        If the HAVING clause is either impossible or always true, then
 
1679
        JOIN::having is set to NULL by optimize_cond.
 
1680
        In this case JOIN::exec must check for JOIN::having_value, in the
 
1681
        same way it checks for JOIN::cond_value.
1679
1682
      */
1680
1683
      if (cond_value != Item::COND_FALSE &&
 
1684
          having_value != Item::COND_FALSE &&
1681
1685
          (!conds || conds->val_int()) &&
1682
1686
          (!having || having->val_int()))
1683
1687
      {
1874
1878
      
1875
1879
      /* Free first data from old join */
1876
1880
      curr_join->join_free();
1877
 
      if (make_simple_join(curr_join, curr_tmp_table))
 
1881
      if (curr_join->make_simple_join(this, curr_tmp_table))
1878
1882
        DBUG_VOID_RETURN;
1879
1883
      calc_group_buffer(curr_join, group_list);
1880
1884
      count_field_types(select_lex, &curr_join->tmp_table_param,
1997
2001
      curr_join->select_distinct=0;
1998
2002
    }
1999
2003
    curr_tmp_table->reginfo.lock_type= TL_UNLOCK;
2000
 
    if (make_simple_join(curr_join, curr_tmp_table))
 
2004
    if (curr_join->make_simple_join(this, curr_tmp_table))
2001
2005
      DBUG_VOID_RETURN;
2002
2006
    calc_group_buffer(curr_join, curr_join->group_list);
2003
2007
    count_field_types(select_lex, &curr_join->tmp_table_param, 
2456
2460
*/
2457
2461
 
2458
2462
static bool
2459
 
make_join_statistics(JOIN *join, TABLE_LIST *tables, COND *conds,
 
2463
make_join_statistics(JOIN *join, TABLE_LIST *tables_arg, COND *conds,
2460
2464
                     DYNAMIC_ARRAY *keyuse_array)
2461
2465
{
2462
2466
  int error;
2463
2467
  TABLE *table;
 
2468
  TABLE_LIST *tables= tables_arg;
2464
2469
  uint i,table_count,const_count,key;
2465
2470
  table_map found_const_table_map, all_table_map, found_ref, refs;
2466
2471
  key_map const_ref, eq_part;
2498
2503
    table_vector[i]=s->table=table=tables->table;
2499
2504
    table->pos_in_table_list= tables;
2500
2505
    error= table->file->info(HA_STATUS_VARIABLE | HA_STATUS_NO_LOCK);
2501
 
    if(error)
 
2506
    if (error)
2502
2507
    {
2503
 
        table->file->print_error(error, MYF(0));
2504
 
        DBUG_RETURN(1);
 
2508
      table->file->print_error(error, MYF(0));
 
2509
      goto error;
2505
2510
    }
2506
2511
    table->quick_keys.clear_all();
2507
2512
    table->reginfo.join_tab=s;
2597
2602
      {
2598
2603
        join->tables=0;                 // Don't use join->table
2599
2604
        my_message(ER_WRONG_OUTER_JOIN, ER(ER_WRONG_OUTER_JOIN), MYF(0));
2600
 
        DBUG_RETURN(1);
 
2605
        goto error;
2601
2606
      }
2602
2607
      s->key_dependent= s->dependent;
2603
2608
    }
2607
2612
    if (update_ref_and_keys(join->thd, keyuse_array, stat, join->tables,
2608
2613
                            conds, join->cond_equal,
2609
2614
                            ~outer_join, join->select_lex, &sargables))
2610
 
      DBUG_RETURN(1);
 
2615
      goto error;
2611
2616
 
2612
2617
  /* Read tables with 0 or 1 rows (system tables) */
2613
2618
  join->const_table_map= 0;
2623
2628
    if ((tmp=join_read_const_table(s, p_pos)))
2624
2629
    {
2625
2630
      if (tmp > 0)
2626
 
        DBUG_RETURN(1);                 // Fatal error
 
2631
        goto error;             // Fatal error
2627
2632
    }
2628
2633
    else
2629
2634
      found_const_table_map|= s->table->map;
2695
2700
          if ((tmp= join_read_const_table(s, join->positions+const_count-1)))
2696
2701
          {
2697
2702
            if (tmp > 0)
2698
 
              DBUG_RETURN(1);                   // Fatal error
 
2703
              goto error;                       // Fatal error
2699
2704
          }
2700
2705
          else
2701
2706
            found_const_table_map|= table->map;
2744
2749
                set_position(join,const_count++,s,start_keyuse);
2745
2750
                if (create_ref_for_key(join, s, start_keyuse,
2746
2751
                                       found_const_table_map))
2747
 
                  DBUG_RETURN(1);
 
2752
                  goto error;
2748
2753
                if ((tmp=join_read_const_table(s,
2749
2754
                                               join->positions+const_count-1)))
2750
2755
                {
2751
2756
                  if (tmp > 0)
2752
 
                    DBUG_RETURN(1);                     // Fatal error
 
2757
                    goto error;                 // Fatal error
2753
2758
                }
2754
2759
                else
2755
2760
                  found_const_table_map|= table->map;
2826
2831
                          *s->on_expr_ref ? *s->on_expr_ref : conds,
2827
2832
                          1, &error);
2828
2833
      if (!select)
2829
 
        DBUG_RETURN(1);
 
2834
        goto error;
2830
2835
      records= get_quick_record_count(join->thd, select, s->table,
2831
2836
                                      &s->const_keys, join->row_limit);
2832
2837
      s->quick=select->quick;
2872
2877
  {
2873
2878
    optimize_keyuse(join, keyuse_array);
2874
2879
    if (choose_plan(join, all_table_map & ~join->const_table_map))
2875
 
      DBUG_RETURN(TRUE);
 
2880
      goto error;
2876
2881
  }
2877
2882
  else
2878
2883
  {
2882
2887
  }
2883
2888
  /* Generate an execution plan from the found optimal join order. */
2884
2889
  DBUG_RETURN(join->thd->killed || get_best_combination(join));
 
2890
 
 
2891
error:
 
2892
  /*
 
2893
    Need to clean up join_tab from TABLEs in case of error.
 
2894
    They won't get cleaned up by JOIN::cleanup() because JOIN::join_tab
 
2895
    may not be assigned yet by this function (which is building join_tab).
 
2896
    Dangling TABLE::reginfo.join_tab may cause part_of_refkey to choke. 
 
2897
  */
 
2898
  for (tables= tables_arg; tables; tables= tables->next_leaf)
 
2899
    tables->table->reginfo.join_tab= NULL;
 
2900
  DBUG_RETURN (1);
2885
2901
}
2886
2902
 
2887
2903
 
4889
4905
    */
4890
4906
    join->positions[idx]= best_pos;
4891
4907
 
 
4908
    /*
 
4909
      Update the interleaving state after extending the current partial plan
 
4910
      with a new table.
 
4911
      We are doing this here because best_extension_by_limited_search reverts
 
4912
      the interleaving state to the one of the non-extended partial plan 
 
4913
      on exit.
 
4914
    */
 
4915
    IF_DBUG(bool is_interleave_error= )
 
4916
    check_interleaving_with_nj (best_table);
 
4917
    /* This has been already checked by best_extension_by_limited_search */
 
4918
    DBUG_ASSERT(!is_interleave_error);
 
4919
 
4892
4920
    /* find the position of 'best_table' in 'join->best_ref' */
4893
4921
    best_idx= idx;
4894
4922
    JOIN_TAB *pos= join->best_ref[best_idx];
4906
4934
    --size_remain;
4907
4935
    ++idx;
4908
4936
 
4909
 
    DBUG_EXECUTE("opt", print_plan(join, join->tables,
 
4937
    DBUG_EXECUTE("opt", print_plan(join, idx,
4910
4938
                                   record_count, read_time, read_time,
4911
4939
                                   "extended"););
4912
4940
  } while (TRUE);
5064
5092
    table_map real_table_bit= s->table->map;
5065
5093
    if ((remaining_tables & real_table_bit) && 
5066
5094
        !(remaining_tables & s->dependent) && 
5067
 
        (!idx || !check_interleaving_with_nj(join->positions[idx-1].table, s)))
 
5095
        (!idx || !check_interleaving_with_nj(s)))
5068
5096
    {
5069
5097
      double current_record_count, current_read_time;
5070
5098
 
5210
5238
  {
5211
5239
    table_map real_table_bit=s->table->map;
5212
5240
    if ((rest_tables & real_table_bit) && !(rest_tables & s->dependent) &&
5213
 
        (!idx|| !check_interleaving_with_nj(join->positions[idx-1].table, s)))
 
5241
        (!idx|| !check_interleaving_with_nj(s)))
5214
5242
    {
5215
5243
      double records, best;
5216
5244
      best_access_path(join, s, thd, rest_tables, idx, record_count, 
5669
5697
}
5670
5698
 
5671
5699
 
5672
 
static bool
5673
 
make_simple_join(JOIN *join,TABLE *tmp_table)
 
5700
/**
 
5701
  @details Initialize a JOIN as a query execution plan
 
5702
  that accesses a single table via a table scan.
 
5703
 
 
5704
  @param  parent      contains JOIN_TAB and TABLE object buffers for this join
 
5705
  @param  tmp_table   temporary table
 
5706
 
 
5707
  @retval FALSE       success
 
5708
  @retval TRUE        error occurred
 
5709
*/
 
5710
bool
 
5711
JOIN::make_simple_join(JOIN *parent, TABLE *tmp_table)
5674
5712
{
5675
 
  TABLE **tableptr;
5676
 
  JOIN_TAB *join_tab;
5677
 
  DBUG_ENTER("make_simple_join");
 
5713
  DBUG_ENTER("JOIN::make_simple_join");
5678
5714
 
5679
5715
  /*
5680
5716
    Reuse TABLE * and JOIN_TAB if already allocated by a previous call
5681
5717
    to this function through JOIN::exec (may happen for sub-queries).
5682
5718
  */
5683
 
  if (!join->table_reexec)
5684
 
  {
5685
 
    if (!(join->table_reexec= (TABLE**) join->thd->alloc(sizeof(TABLE*))))
5686
 
      DBUG_RETURN(TRUE);                        /* purecov: inspected */
5687
 
    if (join->tmp_join)
5688
 
      join->tmp_join->table_reexec= join->table_reexec;
5689
 
  }
5690
 
  if (!join->join_tab_reexec)
5691
 
  {
5692
 
    if (!(join->join_tab_reexec=
5693
 
          (JOIN_TAB*) join->thd->alloc(sizeof(JOIN_TAB))))
5694
 
      DBUG_RETURN(TRUE);                        /* purecov: inspected */
5695
 
    if (join->tmp_join)
5696
 
      join->tmp_join->join_tab_reexec= join->join_tab_reexec;
5697
 
  }
5698
 
  tableptr= join->table_reexec;
5699
 
  join_tab= join->join_tab_reexec;
 
5719
  if (!parent->join_tab_reexec &&
 
5720
      !(parent->join_tab_reexec= (JOIN_TAB*) thd->alloc(sizeof(JOIN_TAB))))
 
5721
    DBUG_RETURN(TRUE);                        /* purecov: inspected */
5700
5722
 
5701
 
  join->join_tab=join_tab;
5702
 
  join->table=tableptr; tableptr[0]=tmp_table;
5703
 
  join->tables=1;
5704
 
  join->const_tables=0;
5705
 
  join->const_table_map=0;
5706
 
  join->tmp_table_param.field_count= join->tmp_table_param.sum_func_count=
5707
 
    join->tmp_table_param.func_count=0;
5708
 
  join->tmp_table_param.copy_field=join->tmp_table_param.copy_field_end=0;
5709
 
  join->first_record=join->sort_and_group=0;
5710
 
  join->send_records=(ha_rows) 0;
5711
 
  join->group=0;
5712
 
  join->row_limit=join->unit->select_limit_cnt;
5713
 
  join->do_send_rows = (join->row_limit) ? 1 : 0;
 
5723
  join_tab= parent->join_tab_reexec;
 
5724
  table= &parent->table_reexec[0]; parent->table_reexec[0]= tmp_table;
 
5725
  tables= 1;
 
5726
  const_tables= 0;
 
5727
  const_table_map= 0;
 
5728
  tmp_table_param.field_count= tmp_table_param.sum_func_count=
 
5729
    tmp_table_param.func_count= 0;
 
5730
  tmp_table_param.copy_field= tmp_table_param.copy_field_end=0;
 
5731
  first_record= sort_and_group=0;
 
5732
  send_records= (ha_rows) 0;
 
5733
  group= 0;
 
5734
  row_limit= unit->select_limit_cnt;
 
5735
  do_send_rows= row_limit ? 1 : 0;
5714
5736
 
5715
5737
  join_tab->cache.buff=0;                       /* No caching */
5716
5738
  join_tab->table=tmp_table;
5727
5749
  join_tab->ref.key = -1;
5728
5750
  join_tab->not_used_in_distinct=0;
5729
5751
  join_tab->read_first_record= join_init_read_record;
5730
 
  join_tab->join=join;
 
5752
  join_tab->join= this;
5731
5753
  join_tab->ref.key_parts= 0;
5732
5754
  bzero((char*) &join_tab->read_record,sizeof(join_tab->read_record));
5733
5755
  tmp_table->status=0;
7603
7625
    if (and_level)
7604
7626
    {
7605
7627
      /*
7606
 
         Retrieve all conjucts of this level detecting the equality
 
7628
         Retrieve all conjuncts of this level detecting the equality
7607
7629
         that are subject to substitution by multiple equality items and
7608
7630
         removing each such predicate from the conjunction after having 
7609
7631
         found/created a multiple equality whose inference the predicate is.
7619
7641
          li.remove();
7620
7642
      }
7621
7643
 
 
7644
      /*
 
7645
        Check if we eliminated all the predicates of the level, e.g.
 
7646
        (a=a AND b=b AND a=a).
 
7647
      */
 
7648
      if (!args->elements && 
 
7649
          !cond_equal.current_level.elements && 
 
7650
          !eq_list.elements)
 
7651
        return new Item_int((longlong) 1, 1);
 
7652
 
7622
7653
      List_iterator_fast<Item_equal> it(cond_equal.current_level);
7623
7654
      while ((item_equal= it++))
7624
7655
      {
8790
8821
             the partial join order.
8791
8822
  @endverbatim
8792
8823
 
8793
 
  @param join       Join being processed
8794
 
  @param last_tab   Last table in current partial join order (this function is
8795
 
                    not called for empty partial join orders)
8796
8824
  @param next_tab   Table we're going to extend the current partial join with
8797
8825
 
8798
8826
  @retval
8802
8830
    TRUE   Requested join order extension not allowed.
8803
8831
*/
8804
8832
 
8805
 
static bool check_interleaving_with_nj(JOIN_TAB *last_tab, JOIN_TAB *next_tab)
 
8833
static bool check_interleaving_with_nj(JOIN_TAB *next_tab)
8806
8834
{
8807
8835
  TABLE_LIST *next_emb= next_tab->table->pos_in_table_list->embedding;
8808
 
  JOIN *join= last_tab->join;
 
8836
  JOIN *join= next_tab->join;
8809
8837
 
8810
8838
  if (join->cur_embedding_map & ~next_tab->embedding_map)
8811
8839
  {
9769
9797
  table->in_use= thd;
9770
9798
  table->quick_keys.init();
9771
9799
  table->covering_keys.init();
 
9800
  table->merge_keys.init();
9772
9801
  table->keys_in_use_for_query.init();
9773
9802
 
9774
9803
  table->s= share;