~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to drizzled/sql_select.cc

Merge Stewart's dead code removal

Show diffs side-by-side

added added

removed removed

Lines of Context:
22
22
  @defgroup Query_Optimizer  Query Optimizer
23
23
  @{
24
24
*/
25
 
#include "config.h"
 
25
#include "drizzled/server_includes.h"
26
26
 
27
27
#include <string>
28
28
#include <iostream>
30
30
#include <vector>
31
31
 
32
32
#include "drizzled/sql_select.h" /* include join.h */
 
33
#include "drizzled/table_map_iterator.h"
33
34
 
34
35
#include "drizzled/error.h"
35
36
#include "drizzled/gettext.h"
38
39
#include "drizzled/nested_join.h"
39
40
#include "drizzled/probes.h"
40
41
#include "drizzled/show.h"
 
42
#include "drizzled/plugin/info_schema_table.h"
41
43
#include "drizzled/item/cache.h"
42
44
#include "drizzled/item/cmpfunc.h"
43
45
#include "drizzled/item/copy_string.h"
50
52
#include "drizzled/item/outer_ref.h"
51
53
#include "drizzled/index_hint.h"
52
54
#include "drizzled/memory/multi_malloc.h"
53
 
#include "drizzled/records.h"
54
 
#include "drizzled/internal/iocache.h"
55
55
 
56
56
#include "drizzled/sql_union.h"
57
57
#include "drizzled/optimizer/key_field.h"
58
58
#include "drizzled/optimizer/position.h"
59
59
#include "drizzled/optimizer/sargable_param.h"
60
60
#include "drizzled/optimizer/key_use.h"
61
 
#include "drizzled/optimizer/range.h"
62
 
#include "drizzled/optimizer/quick_range_select.h"
63
 
#include "drizzled/optimizer/quick_ror_intersect_select.h"
64
61
 
65
62
using namespace std;
 
63
using namespace drizzled;
66
64
 
67
 
namespace drizzled
 
65
static const string access_method_str[]=
68
66
{
 
67
  "UNKNOWN",
 
68
  "system",
 
69
  "const",
 
70
  "eq_ref",
 
71
  "ref",
 
72
  "MAYBE_REF",
 
73
  "ALL",
 
74
  "range",
 
75
  "index",
 
76
  "ref_or_null",
 
77
  "unique_subquery",
 
78
  "index_subquery",
 
79
  "index_merge"
 
80
};
69
81
 
70
82
static int sort_keyuse(optimizer::KeyUse *a, optimizer::KeyUse *b);
71
83
static COND *build_equal_items(Session *session, COND *cond,
115
127
{
116
128
  bool res;
117
129
  register Select_Lex *select_lex= &lex->select_lex;
118
 
  DRIZZLE_SELECT_START(session->query.c_str());
 
130
  DRIZZLE_SELECT_START(session->query);
119
131
 
120
132
  if (select_lex->master_unit()->is_union() ||
121
133
      select_lex->master_unit()->fake_select_lex)
321
333
                              for a, b and c in this list.
322
334
  @param conds                top level item of an expression representing
323
335
                              WHERE clause of the top level select
324
 
  @param og_num               total number of ORDER BY and GROUP BY clauses
 
336
  @param og_num               total number of order_st BY and GROUP BY clauses
325
337
                              arguments
326
 
  @param order                linked list of ORDER BY agruments
 
338
  @param order                linked list of order_st BY agruments
327
339
  @param group                linked list of GROUP BY arguments
328
340
  @param having               top level item of HAVING expression
329
341
  @param select_options       select options (BIG_RESULT, etc)
346
358
*/
347
359
bool mysql_select(Session *session,
348
360
                  Item ***rref_pointer_array,
349
 
                  TableList *tables, 
 
361
                        TableList *tables, 
350
362
                  uint32_t wild_num, 
351
363
                  List<Item> &fields,
352
 
                  COND *conds, 
 
364
                        COND *conds, 
353
365
                  uint32_t og_num,  
354
366
                  order_st *order, 
355
367
                  order_st *group,
356
 
                  Item *having, 
 
368
                        Item *having, 
357
369
                  uint64_t select_options,
358
 
                  select_result *result, 
 
370
                        select_result *result, 
359
371
                  Select_Lex_Unit *unit,
360
 
                  Select_Lex *select_lex)
 
372
                        Select_Lex *select_lex)
361
373
{
362
374
  bool err;
363
375
  bool free_join= 1;
408
420
    }
409
421
  }
410
422
 
411
 
  err= join->optimize();
412
 
  if (err)
 
423
  if ((err= join->optimize()))
413
424
  {
414
 
    goto err; // 1
 
425
    goto err;                                   // 1
415
426
  }
416
427
 
417
428
  if (session->lex->describe & DESCRIBE_EXTENDED)
463
474
  Create JoinTableS, make a guess about the table types,
464
475
  Approximate how many records will be used in each table
465
476
*****************************************************************************/
466
 
ha_rows get_quick_record_count(Session *session, optimizer::SqlSelect *select, Table *table, const key_map *keys,ha_rows limit)
 
477
ha_rows get_quick_record_count(Session *session, SQL_SELECT *select, Table *table, const key_map *keys,ha_rows limit)
467
478
{
468
479
  int error;
469
480
  if (check_stack_overrun(session, STACK_MIN_SIZE, NULL))
647
658
  {
648
659
    optimizer::KeyUse key_end,*prev,*save_pos,*use;
649
660
 
650
 
    internal::my_qsort(keyuse->buffer,keyuse->elements,sizeof(optimizer::KeyUse),
651
 
                       (qsort_cmp) sort_keyuse);
 
661
    my_qsort(keyuse->buffer,keyuse->elements,sizeof(optimizer::KeyUse),
 
662
          (qsort_cmp) sort_keyuse);
652
663
 
653
664
    memset(&key_end, 0, sizeof(key_end)); /* Add for easy testing */
654
665
    insert_dynamic(keyuse,(unsigned char*) &key_end);
717
728
      if (map == 1)                     // Only one table
718
729
      {
719
730
        Table *tmp_table=join->all_tables[tablenr];
720
 
        keyuse->setTableRows(max(tmp_table->cursor->stats.records, (ha_rows)100));
 
731
        keyuse->setTableRows(max(tmp_table->file->stats.records, (ha_rows)100));
721
732
      }
722
733
    }
723
734
    /*
871
882
    rec_length+=sizeof(bool);
872
883
  if (blobs)
873
884
  {
874
 
    uint32_t blob_length=(uint32_t) (join_tab->table->cursor->stats.mean_rec_length-
 
885
    uint32_t blob_length=(uint32_t) (join_tab->table->file->stats.mean_rec_length-
875
886
                                     (join_tab->table->getRecordLength()- rec_length));
876
887
    rec_length+= max((uint32_t)4,blob_length);
877
888
  }
888
899
                         uint32_t maybe_null)
889
900
{
890
901
  Item_ref *key_use_val= static_cast<Item_ref *>(keyuse->getVal());
 
902
  Item_ref **dir_val= reinterpret_cast<Item_ref **>(key_use_val->ref);
891
903
  if (! ((~used_tables) & keyuse->getUsedTables())) // if const item
892
904
  {
893
905
    return new store_key_const_item(session,
900
912
  else if (key_use_val->type() == Item::FIELD_ITEM ||
901
913
           (key_use_val->type() == Item::REF_ITEM &&
902
914
            key_use_val->ref_type() == Item_ref::OUTER_REF &&
903
 
            (*(Item_ref**)((Item_ref*)key_use_val)->ref)->ref_type() == Item_ref::DIRECT_REF &&
 
915
            (*dir_val)->ref_type() == Item_ref::DIRECT_REF &&
904
916
            key_use_val->real_item()->type() == Item::FIELD_ITEM))
905
917
  {
906
918
    return new store_key_field(session,
1465
1477
    if (table->key_read)
1466
1478
    {
1467
1479
      table->key_read= 0;
1468
 
      table->cursor->extra(HA_EXTRA_NO_KEYREAD);
 
1480
      table->file->extra(HA_EXTRA_NO_KEYREAD);
1469
1481
    }
1470
 
    table->cursor->ha_index_or_rnd_end();
 
1482
    table->file->ha_index_or_rnd_end();
1471
1483
    /*
1472
1484
      We need to reset this for next select
1473
1485
      (Tested in part_of_refkey)
1488
1500
}
1489
1501
 
1490
1502
/**
1491
 
  Remove the following expressions from ORDER BY and GROUP BY:
 
1503
  Remove the following expressions from order_st BY and GROUP BY:
1492
1504
  Constant expressions @n
1493
1505
  Expression that only uses tables that are of type EQ_REF and the reference
1494
1506
  is in the order_st list or if all refereed tables are of the above type.
1495
1507
 
1496
1508
  In the following, the X field can be removed:
1497
1509
  @code
1498
 
  SELECT * FROM t1,t2 WHERE t1.a=t2.a ORDER BY t1.a,t2.X
1499
 
  SELECT * FROM t1,t2,t3 WHERE t1.a=t2.a AND t2.b=t3.b ORDER BY t1.a,t3.X
 
1510
  SELECT * FROM t1,t2 WHERE t1.a=t2.a order_st BY t1.a,t2.X
 
1511
  SELECT * FROM t1,t2,t3 WHERE t1.a=t2.a AND t2.b=t3.b order_st BY t1.a,t3.X
1500
1512
  @endcode
1501
1513
 
1502
1514
  These can't be optimized:
1503
1515
  @code
1504
 
  SELECT * FROM t1,t2 WHERE t1.a=t2.a ORDER BY t2.X,t1.a
1505
 
  SELECT * FROM t1,t2 WHERE t1.a=t2.a AND t1.b=t2.b ORDER BY t1.a,t2.c
1506
 
  SELECT * FROM t1,t2 WHERE t1.a=t2.a ORDER BY t2.b,t1.a
 
1516
  SELECT * FROM t1,t2 WHERE t1.a=t2.a order_st BY t2.X,t1.a
 
1517
  SELECT * FROM t1,t2 WHERE t1.a=t2.a AND t1.b=t2.b order_st BY t1.a,t2.c
 
1518
  SELECT * FROM t1,t2 WHERE t1.a=t2.a order_st BY t2.b,t1.a
1507
1519
  @endcode
1508
1520
*/
1509
1521
bool eq_ref_table(JOIN *join, order_st *start_order, JoinTable *tab)
3284
3296
 
3285
3297
  if (table)
3286
3298
  {
3287
 
    table->cursor->extra(HA_EXTRA_WRITE_CACHE);
 
3299
    table->file->extra(HA_EXTRA_WRITE_CACHE);
3288
3300
    table->emptyRecord();
3289
3301
    if (table->group && join->tmp_table_param.sum_func_count &&
3290
 
        table->s->keys && !table->cursor->inited)
3291
 
      table->cursor->ha_index_init(0, 0);
 
3302
        table->s->keys && !table->file->inited)
 
3303
      table->file->ha_index_init(0, 0);
3292
3304
  }
3293
3305
  /* Set up select_end */
3294
3306
  Next_select_func end_select= setup_end_select_func(join);
3360
3372
  if (table)
3361
3373
  {
3362
3374
    int tmp, new_errno= 0;
3363
 
    if ((tmp=table->cursor->extra(HA_EXTRA_NO_CACHE)))
 
3375
    if ((tmp=table->file->extra(HA_EXTRA_NO_CACHE)))
3364
3376
    {
3365
3377
      new_errno= tmp;
3366
3378
    }
3367
 
    if ((tmp=table->cursor->ha_index_or_rnd_end()))
 
3379
    if ((tmp=table->file->ha_index_or_rnd_end()))
3368
3380
    {
3369
3381
      new_errno= tmp;
3370
3382
    }
3371
3383
    if (new_errno)
3372
 
      table->print_error(new_errno,MYF(0));
 
3384
      table->file->print_error(new_errno,MYF(0));
3373
3385
  }
3374
3386
  return(join->session->is_error() ? -1 : rc);
3375
3387
}
3586
3598
{
3587
3599
  int error;
3588
3600
  Table *table= tab->table;
3589
 
  if ((error=table->cursor->index_read_map(table->record[0],
 
3601
  if ((error=table->file->index_read_map(table->record[0],
3590
3602
                                         tab->ref.key_buff,
3591
3603
                                         make_prev_keypart_map(tab->ref.key_parts),
3592
3604
                                         HA_READ_KEY_EXACT)))
3622
3634
        (int) table->reginfo.lock_type <= (int) TL_READ_WITH_SHARED_LOCKS)
3623
3635
    {
3624
3636
      table->key_read=1;
3625
 
      table->cursor->extra(HA_EXTRA_KEYREAD);
 
3637
      table->file->extra(HA_EXTRA_KEYREAD);
3626
3638
      tab->index= tab->ref.key;
3627
3639
    }
3628
3640
    error=join_read_const(tab);
3629
3641
    if (table->key_read)
3630
3642
    {
3631
3643
      table->key_read=0;
3632
 
      table->cursor->extra(HA_EXTRA_NO_KEYREAD);
 
3644
      table->file->extra(HA_EXTRA_NO_KEYREAD);
3633
3645
    }
3634
3646
    if (error)
3635
3647
    {
3678
3690
  int error;
3679
3691
  if (table->status & STATUS_GARBAGE)           // If first read
3680
3692
  {
3681
 
    if ((error=table->cursor->read_first_row(table->record[0],
 
3693
    if ((error=table->file->read_first_row(table->record[0],
3682
3694
                                           table->s->primary_key)))
3683
3695
    {
3684
3696
      if (error != HA_ERR_END_OF_FILE)
3718
3730
      error= HA_ERR_KEY_NOT_FOUND;
3719
3731
    else
3720
3732
    {
3721
 
      error=table->cursor->index_read_idx_map(table->record[0],tab->ref.key,
 
3733
      error=table->file->index_read_idx_map(table->record[0],tab->ref.key,
3722
3734
                                            (unsigned char*) tab->ref.key_buff,
3723
3735
                                            make_prev_keypart_map(tab->ref.key_parts),
3724
3736
                                            HA_READ_KEY_EXACT);
3764
3776
  int error;
3765
3777
  Table *table= tab->table;
3766
3778
 
3767
 
  if (!table->cursor->inited)
 
3779
  if (!table->file->inited)
3768
3780
  {
3769
 
    table->cursor->ha_index_init(tab->ref.key, tab->sorted);
 
3781
    table->file->ha_index_init(tab->ref.key, tab->sorted);
3770
3782
  }
3771
3783
 
3772
3784
  /* TODO: Why don't we do "Late NULLs Filtering" here? */
3778
3790
      table->status=STATUS_NOT_FOUND;
3779
3791
      return -1;
3780
3792
    }
3781
 
    error=table->cursor->index_read_map(table->record[0],
 
3793
    error=table->file->index_read_map(table->record[0],
3782
3794
                                      tab->ref.key_buff,
3783
3795
                                      make_prev_keypart_map(tab->ref.key_parts),
3784
3796
                                      HA_READ_KEY_EXACT);
3813
3825
  Table *table= tab->table;
3814
3826
 
3815
3827
  /* Initialize the index first */
3816
 
  if (!table->cursor->inited)
3817
 
    table->cursor->ha_index_init(tab->ref.key, tab->sorted);
 
3828
  if (!table->file->inited)
 
3829
    table->file->ha_index_init(tab->ref.key, tab->sorted);
3818
3830
 
3819
3831
  /* Perform "Late NULLs Filtering" (see internals manual for explanations) */
3820
3832
  for (uint32_t i= 0 ; i < tab->ref.key_parts ; i++)
3825
3837
 
3826
3838
  if (cp_buffer_from_ref(tab->join->session, &tab->ref))
3827
3839
    return -1;
3828
 
  if ((error=table->cursor->index_read_map(table->record[0],
 
3840
  if ((error=table->file->index_read_map(table->record[0],
3829
3841
                                         tab->ref.key_buff,
3830
3842
                                         make_prev_keypart_map(tab->ref.key_parts),
3831
3843
                                         HA_READ_KEY_EXACT)))
3839
3851
}
3840
3852
 
3841
3853
/**
3842
 
  This function is used when optimizing away ORDER BY in
3843
 
  SELECT * FROM t1 WHERE a=1 ORDER BY a DESC,b DESC.
 
3854
  This function is used when optimizing away order_st BY in
 
3855
  SELECT * FROM t1 WHERE a=1 order_st BY a DESC,b DESC.
3844
3856
*/
3845
3857
int join_read_last_key(JoinTable *tab)
3846
3858
{
3847
3859
  int error;
3848
3860
  Table *table= tab->table;
3849
3861
 
3850
 
  if (!table->cursor->inited)
3851
 
    table->cursor->ha_index_init(tab->ref.key, tab->sorted);
 
3862
  if (!table->file->inited)
 
3863
    table->file->ha_index_init(tab->ref.key, tab->sorted);
3852
3864
  if (cp_buffer_from_ref(tab->join->session, &tab->ref))
3853
3865
    return -1;
3854
 
  if ((error=table->cursor->index_read_last_map(table->record[0],
 
3866
  if ((error=table->file->index_read_last_map(table->record[0],
3855
3867
                                              tab->ref.key_buff,
3856
3868
                                              make_prev_keypart_map(tab->ref.key_parts))))
3857
3869
  {
3880
3892
      /* Save index tuple from record to the buffer */
3881
3893
      key_copy(tab->insideout_buf, info->record, key, 0);
3882
3894
 
3883
 
      if ((error=table->cursor->index_next_same(table->record[0],
 
3895
      if ((error=table->file->index_next_same(table->record[0],
3884
3896
                                              tab->ref.key_buff,
3885
3897
                                              tab->ref.key_length)))
3886
3898
      {
3904
3916
  Table *table= info->table;
3905
3917
  JoinTable *tab=table->reginfo.join_tab;
3906
3918
 
3907
 
  if ((error=table->cursor->index_next_same(table->record[0],
 
3919
  if ((error=table->file->index_next_same(table->record[0],
3908
3920
                                          tab->ref.key_buff,
3909
3921
                                          tab->ref.key_length)))
3910
3922
  {
3923
3935
  Table *table= info->table;
3924
3936
  JoinTable *tab=table->reginfo.join_tab;
3925
3937
 
3926
 
  if ((error=table->cursor->index_prev(table->record[0])))
 
3938
  if ((error=table->file->index_prev(table->record[0])))
3927
3939
    return table->report_error(error);
3928
3940
  if (key_cmp_if_same(table, tab->ref.key_buff, tab->ref.key,
3929
3941
                      tab->ref.key_length))
3945
3957
int init_read_record_seq(JoinTable *tab)
3946
3958
{
3947
3959
  tab->read_record.read_record= rr_sequential;
3948
 
  if (tab->read_record.cursor->ha_rnd_init(1))
 
3960
  if (tab->read_record.file->ha_rnd_init(1))
3949
3961
    return 1;
3950
3962
  return (*tab->read_record.read_record)(&tab->read_record);
3951
3963
}
3975
3987
      !table->no_keyread)
3976
3988
  {
3977
3989
    table->key_read=1;
3978
 
    table->cursor->extra(HA_EXTRA_KEYREAD);
 
3990
    table->file->extra(HA_EXTRA_KEYREAD);
3979
3991
  }
3980
3992
  tab->table->status=0;
3981
3993
  tab->read_record.table=table;
3982
 
  tab->read_record.cursor=table->cursor;
 
3994
  tab->read_record.file=table->file;
3983
3995
  tab->read_record.index=tab->index;
3984
3996
  tab->read_record.record=table->record[0];
3985
3997
  if (tab->insideout_match_tab)
3994
4006
    tab->read_record.do_insideout_scan= 0;
3995
4007
  }
3996
4008
 
3997
 
  if (!table->cursor->inited)
3998
 
    table->cursor->ha_index_init(tab->index, tab->sorted);
3999
 
  if ((error=tab->table->cursor->index_first(tab->table->record[0])))
 
4009
  if (!table->file->inited)
 
4010
    table->file->ha_index_init(tab->index, tab->sorted);
 
4011
  if ((error=tab->table->file->index_first(tab->table->record[0])))
4000
4012
  {
4001
4013
    if (error != HA_ERR_KEY_NOT_FOUND && error != HA_ERR_END_OF_FILE)
4002
4014
      table->report_error(error);
4018
4030
      /* Save index tuple from record to the buffer */
4019
4031
      key_copy(tab->insideout_buf, info->record, key, 0);
4020
4032
 
4021
 
      if ((error=info->cursor->index_next(info->record)))
 
4033
      if ((error=info->file->index_next(info->record)))
4022
4034
        return info->table->report_error(error);
4023
4035
    } while (!key_cmp(tab->table->key_info[tab->index].key_part,
4024
4036
                      tab->insideout_buf, key->key_length));
4032
4044
int join_read_next(READ_RECORD *info)
4033
4045
{
4034
4046
  int error;
4035
 
  if ((error=info->cursor->index_next(info->record)))
 
4047
  if ((error=info->file->index_next(info->record)))
4036
4048
    return info->table->report_error(error);
4037
4049
  return 0;
4038
4050
}
4045
4057
      !table->no_keyread)
4046
4058
  {
4047
4059
    table->key_read=1;
4048
 
    table->cursor->extra(HA_EXTRA_KEYREAD);
 
4060
    table->file->extra(HA_EXTRA_KEYREAD);
4049
4061
  }
4050
4062
  tab->table->status=0;
4051
4063
  tab->read_record.read_record=join_read_prev;
4052
4064
  tab->read_record.table=table;
4053
 
  tab->read_record.cursor=table->cursor;
 
4065
  tab->read_record.file=table->file;
4054
4066
  tab->read_record.index=tab->index;
4055
4067
  tab->read_record.record=table->record[0];
4056
 
  if (!table->cursor->inited)
4057
 
    table->cursor->ha_index_init(tab->index, 1);
4058
 
  if ((error= tab->table->cursor->index_last(tab->table->record[0])))
 
4068
  if (!table->file->inited)
 
4069
    table->file->ha_index_init(tab->index, 1);
 
4070
  if ((error= tab->table->file->index_last(tab->table->record[0])))
4059
4071
    return table->report_error(error);
4060
4072
 
4061
4073
  return 0;
4064
4076
int join_read_prev(READ_RECORD *info)
4065
4077
{
4066
4078
  int error;
4067
 
  if ((error= info->cursor->index_prev(info->record)))
 
4079
  if ((error= info->file->index_prev(info->record)))
4068
4080
    return info->table->report_error(error);
4069
4081
 
4070
4082
  return 0;
4216
4228
        copy_sum_funcs(join->sum_funcs, join->sum_funcs_end[send_group_parts]);
4217
4229
        if (!join->having || join->having->val_int())
4218
4230
        {
4219
 
          int error= table->cursor->ha_write_row(table->record[0]);
 
4231
          int error= table->file->ha_write_row(table->record[0]);
4220
4232
          if (error && create_myisam_from_heap(join->session, table,
4221
4233
                                              join->tmp_table_param.start_recinfo,
4222
4234
                                                &join->tmp_table_param.recinfo,
4509
4521
 
4510
4522
    /*
4511
4523
      Skip key parts that are constants in the WHERE clause.
4512
 
      These are already skipped in the ORDER BY by const_expression_in_where()
 
4524
      These are already skipped in the order_st BY by const_expression_in_where()
4513
4525
    */
4514
4526
    for (; const_key_parts & 1 ; const_key_parts>>= 1)
4515
4527
      key_part++;
4522
4534
        the primary key as a suffix.
4523
4535
      */
4524
4536
      if (!on_primary_key &&
4525
 
          (table->cursor->getEngine()->check_flag(HTON_BIT_PRIMARY_KEY_IN_READ_INDEX)) &&
 
4537
          (table->file->ha_table_flags() & HA_PRIMARY_KEY_IN_READ_INDEX) &&
4526
4538
          table->s->primary_key != MAX_KEY)
4527
4539
      {
4528
4540
        on_primary_key= true;
4556
4568
  }
4557
4569
  *used_key_parts= on_primary_key ? table->key_info[idx].key_parts :
4558
4570
    (uint32_t) (key_part - table->key_info[idx].key_part);
4559
 
  if (reverse == -1 && !(table->index_flags(idx) &
 
4571
  if (reverse == -1 && !(table->file->index_flags(idx, *used_key_parts-1, 1) &
4560
4572
                         HA_READ_PREV))
4561
4573
    reverse= 0;                                 // Index can't be used
4562
4574
  return(reverse);
4748
4760
}
4749
4761
 
4750
4762
/**
4751
 
  Test if we can skip the ORDER BY by using an index.
 
4763
  Test if we can skip the order_st BY by using an index.
4752
4764
 
4753
4765
  SYNOPSIS
4754
4766
    test_if_skip_sort_order()
4779
4791
  int order_direction;
4780
4792
  uint32_t used_key_parts;
4781
4793
  Table *table=tab->table;
4782
 
  optimizer::SqlSelect *select= tab->select;
 
4794
  SQL_SELECT *select=tab->select;
4783
4795
  key_map usable_keys;
4784
 
  optimizer::QuickSelectInterface *save_quick= NULL;
 
4796
  QUICK_SELECT_I *save_quick= 0;
4785
4797
 
4786
4798
  /*
4787
4799
    Keys disabled by ALTER Table ... DISABLE KEYS should have already
4811
4823
    if (tab->type == AM_REF_OR_NULL)
4812
4824
      return(0);
4813
4825
  }
4814
 
  else if (select && select->quick)             // Range found by optimizer/range
 
4826
  else if (select && select->quick)             // Range found by opt_range
4815
4827
  {
4816
4828
    int quick_type= select->quick->get_type();
4817
4829
    save_quick= select->quick;
4821
4833
      by clustered PK values.
4822
4834
    */
4823
4835
 
4824
 
    if (quick_type == optimizer::QuickSelectInterface::QS_TYPE_INDEX_MERGE ||
4825
 
        quick_type == optimizer::QuickSelectInterface::QS_TYPE_ROR_UNION ||
4826
 
        quick_type == optimizer::QuickSelectInterface::QS_TYPE_ROR_INTERSECT)
 
4836
    if (quick_type == QUICK_SELECT_I::QS_TYPE_INDEX_MERGE ||
 
4837
        quick_type == QUICK_SELECT_I::QS_TYPE_ROR_UNION ||
 
4838
        quick_type == QUICK_SELECT_I::QS_TYPE_ROR_INTERSECT)
4827
4839
      return(0);
4828
4840
    ref_key=       select->quick->index;
4829
4841
    ref_key_parts= select->quick->used_key_parts;
4873
4885
        else
4874
4886
        {
4875
4887
          /*
4876
 
            The range optimizer constructed QuickRange for ref_key, and
 
4888
            The range optimizer constructed QUICK_RANGE for ref_key, and
4877
4889
            we want to use instead new_ref_key as the index. We can't
4878
4890
            just change the index of the quick select, because this may
4879
4891
            result in an incosistent QUICK_SELECT object. Below we
4920
4932
    double fanout= 1;
4921
4933
    JOIN *join= tab->join;
4922
4934
    uint32_t tablenr= tab - join->join_tab;
4923
 
    ha_rows table_records= table->cursor->stats.records;
 
4935
    ha_rows table_records= table->file->stats.records;
4924
4936
    bool group= join->group && order == join->group_list;
4925
4937
    optimizer::Position cur_pos;
4926
4938
 
4937
4949
        */
4938
4950
      if (tab->type == AM_ALL && tab->join->tables > tab->join->const_tables + 1)
4939
4951
        return(0);
4940
 
      keys= *table->cursor->keys_to_use_for_scanning();
 
4952
      keys= *table->file->keys_to_use_for_scanning();
4941
4953
      keys|= table->covering_keys;
4942
4954
 
4943
4955
      /*
4967
4979
      if (keys.test(nr) &&
4968
4980
          (direction= test_if_order_by_key(order, table, nr, &used_key_parts)))
4969
4981
      {
4970
 
        bool is_covering= table->covering_keys.test(nr) || (nr == table->s->primary_key && table->cursor->primary_key_is_clustered());
 
4982
        bool is_covering= table->covering_keys.test(nr) || (nr == table->s->primary_key && table->file->primary_key_is_clustered());
4971
4983
 
4972
4984
        /*
4973
 
          Don't use an index scan with ORDER BY without limit.
 
4985
          Don't use an index scan with order_st BY without limit.
4974
4986
          For GROUP BY without limit always use index scan
4975
4987
          if there is a suitable index.
4976
4988
          Why we hold to this asymmetry hardly can be explained
5037
5049
            Rows in such a sequence are supposed to be ordered
5038
5050
            by rowid/primary key. When reading the data
5039
5051
            in a sequence we'll touch not more pages than the
5040
 
            table cursor contains.
 
5052
            table file contains.
5041
5053
            TODO. Use the formula for a disk sweep sequential access
5042
5054
            to calculate the cost of accessing data rows for one
5043
5055
            index entry.
5044
5056
          */
5045
5057
          index_scan_time= select_limit/rec_per_key *
5046
 
                           min(rec_per_key, table->cursor->scan_time());
 
5058
                           min(rec_per_key, table->file->scan_time());
5047
5059
          if (is_covering || (ref_key < 0 && (group || table->force_index)) ||
5048
5060
              index_scan_time < read_time)
5049
5061
          {
5098
5110
          if (table->covering_keys.test(best_key))
5099
5111
          {
5100
5112
            table->key_read=1;
5101
 
            table->cursor->extra(HA_EXTRA_KEYREAD);
 
5113
            table->file->extra(HA_EXTRA_KEYREAD);
5102
5114
          }
5103
 
          table->cursor->ha_index_or_rnd_end();
 
5115
          table->file->ha_index_or_rnd_end();
5104
5116
          if (join->select_options & SELECT_DESCRIBE)
5105
5117
          {
5106
5118
            tab->ref.key= -1;
5132
5144
  }
5133
5145
 
5134
5146
check_reverse_order:
5135
 
  if (order_direction == -1)            // If ORDER BY ... DESC
 
5147
  if (order_direction == -1)            // If order_st BY ... DESC
5136
5148
  {
5137
5149
    if (select && select->quick)
5138
5150
    {
5140
5152
        Don't reverse the sort order, if it's already done.
5141
5153
        (In some cases test_if_order_by_key() can be called multiple times
5142
5154
      */
5143
 
      if (! select->quick->reverse_sorted())
 
5155
      if (!select->quick->reverse_sorted())
5144
5156
      {
5145
 
        optimizer::QuickSelectDescending *tmp= NULL;
 
5157
        QUICK_SELECT_DESC *tmp;
5146
5158
        bool error= false;
5147
5159
        int quick_type= select->quick->get_type();
5148
 
        if (quick_type == optimizer::QuickSelectInterface::QS_TYPE_INDEX_MERGE ||
5149
 
            quick_type == optimizer::QuickSelectInterface::QS_TYPE_ROR_INTERSECT ||
5150
 
            quick_type == optimizer::QuickSelectInterface::QS_TYPE_ROR_UNION ||
5151
 
            quick_type == optimizer::QuickSelectInterface::QS_TYPE_GROUP_MIN_MAX)
 
5160
        if (quick_type == QUICK_SELECT_I::QS_TYPE_INDEX_MERGE ||
 
5161
            quick_type == QUICK_SELECT_I::QS_TYPE_ROR_INTERSECT ||
 
5162
            quick_type == QUICK_SELECT_I::QS_TYPE_ROR_UNION ||
 
5163
            quick_type == QUICK_SELECT_I::QS_TYPE_GROUP_MIN_MAX)
5152
5164
        {
5153
5165
          tab->limit= 0;
5154
5166
          select->quick= save_quick;
5155
 
          return 0; // Use filesort
 
5167
          return(0);                   // Use filesort
5156
5168
        }
5157
5169
 
5158
 
        /* ORDER BY range_key DESC */
5159
 
        tmp= new optimizer::QuickSelectDescending((optimizer::QuickRangeSelect*)(select->quick),
5160
 
                                                  used_key_parts, 
5161
 
                                                  &error);
5162
 
        if (! tmp || error)
 
5170
        /* order_st BY range_key DESC */
 
5171
        tmp= new QUICK_SELECT_DESC((QUICK_RANGE_SELECT*)(select->quick),
 
5172
                                          used_key_parts, &error);
 
5173
        if (!tmp || error)
5163
5174
        {
5164
5175
          delete tmp;
5165
 
          select->quick= save_quick;
5166
 
          tab->limit= 0;
5167
 
          return 0; // Reverse sort not supported
 
5176
                select->quick= save_quick;
 
5177
                tab->limit= 0;
 
5178
          return(0);            // Reverse sort not supported
5168
5179
        }
5169
5180
        select->quick=tmp;
5170
5181
      }
5173
5184
             tab->ref.key >= 0 && tab->ref.key_parts <= used_key_parts)
5174
5185
    {
5175
5186
      /*
5176
 
        SELECT * FROM t1 WHERE a=1 ORDER BY a DESC,b DESC
 
5187
        SELECT * FROM t1 WHERE a=1 order_st BY a DESC,b DESC
5177
5188
 
5178
5189
        Use a traversal function that starts by reading the last row
5179
5190
        with key part (A) and then traverse the index backwards.
5184
5195
  }
5185
5196
  else if (select && select->quick)
5186
5197
    select->quick->sorted= 1;
5187
 
  return 1;
 
5198
  return(1);
5188
5199
}
5189
5200
 
5190
5201
/*
5205
5216
  IMPLEMENTATION
5206
5217
   - If there is an index that can be used, 'tab' is modified to use
5207
5218
     this index.
5208
 
   - If no index, create with filesort() an index cursor that can be used to
 
5219
   - If no index, create with filesort() an index file that can be used to
5209
5220
     retrieve rows in order (should be done with 'read_record').
5210
5221
     The sorted data is stored in tab->table and will be freed when calling
5211
5222
     tab->table->free_io_cache().
5220
5231
  uint32_t length= 0;
5221
5232
  ha_rows examined_rows;
5222
5233
  Table *table;
5223
 
  optimizer::SqlSelect *select= NULL;
 
5234
  SQL_SELECT *select;
5224
5235
  JoinTable *tab;
5225
5236
 
5226
5237
  if (join->tables == join->const_tables)
5237
5248
  */
5238
5249
  if ((order != join->group_list ||
5239
5250
       !(join->select_options & SELECT_BIG_RESULT) ||
5240
 
       (select && select->quick && (select->quick->get_type() == optimizer::QuickSelectInterface::QS_TYPE_GROUP_MIN_MAX))) &&
 
5251
       (select && select->quick && (select->quick->get_type() == QUICK_SELECT_I::QS_TYPE_GROUP_MIN_MAX))) &&
5241
5252
      test_if_skip_sort_order(tab,order,select_limit,0,
5242
5253
                              is_order_by ?  &table->keys_in_use_for_order_by :
5243
5254
                              &table->keys_in_use_for_group_by))
5248
5259
        make_unireg_sortorder(order, &length, join->sortorder)))
5249
5260
    goto err;
5250
5261
 
5251
 
  table->sort.io_cache= new internal::IO_CACHE;
5252
 
  memset(table->sort.io_cache, 0, sizeof(internal::IO_CACHE));
 
5262
  table->sort.io_cache= new IO_CACHE;
 
5263
  memset(table->sort.io_cache, 0, sizeof(IO_CACHE));
5253
5264
  table->status=0;                              // May be wrong if quick_select
5254
5265
 
5255
5266
  // If table has a range, move it to select
5266
5277
      if (table->key_read && ((uint32_t) tab->ref.key != select->quick->index))
5267
5278
      {
5268
5279
        table->key_read=0;
5269
 
        table->cursor->extra(HA_EXTRA_NO_KEYREAD);
 
5280
        table->file->extra(HA_EXTRA_NO_KEYREAD);
5270
5281
      }
5271
5282
    }
5272
5283
    else
5277
5288
        For impossible ranges (like when doing a lookup on NULL on a NOT NULL
5278
5289
        field, quick will contain an empty record set.
5279
5290
      */
5280
 
      if (! (select->quick= (optimizer::get_quick_select_for_ref(session, 
5281
 
                                                                 table, 
5282
 
                                                                 &tab->ref,
5283
 
                                                                 tab->found_records))))
5284
 
      {
 
5291
      if (!(select->quick= (get_quick_select_for_ref(session, table, &tab->ref,
 
5292
                                                     tab->found_records))))
5285
5293
        goto err;
5286
 
      }
5287
5294
    }
5288
5295
  }
5289
5296
 
 
5297
  /* Fill schema tables with data before filesort if it's necessary */
 
5298
  if ((join->select_lex->options & OPTION_SCHEMA_TABLE) &&
 
5299
      get_schema_tables_result(join, PROCESSED_BY_CREATE_SORT_INDEX))
 
5300
    goto err;
 
5301
 
5290
5302
  if (table->s->tmp_table)
5291
 
    table->cursor->info(HA_STATUS_VARIABLE);    // Get record count
 
5303
    table->file->info(HA_STATUS_VARIABLE);      // Get record count
5292
5304
  table->sort.found_records=filesort(session, table,join->sortorder, length,
5293
5305
                                     select, filesort_limit, 0,
5294
5306
                                     &examined_rows);
5307
5319
  if (table->key_read)                          // Restore if we used indexes
5308
5320
  {
5309
5321
    table->key_read=0;
5310
 
    table->cursor->extra(HA_EXTRA_NO_KEYREAD);
 
5322
    table->file->extra(HA_EXTRA_NO_KEYREAD);
5311
5323
  }
5312
5324
  return(table->sort.found_records == HA_POS_ERROR);
5313
5325
err:
5316
5328
 
5317
5329
int remove_dup_with_compare(Session *session, Table *table, Field **first_field, uint32_t offset, Item *having)
5318
5330
{
5319
 
  Cursor *cursor=table->cursor;
 
5331
  Cursor *file=table->file;
5320
5332
  char *org_record,*new_record;
5321
5333
  unsigned char *record;
5322
5334
  int error;
5325
5337
  org_record=(char*) (record=table->record[0])+offset;
5326
5338
  new_record=(char*) table->record[1]+offset;
5327
5339
 
5328
 
  cursor->ha_rnd_init(1);
5329
 
  error=cursor->rnd_next(record);
 
5340
  file->ha_rnd_init(1);
 
5341
  error=file->rnd_next(record);
5330
5342
  for (;;)
5331
5343
  {
5332
5344
    if (session->killed)
5345
5357
    }
5346
5358
    if (having && !having->val_int())
5347
5359
    {
5348
 
      if ((error=cursor->ha_delete_row(record)))
 
5360
      if ((error=file->ha_delete_row(record)))
5349
5361
        goto err;
5350
 
      error=cursor->rnd_next(record);
 
5362
      error=file->rnd_next(record);
5351
5363
      continue;
5352
5364
    }
5353
5365
    if (copy_blobs(first_field))
5358
5370
    }
5359
5371
    memcpy(new_record,org_record,reclength);
5360
5372
 
5361
 
    /* Read through rest of cursor and mark duplicated rows deleted */
 
5373
    /* Read through rest of file and mark duplicated rows deleted */
5362
5374
    bool found=0;
5363
5375
    for (;;)
5364
5376
    {
5365
 
      if ((error=cursor->rnd_next(record)))
 
5377
      if ((error=file->rnd_next(record)))
5366
5378
      {
5367
5379
        if (error == HA_ERR_RECORD_DELETED)
5368
5380
          continue;
5372
5384
      }
5373
5385
      if (table->compare_record(first_field) == 0)
5374
5386
      {
5375
 
        if ((error=cursor->ha_delete_row(record)))
 
5387
        if ((error=file->ha_delete_row(record)))
5376
5388
          goto err;
5377
5389
      }
5378
5390
      else if (!found)
5379
5391
      {
5380
5392
        found= 1;
5381
 
        cursor->position(record);       // Remember position
 
5393
        file->position(record); // Remember position
5382
5394
      }
5383
5395
    }
5384
5396
    if (!found)
5385
 
      break;                                    // End of cursor
 
5397
      break;                                    // End of file
5386
5398
    /* Restart search on next row */
5387
 
    error=cursor->restart_rnd_next(record,cursor->ref);
 
5399
    error=file->restart_rnd_next(record,file->ref);
5388
5400
  }
5389
5401
 
5390
 
  cursor->extra(HA_EXTRA_NO_CACHE);
 
5402
  file->extra(HA_EXTRA_NO_CACHE);
5391
5403
  return(0);
5392
5404
err:
5393
 
  cursor->extra(HA_EXTRA_NO_CACHE);
 
5405
  file->extra(HA_EXTRA_NO_CACHE);
5394
5406
  if (error)
5395
 
    table->print_error(error,MYF(0));
 
5407
    file->print_error(error,MYF(0));
5396
5408
  return(1);
5397
5409
}
5398
5410
 
5411
5423
{
5412
5424
  unsigned char *key_buffer, *key_pos, *record=table->record[0];
5413
5425
  int error;
5414
 
  Cursor *cursor= table->cursor;
 
5426
  Cursor *file= table->file;
5415
5427
  uint32_t extra_length= ALIGN_SIZE(key_length)-key_length;
5416
5428
  uint32_t *field_lengths,*field_length;
5417
5429
  HASH hash;
5419
5431
  if (! memory::multi_malloc(false,
5420
5432
                       &key_buffer,
5421
5433
                       (uint32_t) ((key_length + extra_length) *
5422
 
                               (long) cursor->stats.records),
 
5434
                               (long) file->stats.records),
5423
5435
                       &field_lengths,
5424
5436
                       (uint32_t) (field_count*sizeof(*field_lengths)),
5425
5437
                       NULL))
5439
5451
    extra_length= ALIGN_SIZE(key_length)-key_length;
5440
5452
  }
5441
5453
 
5442
 
  if (hash_init(&hash, &my_charset_bin, (uint32_t) cursor->stats.records, 0,
 
5454
  if (hash_init(&hash, &my_charset_bin, (uint32_t) file->stats.records, 0,
5443
5455
                key_length, (hash_get_key) 0, 0, 0))
5444
5456
  {
5445
5457
    free((char*) key_buffer);
5446
5458
    return(1);
5447
5459
  }
5448
5460
 
5449
 
  cursor->ha_rnd_init(1);
 
5461
  file->ha_rnd_init(1);
5450
5462
  key_pos=key_buffer;
5451
5463
  for (;;)
5452
5464
  {
5457
5469
      error=0;
5458
5470
      goto err;
5459
5471
    }
5460
 
    if ((error=cursor->rnd_next(record)))
 
5472
    if ((error=file->rnd_next(record)))
5461
5473
    {
5462
5474
      if (error == HA_ERR_RECORD_DELETED)
5463
5475
        continue;
5467
5479
    }
5468
5480
    if (having && !having->val_int())
5469
5481
    {
5470
 
      if ((error=cursor->ha_delete_row(record)))
 
5482
      if ((error=file->ha_delete_row(record)))
5471
5483
        goto err;
5472
5484
      continue;
5473
5485
    }
5484
5496
    if (hash_search(&hash, org_key_pos, key_length))
5485
5497
    {
5486
5498
      /* Duplicated found ; Remove the row */
5487
 
      if ((error=cursor->ha_delete_row(record)))
 
5499
      if ((error=file->ha_delete_row(record)))
5488
5500
        goto err;
5489
5501
    }
5490
5502
    else
5493
5505
  }
5494
5506
  free((char*) key_buffer);
5495
5507
  hash_free(&hash);
5496
 
  cursor->extra(HA_EXTRA_NO_CACHE);
5497
 
  (void) cursor->ha_rnd_end();
 
5508
  file->extra(HA_EXTRA_NO_CACHE);
 
5509
  (void) file->ha_rnd_end();
5498
5510
  return(0);
5499
5511
 
5500
5512
err:
5501
5513
  free((char*) key_buffer);
5502
5514
  hash_free(&hash);
5503
 
  cursor->extra(HA_EXTRA_NO_CACHE);
5504
 
  (void) cursor->ha_rnd_end();
 
5515
  file->extra(HA_EXTRA_NO_CACHE);
 
5516
  (void) file->ha_rnd_end();
5505
5517
  if (error)
5506
 
    table->print_error(error,MYF(0));
 
5518
    file->print_error(error,MYF(0));
5507
5519
  return(1);
5508
5520
}
5509
5521
 
5516
5528
  for (order_st *tmp = order; tmp; tmp=tmp->next)
5517
5529
    count++;
5518
5530
  if (!sortorder)
5519
 
    sortorder= (SORT_FIELD*) memory::sql_alloc(sizeof(SORT_FIELD) *
 
5531
    sortorder= (SORT_FIELD*) sql_alloc(sizeof(SORT_FIELD) *
5520
5532
                                       (max(count, *length) + 1));
5521
5533
  pos= sort= sortorder;
5522
5534
 
5604
5616
*****************************************************************************/
5605
5617
 
5606
5618
/**
5607
 
  Resolve an ORDER BY or GROUP BY column reference.
 
5619
  Resolve an order_st BY or GROUP BY column reference.
5608
5620
 
5609
5621
  Given a column reference (represented by 'order') from a GROUP BY or order_st
5610
5622
  BY clause, find the actual column it represents. If the column being
5611
5623
  resolved is from the GROUP BY clause, the procedure searches the SELECT
5612
5624
  list 'fields' and the columns in the FROM list 'tables'. If 'order' is from
5613
 
  the ORDER BY clause, only the SELECT list is being searched.
 
5625
  the order_st BY clause, only the SELECT list is being searched.
5614
5626
 
5615
5627
  If 'order' is resolved to an Item, then order->item is set to the found
5616
5628
  Item. If there is no item for the found column (that is, it was resolved
6151
6163
                another extra byte to not get warnings from purify in
6152
6164
                Field_varstring::val_int
6153
6165
              */
6154
 
        if (!(tmp= (unsigned char*) memory::sql_alloc(field->pack_length()+2)))
 
6166
        if (!(tmp= (unsigned char*) sql_alloc(field->pack_length()+2)))
6155
6167
          goto err;
6156
6168
        if (copy)
6157
6169
        {
6197
6209
    itr++;
6198
6210
  itr.sublist(res_selected_fields, elements);
6199
6211
  /*
6200
 
    Put elements from HAVING, ORDER BY and GROUP BY last to ensure that any
 
6212
    Put elements from HAVING, order_st BY and GROUP BY last to ensure that any
6201
6213
    reference used in these will resolve to a item that is already calculated
6202
6214
  */
6203
6215
  param->copy_funcs.concat(&extra_funcs);
6537
6549
  return 0;
6538
6550
}
6539
6551
 
 
6552
/**
 
6553
  EXPLAIN handling.
 
6554
 
 
6555
  Send a description about what how the select will be done to stdout.
 
6556
*/
 
6557
void select_describe(JOIN *join, bool need_tmp_table, bool need_order,
 
6558
                     bool distinct,const char *message)
 
6559
{
 
6560
  List<Item> field_list;
 
6561
  List<Item> item_list;
 
6562
  Session *session=join->session;
 
6563
  select_result *result=join->result;
 
6564
  Item *item_null= new Item_null();
 
6565
  const CHARSET_INFO * const cs= system_charset_info;
 
6566
  int quick_type;
 
6567
  /* Don't log this into the slow query log */
 
6568
  session->server_status&= ~(SERVER_QUERY_NO_INDEX_USED | SERVER_QUERY_NO_GOOD_INDEX_USED);
 
6569
  join->unit->offset_limit_cnt= 0;
 
6570
 
 
6571
  /*
 
6572
    NOTE: the number/types of items pushed into item_list must be in sync with
 
6573
    EXPLAIN column types as they're "defined" in Session::send_explain_fields()
 
6574
  */
 
6575
  if (message)
 
6576
  {
 
6577
    item_list.push_back(new Item_int((int32_t)
 
6578
                                     join->select_lex->select_number));
 
6579
    item_list.push_back(new Item_string(join->select_lex->type,
 
6580
                                        strlen(join->select_lex->type), cs));
 
6581
    for (uint32_t i=0 ; i < 7; i++)
 
6582
      item_list.push_back(item_null);
 
6583
    if (join->session->lex->describe & DESCRIBE_EXTENDED)
 
6584
      item_list.push_back(item_null);
 
6585
 
 
6586
    item_list.push_back(new Item_string(message,strlen(message),cs));
 
6587
    if (result->send_data(item_list))
 
6588
      join->error= 1;
 
6589
  }
 
6590
  else if (join->select_lex == join->unit->fake_select_lex)
 
6591
  {
 
6592
    /*
 
6593
      here we assume that the query will return at least two rows, so we
 
6594
      show "filesort" in EXPLAIN. Of course, sometimes we'll be wrong
 
6595
      and no filesort will be actually done, but executing all selects in
 
6596
      the UNION to provide precise EXPLAIN information will hardly be
 
6597
      appreciated :)
 
6598
    */
 
6599
    char table_name_buffer[NAME_LEN];
 
6600
    item_list.empty();
 
6601
    /* id */
 
6602
    item_list.push_back(new Item_null);
 
6603
    /* select_type */
 
6604
    item_list.push_back(new Item_string(join->select_lex->type,
 
6605
                                        strlen(join->select_lex->type),
 
6606
                                        cs));
 
6607
    /* table */
 
6608
    {
 
6609
      Select_Lex *sl= join->unit->first_select();
 
6610
      uint32_t len= 6, lastop= 0;
 
6611
      memcpy(table_name_buffer, STRING_WITH_LEN("<union"));
 
6612
      for (; sl && len + lastop + 5 < NAME_LEN; sl= sl->next_select())
 
6613
      {
 
6614
        len+= lastop;
 
6615
        lastop= snprintf(table_name_buffer + len, NAME_LEN - len,
 
6616
                         "%u,", sl->select_number);
 
6617
      }
 
6618
      if (sl || len + lastop >= NAME_LEN)
 
6619
      {
 
6620
        memcpy(table_name_buffer + len, STRING_WITH_LEN("...>") + 1);
 
6621
        len+= 4;
 
6622
      }
 
6623
      else
 
6624
      {
 
6625
        len+= lastop;
 
6626
        table_name_buffer[len - 1]= '>';  // change ',' to '>'
 
6627
      }
 
6628
      item_list.push_back(new Item_string(table_name_buffer, len, cs));
 
6629
    }
 
6630
    /* type */
 
6631
    item_list.push_back(new Item_string(access_method_str[AM_ALL].c_str(),
 
6632
                                        access_method_str[AM_ALL].length(),
 
6633
                                        cs));
 
6634
    /* possible_keys */
 
6635
    item_list.push_back(item_null);
 
6636
    /* key*/
 
6637
    item_list.push_back(item_null);
 
6638
    /* key_len */
 
6639
    item_list.push_back(item_null);
 
6640
    /* ref */
 
6641
    item_list.push_back(item_null);
 
6642
    /* in_rows */
 
6643
    if (join->session->lex->describe & DESCRIBE_EXTENDED)
 
6644
      item_list.push_back(item_null);
 
6645
    /* rows */
 
6646
    item_list.push_back(item_null);
 
6647
    /* extra */
 
6648
    if (join->unit->global_parameters->order_list.first)
 
6649
      item_list.push_back(new Item_string("Using filesort",
 
6650
                                          14, cs));
 
6651
    else
 
6652
      item_list.push_back(new Item_string("", 0, cs));
 
6653
 
 
6654
    if (result->send_data(item_list))
 
6655
      join->error= 1;
 
6656
  }
 
6657
  else
 
6658
  {
 
6659
    table_map used_tables=0;
 
6660
    for (uint32_t i=0 ; i < join->tables ; i++)
 
6661
    {
 
6662
      JoinTable *tab=join->join_tab+i;
 
6663
      Table *table=tab->table;
 
6664
      TableList *table_list= tab->table->pos_in_table_list;
 
6665
      char buff[512];
 
6666
      char buff1[512], buff2[512], buff3[512];
 
6667
      char keylen_str_buf[64];
 
6668
      String extra(buff, sizeof(buff),cs);
 
6669
      char table_name_buffer[NAME_LEN];
 
6670
      String tmp1(buff1,sizeof(buff1),cs);
 
6671
      String tmp2(buff2,sizeof(buff2),cs);
 
6672
      String tmp3(buff3,sizeof(buff3),cs);
 
6673
      extra.length(0);
 
6674
      tmp1.length(0);
 
6675
      tmp2.length(0);
 
6676
      tmp3.length(0);
 
6677
 
 
6678
      quick_type= -1;
 
6679
      item_list.empty();
 
6680
      /* id */
 
6681
      item_list.push_back(new Item_uint((uint32_t)
 
6682
                                       join->select_lex->select_number));
 
6683
      /* select_type */
 
6684
      item_list.push_back(new Item_string(join->select_lex->type,
 
6685
                                          strlen(join->select_lex->type),
 
6686
                                          cs));
 
6687
      if (tab->type == AM_ALL && tab->select && tab->select->quick)
 
6688
      {
 
6689
        quick_type= tab->select->quick->get_type();
 
6690
        if ((quick_type == QUICK_SELECT_I::QS_TYPE_INDEX_MERGE) ||
 
6691
            (quick_type == QUICK_SELECT_I::QS_TYPE_ROR_INTERSECT) ||
 
6692
            (quick_type == QUICK_SELECT_I::QS_TYPE_ROR_UNION))
 
6693
          tab->type = AM_INDEX_MERGE;
 
6694
        else
 
6695
          tab->type = AM_RANGE;
 
6696
      }
 
6697
      /* table */
 
6698
      if (table->derived_select_number)
 
6699
      {
 
6700
        /* Derived table name generation */
 
6701
        int len= snprintf(table_name_buffer, sizeof(table_name_buffer)-1,
 
6702
                          "<derived%u>",
 
6703
                          table->derived_select_number);
 
6704
        item_list.push_back(new Item_string(table_name_buffer, len, cs));
 
6705
      }
 
6706
      else
 
6707
      {
 
6708
        TableList *real_table= table->pos_in_table_list;
 
6709
        item_list.push_back(new Item_string(real_table->alias,
 
6710
                                            strlen(real_table->alias),
 
6711
                                            cs));
 
6712
      }
 
6713
      /* "type" column */
 
6714
      item_list.push_back(new Item_string(access_method_str[tab->type].c_str(),
 
6715
                                          access_method_str[tab->type].length(),
 
6716
                                          cs));
 
6717
      /* Build "possible_keys" value and add it to item_list */
 
6718
      if (tab->keys.any())
 
6719
      {
 
6720
        uint32_t j;
 
6721
        for (j=0 ; j < table->s->keys ; j++)
 
6722
        {
 
6723
          if (tab->keys.test(j))
 
6724
          {
 
6725
            if (tmp1.length())
 
6726
              tmp1.append(',');
 
6727
            tmp1.append(table->key_info[j].name,
 
6728
                        strlen(table->key_info[j].name),
 
6729
                        system_charset_info);
 
6730
          }
 
6731
        }
 
6732
      }
 
6733
      if (tmp1.length())
 
6734
        item_list.push_back(new Item_string(tmp1.ptr(),tmp1.length(),cs));
 
6735
      else
 
6736
        item_list.push_back(item_null);
 
6737
 
 
6738
      /* Build "key", "key_len", and "ref" values and add them to item_list */
 
6739
      if (tab->ref.key_parts)
 
6740
      {
 
6741
        KEY *key_info=table->key_info+ tab->ref.key;
 
6742
        register uint32_t length;
 
6743
        item_list.push_back(new Item_string(key_info->name,
 
6744
                                            strlen(key_info->name),
 
6745
                                            system_charset_info));
 
6746
        length= int64_t2str(tab->ref.key_length, keylen_str_buf, 10) -
 
6747
                keylen_str_buf;
 
6748
        item_list.push_back(new Item_string(keylen_str_buf, length,
 
6749
                                            system_charset_info));
 
6750
        for (StoredKey **ref=tab->ref.key_copy ; *ref ; ref++)
 
6751
        {
 
6752
          if (tmp2.length())
 
6753
            tmp2.append(',');
 
6754
          tmp2.append((*ref)->name(), strlen((*ref)->name()),
 
6755
                      system_charset_info);
 
6756
        }
 
6757
        item_list.push_back(new Item_string(tmp2.ptr(),tmp2.length(),cs));
 
6758
      }
 
6759
      else if (tab->type == AM_NEXT)
 
6760
      {
 
6761
        KEY *key_info=table->key_info+ tab->index;
 
6762
        register uint32_t length;
 
6763
        item_list.push_back(new Item_string(key_info->name,
 
6764
                                            strlen(key_info->name),cs));
 
6765
        length= int64_t2str(key_info->key_length, keylen_str_buf, 10) -
 
6766
                keylen_str_buf;
 
6767
        item_list.push_back(new Item_string(keylen_str_buf,
 
6768
                                            length,
 
6769
                                            system_charset_info));
 
6770
        item_list.push_back(item_null);
 
6771
      }
 
6772
      else if (tab->select && tab->select->quick)
 
6773
      {
 
6774
        tab->select->quick->add_keys_and_lengths(&tmp2, &tmp3);
 
6775
        item_list.push_back(new Item_string(tmp2.ptr(),tmp2.length(),cs));
 
6776
        item_list.push_back(new Item_string(tmp3.ptr(),tmp3.length(),cs));
 
6777
        item_list.push_back(item_null);
 
6778
      }
 
6779
      else
 
6780
      {
 
6781
        if (table_list->schema_table && 
 
6782
            table_list->schema_table->getRequestedObject() & OPTIMIZE_I_S_TABLE)
 
6783
        {
 
6784
          if (table_list->has_db_lookup_value)
 
6785
          {
 
6786
            int f_idx= table_list->schema_table->getFirstColumnIndex();
 
6787
            const string &tmp_buff= table_list->schema_table->getColumnName(f_idx);
 
6788
            tmp2.append(tmp_buff.c_str(), tmp_buff.length(), cs);
 
6789
          }
 
6790
          if (table_list->has_table_lookup_value)
 
6791
          {
 
6792
            if (table_list->has_db_lookup_value)
 
6793
              tmp2.append(',');
 
6794
            int f_idx= table_list->schema_table->getSecondColumnIndex();
 
6795
            const string &tmp_buff= table_list->schema_table->getColumnName(f_idx);
 
6796
            tmp2.append(tmp_buff.c_str(), tmp_buff.length(), cs);
 
6797
          }
 
6798
          if (tmp2.length())
 
6799
            item_list.push_back(new Item_string(tmp2.ptr(),tmp2.length(),cs));
 
6800
          else
 
6801
            item_list.push_back(item_null);
 
6802
        }
 
6803
        else
 
6804
          item_list.push_back(item_null);
 
6805
        item_list.push_back(item_null);
 
6806
        item_list.push_back(item_null);
 
6807
      }
 
6808
 
 
6809
      /* Add "rows" field to item_list. */
 
6810
      if (table_list->schema_table)
 
6811
      {
 
6812
        /* in_rows */
 
6813
        if (join->session->lex->describe & DESCRIBE_EXTENDED)
 
6814
          item_list.push_back(item_null);
 
6815
        /* rows */
 
6816
        item_list.push_back(item_null);
 
6817
      }
 
6818
      else
 
6819
      {
 
6820
        double examined_rows;
 
6821
        if (tab->select && tab->select->quick)
 
6822
          examined_rows= rows2double(tab->select->quick->records);
 
6823
        else if (tab->type == AM_NEXT || tab->type == AM_ALL)
 
6824
          examined_rows= rows2double(tab->limit ? tab->limit :
 
6825
                                     tab->table->file->records());
 
6826
        else
 
6827
        {
 
6828
          optimizer::Position cur_pos= join->getPosFromOptimalPlan(i);
 
6829
          examined_rows= cur_pos.getFanout();
 
6830
        }
 
6831
 
 
6832
        item_list.push_back(new Item_int((int64_t) (uint64_t) examined_rows,
 
6833
                                         MY_INT64_NUM_DECIMAL_DIGITS));
 
6834
 
 
6835
        /* Add "filtered" field to item_list. */
 
6836
        if (join->session->lex->describe & DESCRIBE_EXTENDED)
 
6837
        {
 
6838
          float f= 0.0;
 
6839
          if (examined_rows)
 
6840
          {
 
6841
            optimizer::Position cur_pos= join->getPosFromOptimalPlan(i);
 
6842
            f= (float) (100.0 * cur_pos.getFanout() /
 
6843
                        examined_rows);
 
6844
          }
 
6845
          item_list.push_back(new Item_float(f, 2));
 
6846
        }
 
6847
      }
 
6848
 
 
6849
      /* Build "Extra" field and add it to item_list. */
 
6850
      bool key_read=table->key_read;
 
6851
      if ((tab->type == AM_NEXT || tab->type == AM_CONST) &&
 
6852
          table->covering_keys.test(tab->index))
 
6853
        key_read=1;
 
6854
      if (quick_type == QUICK_SELECT_I::QS_TYPE_ROR_INTERSECT &&
 
6855
          !((QUICK_ROR_INTERSECT_SELECT*)tab->select->quick)->need_to_fetch_row)
 
6856
        key_read=1;
 
6857
 
 
6858
      if (tab->info)
 
6859
        item_list.push_back(new Item_string(tab->info,strlen(tab->info),cs));
 
6860
      else if (tab->packed_info & TAB_INFO_HAVE_VALUE)
 
6861
      {
 
6862
        if (tab->packed_info & TAB_INFO_USING_INDEX)
 
6863
          extra.append(STRING_WITH_LEN("; Using index"));
 
6864
        if (tab->packed_info & TAB_INFO_USING_WHERE)
 
6865
          extra.append(STRING_WITH_LEN("; Using where"));
 
6866
        if (tab->packed_info & TAB_INFO_FULL_SCAN_ON_NULL)
 
6867
          extra.append(STRING_WITH_LEN("; Full scan on NULL key"));
 
6868
        /* Skip initial "; "*/
 
6869
        const char *str= extra.ptr();
 
6870
        uint32_t len= extra.length();
 
6871
        if (len)
 
6872
        {
 
6873
          str += 2;
 
6874
          len -= 2;
 
6875
        }
 
6876
        item_list.push_back(new Item_string(str, len, cs));
 
6877
      }
 
6878
      else
 
6879
      {
 
6880
        uint32_t keyno= MAX_KEY;
 
6881
        if (tab->ref.key_parts)
 
6882
          keyno= tab->ref.key;
 
6883
        else if (tab->select && tab->select->quick)
 
6884
          keyno = tab->select->quick->index;
 
6885
 
 
6886
        if (quick_type == QUICK_SELECT_I::QS_TYPE_ROR_UNION ||
 
6887
            quick_type == QUICK_SELECT_I::QS_TYPE_ROR_INTERSECT ||
 
6888
            quick_type == QUICK_SELECT_I::QS_TYPE_INDEX_MERGE)
 
6889
        {
 
6890
          extra.append(STRING_WITH_LEN("; Using "));
 
6891
          tab->select->quick->add_info_string(&extra);
 
6892
        }
 
6893
          if (tab->select)
 
6894
        {
 
6895
          if (tab->use_quick == 2)
 
6896
          {
 
6897
            /*
 
6898
             * To print out the bitset in tab->keys, we go through
 
6899
             * it 32 bits at a time. We need to do this to ensure
 
6900
             * that the to_ulong() method will not throw an
 
6901
             * out_of_range exception at runtime which would happen
 
6902
             * if the bitset we were working with was larger than 64
 
6903
             * bits on a 64-bit platform (for example).
 
6904
             */
 
6905
            stringstream s, w;
 
6906
            string str;
 
6907
            w << tab->keys;
 
6908
            w >> str;
 
6909
            for (uint32_t pos= 0; pos < tab->keys.size(); pos+= 32)
 
6910
            {
 
6911
              bitset<32> tmp(str, pos, 32);
 
6912
              if (tmp.any())
 
6913
                s << uppercase << hex << tmp.to_ulong();
 
6914
            }
 
6915
            extra.append(STRING_WITH_LEN("; Range checked for each "
 
6916
                                         "record (index map: 0x"));
 
6917
            extra.append(s.str().c_str());
 
6918
            extra.append(')');
 
6919
          }
 
6920
          else if (tab->select->cond)
 
6921
          {
 
6922
            extra.append(STRING_WITH_LEN("; Using where"));
 
6923
          }
 
6924
        }
 
6925
        if (key_read)
 
6926
        {
 
6927
          if (quick_type == QUICK_SELECT_I::QS_TYPE_GROUP_MIN_MAX)
 
6928
            extra.append(STRING_WITH_LEN("; Using index for group-by"));
 
6929
          else
 
6930
            extra.append(STRING_WITH_LEN("; Using index"));
 
6931
        }
 
6932
        if (table->reginfo.not_exists_optimize)
 
6933
          extra.append(STRING_WITH_LEN("; Not exists"));
 
6934
 
 
6935
        if (table_list->schema_table &&
 
6936
            table_list->schema_table->getRequestedObject() & OPTIMIZE_I_S_TABLE)
 
6937
        {
 
6938
          if (!table_list->table_open_method)
 
6939
            extra.append(STRING_WITH_LEN("; Skip_open_table"));
 
6940
          else if (table_list->table_open_method == OPEN_FRM_ONLY)
 
6941
            extra.append(STRING_WITH_LEN("; Open_frm_only"));
 
6942
          else
 
6943
            extra.append(STRING_WITH_LEN("; Open_full_table"));
 
6944
          if (table_list->has_db_lookup_value &&
 
6945
              table_list->has_table_lookup_value)
 
6946
            extra.append(STRING_WITH_LEN("; Scanned 0 databases"));
 
6947
          else if (table_list->has_db_lookup_value ||
 
6948
                   table_list->has_table_lookup_value)
 
6949
            extra.append(STRING_WITH_LEN("; Scanned 1 database"));
 
6950
          else
 
6951
            extra.append(STRING_WITH_LEN("; Scanned all databases"));
 
6952
        }
 
6953
        if (need_tmp_table)
 
6954
        {
 
6955
          need_tmp_table=0;
 
6956
          extra.append(STRING_WITH_LEN("; Using temporary"));
 
6957
        }
 
6958
        if (need_order)
 
6959
        {
 
6960
          need_order=0;
 
6961
          extra.append(STRING_WITH_LEN("; Using filesort"));
 
6962
        }
 
6963
        if (distinct & test_all_bits(used_tables,session->used_tables))
 
6964
          extra.append(STRING_WITH_LEN("; Distinct"));
 
6965
 
 
6966
        if (tab->insideout_match_tab)
 
6967
        {
 
6968
          extra.append(STRING_WITH_LEN("; LooseScan"));
 
6969
        }
 
6970
 
 
6971
        for (uint32_t part= 0; part < tab->ref.key_parts; part++)
 
6972
        {
 
6973
          if (tab->ref.cond_guards[part])
 
6974
          {
 
6975
            extra.append(STRING_WITH_LEN("; Full scan on NULL key"));
 
6976
            break;
 
6977
          }
 
6978
        }
 
6979
 
 
6980
        if (i > 0 && tab[-1].next_select == sub_select_cache)
 
6981
          extra.append(STRING_WITH_LEN("; Using join buffer"));
 
6982
 
 
6983
        /* Skip initial "; "*/
 
6984
        const char *str= extra.ptr();
 
6985
        uint32_t len= extra.length();
 
6986
        if (len)
 
6987
        {
 
6988
          str += 2;
 
6989
          len -= 2;
 
6990
        }
 
6991
        item_list.push_back(new Item_string(str, len, cs));
 
6992
      }
 
6993
      // For next iteration
 
6994
      used_tables|=table->map;
 
6995
      if (result->send_data(item_list))
 
6996
        join->error= 1;
 
6997
    }
 
6998
  }
 
6999
  for (Select_Lex_Unit *unit= join->select_lex->first_inner_unit();
 
7000
       unit;
 
7001
       unit= unit->next_unit())
 
7002
  {
 
7003
    if (mysql_explain_union(session, unit, result))
 
7004
      return;
 
7005
  }
 
7006
  return;
 
7007
}
 
7008
 
 
7009
bool mysql_explain_union(Session *session, Select_Lex_Unit *unit, select_result *result)
 
7010
{
 
7011
  bool res= false;
 
7012
  Select_Lex *first= unit->first_select();
 
7013
 
 
7014
  for (Select_Lex *sl= first;
 
7015
       sl;
 
7016
       sl= sl->next_select())
 
7017
  {
 
7018
    // drop UNCACHEABLE_EXPLAIN, because it is for internal usage only
 
7019
    uint8_t uncacheable= (sl->uncacheable & ~UNCACHEABLE_EXPLAIN);
 
7020
    sl->type= (((&session->lex->select_lex)==sl)?
 
7021
               (sl->first_inner_unit() || sl->next_select() ?
 
7022
                "PRIMARY" : "SIMPLE"):
 
7023
               ((sl == first)?
 
7024
                ((sl->linkage == DERIVED_TABLE_TYPE) ?
 
7025
                 "DERIVED":
 
7026
                 ((uncacheable & UNCACHEABLE_DEPENDENT) ?
 
7027
                  "DEPENDENT SUBQUERY":
 
7028
                  (uncacheable?"UNCACHEABLE SUBQUERY":
 
7029
                   "SUBQUERY"))):
 
7030
                ((uncacheable & UNCACHEABLE_DEPENDENT) ?
 
7031
                 "DEPENDENT UNION":
 
7032
                 uncacheable?"UNCACHEABLE UNION":
 
7033
                 "UNION")));
 
7034
    sl->options|= SELECT_DESCRIBE;
 
7035
  }
 
7036
  if (unit->is_union())
 
7037
  {
 
7038
    unit->fake_select_lex->select_number= UINT_MAX; // jost for initialization
 
7039
    unit->fake_select_lex->type= "UNION RESULT";
 
7040
    unit->fake_select_lex->options|= SELECT_DESCRIBE;
 
7041
    if (!(res= unit->prepare(session, result, SELECT_NO_UNLOCK | SELECT_DESCRIBE)))
 
7042
      res= unit->exec();
 
7043
    res|= unit->cleanup();
 
7044
  }
 
7045
  else
 
7046
  {
 
7047
    session->lex->current_select= first;
 
7048
    unit->set_limit(unit->global_parameters);
 
7049
    res= mysql_select(session, &first->ref_pointer_array,
 
7050
                        (TableList*) first->table_list.first,
 
7051
                        first->with_wild, first->item_list,
 
7052
                        first->where,
 
7053
                        first->order_list.elements +
 
7054
                        first->group_list.elements,
 
7055
                        (order_st*) first->order_list.first,
 
7056
                        (order_st*) first->group_list.first,
 
7057
                        first->having,
 
7058
                        first->options | session->options | SELECT_DESCRIBE,
 
7059
                        result, unit, first);
 
7060
  }
 
7061
  return(res || session->is_error());
 
7062
}
6540
7063
 
6541
7064
static void print_table_array(Session *session, String *str, TableList **table,
6542
7065
                              TableList **end)
6702
7225
/**
6703
7226
  @} (end of group Query_Optimizer)
6704
7227
*/
6705
 
 
6706
 
} /* namespace drizzled */