~ubuntu-branches/ubuntu/trusty/drizzle/trusty

« back to all changes in this revision

Viewing changes to drizzled/optimizer/access_method/scan.cc

  • Committer: Bazaar Package Importer
  • Author(s): Monty Taylor
  • Date: 2010-10-02 14:17:48 UTC
  • mfrom: (1.1.1 upstream)
  • mto: (2.1.17 sid)
  • mto: This revision was merged to the branch mainline in revision 3.
  • Revision ID: james.westby@ubuntu.com-20101002141748-m6vbfbfjhrw1153e
Tags: 2010.09.1802-1
* New upstream release.
* Removed pid-file argument hack.
* Updated GPL-2 address to be new address.
* Directly copy in drizzledump.1 since debian doesn't have sphinx 1.0 yet.
* Link to jquery from libjs-jquery. Add it as a depend.
* Add drizzled.8 symlink to the install files.

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/* -*- mode: c++; c-basic-offset: 2; indent-tabs-mode: nil; -*-
 
2
 *  vim:expandtab:shiftwidth=2:tabstop=2:smarttab:
 
3
 *
 
4
 *  Copyright (C) 2010 Padraig O'Sullivan
 
5
 *
 
6
 *  This program is free software; you can redistribute it and/or modify
 
7
 *  it under the terms of the GNU General Public License as published by
 
8
 *  the Free Software Foundation; either version 2 of the License, or
 
9
 *  (at your option) any later version.
 
10
 *
 
11
 *  This program is distributed in the hope that it will be useful,
 
12
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 
13
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 
14
 *  GNU General Public License for more details.
 
15
 *
 
16
 *  You should have received a copy of the GNU General Public License
 
17
 *  along with this program; if not, write to the Free Software
 
18
 *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
 
19
 */
 
20
 
 
21
#include "config.h"
 
22
#include "drizzled/session.h"
 
23
#include "drizzled/join_table.h"
 
24
#include "drizzled/table.h"
 
25
#include "drizzled/sql_select.h"
 
26
#include "drizzled/internal/my_sys.h"
 
27
#include "drizzled/optimizer/access_method/scan.h"
 
28
 
 
29
using namespace drizzled;
 
30
 
 
31
static uint32_t make_join_orderinfo(Join *join);
 
32
 
 
33
bool optimizer::Scan::getStats(Table *table,
 
34
                               JoinTable *join_tab)
 
35
{
 
36
  Join *join= join_tab->join;
 
37
  bool statistics= test(! (join->select_options & SELECT_DESCRIBE));
 
38
  uint64_t options= (join->select_options &
 
39
                     (SELECT_DESCRIBE | SELECT_NO_JOIN_CACHE)) |
 
40
                     (0);
 
41
  uint32_t no_jbuf_after= make_join_orderinfo(join);
 
42
  uint32_t index= join_tab - join->join_tab;
 
43
 
 
44
  /*
 
45
   * If previous table use cache
 
46
   * If the incoming data set is already sorted don't use cache.
 
47
   */
 
48
  table->status= STATUS_NO_RECORD;
 
49
 
 
50
  if (index != join->const_tables && 
 
51
      ! (options & SELECT_NO_JOIN_CACHE) &&
 
52
      join_tab->use_quick != 2 && 
 
53
      ! join_tab->first_inner && 
 
54
      index <= no_jbuf_after &&
 
55
      ! join_tab->insideout_match_tab)
 
56
  {
 
57
    if ((options & SELECT_DESCRIBE) ||
 
58
        ! join_init_cache(join->session,
 
59
                          join->join_tab + join->const_tables,
 
60
                          index - join->const_tables))
 
61
    {
 
62
      join_tab[-1].next_select= sub_select_cache; /* Patch previous */
 
63
    }
 
64
  }
 
65
 
 
66
  /* These init changes read_record */
 
67
  if (join_tab->use_quick == 2)
 
68
  {
 
69
    join->session->server_status|= SERVER_QUERY_NO_GOOD_INDEX_USED;
 
70
    join_tab->read_first_record= join_init_quick_read_record;
 
71
    if (statistics)
 
72
    {
 
73
      join->session->status_var.select_range_check_count++;
 
74
    }
 
75
  }
 
76
  else
 
77
  {
 
78
    join_tab->read_first_record= join_init_read_record;
 
79
    if (index == join->const_tables)
 
80
    {
 
81
      if (join_tab->select && join_tab->select->quick)
 
82
      {
 
83
        if (statistics)
 
84
        {
 
85
          join->session->status_var.select_range_count++;
 
86
        }
 
87
      }
 
88
      else
 
89
      {
 
90
        join->session->server_status|= SERVER_QUERY_NO_INDEX_USED;
 
91
        if (statistics)
 
92
        {
 
93
          join->session->status_var.select_scan_count++;
 
94
        }
 
95
      }
 
96
    }
 
97
    else
 
98
    {
 
99
      if (join_tab->select && join_tab->select->quick)
 
100
      {
 
101
        if (statistics)
 
102
        {
 
103
          join->session->status_var.select_full_range_join_count++;
 
104
        }
 
105
      }
 
106
      else
 
107
      {
 
108
        join->session->server_status|= SERVER_QUERY_NO_INDEX_USED;
 
109
        if (statistics)
 
110
        {
 
111
          join->session->status_var.select_full_join_count++;
 
112
        }
 
113
      }
 
114
    }
 
115
    if (! table->no_keyread)
 
116
    {
 
117
      if (join_tab->select && 
 
118
          join_tab->select->quick &&
 
119
          join_tab->select->quick->index != MAX_KEY && //not index_merge
 
120
          table->covering_keys.test(join_tab->select->quick->index))
 
121
      {
 
122
        table->key_read= 1;
 
123
        table->cursor->extra(HA_EXTRA_KEYREAD);
 
124
      }
 
125
      else if (! table->covering_keys.none() &&
 
126
               ! (join_tab->select && join_tab->select->quick))
 
127
      { // Only read index tree
 
128
        if (! join_tab->insideout_match_tab)
 
129
        {
 
130
          /*
 
131
             See bug #26447: "Using the clustered index for a table scan
 
132
             is always faster than using a secondary index".
 
133
           */
 
134
          if (table->getShare()->hasPrimaryKey() &&
 
135
              table->cursor->primary_key_is_clustered())
 
136
          {
 
137
            join_tab->index= table->getShare()->getPrimaryKey();
 
138
          }
 
139
          else
 
140
          {
 
141
            join_tab->index= table->find_shortest_key(&table->covering_keys);
 
142
          }
 
143
        }
 
144
        join_tab->read_first_record= join_read_first;
 
145
        join_tab->type= AM_NEXT; // Read with index_first / index_next
 
146
      }
 
147
    }
 
148
  }
 
149
 
 
150
  return false;
 
151
}
 
152
 
 
153
/**
 
154
  Determine if the set is already ordered for order_st BY, so it can
 
155
  disable join cache because it will change the ordering of the results.
 
156
  Code handles sort table that is at any location (not only first after
 
157
  the const tables) despite the fact that it's currently prohibited.
 
158
  We must disable join cache if the first non-const table alone is
 
159
  ordered. If there is a temp table the ordering is done as a last
 
160
  operation and doesn't prevent join cache usage.
 
161
*/
 
162
static uint32_t make_join_orderinfo(Join *join)
 
163
{
 
164
  uint32_t i= 0;
 
165
  if (join->need_tmp)
 
166
  {
 
167
    return join->tables;
 
168
  }
 
169
 
 
170
  for (i= join->const_tables ; i < join->tables ; i++)
 
171
  {
 
172
    JoinTable *tab= join->join_tab + i;
 
173
    Table *table= tab->table;
 
174
    if ((table == join->sort_by_table &&
 
175
        (! join->order || join->skip_sort_order)) ||
 
176
        (join->sort_by_table == (Table *) 1 &&  i != join->const_tables))
 
177
    {
 
178
      break;
 
179
    }
 
180
  }
 
181
  return i;
 
182
}